Jump to content


  • Posts

  • Joined

  • Last visited

Posts posted by Hippocode

  1. I'm using the CParametricCustomBar wrapper class instead.

    This example comes from a cursor event that shows and allows to change the angle between two lines.


    I initiate it on OnCursorAction_MouseDown on first click

                fAngleBar.SetFieldLock(0, false);


    On any other click, within the same function I close it because what I was doing has completed.



    while mousemove I modify the value to match the situation:

            gSDK->CustomBarSetFieldAngle(fAngleBar.GetCustomBarID(), 0, Utility::GetAngleBetweenVectors(-V1, VDir));


    • Like 2
  2. You can handle creation/deletion/position as mentioned on that page. Depending on how flexible this should be I do this on kobjectCreated event or in the recalc event.


    But for managing the images, displayed hover text and other specific actions I advice to use the IProviderCursorHandles interface. This also replaces the old code you mentioned. The interface will catch these events.

    • Like 1
  3. Hi Julian


    I have only tested this with the SDK but this is the equivalent function in VS.



    The kObjXPropSpecialEditEditGroup constant should get you into the profile group. I'm calling this from a button widget on the OIP.

    const TObjSpecialEdit kObjXPropSpecialEditDefault = 0;
    const TObjSpecialEdit kObjXPropSpecialEditCustom = 1;
    const TObjSpecialEdit kObjXPropSpecialEditProperties = 2;
    const TObjSpecialEdit kObjXPropSpecialEditReshape = 3;
    const TObjSpecialEdit kObjXPropSpecialEditEditGroup = 4;
    const TObjSpecialEdit kObjXPropSpecialEditSpecial = 5;


    • Like 1
  4. It seems that the editing dialog / OIP controls the data and since the record is read only you won't have access.

    I couldn't find anything in the SDK related to this special hidden record type (besides some kludge calls) . I find it interesting myself as I'd like to have readonly records as well;


    @Vlado Is this feature exposed to VS / SDK?

  5. The typical way is to hide it from the resource browser. Just like object format records are not visible. If that isn't sufficient you might try working with catching the kNotifyRecordChange event but I doubt you can catch the exact change, you could compare this from a default sitting in your resource library.

  6. For exactly the same reason I did save this data within the plug-in itself. I attached the data to the object handle itself or using parameters.

    Because the objects are accessible you can determine versions etc..

  7. I believe when creating a symbol from the VWSymbolObj wrapper class it's not properly attached to a container, in your case the active layer.

    Try additing it manually after you create the symbol, and before you reset it using "gSDK->AddObjectToContainer"


    • Like 1
  8. Have a look in this topic:

    If you don't create something, your can use other functions to traverse the workspace, find the palette by name or identifier and use that handle to show/hide these.

  9. Well it could be any of these settings. I'm setting all these to show the palette in a specific spot.


                        bool inTearOffState = false;
                        bool inTopPosition = false;
                        Sint16 ToolinSortStyle = 1;
                        Sint16 ToolinViewStyle = 2;
                        Sint16 ToolSetinSortStyle = 1;
                        Sint16 ToolSetinViewStyle = 2;
                        bool inVisibilityState = true;
                        bool inWindowShadeState = false;
                        EWindowHomeCorner inHomeCorner = EWindowHomeCorner::eWindowHomeCorner_ScreenUpperLeft;
                        Sint16 inHorizontalOffset = 0;
                        Sint16 inVerticalOffset = 0;
                        ViewRect screenRect;
                        ViewPt Center = screenRect.Center();
                        inHorizontalOffset = +Center.x;
                        inVerticalOffset = +Center.y;
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetTearOffState(inTearOffState);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetToolSetPosition(inTopPosition);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetToolSetSortStyle(ToolSetinSortStyle);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetToolSetViewStyle(ToolSetinViewStyle);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetToolViewStyle(ToolinViewStyle);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetToolSortStyle(ToolinSortStyle);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetVisibilityState(inVisibilityState);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetWindowShadeState(inWindowShadeState);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetHomeCorner(inHomeCorner);
                        if(VCOM_SUCCEEDED(errorCode)) errorCode = pToolPalette->SetHomeCornerOffset(inHorizontalOffset, inVerticalOffset);


  10. Is there any way we can provide a link to our own help documentation/wiki when creating tools with the SDK? When you hit F1 on default tools you end up on the specific article explained in the Vectorworks help.

  11. Make sure that the workspace interfaces are initiated correctly. This is a snippet of my workspace wrapper class and confirmed to be working:

    VCOMPtr<IWorkspaces> pWorkspace(IID_Workspaces);
    // Get current workspace file name.
    TXString workspaceFileName;
    // Current workspace full file name.
    TXString workspaceFullFileName = workspaceFileName + ".vww";
    VCOMPtr<IWorkspaceFile> pWorkspaceFile(IID_WorkspaceFile);
    if(pWorkspaceFile && pWorkspace)
    		errorCode = pWorkspaceFile->Open(workspaceFullFileName, kFileReadPermission);
    		VCOMPtr< IWorkspaceToolPalette >		pToolPalette;
            VCOMPtr< IWorkspaceTool >				pTool;
            TXString ToolPaletteName = "VectorMEP";
            TXString ToolPaletteIdentifier;
            if(VCOM_SUCCEEDED(errorCode)) errorCode = pWorkspace->CreateIdentifier(VectorWorks::Workspaces::EWorkspaceItemType::eWorkspaceItemType_ToolPalette, ToolPaletteIdentifier);
            if(VCOM_SUCCEEDED(errorCode)) errorCode = pWorkspaceFile->CreateToolPalette(ToolPaletteIdentifier, &pToolPalette);


    • Like 1
  12. In short:


    Only the creator of the voids requires a VectorMEP license. All the other communication tools are free.

    The mapping tool allows you to predefine filters of objects you would like to compare. For instances all pipes versus floors. You can even define a parameter value to filter even further.
    You can also setup additional dimensions when creating voids, based on some categories. If you map a "pipe" as "Plumbing" category, the additional offsets will be used as set in the dimensions dialog.


    Person A creates the voids by selecting the mappings.

    Person B references the file that contains the voids.

    Person B can now manage the status and comments of these voids within his own project.

    Person B can export his modifications to an XML file.

    Person A imports the XML file, which updates the status and any comments of each void.

    This process can be repeated.


    Note the the openings are only created for those objects that support it, but in both cases the void object will be present.

    You can create unlimited void mappings based on object names and optionally based on a parameter value. Also supports custom objects.


    I'm about to update some of it's functionality so wait a tiny bit if you plan on testing it out.

  13. 4 hours ago, str said:

    I follow this topic with great interest. A while ago I bumped into this by @Hippocode but it looks like is meant for mep design rather than architectural design.




    This plug-in is part of our VectorMEP bundle. It's not meant to be a clashing tool, but rather a tool that automates openings and allows you to communicate about it.
    While the example shows automated voids between pipes and walls, the tool allows you to select any kind of "clashing" object, thus not limited to MEP design.
    It also allows you to export/import voids between users as a communication tool. You can add comments, accept or deny void suggestions etc...


    Showcase video:



    • Like 2
  14. Couldn't find any constant to read that property in the minicads file. I vagely remember when building lists the filename was used as prefix or something similar but that would require you to build a huge list of all available resources, which is still a valid possibility. From looking at this article, one of the other similar functions will probably return the filename within the symbolname if from an external file, but it might only work if those are duplicate: http://developer.vectorworks.net/index.php/VS:GetActualNameFromResourceList


    You could also try using the IResourceManagerContent VCOM interface to search for the specific symbols, maybe some of the functions also return the filename.

  15. I faced a similar issue trying to find out if some of my custom plug-ins were referenced or not. I used the following approach which seemed to work as the "IsObjectFromReferencedFile" function didn't (always) return the expected results you can just look at the object's layer name instead.


    	// Referenced?
    	fInfo.IsReferenced = gSDK->IsObjectFromReferencedFile(this->GetThisObject()) || gSDK->IsViewportGroupContainedObject(this->GetThisObject(), kViewportGroupCrop);
    	// Since above doesn't work :(
    	MCObjectHandle hLayer = this->GetParentLayer();
    	if(hLayer && VWLayerObj::IsLayerObject(hLayer))
    		VWLayerObj L(hLayer);
    		TXString strLevel = L.GetName();
    		fInfo.IsReferenced = strLevel.Find("NNA") != -1; // NNA seems to be put in all referenced layers, so any object that is referenced matches this parent layer name.


  16. I can provide you with some other samples if you need some. They come in handy sometimes, the benefit is that such a tiny script has access to your complete SDK. If you have SDK bases plug-ins you can use this to make certain data or functionality accessible through VS.

    I have made several of those for my plug-ins. e.g.:

    The ability to activate our license to use our software for the current session, bypassing our default activation method. It requires a custom hash to unlock the current specific day.




    • Like 1
    • Love 1
  17. I removed the quarantaine of the buildvwr tool instead of disabling scrutil so I can see the error messages myself.

    Signing alone doesn't do it and I'm unable to create an archive of the plugin in order to get it notarised (Also tried it on the TesterModule sample). Has anyone done this before? I'll see if I can do it manually using terminal instead.




  18. All of them as zipped files (download available on a website or Google Drive). Some bundles support the third party plug-in installer within Vectorworks, which requires the files to be zipped.
    I also zip them because some browsers/cloud solutions rename extensions and capital letters in the VWR resource on download/zip which breaks the plug-in.


    I can't really imagine doing this without these files being zipped 😮

  19. On 10/17/2019 at 6:37 AM, JBenghiat said:

    At the moment, the solution is to use csrutil to disable System Integrity Protection. I’m not sure if there is a longer term fix with adjusting entitlements.


    Thanks, this helped me out on the developer side. But clients are now reporting Vectorworks prevents them of using the plug-in because of restrictions obviously...

    Do we need to modify some settings of our projects for them to be accepted somehow?

  20. Hi


    There is not much to be done, as most of it should be handled by the default implementation.

    I use a custom class (VWStyledParametricObj) to help with this which I attached (had to zip it as the file extensions weren't allowed). This class also holds some comments on what each action is for.


    This is an example of how I implemented it:


    EObjectEvent ElectricalDevice_EventSink::OnEditPluginStyle(MCObjectHandle symDefHandle)
    	return VWStyledParametricObj::OnEditPluginStyle_Default(symDefHandle);
    EObjectEvent ElectricalDevice_EventSink::OnCreatePluginStyle(MCObjectHandle symDefHandle)
    	return VWStyledParametricObj::OnCreatePluginStyle_Default(symDefHandle);
    EObjectEvent ElectricalDevice_EventSink::OnUpdateStyledObject(MCObjectHandle symDefHandle)
    	// Copy over the saved references...
    	EPluginStyleParameter ParameterStyle = gSDK->GetPluginStyleParameterType(fhObject, "__ManageOperatingAreas");
    	if(ParameterStyle == kPluginStyleParameter_ByStyle)
    		VWSymbolDefObj symDef(symDefHandle);
    		MCObjectHandle hObject = symDef.GetFirstMemberObject();
    		if(hObject && VWDeviceObj::GetDeviceType(hObject) != eDeviceType::kUnkownDevice)
    			sOperatingAreaArray Areas;
    			OperatingArea::Get(hObject, Areas);
    			OperatingArea::Save(fhObject, Areas);
    	return VWStyledParametricObj::OnUpdateStyledObject_Default(symDefHandle);
    EObjectEvent ElectricalDevice_EventSink::OnFinalizeCreatePluginStyle(MCObjectHandle symDefHandle)
    	/*EObjectEvent Result =*/ VWStyledParametricObj::OnFinalizeCreatePluginStyle(symDefHandle, VWDeviceObj::GetStyleMap());
    	return VWStyledParametricObj::OnFinalizeCreatePluginStyle_Default(symDefHandle);
    EObjectEvent ElectricalDevice_EventSink::OnFinalizeUpdateStyledObject(MCObjectHandle symDefHandle)
    	return VWStyledParametricObj::OnFinalizeUpdateStyledObject_Default(symDefHandle);



  21. I believe this does sort of the same, but only on the visible part of the screen instead of all objects:

    void Utility::RefreshView()
        WorldCoord perspectiveDistance, clipDistance;
        WorldRect clipRect;
        gSDK->GetPerspectiveInfo(gSDK->GetActiveLayer(), perspectiveDistance, clipDistance, clipRect);


    Also, I tend to draw all temporarily objects using these two functions on these events:


    void X_EventSink::DoSetDown(bool bRestore, const IToolModeBarInitProvider* pModeBarInitProvider)
    void X_EventSink::MouseMove()
    void X_EventSink::ClearAllToolInteractiveObjects()
    			VectorWorks::IToolInteractiveDrawPtr toolInteractive;
    			gSDK->GetCurrToolInteractiveDraw( & toolInteractive );
    			if (toolInteractive)
    		void X_EventSink::UpdateToolInteractiveObjects()
    			VectorWorks::IToolInteractiveDrawPtr toolInteractive;
    			gSDK->GetCurrToolInteractiveDraw( & toolInteractive );
    			if ( toolInteractive )
    				size_t	ptCnt	= this->GetToolPointsCount();
    				if ( ptCnt > 0 )
    					// Create full path
    					VWPolygon3D poly;
    					for(size_t i=0; i < ptCnt; i++)
    					VWPoint3D	MousePosition;
    					this->GetToolPtCurren3D( MousePosition );
    					if((fModeBarState[ModeGroup::Mode_H_Outline] != eHAlign::kHAlign_Center) || (fModeBarState[ModeGroup::Mode_V_Outline] != eVAlign::kVAlign_Center) || fSlope != 0)
    						eHAlign HAlign = static_cast<eHAlign>(fModeBarState[ModeGroup::Mode_H_Outline]);
    						eVAlign VAlign = static_cast<eVAlign>(fModeBarState[ModeGroup::Mode_V_Outline]);
    						poly = MathUtilsExt::GenerateOffsetPolygon(poly, HAlign, fH_Offset, VAlign, fV_Offset, fSlope);
    					VWPolygon3DObj	polyObj( toolInteractive->GetObject( qPolyNode ) );


  22. How do we properly support IFC mapping for our custom objects?


    - Do we need to add default mapping sets on document open? I noticed that the default mapping dialog only shows native objects.

    - Do we need to handle the mapping ourselves or is it done by Vectorworks on export? Is there a specific event triggered to apply the mapping or should we just do it in the Recalculate event?




  23. On 8/22/2018 at 12:54 AM, WhoCanDo said:

    I'll use that while everyone is waiting for the attached records to be put back into the OIP for quick and easy deletion. 🎉




    Assuming this won't happen anytime soon... this could be solved by a simple script that lets you filter your selection, by choosing one of the records attached to your selection from a drop down menu.

  • Create New...