Jump to content
The Hamma

Script affecting objects selected on Sheet Layers when in design layer

Recommended Posts

I need some help.  Apparently this script is editing objects that are selected on sheet layers even though the sheet layer is not active.  Does anyone know how to limit the selection to just the viewable and editable layers.  I thought about using ForEachObjectInLayer but it does not work for symbols and PIO in walls. 

 

"""
This script assigns selected objects to class "1_Exist-(original class)" and set Construction Phase to 'EXISTING TO REMAIN'.

If a in wall object is selected without selecting the wall the script will only change those in wall objects.
If a wall is selected it will change the wall and all objects inserted in that wall.
If New class does not exist objects original class is duplicated to retain class attributes.

To take full advantage of this script use "Data Visualization" to display the "Construction Phase"
  record objects as desired.
     1. Set "Data Visualization" to modify drawings per "Construction Phase" record
     2. To make a "Construction Phase" invisible set the attributes of that phase to:
           Line settings to Fill "Solid White" and Line weight "0"

This Python Script may be freely distributed. No warranty provided.
Use at your own risk.

Vectorworks bug does not show changes to symbols inserted in wall until either:
   Drawing is saved and reopened.
   Setting in Data Visualization dialog is changed.
   Symbol is removed from wall, can then be reinserted

David Hamer, 2020
"""


# Modifications to any objects happen here
def assign(h):
    CName = vs.GetClass(h)
    CLen = vs.Len(CName)
    CNameE = vs.Copy(CName, 1, 8)  # Grab First 8 letters of handle's class
    CNameD = vs.Copy(CName, 1, 7)  # Grab First 7 letters of handle's class
    if CNameD == '2_Demo-':  # Check if first 7 letters equal '2_Demo-'
        CName = vs.Copy(CName, 8, CLen)  # if true grab root name of class
    # check if the class is new, if so delete new class and duplicate objects class and rename.
    if CNameE == '1_Exist-':
        CNameN = CName
    else:
        CNameN = vs.Concat('1_Exist-', CName)  # If not add '1_Exist-' to name
    ClassCount = vs.ClassNum()  # determine number of classes in drawing
    vs.NameClass(CNameN)  # set the name of the class to be applied to handle if new class will be created
    if ClassCount + 1 == vs.ClassNum():  # check if the class is new and if delete new class and duplicate source
        vs.ReDraw()
        vs.DelClass(CNameN)  # Delete new class
        CHandle = vs.GetObject(CName)  # get handle to source class
        NDCHandle = vs.CreateDuplicateObject(CHandle, vs.GetParent(CHandle))  # duplicate source class
        vs.SetName(NDCHandle, CNameN)  # rename duplicate class to name to be applied to handle
        vs.ResetObject(NDCHandle)
        vs.ResetObject(h)
    vs.SetClass(h, CNameN)  # name handle's class
    vs.SetRecord(h, 'Construction Phase')  # add record to inserted object
    vs.SetRField(h, 'Construction Phase', 'Phase', 'EXISTING TO REMAIN')  # modify record to inserted object


# Passes Handle to "def assign(h):" of PIO or Symbol selected
def pio_processing(h):
    global container  # declare global variable to be retained
    assign(h)  # Runs "def assign(h):"
    hParent = vs.GetParent(h)  # Get Parent handle
    itParent = vs.GetTypeN(hParent)  # Get Parent type
    if itParent != []:
        if itParent == 68:  # If Parent type is a wall set container to state PIOinwallwasdetected
            container = 'PIOinwallwasdetected'
        if itParent == 89:  # If Parent type is a round wall set container to state PIOinwallwasdetected
            container = 'PIOinwallwasdetected'


# Passes Handle to "def assign(h):" of every object except PIO and Symbols outside walls selected
def object_processing(h):
    assign(h)  # Runs "def assign(h):"
    h1 = vs.FIn3D(h)
    while h1 != []:
        if vs.GetTypeN(h1) == 15:
            assign(h1)  # Runs "def assign(h):" on symbol inserted
        if vs.GetTypeN(h1) == 86:
            assign(h1)  # Runs "def assign(h):" on PIO inserted
        h1 = vs.NextObj(h1)


container = 'none'  # Declare container var
ACName = vs.ActiveClass()  # Record name of active class

if vs.GetObject('Construction Phase') == ():  # Creates "Construction Phase" record if not present
    vs.NewField('Construction Phase', 'Phase', '<none>', 4, 0)

# Passes Handle to "def pio_processing(h):" of PIO and Symbols selected
vs.ForEachObject(pio_processing, "((((T=PLUGINOBJECT)|(T=SYMBOL)) & (V) & (SEL=TRUE)))")

# Passes Handle to "def object_processing(h):" of objects selected except PIO and Symbols outside walls selected
# Skipped if PIO or Symbol selected was in wall
if container != 'PIOinwallwasdetected':
    vs.ForEachObject(object_processing, "(((T<>PLUGINOBJECT)&(T<>SYMBOL) & (V) & (VSEL=TRUE)))")

vs.NameClass(ACName)  # Return active class
 

Share this post


Link to post

I am a Pascal (Vectorscript) guy, so I am not going to try and edit your code, but I would probably just add a test for the layer type into both the pio_processing and object_processing subroutine.

 

Something like.

 

If GetObjectVariableInt(GetLayer(Handle to object), 154)=1 Then

 

Where GetLayer returns a handle to the layer the object is on and GetObjectVariableInt(154) return the type of layer with 1 being a design layer and 2 being a sheet (presentation layer in the documentation) layer.

 

HTH.

  • Like 1

Share this post


Link to post

Great Idea.  Now I can isolate it and now I can get it to run in sheet layers or veiwport annotations if they are the active layer. 

 

"""
This script assigns selected objects to class "1_Exist-(original class)" and set Construction Phase to 'EXISTING TO REMAIN'.

If a in wall object is selected without selecting the wall the script will only change those in wall objects.
If a wall is selected it will change the wall and all objects inserted in that wall.
If New class does not exist objects original class is duplicated to retain class attributes.

To take full advantage of this script use "Data Visualization" to display the "Construction Phase"
  record objects as desired.
     1. Set "Data Visualization" to modify drawings per "Construction Phase" record
     2. To make a "Construction Phase" invisible set the attributes of that phase to:
           Line settings to Fill "Solid White" and Line weight "0"

This Python Script may be freely distributed. No warranty provided.
Use at your own risk.

Vectorworks bug does not show changes to symbols inserted in wall until either:
   Drawing is saved and reopened.
   Setting in Data Visualization dialog is changed.
   Symbol is removed from wall, can then be reinserted

David Hamer, 2020
"""


# Modifications to any objects happen here
def assign(h):
    CName = vs.GetClass(h)
    CLen = vs.Len(CName)
    CNameE = vs.Copy(CName, 1, 8)  # Grab First 8 letters of handle's class
    CNameD = vs.Copy(CName, 1, 7)  # Grab First 7 letters of handle's class
    if CNameD == '2_Demo-':  # Check if first 7 letters equal '2_Demo-'
        CName = vs.Copy(CName, 8, CLen)  # if true grab root name of class
    # check if the class is new, if so delete new class and duplicate objects class and rename.
    if CNameE == '1_Exist-':
        CNameN = CName
    else:
        CNameN = vs.Concat('1_Exist-', CName)  # If not add '1_Exist-' to name
    ClassCount = vs.ClassNum()  # determine number of classes in drawing
    vs.NameClass(CNameN)  # set the name of the class to be applied to handle if new class will be created
    if ClassCount + 1 == vs.ClassNum():  # check if the class is new and if delete new class and duplicate source
        vs.ReDraw()
        vs.DelClass(CNameN)  # Delete new class
        CHandle = vs.GetObject(CName)  # get handle to source class
        NDCHandle = vs.CreateDuplicateObject(CHandle, vs.GetParent(CHandle))  # duplicate source class
        vs.SetName(NDCHandle, CNameN)  # rename duplicate class to name to be applied to handle
        vs.ResetObject(NDCHandle)
        vs.ResetObject(h)
    vs.SetClass(h, CNameN)  # name handle's class
    vs.SetRecord(h, 'Construction Phase')  # add record to inserted object
    vs.SetRField(h, 'Construction Phase', 'Phase', 'EXISTING TO REMAIN')  # modify record to inserted object


# Passes Handle to "def assign(h):" of PIO or Symbol selected
def pio_processing(h):
    global container  # declare global variable to be retained
    if vs.GetObjectVariableInt(vs.GetLayer(h), 154) == activetype:
        assign(h)  # Runs "def assign(h):"
        hParent = vs.GetParent(h)  # Get Parent handle
        itParent = vs.GetTypeN(hParent)  # Get Parent type
        if itParent != []:
            if itParent == 68:  # If Parent type is a wall set container to state PIOinwallwasdetected
                container = 'PIOinwallwasdetected'
            if itParent == 89:  # If Parent type is a round wall set container to state PIOinwallwasdetected
                container = 'PIOinwallwasdetected'


# Passes Handle to "def assign(h):" of every object except PIO and Symbols outside walls selected
def object_processing(h):
	if vs.GetObjectVariableInt(vs.GetLayer(h), 154) == activetype:
		assign(h)  # Runs "def assign(h):"
		h1 = vs.FIn3D(h)
		while h1 != []:
			if vs.GetObjectVariableInt(vs.GetLayer(h1), 154) == activetype:
				if vs.GetTypeN(h1) == 15:
					assign(h1)  # Runs "def assign(h):" on symbol inserted
				if vs.GetTypeN(h1) == 86:
					assign(h1)  # Runs "def assign(h):" on PIO inserted
			h1 = vs.NextObj(h1)

def sl_processing(h): # Omit's Viewports in Sheet Layers
	if vs.GetTypeN(h) != 122:
		assign(h) 


activetype = 1
container = 'none'  # Declare container var
ACName = vs.ActiveClass()  # Record name of active class
if vs.GetObject('Construction Phase') == ():  # Creates "Construction Phase" record if not present
	vs.NewField('Construction Phase', 'Phase', '<none>', 4, 0)
	
if vs.GetObjectVariableInt(vs.ActLayer(), 154) == 2:
	activetype = 2
	vs.ForEachObjectInLayer(sl_processing, 2, 0, 0)
else:
    # Passes Handle to "def pio_processing(h):" of PIO and Symbols selected
    vs.ForEachObject(pio_processing, "((((T=PLUGINOBJECT)|(T=SYMBOL)) & (V) & (SEL=TRUE)))")

    # Passes Handle to "def object_processing(h):" of objects selected except PIO and Symbols outside walls selected
    # Skipped if PIO or Symbol selected was in wall
    if container != 'PIOinwallwasdetected':
        vs.ForEachObject(object_processing, "(((T<>PLUGINOBJECT)&(T<>SYMBOL)&(T<>VIEWPORT) & (V) & (VSEL=TRUE)))")

vs.NameClass(ACName)  # Return active class

 

Edited by The Hamma

Share this post


Link to post

Are you aware that Annotations are a Group inside a Viewport? So to check if you are in annotations, you actually have to check the type of the Parent of the Parent

 

Annotation -> Group(Parent) -> Viewport(Parent of Parent)

 

Looks good. Glad I could help.

Share this post


Link to post

Yes, I was aware but in this case I don't need to test for objects in a VP because It's not intended to initiate a global change based on type only on specifically selected objects. 

 

Thanks again for the great advice. 

 

Share this post


Link to post

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.


 

7150 Riverwood Drive, Columbia, Maryland 21046, USA   |   Contact Us:   410-290-5114

 

© 2018 Vectorworks, Inc. All Rights Reserved. Vectorworks, Inc. is part of the Nemetschek Group.

×
×
  • Create New...