Jump to content

twk

Member
  • Posts

    877
  • Joined

  • Last visited

Posts posted by twk

  1. 6 hours ago, Neda Roohnia said:

    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! 

    I'll have to think about this, the vs.GetObjectVariableReal(vp_largest, 1003) function returns the scale in mm, regardless of the document units. I don't have any experience either in imperial scales as we use the metric system.
    Will post back when found a solution..

    • Like 1
  2. @tbexon, you're a genius, I kept crashing previously, regardless of the developer mode on or off. The only thing that was missing from my code, was the reset object_hand call.

     

    Also, what is happening here:

        if theEvent == tb.Constants.kObjXPropPreference:
            defaultVals = {} # Creates blank Dict for default vals
            MakePropertiesDialog()

     

    don't think I've ever use the kObjXPropPreference constant in my plugins

  3. I noticed that in your code, the try and except block within the create_tab_definition function may not work as intended. Vectorworks won't actually throw an exception if the object name already exists, so the except block might never be executed.

    Instead, you could check whether vs.NameObject(f"RST_{story}") returns a valid handle (i.e., not [0, None]) to determine if the object already exists. If it does, you can simply retrieve the handle and create the duplicate object within the existing folder. Here's an updated version of the create_tab_definition function with this check:

    def create_tab_definition(handle_ref_tab, story):
        rst_handle = vs.NameObject(f"RST_{story}")
        if rst_handle != [0, None]:
            folder_handle = rst_handle[0]
        else:
            folder_handle = vs.BeginFolderN(18)
            vs.NameObject(f"RST_{story}", folder_handle)
            vs.EndFolder()
    	
        ws_handle = vs.CreateDuplicateObject(handle_ref_tab, folder_handle)
        return ws_handle

     

     

    The other thing that I havent tested, or come accross is using the vs.CreateDuplicateObject to duplicate resources. Does that actually work? I will try later.

     

     

  4. What is the logic flow of your code?

     

    -> get_custom_info_ok, plugin_name_internal, plugin_handle, plugin_record_handle, plugin_wallHand = vs.GetCustomObjectInfo()

     

    -> if get_custom_info_ok:

    <main plugin code functions>

     

    -> theEvent, theMessage = vs.vsoGetEventInfo()

    set an AlrtDialog for both theEvent, and theMessage and see what you get

     

     

     

  5. You could play around with putting each site model on its own layer for the 3 park levels as suggested above? If i'm understanding correctly?

    Then using hardscapes, with targetted design layer modifiers, for both the hardscape and the site model. ie:

    - each level will have additional design layers specific to it, for restricting modifiers to each site model DTM

     

    Do you have sections/sketches to show your intention?

  6. Interesting, "Title Block Border" objects may have a symbol name within it that controls the graphical layout of it, however this symbol is housed in a unique object (the Title Block Border object), that is placed on each sheet layer separately. If you were to go down the naming route, you'd have to have a unique name for each title block border object on each sheet layer, which is not optimal.

    I've added checks in the code below, to alert you of the amount of sheets found in the document, and then another alert dialog to tell you if the criteria didn't find any title blocks or viewports on the layer, as its looping through it.

    Try it again and see what messages the alert dialog throws out.

     

    If not, post/DM me your VWX file, maybe your sheet/title block setup is different.

     

    import vs
    
    alert_dialog = lambda x:vs.AlrtDialog(str(x))
    
    def list_sheet_layer_names():
        layer_names = []
        hLayer = vs.FLayer()
    
        while hLayer != None:
            layer_names.append(hLayer)
            hLayer = vs.NextLayer(hLayer)
    
        layer_type = lambda x: vs.GetObjectVariableInt(x, 154)
    
        layer_names = [vs.GetLName(x) for x in layer_names if layer_type(x) == 2]  # filter to only include sheet layers
    
        return layer_names
    
    
    def get_objects_from_criteria(criteria):
        object_handles = []
    
        def get_obj(h):
            object_handles.append(h)
    
        vs.ForEachObject(get_obj, criteria)
    
        return object_handles
    
    
    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
    
    sheet_layer_names = list_sheet_layer_names()
    
    alert_dialog(f"No. Sheets in Document : {len(sheet_layer_names)}")
    
    if len(sheet_layer_names) > 0:
        for layer in list_sheet_layer_names():
            titleblock_crit_str = f"(((L='{layer}') & (PON='Title Block Border')))"
            viewports_crit = f"(((L='{layer}') & (T=VIEWPORT)))"
    
            titleblocks = get_objects_from_criteria(titleblock_crit_str)
            viewports = get_objects_from_criteria(viewports_crit)
    
            if all([len(titleblocks) > 0, len(viewports) > 0]):
                titleblock = titleblocks[0]  # get single first found only
    
                vp_area_max = 0.0
                vp_largest = None
    
                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 vp_largest:
                    vp_scale = vs.GetObjectVariableReal(vp_largest, 1003)
                    vs.SetRField(titleblock, 'Title Block Sheet Data', 'Scale', f'1:{vp_scale:.0f}')
            else:
                alert_dialog(f"No Title Block or Viewport found on sheet {layer}")

     

  7. And here is what I came up with, (FYI, I used chatGPT to explain the code with inline comments!).
    ** As always, save before running the script, and no responsibility taken for loss of work 😅 **

     

    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
    
    # 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:
                vp_scale = vs.GetObjectVariableReal(vp_largest, 1003)
                vs.SetRField(titleblock, 'Title Block Sheet Data', 'Scale', f'1:{vp_scale:.0f}')

     

  8. I’d actually loop through viewports via sheets:

    1. Generate a list of sheet layers.

    2. For each sheet layer in the list, use a criteria that searches for viewports with T=Viewport only on this layer.

    3. To find a title block within the same loop, use another criteria that searches for a plugin name of "Title Block Border" on the same layer.

    4. Within the loop of step 2, locate the largest viewport. You can choose to use the viewport with the largest scale or the one with the largest bounding box. Once found, write the scale to the handle of the title block found in step 3.

    When I have time to code, I'll see if I can post something

    Also try to always use f-strings for concatenation. eg
     

    criteria = f"((R in ['{strRecordName}']))"

     

    • Like 1
  9. Not until now 🤣..

    This is a direct copy and paste of my prompt and the result, however, I'm pretty sure its a simpe scenario, and there will be hallucinations for more advanced requests. But certainly there are tools out there that will make all these possible some day..

    Prompt:
    With your knowledge of Marionette coding and Vectorworks python api functions, build another Marionette node code that creates a rectangle.
    The two input nodes are just the width and height, and the output node is the resulting rectangle created


    Result:

     

    Certainly, here's a Marionette node code that takes width and height as input and creates a rectangle with those dimensions:

    #COMMAND;READONLYREFFILE;[VWLibDef]/Objects\Parametric\Rect-2.vwx;
    #Modified by [Your Name] [Current Date]
    @Marionette.NodeDefinition
    class Params(metaclass = Marionette.OrderedClass):
        # APPEARANCE
        this = Marionette.Node('Rectangle')
        this.SetDescription('Creates a rectangle with the specified dimensions.')
    
        # INPUTS
        width = Marionette.PortIn(0, 'Width')
        width.SetDescription('The width of the rectangle.')
        height = Marionette.PortIn(0, 'Height')
        height.SetDescription('The height of the rectangle.')
    
        # OUTPUTS
        rect = Marionette.PortOut('h', 'Rectangle')
        rect.SetDescription('The resulting rectangle.')
    
    def RunNode():
        # Inputs
        w = Params.width.value
        h = Params.height.value
    
        # Script
        rect = vs.CreateRectangle(vs.Vector(0, 0), w, h)
    
        # Outputs
        Params.rect.value = rect

    This code defines a Marionette node that takes two inputs, width and height, and outputs a rectangle object with those dimensions. The script creates a rectangle using the vs.CreateRectangle function from the Vectorworks Python API, which takes a position vector and the width and height of the rectangle. The rect object is then outputted as the result of the node.

     

    As you can see it came up with the first two lines just because of the context of the chat session I'm sure. This is still crazy though.

     

    • Like 1
  10. Agree with all of what Pat and Sam Jones said. With regards to your specific questions:
     

    I’m wanting to start to push the boundaries of what can be done with Vectorworks, and am seeking direction for best practices, Scripting resources, and or any additional materials that you may deem helpful in this endeavor. 
    - This forum, and the vectorworks dev wiki (link stickied in scripting forum), are your best resources. Vectorworks also ships with a PDF for the vectorscript language.

     

    Really looking to program repeat tasks and sequences that I currently use in my daily workflow.

    - This can be done with all three routes, ie Vectroscript, Python, C++

     

    And I would like to be able to develop a customized “super” template that has a centralized repository for all future drawings to save time on production efforts.

    - Depending on your actual specifics, template scripting has been attempted in the past. Search the forums. There were some pitfalls users faced.

     

    Which language should be best utilized from a programming point of view, and is there recent documentation for the most current release?

    - Which language? from a programming point of view? all three of them will help you, and the recent documentation is on the Vectorworks Dev Wiki.

     

    My experience with the languages are as such:
    Vectorscript
    Pros:
    - Native debugger within Vectorworks.

    - You can script in user-interactivity easier than using Python

    - Native vectorworks language
    Cons

    - Explicit variables(yes this is contrary to what Sam mentioned 😁)

    - Intermedia learning curve if new to programming

     

    Python

    Pros:

    - Easy learning curve. Plethora of tutorials online

    - Access to every external library from the python development community

    - Faster development testing (in my tests)

    - Debugging can be done in an external ide with code error checking, syntax highlighting. (I use PyCharm, but there are others out there)

    Cons

    - Hard to script in user-interactivity

     

    C++

    Pros:

    - You have more access to the Vectorworks under-the-hood functions

    Cons:

    - Steep learning curve. (I have yet to dive into this one. But when I will....)

     

    I spent about 2 years learning and developing plugins using vectorscript, when python support came out, I spent 1 year learning python, and then abandoned vectorscript, and develop solely in python ever since.
    But if you've read the forums you'd see alot people still using vectorscipt and others python.

    Well that was a round-about-post to say: "It all depends.." 

     

     

    • Like 2
  11. 6 hours ago, matteoluigi said:

    there's no control model view in my text2img section, why? 😉 , maybe i am using the wrong weight? or the wrong stavble diffusion version?

    I should've prefaced my post, by saying I haven't actually tried any of this 😂😂. Ever since reading and liking a few posts on twitter, my feed has been flooded with videos and tweets like the ones I posted here.

     

    I should also mention, that everything is moving incredibly fast to follow whats happening. The amount of offshoot diffusion models, gpt models, locally run gpt/diffusion models, being released daily is quite mind blowing. It's like seeing a beautiful avalanche; from a distance it looks beautiful, the sheer mass of it so very difficult to comprehend, but at the back of your mind you know alot is getting destroyed in the process.

     

    • Like 1
×
×
  • Create New...