Jump to content
The Hamma

Script to add or modify selected objects records

Recommended Posts

Posted (edited)

I made this script to apply a record to items selected.  The goal is the following:

If object in wall is selected add and change record to the object in the wall only. (works as designed)

If wall is selected add and change record to the wall and all objects inserted in the wall. (Only changes the wall not the inserted objects)

#set global variable
container = 'none'

def SetPIOAttribute(h):   
		global container #declare global variable to be retained
		vs.SetRecord(h,'Construction Phase') #add record to inserted object
		vs.SetRField(h,'Construction Phase','Phase','New') #modify record to inserted object
		itChild = vs.GetTypeN(h) #Get Child type (not necessary)
		hParent = vs.GetParent(h) #Get Parent handle
		itParent = vs.GetTypeN(hParent)#Get Parent type 
		if itParent == 68: #If Parent type is a wall set container to state PIOinwallwasdetected
			container = 'PIOinwallwasdetected'

#Add and change record of wall and inserted items (only changes wall at this time) 
def SetAttribute(h):
	vs.SetRecord(h,'Construction Phase')
	vs.SetRField(h,'Construction Phase','Phase','New')


vs.ForEachObject(SetPIOAttribute, "((NOTINDLVP & NOTINREFDLVP & ((PON='Door')|(T=SYMBOL)|(PON='Window')) & (V) & (SEL=TRUE)))")
#If PIO was selected and wall was not then container var PIOinwallwasdetected is true then script will end if not then wall was selected and script will continue to def SetAttribute
if container != 'PIOinwallwasdetected': 
	vs.ForEachObject(SetAttribute, "((NOTINDLVP & NOTINREFDLVP & (V) & (SEL=TRUE)))")
	

 

Edited by The Hamma

Share this post


Link to post

Just to make this more fun, I am going to throw some Vectorscript in here.  ;-)

 

I think you need to approach this from the other direction. If the selected object is a wall, then you need to use Fin3D to find the objects in the wall and then attach the records to them.

 

Create a new file with a single wall and a door (or multiple doors/windows/symbols) and leave the wall selected and run the following script.

 

After a "few" (I think it will depend on the wall styles how many object you will see), eventually you will come up with an object of Type 86 (Plug-in Object) or 15 (Symbol). You may need to check more thoroughly if they are doors or windows, but at least you will have a handle to the PIOs in the wall and can determine if you want to attach your record or not.

 

Ask again if you need more help.

 

Procedure Test;

Var	H1: Handle;

Begin
	H1:=Fin3D(FSActLayer);
	While H1 <> Nil do
		Begin
			ALrtDialog(Concat(GetTypeN(H1)));
			H1:=NextObj(H1);
		End;
End;

Run(Test);

 

Share this post


Link to post
Posted (edited)
19 hours ago, Pat Stanford said:

Just to make this more fun, I am going to throw some Vectorscript in here. 😉

 

I added your script to mine and it works great but I think I found a Vectorworks bug. 

 

This is a view of a wall with objects after running the script on the symbol in the wall.  As you can see in the record the phase has been changed to Existing but the appearance still shows as New. 

image.thumb.png.2c015dd18a9ae0280d0d3e407e29c926.png

 

Now if I change the Object Criteria in the Data Visualization or close and reopen the drawing the symbol in wall will appear correctly.  I have set my graphic settings up and down with no change.  PIO object change fine, I only have this issue with symbols in wall and the issue is not isolated to the script.  If I change the phase manually I have the same issue. 

image.thumb.png.d4efe36f278815fd671e8442e2cd4239.png

 

container = 'none' #set global variable
phase = 'Existing'

def SetPIOAttribute(h):   
		global container #declare global variable to be retained
		vs.SetRecord(h,'Construction Phase') #add record to inserted object
		vs.SetRField(h,'Construction Phase','Phase', phase) #modify record to inserted object
		itChild = vs.GetTypeN(h) #Get Child type (not necessary)
		hParent = vs.GetParent(h) #Get Parent handle
		itParent = vs.GetTypeN(hParent) #Get Parent type 
		#If Parent type is a wall set container to state PIOinwallwasdetected
		if itParent == 68: 
			container = 'PIOinwallwasdetected'

#Add and change record of wall and inserted items (only changes wall at this time) 
def SetAttribute(h):
	vs.SetRecord(h,'Construction Phase')
	vs.SetRField(h,'Construction Phase','Phase', phase)

vs.ForEachObject(SetPIOAttribute, "((NOTINDLVP & NOTINREFDLVP & ((PON='Door')|(T=SYMBOL)|(PON='Window')) & (V) & (SEL=TRUE)))")
#If PIO was selected and wall was not then container var PIOinwallwasdetected is true then script will end if not then wall was selected and script will continue to def SetAttribute
if container != 'PIOinwallwasdetected': 
	h1 = vs.FIn3D(vs.FSActLayer())
	while h1 != ():
		if vs.GetTypeN(h1) == 15:
			vs.SetRecord(h1,'Construction Phase')
			vs.SetRField(h1,'Construction Phase','Phase', phase)
		if vs.GetTypeN(h1) == 86:
			vs.SetRecord(h1,'Construction Phase')
			vs.SetRField(h1,'Construction Phase','Phase', phase)
		h1=vs.NextObj(h1)
	vs.ForEachObject(SetAttribute, "((NOTINDLVP & NOTINREFDLVP & (V) & (SEL=TRUE)))")	

 

 

Edited by The Hamma

Share this post


Link to post

That is the way symbols work. They are always drawn the same as the definition.

 

Three possible ways to overcome this:

 

1. Make all the attributes in they symbol By Class and when you change the phase also change the class that the symbol (and the component parts) are in.

 

2. Create your symbols as "Blue" symbols by checking the Convert to Group button in the Symbol Insertion Options. Then you have a symbol so it can be accessed from the Resource Manager, but it converts to a group when inserted in the drawing so that you can change the attributes. The down side to this is that it is a group and not a symbol and you can't change every instance in the drawing by editing the symbol.

 

3. Make Plug-in Objects instead of symbols and have them change attributes when the phase changes.

 

 

Share this post


Link to post

Not inserting the symbol in the wall or using PIO seems to be the best course of action.  The symbols visualization works fine if is not nested in a wall.  If it is nested I can remove it and re-nest it and the visualization works fine.   I still think this is a glitch since it just takes some sort of refresh to make it work.  That being said vs.redrawall() does not work (it actually causes every item changed not to refresh).  For the most part I think I can work around it but it a bit aggravating. 

Share this post


Link to post

I thought it was working perfectly but it does if I select one wall at a time.  In that instance it will change the wall and all the PIO objects within but If I select several walls it does not edit all of the PIO objects, it only edits the PIO in the first item selected. 

 

container = 'none' #set global variable
phase = 'Existing'

def SetPIOAttribute(h):   
		global container #declare global variable to be retained
		vs.SetRecord(h,'Construction Phase') #add record to inserted object
		vs.SetRField(h,'Construction Phase','Phase', phase) #modify record to inserted object
		itChild = vs.GetTypeN(h) #Get Child type (not necessary)
		hParent = vs.GetParent(h) #Get Parent handle
		itParent = vs.GetTypeN(hParent) #Get Parent type 
		#If Parent type is a wall set container to state PIOinwallwasdetected
		if itParent == 68: 
			container = 'PIOinwallwasdetected'


#Add and change record of wall and inserted items (only changes wall at this time) 
def SetAttribute(h):
	vs.SetRecord(h,'Construction Phase')
	vs.SetRField(h,'Construction Phase','Phase', phase)
	h1 = vs.FIn3D(vs.FSActLayer())
	while h1 != ():
		vs.SetRecord(h1,'Construction Phase')
		vs.SetRField(h1,'Construction Phase','Phase', phase)
		h1=vs.NextObj(h1)



vs.ForEachObject(SetPIOAttribute, "((NOTINDLVP & NOTINREFDLVP & ((PON='Door')|(T=SYMBOL)|(PON='Window')) & (V) & (SEL=TRUE)))")
#If PIO was selected and wall was not then container var PIOinwallwasdetected is true then script will end if not then wall was selected and script will continue to def SetAttribute
if container != 'PIOinwallwasdetected': 
	vs.ForEachObject(SetAttribute, "((NOTINDLVP & NOTINREFDLVP & (V) & (SEL=TRUE)))")	

 

Share this post


Link to post

You need to change the FSActLayer to a loop that will step through each wall and do the FIn3D on each wall.

 

 

Share this post


Link to post
Posted (edited)

 

13 hours ago, Pat Stanford said:

You need to change the FSActLayer to a loop that will step through each wall and do the FIn3D on each wall.

 

 

 

LOL or just change FSActLayer to h.  I didn't even stop to think about that.  I was assuming that FSActLayer was passing the handle from :

def SetAttribute(h):

 

container = 'none' #set global variable
phase = 'Demo'

def SetPIOAttribute(h):   
		global container #declare global variable to be retained
		vs.SetRecord(h,'Construction Phase') #add record to inserted object
		vs.SetRField(h,'Construction Phase','Phase', phase) #modify record to inserted object
		itChild = vs.GetTypeN(h) #Get Child type (not necessary)
		hParent = vs.GetParent(h) #Get Parent handle
		itParent = vs.GetTypeN(hParent) #Get Parent type 
		#If Parent type is a wall set container to state PIOinwallwasdetected
		if itParent == 68: 
			container = 'PIOinwallwasdetected'


#Add and change record of wall and PIO or symbols inserted in wall  
def SetAttribute(h):
	vs.SetRecord(h,'Construction Phase')
	vs.SetRField(h,'Construction Phase','Phase', phase)
	h1 = vs.FIn3D(h)
	while h1 != ():
		if vs.GetTypeN(h1) == 15:
			vs.SetRecord(h1,'Construction Phase')
			vs.SetRField(h1,'Construction Phase','Phase', phase)
		if vs.GetTypeN(h1) == 86:
			vs.SetRecord(h1,'Construction Phase')
			vs.SetRField(h1,'Construction Phase','Phase', phase)
		h1=vs.NextObj(h1)

vs.ForEachObject(SetPIOAttribute, "((NOTINDLVP & NOTINREFDLVP & ((PON='Door')|(T=SYMBOL)|(PON='Window')) & (V) & (SEL=TRUE)))")
#If PIO was selected and wall was not then container var PIOinwallwasdetected is true then script will end if not then wall was selected and script will continue to def SetAttribute
if container != 'PIOinwallwasdetected': 

	vs.ForEachObject(SetAttribute, "((NOTINDLVP & NOTINREFDLVP & (V) & (SEL=TRUE)))")	

 

Edited by The Hamma

Share this post


Link to post
Posted (edited)

Below are the final results:

Three scripts to assigns selected objects to class "1_Exist-(original class)", "2_Demo-(original class)" , or original class and set Construction Phase Existing, Demo, or New

 

"""
This script assigns selected objects to class "1_Exist-(original class)" and set Construction Phase to Existing.

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')  # 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) & (SEL=TRUE)))")

vs.NameClass(ACName)  # Return active class
"""
This script assigns selected objects to class "2_Demo-(original class)" and set Construction Phase to Demo.

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 CNameE == '1_Exist-':  # Check if first 8 letters equal '1_Exist-'
        CName = vs.Copy(CName, 9, CLen)  # if true grab root name of class
    if CNameD == '2_Demo-':  # Check if first 7 letters equal '2_Demo-' if so retain name
        CNameN = CName
    else:
        CNameN = vs.Concat('2_Demo-', CName)  # If not add '2_Demo-' 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', 'Demo')  # 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) & (SEL=TRUE)))")

vs.NameClass(ACName)  # Return active class
"""
This script assigns selected objects to class "(original class)" and set Construction Phase to New

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)
	CNameN = 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-'
		CNameN=vs.Copy(CName,8,CLen) # if true grab root name of class
	if CNameE=='1_Exist-': #Check if first 8 letters equal '1_Exist-'
		CNameN=vs.Copy(CName,9,CLen) # if true grab root name of class
	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', 'New') #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) & (SEL=TRUE)))")

vs.NameClass(ACName)  # Return active class

 

DataVisualizationsInfo.vwx

1 Existing Object.vsm 2 Demo Object.vsm 3 New Object.vsm

Edited by The Hamma

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...