Jump to content

to automate updating titleblock w/ viewport scale


Recommended Posts

3 hours ago, twk said:

Apologies looks like there was an extra line after the 'while' call. correct below:

 

# Define a function to list the names of all sheet layers in the current document
def list_sheet_layer_names(excluded_layer_names=None):
    """
    @type filter_layer_names: exclusive layer names list ie, only these layers to be returned
    """
    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:
        if vs.GetObjectVariableInt(hLayer, 154) == 2:
            layer_name = vs.GetLName(hLayer)
            if excluded_layer_names:
                if layer_name not in excluded_layer_names:
                    layer_names.append(layer_name)
            else:
                layer_names.append(layer_name)
        hLayer = vs.NextLayer(hLayer)

    return layer_names

 

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

Link to comment

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!

Link to comment

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

 

Edited by Neda Roohnia
Link to comment

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)
 

Link to comment

Thank you for posting that.  One suggestion for the future.  It is probably better to post code into a Code Block. It will wrap better and be easier for someone else to copy and paste.

 

I created this code block by:
	1. Clicking the <> icon in the editor tool bar.
	2. Writing this.
	3. Clicking the Insert into Post button

 

image.png.24aef6ec0ab3345e9ef686c316a40d92.png

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