Jump to content
Developer Wiki and Function Reference Links ×

Resetting multiple pio's


Hippocode

Recommended Posts

I know its limited but I would like to trigger a chain reset on X objects from one object.

Basicly PIO 1 has a linked ID from PIO 2 and so on.

My loop in PIO 1 changes a field of PIO 2 and so on ( recursive loop ). All the resets are called trough PIO 1.

All of that works but not the reset part,

The resetting works BUT there is no redraw of the pio with the new values. I've tried resetobject(), hmove and hrotate to trigger a reset redraw but none of them respond.

Edited by hippothamus
Link to comment
  • Vectorworks, Inc Employee

There are several problems calling reset from Vectorscript

1) You can not control the order of the reset.

2) The reset is not immediate.

3) There is a limit the the number of nested resets.

The way the system works in Vectorscript is that when you call ResetObject() from a script the object is marked for reset. Once the script completes the object is actually reset. Objects are reset in the order they were created, not the order you asked for them to be reset.

There is also a limit the the number of iterations that can be done to prevent looping and other runaway situations.

A can reset B without a problem but you won't see the results on B till after the script A complete and the script in B completes. So Script A can't depend on the results of Script B.

A can reset B and B can reset C but there is a limit to this chain.

You want to make sure B doesn't reset A, and C never resets A or B.

The best way to code is to have A reset objects B and C.

Link to comment

It seems I was a bit wrong in my first post.

The resetting works, but there is no redraw done, not even in the first following object. I know they all have reset because the pio shows the new correct calculated fields.

The first object is the one resetting all the others as you mentioned, this made it easier to script.

I've tried using redraw;, redrawall; and redrawselectio;n but none of them seem to have any influence.

Any other way I can force it ?

Edited by hippothamus
Link to comment

It seems Ive all been wrong about it .

The objects do get reset AND redrawn. However, they don't use the new "in-object-calculated-params" to form the object which is weird because they are being calculated AND changed.

Can someone explain me how the script in the pio is reset, the values are changed yet on drawing it seems to use the older values.

PROCEDURE TakReset(h:HANDLE);
VAR
MasterId	:STRING;
BEGIN
ResetObject(h);
MasterId:=GetRField(h,Objname,'pMasterID');
IF (MasterId <> '') AND (GetObject(MasterId) <> NIL) THEN TakReset(GetObject(Masterid));
END;

Edited by hippothamus
Link to comment

A few things:

Forgive me for stating the obvious, but do your slave objects display properly when you manually change a parameter or force a rgen (for example change the class)?

SetRField / GetRField should use the universal parameter name without the "P". Only use the P for handling the parameter value as a constant.

For all intents and purposes, the P value is a constant for each regen -- it will not change after a SetRField.

I'm a little confused as to why you use a recursive procedure. Without knowing more about your plug-ins, if you pass this a handle to a slave, it will regen itself, then regen the master and then stop. If you pass a handle to the master, it will just be an endless loop. Instead, why not use:

ForEachObject( ResetObject, ObjectName.'MasterID' = MasterID);

You can add checks to make sure the master doesn't necessarily reset itself. Often object events are the key to making master slave relationships run the smoothest.

HTH,

Josh

Link to comment
A few things:

Forgive me for stating the obvious, but do your slave objects display properly when you manually change a parameter or force a rgen (for example change the class)?

Yes it works properly.

SetRField / GetRField should use the universal parameter name without the "P". Only use the P for handling the parameter value as a constant.

For all intents and purposes, the P value is a constant for each regen -- it will not change after a SetRField.

That p is in the parametername, I know its not captain logic but in my script I load the Parameter with 2p"s upfront :)

I'm a little confused as to why you use a recursive procedure. Without knowing more about your plug-ins, if you pass this a handle to a slave, it will regen itself, then regen the master and then stop. If you pass a handle to the master, it will just be an endless loop. Instead, why not use:

ForEachObject( ResetObject, ObjectName.'MasterID' = MasterID);

The direction is opposite, I start with a slave which will find it's master, and the master for each found master. The loop isn't endless, it'll just reach the last master in the selected chain and stop.

I'm actually using foreachobject to find the first master (although there can only be one master for an object), the above mentioned function is the recursive function used in the foreachobject loop so it finds the master of each found master.

You can add checks to make sure the master doesn't necessarily reset itself. Often object events are the key to making master slave relationships run the smoothest.

HTH,

Josh

I'm using events, this chain is only allowed on a certain parameter change in a slave object to prevent my objects from updating constantly.

Why I need that calculation is because its a MEP tool. A master needs to SUM the flow of each of his slaves to calculate its dimensions. The master might be a slave for another master and so on.

If I change a flow parameter at the beginning of a chain, the whole chain needs to recalculate its flow for each segment. This part works, only, the reset-drawing-part seems to happen with the old parameter value as if the draw-resets happen before the recalculation which is weird in my opinion.

Working example

flow @ beginchain is y.

If I now change it to X, each new segment uses X in its flow total (is updates in each infopalette), but it uses Y to draw.

If I now change X to Z, each new segment uses Z in its flow total, but it now uses X to draw.

Each time the previous value :/

Here is the full resetting function:

PROCEDURE UpdateObject(h:HANDLE);
VAR
DBSubCrit	:STRING;

FUNCTION NeedsRedraw(a:STRING):BOOLEAN;
VAR
	OutWidgetID	:LONGINT;
	OutParamIndex	:INTEGER;
	OutOldValue	:STRING;
BEGIN
	IF vsoStateGetParamChng(ObjHd, OutWidgetID, OutParamIndex, OutOldValue) THEN BEGIN
		IF 
		(OutParamIndex=kp_pType) OR 
		(OutParamIndex=kp_pFlowRate) OR
		(OutParamIndex=kp_pMaxAirSpeed) OR
		(OutParamIndex=kp_pOD1) OR
		(OutParamIndex=kp_pOD2) OR
		(OutParamIndex=kp_pMasterID) OR
		(OutParamIndex=kp_pSymbolID)
		THEN NeedsRedraw:=TRUE;
	END;
END;

PROCEDURE TakReset(h:HANDLE);
VAR
	MasterId	:STRING;
BEGIN
	ResetObject(h);

	MasterId:=GetRField(h,Objname,'pMasterID');
	IF (MasterId <> '') AND (GetObject(MasterId) <> NIL) THEN TakReset(GetObject(Masterid));
END;
BEGIN
Result:=NeedsRedraw('dummy');
IF Result THEN BEGIN
	TakReset(h);
END;

END;


DBCrit:=concat('(',LayerCriteria,'(PON=',Chr(39),ObjName,Chr(39),') & (n=',Chr(39),pMasterID,Chr(39),'))');
a_Out:= COUNT(DBCrit);
IF a_Out = 1 THEN BEGIN
ForEachObject(UpdateObject, DBCrit);
pStatusOutx:=concat('ACTIEF');
END
ELSE pStatusOutx:=concat('-----');

Edited by hippothamus
Link to comment

I suspect your issue is that your recursive loop isn't iterating over your objects as you expect. Generally, the master controls the slave object, so your nomenclature may be getting in the way of our ability to advise.

Can you go into specifics as to what these drawing objects are and how they should relate?

Also, a simple test would be to select one of your un-updated objects and run ResetObject(FSActLayer). If it now looks right, it isn't being touches by your reset loop.

And as a side note, I usually SetRField and ResetObject in the same code sequence (perhaps you just edited out lines)

-Josh

Link to comment
I suspect your issue is that your recursive loop isn't iterating over your objects as you expect. Generally, the master controls the slave object, so your nomenclature may be getting in the way of our ability to advise.

Can you go into specifics as to what these drawing objects are and how they should relate?

Its a HVAC 3D duct. Segments connect automaticly when drawing the begin vertex of one segment on the end vertex of another. This allows me to make easy editable "chains" in one direction.

The size of a segment depends on the air flow rate, so a master collects the flow of each of his slaves and uses the total to calculate its dimensions. A master object can also be a slave object and so on.

When updating the flow of a segment, the masted needs to update his total. I'm trying to automate the whole chain when something changes afterwards. This works for the calculation part because the chain updates fully "flow-wise" but doesn't redraw with the new flow value.

Also, a simple test would be to select one of your un-updated objects and run ResetObject(FSActLayer). If it now looks right, it isn't being touches by your reset loop.

It now looks right. But if it hasn't been touched by the reset loop then how do you explain the flow parameter is correctly updated before I run this resetfunction from the palette ?

And as a side note, I usually SetRField and ResetObject in the same code sequence (perhaps you just edited out lines)

-Josh

Didn't edit anything out. The object that triggers the reset of all other objects only needs GetRField to load the "name" of the following object.

Link to comment

I've added a picture explaining the chain. A connection is made by adding the unique name of the master into a paramfield of a slave.

The red dots are "connectionpoints". Paint skilled arrows is the direction of the chain.

flow Master A = slave A1 + Slave A2

flow Master B = Master A + Slave B2

When updating slave A2 I want MAster A to update, and the other connected masters in this chain. In this example Master A and Master B

Edited by hippothamus
Link to comment

This image might be better to understand:

All the slaves have a flow of 100.

This means that

flow Master A = 200

flow Master B = 300

If we go to the image below I've changed the flow of slave A to 500. Both master A and B now update and reflect their new flowrate being

flow Master A = 600

flow Master B = 700

This can be read from the object infopalette.

What you can see on the image is that master A and B don't change size while they should ( see slave A got bigger). I can't think of the loop not working because the flow rates have been updated in each master, so why don't they redraw with these values..

Edited by hippothamus
Link to comment

Ok, thanks for the further explanation. I would say that instead of using the terms

"master" and "slave," you really mean "upstream" and "downstream." The master doesn't necessarily control the slave (which is what the terms imply), it just provides information on where to look to gather data.

If I'm understanding correctly, each object does its own calculations. The alternative would be for the master objects to do all the calculations and set data in the slave objects. I touched on this before, but I think your issue is how you store / retrieve calculated data.

PParam values are basically constants for the run of your script. For calculated fields, load the parameter value into a variable. Set the variable to any calculated values, and use it to draw your objects. Store the data with SetRField at the end of the script.

Your description leads me to believe you are drawing the object based on the constant values, which wouldn't update until the next run of the script.

Think about the object record like a disk file. Read the file data into memory at the beginning of the script (PParam and GetRField are reads), calculate and draw, then write to disk at the end (SetRfield).

-Josh

Link to comment
Ok, thanks for the further explanation. I would say that instead of using the terms

"master" and "slave," you really mean "upstream" and "downstream." The master doesn't necessarily control the slave (which is what the terms imply), it just provides information on where to look to gather data.

jup. A simple UID-link.

If I'm understanding correctly, each object does its own calculations. The alternative would be for the master objects to do all the calculations and set data in the slave objects. I touched on this before, but I think your issue is how you store / retrieve calculated data.

Right now its the other way around, each master sums the total of it's slaves, draws the object and resets its own flow parameter.

PParam values are basically constants for the run of your script. For calculated fields, load the parameter value into a variable. Set the variable to any calculated values, and use it to draw your objects. Store the data with SetRField at the end of the script.

This is indeed how it works.

Your description leads me to believe you are drawing the object based on the constant values, which wouldn't update until the next run of the script.

I understand what you are trying to say, but if that's true how come my flow parameters to be correct in each following segment. If they updated correctly ( which is calculated and reset trough each segment ) why hasn't it been drawn that way..

Anyway, it shouldn't be so hard adding the calculation in the object that resets the whole stream, save it in each segment with SetRField and reset them. I think that would solve it. just more coding :)

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...