VS:Mirror: Difference between revisions

From Vectorworks Developer
Jump to navigation Jump to search
(Add info about failures)
m (Transfer Orso to _c_)
Line 1: Line 1:
{{LocationMain|category=LocationVS|specific=}}
__TOC__
<vwDoc>
-----------------------------------------------------------------------------------------------------------
<desc>
Calls a user defined procedure to operate on each object matching the specified search criteria.
The procedure subroutine specified by the callback parameter must have one parameter of type HANDLE, which is passed the handle to an object by the ForEachObject call.
</desc>
-----------------------------------------------------------------------------------------------------------
<def>
<funcDef lang="vs">
PROCEDURE ForEachObject(callback:PROCEDURE; c:CRITERIA);
</funcDef>
<funcDef lang="py">
def vs.ForEachObject(callback, c):
    return None
</funcDef>
</def>
-----------------------------------------------------------------------------------------------------------
<params>
<lineList ident=1>
<line>
callback
PROCEDURE
Name of action procedure to be applied to matching objects
</line>
<line>
c
CRITERIA
Search criteria for locating objects.
</line>
</lineList>
</params>
-----------------------------------------------------------------------------------------------------------
<remark>


[[User:CBM-c-|_c_]] (2016.05.14): Pay attention how you place your brakets while using criteria strings through variables. Extra brakets might not work and never return errors:
<code lang="pas">
{{LocationMain|category=LocationVS|specific=}}
{{LocationMain|category=LocationVS|specific=}}
__TOC__
__TOC__
Line 53: Line 96:
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
<remark>
<remark>
([[User:Orso.b.schmid|Orso]], 2019.11.09) This doesn't support Groups and is unpredictable on 3D objects
[[User:CBM-c-|_c_]] (2019.11.09) This doesn't support Groups and is unpredictable on 3D objects


</remark>
</remark>
Line 73: Line 116:
[[Category:VS Function Reference|Mirror]]
[[Category:VS Function Reference|Mirror]]
[[Category:VS Function Reference:Object Editing|Mirror]]
[[Category:VS Function Reference:Object Editing|Mirror]]
recordName := 'Part Info'; { needs single quotes because of the space }
criteria = Concat('((R in [', '''', recordName, '''', ']))'); { wrap in single quotes }
ForEachObject(ProcThatTakesAHandle, criteria);  { works fine }
ForEachObject(ProcThatTakesAHandle, (criteria));  { doesn't work }
</code>
(Others)
Don't use DelObject inside a ForEachObject callback.
Essentially, ForEachObject is roughly equivalent to
<code lang="pas">
h := FObject;
WHILE h &lt;&gt; NIL DO BEGIN
{do something}
h := NextObj(h);
END;
</code>
The only difference is that ForEachObject is handling the looping for you, and providing a convenient mechanism for filtering the objects by criteria.
Now, if you're deleting h inside that loop, the NextObj call is going to fail miserably. Doing anything that will alter the sequence of entities in the drawing list, inside a loop that walks the drawing list, will produce unexpected results. This includes creating objects, deleting objects, changing the layer of an object, or changing the stacking order ([[VS:HMoveForward]], [[VS:HMoveBackward]]). This will be true if you are walking the drawing list explicitly (using NextObj), or implicitly (using [[VS:ForEachObject]], [[VS:ForEachObjectInLayer]], or [[VS:ForEachObjectInList]]).
So use ForEachObject just to build a handle array. Then go back and iterate through the handles, and delete the ones you don't like.
[[User:Rgm|Rgm]] [2012.11.21]:
Note that you can pass in a string for the c:CRITERIA parameter. This appears to be the best way to use variable criteria, e.g.:
<code lang="pas">
recordName := 'Part Info'; { literal, or maybe the value of a function }
criteria = Concat('((R in [', '''', recordName, '''', ']))'); { '''' gives a single quote when parsed }
ForEachObject(ProcThatTakesAHandle, criteria);
</code>
</remark>
-----------------------------------------------------------------------------------------------------------
<sample>
<code lang="pas">
PROCEDURE PickRect;
    PROCEDURE SelectThem(h :HANDLE);
    BEGIN
        SetSelect(h);
    END;
BEGIN
  ForEachObject(SelectThem, "T=RECT");
END;
RUN(PickRect);
</code>
Python:
<code lang="py">
import vs
def SelectThem(h):
vs.AlrtDialog( "we're in" + str(h))
vs.AlrtDialog( 'should show three consecutive dialogs' )
vs.ForEachObject( SelectThem, "T=WALL" )
</code>
</sample>
-----------------------------------------------------------------------------------------------------------
<version>
Availability: from All Versions
</version>
</vwDoc>
[[Category:VS Function Reference|ForEachObject]]
[[Category:VS Function Reference:Criteria|ForEachObject]]

Revision as of 07:52, 30 December 2020

.VectorScript|VectorScript ..VS:Function Reference|Function Reference ..VS:Function_Reference_Appendix|Appendix

Description

Calls a user defined procedure to operate on each object matching the specified search criteria.

The procedure subroutine specified by the callback parameter must have one parameter of type HANDLE, which is passed the handle to an object by the ForEachObject call.

PROCEDURE ForEachObject(
callback :PROCEDURE;
c :CRITERIA);
def vs.ForEachObject(callback, c):
    return None

Parameters

callback PROCEDURE Name of action procedure to be applied to matching objects
c CRITERIA Search criteria for locating objects.

Return Value

The reflected object (this will be the same as the input object if dup is false).

Remarks

_c_ (2016.05.14): Pay attention how you place your brakets while using criteria strings through variables. Extra brakets might not work and never return errors:

.VectorScript|VectorScript ..VS:Function Reference|Function Reference ..VS:Function_Reference_Appendix|Appendix

<vwDoc>


<desc> Reflect an object across an axis.

For a 2D reflection, the axis is a line containing arbitrary point p and extending along vector v.</desc>


<def>

FUNCTION Mirror(
h :HANDLE;
dup :BOOLEAN;
p1 :POINT;
p2 :POINT) : HANDLE;
def vs.Mirror(h, dup, p1, p2):
    return HANDLE

</def>


<params>

h HANDLE The object to reflect
dup BOOLEAN If false, transform the original object to the new position. If true, create a new object
p1 POINT An arbitrary point on the mirror axis
p2 POINT A second arbitrary point on the mirror axis

</params>


<return></return>


<remark> _c_ (2019.11.09) This doesn't support Groups and is unpredictable on 3D objects

Version

Availability: from Vectorworks 2017


recordName := 'Part Info'; { needs single quotes because of the space } criteria = Concat('((R in [', ', recordName, ', ']))'); { wrap in single quotes } ForEachObject(ProcThatTakesAHandle, criteria); { works fine } ForEachObject(ProcThatTakesAHandle, (criteria)); { doesn't work }


(Others) Don't use DelObject inside a ForEachObject callback.

Essentially, ForEachObject is roughly equivalent to

h := FObject;
WHILE h <> NIL DO BEGIN
{do something}
h := NextObj(h);
END;

The only difference is that ForEachObject is handling the looping for you, and providing a convenient mechanism for filtering the objects by criteria.

Now, if you're deleting h inside that loop, the NextObj call is going to fail miserably. Doing anything that will alter the sequence of entities in the drawing list, inside a loop that walks the drawing list, will produce unexpected results. This includes creating objects, deleting objects, changing the layer of an object, or changing the stacking order (VS:HMoveForward, VS:HMoveBackward). This will be true if you are walking the drawing list explicitly (using NextObj), or implicitly (using VS:ForEachObject, VS:ForEachObjectInLayer, or VS:ForEachObjectInList).

So use ForEachObject just to build a handle array. Then go back and iterate through the handles, and delete the ones you don't like.

Rgm [2012.11.21]: Note that you can pass in a string for the c:CRITERIA parameter. This appears to be the best way to use variable criteria, e.g.:

recordName := 'Part Info'; { literal, or maybe the value of a function }
criteria = Concat('((R in [', '''', recordName, '''', ']))'); { '''' gives a single quote when parsed }
ForEachObject(ProcThatTakesAHandle, criteria); 

</remark>


<sample>

PROCEDURE PickRect;

    PROCEDURE SelectThem(h :HANDLE);
    BEGIN
        SetSelect(h);
    END;

BEGIN
   ForEachObject(SelectThem, "T=RECT");
END;
RUN(PickRect);

Python:

import vs

def SelectThem(h):
	vs.AlrtDialog( "we're in" + str(h))

vs.AlrtDialog( 'should show three consecutive dialogs' )
vs.ForEachObject( SelectThem, "T=WALL" )

</sample>


<version> Availability: from All Versions

</version>

</vwDoc>