Jump to content

Hippocode

Member
  • Posts

    801
  • Joined

  • Last visited

Posts posted by Hippocode

  1. On 5/4/2026 at 10:04 AM, briansia said:

    Hi everyone,

    I’m new here — hello to the Vectorworks community.

    I’m looking for an experienced Vectorworks developer for a small paid task.

    The first version is a lightweight model-data extractor. The goal is to read useful information from a Vectorworks file and send structured JSON to an external HTTPS endpoint.

    For v1, the scope is roughly:

    - read current Vectorworks document/model data
    - extract object IDs / handles where available
    - extract object names
    - extract layers / classes
    - extract object type
    - extract basic dimensions / bounding information where available
    - extract spaces / room-related signals where available
    - extract records / custom properties / metadata where available
    - structure the result as JSON
    - POST the JSON to an HTTPS endpoint
    - save a local JSON/log file if the POST fails

    For v1, I do not need live sync, writeback, model editing, or a complex UI.

    Later, there may be a Phase 2 with bidirectional features, such as writing IDs/status back into object records, detecting changes, selecting/highlighting objects, or placing library symbols/objects.

    I’m also trying to understand the best technical route for this: VectorScript, Python, or the Vectorworks SDK.

    If you have experience building Vectorworks scripts/plugins and this sounds like something you can help with, please reply or message me.

    Thank you.

     

    Since you want to use json and possible more complex behavior in V2: python or the SDK are the best options.

    I only develop with the SDK and could help you out. I'll dm you my contact information.

     

     

  2. On 1/8/2026 at 12:02 AM, Michael Siggers said:

    I struggle to get a connection when trying to create a duct and connect to another duct.

    Hi Michael

     

    This is a matter of snapping and snapping settings. You'll see two helper loci at the start/end of the pipe. Snap on those to traverse the path of the pipe/duct to create a connection on the path. 

     

    That being said, in an upcoming update we've improved this a little bit, when it shows green and you click "not touching the actual path" it'll use the closest point to make the connection instead. When you want to lock the angle for a T connection you'll still need to snap properly, otherwise the calculated point will deviate a bit from your expectation and this will change the angle, so the solution mentioned above is still best for those specific cases.
     

    On 1/7/2026 at 11:09 PM, Michael Siggers said:

    Watched all the videos. Any instructions for adding an air terminal please.

     

    All the technical objects (hvac/san/elec) work in the same way. We provide a container object (point based tool) with functionality but they require symbols for geometry. We have provided some sample symbols to start with but you can use anything that matches your local standards. Connectors can be added into these objects as snap points and they store some info depending on the connector type. 

     

    On 1/7/2026 at 10:47 PM, Michael Siggers said:

    Where are the VectorMEP Symbols located. When trying to insert an Air Outlet, there are no symbols to choose from.

     

    There should be some. For most object types the default library comes some sample symbols. But since they are symbol based you can use any 2D/3D symbol.
    I'm unable to upload an image here, but in the resource dialog you should see a VectorMEP folder. You can create red symbols of your unique combinations to build your library.

     

    On 12/16/2025 at 10:47 AM, zeno said:

    I tried to reply array and very soon this operation generate a crash on 2026 upd2

     

    Hi Zeno, we've identified the issue and have a solution ready in the next update.

    • Like 3
  3. 6 minutes ago, E|FA said:

    @JuanCarlos I was hoping to check it out.  I installed the plugin through the Install Partner Products option in the help menu.  However, it looks like it needs a license (see screenshot) to run.  Am I missing something?  Is it really free per your screenshot above?

     

     

    Yes we've made 2026 free. You shouldn't get that popup unless you opened the license menu yourselves? I'll verify if your version is the correct version that's free. I'll get back to you.

    • Like 1
  4. I would also like to do this. I've been trying various options but none seem to work. Particularly using a background color. It's OR an image/color, OR text, not both in the sense I would like to use it.

    Usually I make the text grey to indicate it's not editable... and with the direct edit option you can now handle this by cell basis.

  5. VectorMEP contains additional tools to model pipes in your drawing. They are not as detailed as the extended library of digitalcarbon but they do benefit from being a dedicated tool that has proper snapping, auto creation of fittings and several display options in 2D and 3D.

     

    This example shows ducts, but the piping tools work exactly the same.

     

  6. I looked into my notes and found this list of events that occur on specific triggers. Looking at these events, it seems that to move an object to another layer it's destroyed and recreated after, or at least those states are triggered. The internal index of the object stays the same though.

     

    With the SDK you can actually catch that exception when looking at the data provided in the event 14, but I'm unsure if this is available in Vectorscript.

    afbeelding.png.725c0e580a10d2cad726e8b9139c9e70.png

    afbeelding.png.5faa64536c5f98a1e684ca9b415485f8.png

  7. 2 minutes ago, DomC said:

    vs.ResetObject() actually regenerates the pio and change the geometry after with vs.SetRField() parameters are changed and I tried also 1167. The specific thing here is, that the cabinet contains also plugins (Custom Parts) which maybe are not reseted as expected and the additional relations of fittings interact with the parts and not directly with the cabinet maybe. I will give accessing the sub-pios of the cabinet and if that not will not be of use i will wait for another solution. 

    Already I am in contact with the genius devs from extragroup but there are always some other more important tasks to address so I wondered if i could bypass this limitation on the script-side.
     

     

    As there are a lot of possibilities in how subobjects are generated and can interact with eachother and parent objects this can be hard to do. Lets hope they find the time to help you out 😉

  8. You can't create your own event types, but you can tag along an existing one.

     

    I think you are overthinking this. What about using a parameter value to execute that specific action? That way, you only need to trigger the action by setting that record field/parameter to a specific value prior to resetting the object. Your object code can filter that value and decide what to do during the recalculate event.

    Setting that value and resetting the object can be done from anywhere as long as you have a refrence (HANDLE) to that object.

     

    • Like 2
  9. Vectorscript based tools/menu commands only live within their own event. They can't catch other events unless they are triggered.

     

    You can do this with the SDK. You could still keep the XML export as a vectorscript and make a small SDK project that triggers a vectorscript/menu command on a specific event.

     

     

    • Like 1
  10. 2 hours ago, JBenghiat said:

    @Hippocode I’m just curious where you’re storing the cursor values so you can retrieve it after the event, especially when multiple objects are selected. A custom parameter seems like the easiest option, but that seems like a lot of overhead. 

     

    In my case it was stored within the drag event sink itself, I believe you are trying something different. I would guess these two options could be useful?

    - Using "VWDataSerializerSimple" class to store the data directly into the object. I'm using this more and more because it's less work to maintain compared to records and fields.

    - In case the value is unique you could also store in permanent memory by using a VCOMImmediateImpl<IVWSingletonUnknown> interface. You could import/export into a custom interface which is accessible during the full execution of Vectorworks. Remember to handle document changes etc if you go this route.


     

  11. I think that is exactly what you should do. I'm using this in one of my tools in "OnDrag()" and it does the job.

     

    Quote

        WorldPt3 CurrentPoint;
        gSDK->GetToolPtCurrent3D(CurrentPoint);
        
        WorldPt3 DragOrigin;
        gSDK->GetToolPt3D(0, DragOrigin);   

        WorldPt3 DraggingOffset = CurrentPoint - DragOrigin;
        WorldPt3 DraggingDirection = DraggingOffset; DraggingDirection.Normalize();
        DraggingOffset.z += (WorldCoord) Utility::GetLayerElevation();

     

  12. Option 2 is probably the hardest because you have to be carefull with undo and manage all actions properly for two objects that are "bound" on a parametric base.

     

    There is another option 3. In the SDK you can choose if the recalculate event removes everything prior to recreation. The inner object would reside permanently in the outer. For simplicity option 1 is probably the best choice.

     

    It also depends of the interaction you need. Does the outer control the inner? Or in reverse order? If it's just a couple fields you could duplicate them in the parent object, which update the inner object with those same fields. This is probably the easiest method.

    If you use the option of the profile group, the benefit is that you can have a button in the info palette that opens the profile group and preselects the inner object, from that point the inner objec's palette is shown for direct access. On exit, you can have the parent object reset and use the new values.

     

    You can  also extend the object info palette with custom fields that are linked to any object or data as long as you handle the conversion as you need to bypass the normal translation from/to, I'm doing this with several plug-ins combined with a selector widget (kWidgetSubSelection) that allows me to iterate several inner objects within the object info palette. This is great for a couple fields but those other options are probably better for larger palettes.

     

    Some small snippets for indication.

     

    bool IProvider_MEPComponent::OnWidgetChange(SShapePaneWidgetOnWidgetChange& data, bool& outNeedReset, bool& outChangeOk)
    else if(fWidgetsContainer.IsWidget(WidgetId, "ToggleLegs"))
        {
            outNeedReset = false;
            eventHandled = false;
            
            using namespace VectorWorks::Extension;
            
            if(fLegs.size() > 0)
            {
                IShapePaneWidgetAccess::ESubSelButton CurrentButton = data.fWidgetAccess->GetCurrentButton();
                if(CurrentButton == IShapePaneWidgetAccess::ESubSelButton::eSubSelButton_CurrentButtonDown)
                {
                    HighlightActiveLeg(&data);
                }
                else if(CurrentButton == IShapePaneWidgetAccess::ESubSelButton::eSubSelButton_NextButtonDown)
                {
                    fNumActiveLeg++;
                    HighlightActiveLeg(&data);
                }
                else if(CurrentButton == IShapePaneWidgetAccess::ESubSelButton::eSubSelButton_PrevButtonDown)
                {
                    if(fNumActiveLeg == 0)
                    {
                        fNumActiveLeg = fLegs.size() -1;
                    }
                    else
                    {
                        fNumActiveLeg--;
                    }
                    
                    HighlightActiveLeg(&data);
                }
                
                else if(CurrentButton == IShapePaneWidgetAccess::eSubSelButton_CurrentButtonUp || CurrentButton == IShapePaneWidgetAccess::eSubSelButton_NextButtonUp || CurrentButton == IShapePaneWidgetAccess::eSubSelButton_PrevButtonUp)
                {
                    data.fWidgetAccess->ClearHighlightPoint();
                    data.fWidgetAccess->SetValueBool(data.fViewWidget, false);
                }
            }
        }

     

     

    You need to manage TransferValue in both directions for widgets not bound to default parameters of your object. In this case I'm referencing data from whichever inner object is the active selection from the previous selector widget.

    bool IProvider_MEPComponent::TransferValue(VectorWorks::Extension::SShapePaneWidgetTransferValue &data)
    {
        using namespace VectorWorks::Extension;
        
        bool handled = false;
        
        // For some widgets we need to switch over the record format to the active connector...
        if(
           fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_DimensionType") ||
           fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Length") ||
           fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Shape") ||
           fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Width") ||
           fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Height")
           )
        {
            if(fLegs.size() > 0)
            {
                sUserData_JunctionLeg* pLeg = &fLegs[fNumActiveLeg % fLegs.size()];
                
                if(data.fTransferToView)
                {
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_DimensionType"))
                    {
                        TXString strValue;
                        strValue.itoa(pLeg->DimensionType);
                        data.fWidgetAccess->SetValueString(data.fViewWidget, strValue);
                    }
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Width"))data.fWidgetAccess->SetValueString(data.fViewWidget, pLeg->NominalWidth);
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Height"))data.fWidgetAccess->SetValueString(data.fViewWidget, pLeg->NominalHeight);
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Shape"))
                    {
                        TXString strShape;
                        strShape.itoa(pLeg->Shape);
                        data.fWidgetAccess->SetValueString(data.fViewWidget, strShape);
                    }
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Length"))data.fWidgetAccess->SetValueReal(data.fViewWidget, pLeg->Length, IShapePaneWidgetAccess::eRealType_Coord);
                }
                else
                {
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_DimensionType"))
                    {
                        pLeg->DimensionType = (VWFC::VWObjects::sUserData_JunctionLeg::eLegDimensions) data.fWidgetAccess->GetValueString(data.fViewWidget).atoi();
                    }
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Width"))pLeg->NominalWidth = data.fWidgetAccess->GetValueString(data.fViewWidget);
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Height"))pLeg->NominalHeight = data.fWidgetAccess->GetValueString(data.fViewWidget);
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Shape"))
                    {
                        pLeg->Shape = (eShape) data.fWidgetAccess->GetValueString(data.fViewWidget).atoi();
                    }
                    if(fWidgetsContainer.IsWidget(data.fWidgetID, "Leg_Length"))pLeg->Length = data.fWidgetAccess->GetValueReal(data.fViewWidget, IShapePaneWidgetAccess::eRealType_Coord);
                    
                    // Save user data back into junction and reset it..
                    VWMEPJunctionObj JunctionObj(fhObject);
                    JunctionObj.SaveLegs(fLegs);
                    JunctionObj.ResetObject();
                }
    
            }
    
            handled =  true;
        }

     

  13. Make sure you are compiling with at least 10.15, target should be 10.13. If you still have an issue I find the easiest way to tackle this is to start fresh from a sample project and copy over your custom files and settings. Old projects can contain deprecated settings and after a while it's hard to find what is used and what not. Also make sure you compile generic to cover both ARM64 and Intel.

     

     

     

  14. 2 hours ago, Thomas K. said:

    Any news regarding that type of plug-in? I am still on the road to find an "easy" way to get all that project data into my file to get the same data to these different positions.

    It will be part of the VectorMEP 2022 release which should be available during September 2021.

×
×
  • Create New...