Jump to content

Neda Roohnia

Member
  • Posts

    25
  • Joined

  • Last visited

Everything posted by Neda Roohnia

  1. I am posting the final version of the code in here in case anyone wanted to have it. import vs # Define a function to list the names of all sheet layers in the current document def list_sheet_layer_names(): layer_names = [] hLayer = vs.FLayer() # Use a while loop and the NextLayer() function to iterate through all the sheet layers in the document while hLayer != None: layer_names.append(hLayer) hLayer = vs.NextLayer(hLayer) # Use a lambda function to filter the list of layer names to only include sheet layers layer_type = lambda x: vs.GetObjectVariableInt(x, 154) layer_names = [vs.GetLName(x) for x in layer_names if layer_type(x) == 2] return layer_names # Define a function to get the handles of all objects in the current document that meet certain criteria def get_objects_from_criteria(criteria): object_handles = [] def get_obj(h): object_handles.append(h) # Use the ForEachObject() function to iterate through all objects in the document and add their handles to the list if they meet the criteria vs.ForEachObject(get_obj, criteria) return object_handles # Define a function to calculate the area of a given object def get_object_area(object): top_left, bot_right = vs.GetBBox(object) length = bot_right[0] - top_left[0] height = top_left[1] - bot_right[1] return length * height def ImpScale(SF): if SF == 12: return "1\" = 1'-0\"" elif SF == 24: return "1/2\" = 1'-0\"" elif SF == 32: return "3/8\" = 1'-0\"" elif SF == 48: return "1/4\" = 1'-0\"" elif SF == 64: return "3/16\" = 1'-0\"" elif SF == 96: return "1/8\" = 1'-0\"" elif SF == 128: return "3/32\" = 1'-0\"" elif SF == 192: return "1/16\" = 1'-0\"" elif SF == 384: return "1/32\" = 1'-0\"" else: return f'1:{SF:.0f}' def exclude_titleblock(tblocks): excluded_blocks = [] exclude_names = ['Landscape Details', 'Landscape Sections', 'Landscape Cut Sheets'] for tblock in tblocks: record_name = 'Title Block Sheet Data' # Adjust the record name based on your specific title block record field_name = 'Sheet Title' # Adjust the field name based on your specific title field strRecordName = vs.GetRField(tblock, record_name, field_name) is_excluded = any(name in strRecordName for name in exclude_names) if not is_excluded: excluded_blocks.append(tblock) return excluded_blocks def include_titleblock(tblocks): included_blocks = [] include_names = ['Landscape Details', 'Landscape Sections'] for tblock in tblocks: record_name = 'Title Block Sheet Data' # Adjust the record name based on your specific title block record field_name = 'Sheet Title' # Adjust the field name based on your specific title field strRecordName = vs.GetRField(tblock, record_name, field_name) is_included = any(name in strRecordName for name in include_names) if is_included: included_blocks.append(tblock) return included_blocks def imclude_titleblock(tblocks): imcluded_blocks = [] imclude_names = ['Landscape Cut Sheets', 'Landscape BS'] for tblock in tblocks: record_name = 'Title Block Sheet Data' # Adjust the record name based on your specific title block record field_name = 'Sheet Title' # Adjust the field name based on your specific title field strRecordName = vs.GetRField(tblock, record_name, field_name) is_imcluded = any(name in strRecordName for name in imclude_names) if is_imcluded: imcluded_blocks.append(tblock) return imcluded_blocks # Iterate through all sheet layers in the current document for layer in list_sheet_layer_names(): # Define criteria strings to find title blocks and viewports on the current layer titleblock_crit_str = f"(((L='{layer}') & (PON='Title Block Border')))" viewports_crit = f"(((L='{layer}') & (T=VIEWPORT)))" # Use the get_objects_from_criteria() function to get lists of title blocks and viewports on the current layer titleblocksss = get_objects_from_criteria(titleblock_crit_str) titleblocks = exclude_titleblock(titleblocksss) viewports = get_objects_from_criteria(viewports_crit) # If there is at least one title block and one viewport on the current layer, find the largest viewport and set the scale of the title block to match if all([len(titleblocks) > 0, len(viewports) > 0]): titleblock = titleblocks[0] # get single first found only vp_area_max = 0.0 vp_largest = None # Iterate through all viewports on the current layer and find the one with the largest area for viewport in viewports: vp_area = get_object_area(viewport) if vp_area > vp_area_max: vp_area_max = vp_area vp_largest = viewport # If a largest viewport is found, set the scale of the title block to match if vp_largest: SF = vs.GetObjectVariableReal(vp_largest, 1003) vs.SetRField(titleblock, 'Title Block Sheet Data', 'Scale', ImpScale(SF)) vs.ResetObject(titleblock) # Iterate through all sheet layers in the current document for layer in list_sheet_layer_names(): # Define criteria strings to find title blocks and viewports on the current layer titleblock_crit_str = f"(((L='{layer}') & (PON='Title Block Border')))" viewports_crit = f"(((L='{layer}') & (T=VIEWPORT)))" # Use the get_objects_from_criteria() function to get lists of title blocks and viewports on the current layer titleblocksss = get_objects_from_criteria(titleblock_crit_str) intitleblocks = include_titleblock(titleblocksss) viewports = get_objects_from_criteria(viewports_crit) # If there is at least one title block and one viewport on the current layer, find the largest viewport and set the scale of the title block to match if all([len(intitleblocks) > 0]): titleblock = intitleblocks[0] # get single first found only vs.SetRField(titleblock, 'Title Block Sheet Data', 'Scale', 'as noted') vs.ResetObject(titleblock) # Iterate through all sheet layers in the current document for layer in list_sheet_layer_names(): # Define criteria strings to find title blocks and viewports on the current layer titleblock_crit_str = f"(((L='{layer}') & (PON='Title Block Border')))" viewports_crit = f"(((L='{layer}') & (T=VIEWPORT)))" # Use the get_objects_from_criteria() function to get lists of title blocks and viewports on the current layer titleblocksss = get_objects_from_criteria(titleblock_crit_str) imtitleblocks = imclude_titleblock(titleblocksss) viewports = get_objects_from_criteria(viewports_crit) # If there is at least one title block and one viewport on the current layer, find the largest viewport and set the scale of the title block to match if all([len(imtitleblocks) > 0]): titleblock = imtitleblocks[0] # get single first found only vs.SetRField(titleblock, 'Title Block Sheet Data', 'Scale', 'n/a') vs.ResetObject(titleblock)
  2. And this, if there is a list of names: def exclude_titleblock(tblocks): excluded_blocks = [] exclude_names = ['Landscape Details', 'Landscape Sections', 'Landscape Cut Sheets'] for tblock in tblocks: record_name = 'Title Block Sheet Data' # Adjust the record name based on your specific title block record field_name = 'Sheet Title' # Adjust the field name based on your specific title field strRecordName = vs.GetRField(tblock, record_name, field_name) is_excluded = any(name in strRecordName for name in exclude_names) if not is_excluded: excluded_blocks.append(tblock) return excluded_blocks
  3. Ah I was able to revise it by adding this: def exclude_titleblock(tblocks): excluded_blocks = [] for tblock in tblocks: strRecordName = vs.GetRField(tblock, 'Title Block Sheet Data', 'Sheet Title') if strRecordName != 'Landscape Details': excluded_blocks.append(tblock) return excluded_blocks # Iterate through all sheet layers in the current document for layer in list_sheet_layer_names(): # Define criteria strings to find title blocks and viewports on the current layer titleblock_crit_str = f"(((L='{layer}') & (PON='Title Block Border')))" viewports_crit = f"(((L='{layer}') & (T=VIEWPORT)))" # Use the get_objects_from_criteria() function to get lists of title blocks and viewports on the current layer titleblocksss = get_objects_from_criteria(titleblock_crit_str) titleblocks = exclude_titleblock(titleblocksss) viewports = get_objects_from_criteria(viewports_crit) Thanks a lot again for everyone's help!
  4. Thanks a lot!! I realized what my problem is. I used vs.AlrtDialog(layer) at the end of this section to see what it returns and I realized it actually returns the sheet numbers rather than sheet titles. Since we have all the sheet titles fixed in our template file (sheet numbers will definitely change), I am trying to find a way to use the sheet titles in the code rather than the sheet numbers. Was trying to change the index numbers in the code to get the sheet titles but had no luck..
  5. Thanks a lot! I tried this, I included those sheetlayer names to be excluded, but still did not work. Very strange!!
  6. Again, thanks a lot for updating this, but I still can not figure out where I should put the specific sheetlayer names that I want to exclude on this code.
  7. Thanks a lot! Really appreciate al your help on this!
  8. Thanks a lot, Pat! Will test this to see! Much appreciated.
  9. One more question on this code; how can I exclude a specific sheet layer on this code? What if we don't want certain sheets to get updated? Any hints will be much appreciated!
  10. The script I posted looks for the largest viewport on the sheet layer and updates the titleblock with its scale.
  11. Hi there. There's a Python scrip developed for this with the great help of folks on the forum and I am going to post it in here. import vs # Define a function to list the names of all sheet layers in the current document def list_sheet_layer_names(): layer_names = [] hLayer = vs.FLayer() # Use a while loop and the NextLayer() function to iterate through all the sheet layers in the document while hLayer != None: layer_names.append(hLayer) hLayer = vs.NextLayer(hLayer) # Use a lambda function to filter the list of layer names to only include sheet layers layer_type = lambda x:vs.GetObjectVariableInt(x, 154) layer_names = [vs.GetLName(x) for x in layer_names if layer_type(x) == 2] return layer_names # Define a function to get the handles of all objects in the current document that meet certain criteria def get_objects_from_criteria(criteria): object_handles = [] def get_obj(h): object_handles.append(h) # Use the ForEachObject() function to iterate through all objects in the document and add their handles to the list if they meet the criteria vs.ForEachObject(get_obj, criteria) return object_handles # Define a function to calculate the area of a given object def get_object_area(object): top_left, bot_right = vs.GetBBox(object) length = bot_right[0] - top_left[0] height = top_left[1] - bot_right[1] return length * height def ImpScale(SF): if SF == 12: return "1\"=1'0\"" elif SF == 24: return "1/2\"=1'0\"" elif SF == 32: return "3/8\"=1'0\"" elif SF == 48: return "1/4\"=1'0\"" elif SF == 64: return "3/16\"=1'0\"" elif SF == 96: return "1/8\"=1'0\"" elif SF == 128: return "3/32\"=1'0\"" elif SF == 192: return "1/16\"=1'0\"" elif SF == 384: return "1/32\"=1'0\"" else: return f'1:{SF:.0f}' # Iterate through all sheet layers in the current document for layer in list_sheet_layer_names(): # Define criteria strings to find title blocks and viewports on the current layer titleblock_crit_str = f"(((L='{layer}') & (PON='Title Block Border')))" viewports_crit = f"(((L='{layer}') & (T=VIEWPORT)))" # Use the get_objects_from_criteria() function to get lists of title blocks and viewports on the current layer titleblocks = get_objects_from_criteria(titleblock_crit_str) viewports = get_objects_from_criteria(viewports_crit) # If there is at least one title block and one viewport on the current layer, find the largest viewport and set the scale of the title block to match if all([len(titleblocks)>0, len(viewports)>0]): titleblock = titleblocks[0] # get single first found only vp_area_max = 0.0 vp_largest = None # Iterate through all viewports on the current layer and find the one with the largest area for viewport in viewports: vp_area = get_object_area(viewport) if vp_area > vp_area_max: vp_area_max = vp_area vp_largest = viewport # If a largest viewport is found, set the scale of the title block to match if vp_largest: SF = vs.GetObjectVariableReal(vp_largest, 1003) vs.SetRField(titleblock, 'Title Block Sheet Data', 'Scale', ImpScale(SF)) vs.ResetObject(titleblock) Hope it's not too late! 🙂
  12. I revised the code to account for the imperial scales as below: import vs # Define a function to list the names of all sheet layers in the current document def list_sheet_layer_names(): layer_names = [] hLayer = vs.FLayer() # Use a while loop and the NextLayer() function to iterate through all the sheet layers in the document while hLayer != None: layer_names.append(hLayer) hLayer = vs.NextLayer(hLayer) # Use a lambda function to filter the list of layer names to only include sheet layers layer_type = lambda x:vs.GetObjectVariableInt(x, 154) layer_names = [vs.GetLName(x) for x in layer_names if layer_type(x) == 2] return layer_names # Define a function to get the handles of all objects in the current document that meet certain criteria def get_objects_from_criteria(criteria): object_handles = [] def get_obj(h): object_handles.append(h) # Use the ForEachObject() function to iterate through all objects in the document and add their handles to the list if they meet the criteria vs.ForEachObject(get_obj, criteria) return object_handles # Define a function to calculate the area of a given object def get_object_area(object): top_left, bot_right = vs.GetBBox(object) length = bot_right[0] - top_left[0] height = top_left[1] - bot_right[1] return length * height def ImpScale(SF): if SF == 48: return "1/4\"=1'0\"" elif SF == 64: return "3/16\"=1'0\"" elif SF == 96: return "1/8\"=1'0\"" elif SF == 128: return "3/32\"=1'0\"" elif SF == 192: return "1/16\"=1'0\"" elif SF == 384: return "1/32\"=1'0\"" else: return f'1:{SF:.0f}' # Iterate through all sheet layers in the current document for layer in list_sheet_layer_names(): # Define criteria strings to find title blocks and viewports on the current layer titleblock_crit_str = f"(((L='{layer}') & (PON='Title Block Border')))" viewports_crit = f"(((L='{layer}') & (T=VIEWPORT)))" # Use the get_objects_from_criteria() function to get lists of title blocks and viewports on the current layer titleblocks = get_objects_from_criteria(titleblock_crit_str) viewports = get_objects_from_criteria(viewports_crit) # If there is at least one title block and one viewport on the current layer, find the largest viewport and set the scale of the title block to match if all([len(titleblocks)>0, len(viewports)>0]): titleblock = titleblocks[0] # get single first found only vp_area_max = 0.0 vp_largest = None # Iterate through all viewports on the current layer and find the one with the largest area for viewport in viewports: vp_area = get_object_area(viewport) if vp_area > vp_area_max: vp_area_max = vp_area vp_largest = viewport # If a largest viewport is found, set the scale of the title block to match if vp_largest: SF = vs.GetObjectVariableReal(vp_largest, 1003) vs.SetRField(titleblock, 'Title Block Sheet Data', 'Scale', ImpScale(SF)) vs.ResetObject(titleblock) Again, thanks a lot all for helping me on this!
  13. Hi Pat, I just added that in and it works like a magic! Thanks a lot! Now I am trying to add some "if" loops for converting the engineering scales to Architectural...I will keep you posted on how it goes!
  14. Oh I figured a partial answer to one of my questions; I need to go to Tools...> Utilities...> Reset All Plug-ins and then it works!
  15. Hi there, thanks a lot for sending the two versions of your script! I just realized that they both work actually, the only thing is that I have to "update" the titleblock for the scale to update by checking and un-checking "Activate Title Block" on the object info panel. I was wondering if there is a way to include this "updating" into the script somehow. My other question is that how should I change the script to show the imperial scales properly.. i.e. 1/8" = 1'0" instead of 1:96. Many thanks!
  16. It's very strange! I tried the code, it doesn't give any errors, but it doesn't do anything, either! I was thinking of a couple of things; what if I revise it in a way that it mentions the titleblock's name directly rather than search for the titleblocks? The titleblock symbol's name is defined in our template file. I appreciate if you point out to any possible issue that causes this! Again, really appreciate your input and help!!
  17. Hi everyone, I am trying to come up with a Python script that identifies the largest viewport on a sheetlayer, gets its scale, and updates the title block scale field for each sheetlayer. I have put together a very preliminary code for this. import vs Handle = vs.GetObject('THISISIT') strNR1 = vs.GetObjectVariableReal(Handle, 1003) #Sheet data record format and field strRecordName = 'Title Block Sheet Data' strRecordField = 'Scale' def SetRecord(h): vs.SetRField(h,strRecordName,strRecordField,strNR1); vs.ResetObject(h); criteria = '((R in [' + "'" + strRecordName + "'" + ']))'; vs.ForEachObject( SetRecord, criteria); This code works as long as I know the viewport's name (in this example: "THISISIT"), also it puts the same scale on all the sheetlayers' titleblocks. Any inputs will be much appreciated!
  18. Thanks a lot, Pat. I am exactly trying to do what you mentioned in here. Trying to use the worksheet to store the value into a Record.Field attached to my title block and use it there. I just don't know how to do it!
  19. Agreed! But what if it asks for some more criteria like class etc.? Then it can filter the main one and get the scale.
  20. That's a very good point! They can set it up in a way that if there is more than one VP on the sheet layer the titleblock text show: N/A or something like that.
  21. Hi Hi Pat, this works perfectly! How can I use this directly for my titleblock to update the sheet scales automatically?
  22. Hi Andy, thanks a lot for your reply! Yes, I was cutting and pasting, I just realized if I change the sheet number on the object info palette, that won't happen! Now there is another issue; if I delete the viewport, the callout on the other sheet disappears! Is there a setting to keep the callout with a broken link symbol on it or something? (to show it is not linked to anything)
  23. Hi everyone. I just learned about the very cool new feature in Vectorworks 2021; the more flexible detail callout that can be linked to a particular viewport and synced automatically. However, it seems this feature has a flaw, and that is when I move a view port to a different sheet layer, the detail callout disappears instead of getting updated based on the new sheet layer number/info. Does anyone know a solution to this? Thanks a lot!
×
×
  • Create New...