Jump to content

Getting started with VWorks SDK 2022


Myke

Recommended Posts

hello,

 

I am looking to create a plugin using the VWorks SDK, but am finding the README documentation to be inconsistent. I believe that I have all of the required components, Visual Studio 2019, Xcode, and the latest SDK. Could someone walk me through setting up my IDE to import the SDK? To clarify I would like to use VS over Xcode.

 

Thanks

Link to comment

You're not going to find a lot of documentation, I'm afraid. Even the release notes haven't been updated in years. https://developer.Vectorworks.net has some useful tidbits, though, even for articles that are out of date.

 

The best place to start is to look in the source/samples folder of the SDK. TesterModule will provide a basic framework for most plug-in types. EmptyModule is a good project to duplicate and modify from there.

 

When the project is setup correctly, and you switch to the Property Manager tab of VS, you'll see a number of property sheets installed under the configuration:

image.png.c01cb0c09b03aa1d05702bf94bd65692.png

 

If you are in a debug config, RELEASE should be DEBUG.

 

You can right-click on the build configuration and choose Properties… Anything that is overriding the property sheets will be in bold. I tend to get rid of any overrides here, and set them in my own property sheet so that I can include it in all projects.

 

Here are the additional configuration settings from my property sheet:

Compiled plug-ins will only work with the corresponding Vectorworks version, so I have a property sheet for each year where I define a version variable, and use that to modify both the output directory and the SDK include directories.

General

  Output directory — customize this using macros so be an absolute path and unique for each yearly version

  Intermediate directory — similar, so rebuilding multiple versions is faster

VC++ Directories

  Include Directories — I add:

    $(SolutionDir)Source\Prefix

    $(SolutionDir)Source

    C:\VWSDKWin2022\SDKLib\Include — I have a folder for each version's SDK that I'll copy the SDKLib into. This makes it easier to update when a new SDK build is released, as well as update my config files each year using a simple find and replace.

    I also add the path to any custom header libraries here

C/C++

  ASM List Location: $(IntDir)

  Basic Runtime Checks: Default

  Debug Information Format: ProgramDatabase (/Zi)

  Object File Name: $(IntDir)

  Optimization: Maximum Optimization (Favor Speed) (/O2)

  Precompiled Header: Use (/Yu)

  Precompiled Header File: StdAfx.h

  Preprocessor Definitions: __FP__;WIN64;<Inherit>

  Program Database File Name: $(IntDir)

  Runtime Library: Multi-threaded DLL (/MD)

  Security Check: Disable Security Check (/GS-)

  Smaller Type Check: No

  Treat WChar_t As Built in Type: Yes (/Zc:wchar_t)

  Warning Level: Level3 (/W3)

Linker

  Additional Dependencies: VWSDK.lib;5(AdditionalDependencies)

  Additional Library Directories: {path_to_your_VWSDK_install}\SDKLib\LibWin\Release

  Generate Debug Info: No (For the release build)

Build Events

  — This is what builds your Vectorworks resource .vwr file

  Command line:

REM VWR Resource build script
set VWR_INPUT=$(ProjectDir)$(TargetName).vwr
set VWR_OUTPUT=$(TargetDir)$(TargetName).vwr
set VWR_MODE=$(Configuration)
set VWR_7ZCMD={path_to_your_VWSDK_install}\SDKLib\ToolsWin\BuildVWR\7z
"{path_to_your_VWSDK_install}\SDKLib\ToolsWin\BuildVWR\buildvwr.exe"

 

 

Debugging has its own complications, and the developer wiki has a guide.

 

Note, for testing, VW will load shortcuts in Windows and aliases in MacOS for the user plug-ins folder, so you can just reference your built file and not worry about copying it for testing (and this is actually necessary for debugging).

 

Note that you ask about both VS and Xcode. While you can do your primary development in one platform or the other, if you want to compile for cross-platform use, you must use the corresponding IDE for to build for each platform.

Link to comment

Wow! Thanks for the replies this information will be really helpful to me. My last question that I have is whether or not I could use C# over C++? If I understand correctly some of the SDKs functionally can be loaded into a DLL and then be referenced from a C# environment. I would like to use C# because I am more familiar with its syntax as mainly a Java dev.

 

Anyway thanks again!

Link to comment
  • Vectorworks, Inc Employee
On 12/18/2021 at 7:54 PM, Myke said:

My last question that I have is whether or not I could use C# over C++? If I understand correctly some of the SDKs functionally can be loaded into a DLL and then be referenced from a C# environment.

 

Hi @Myke it is possible to make C# plugins, but that is connected with having to build your own bridge between C++ and C# as all of the Vectorworks SDK is in C++. I'm afraid it wont be as simple as loading DLL. I mean it could be, but you'll have to create your DLL to load in the C# environment.

 

Again, it's not impossible, but it might require more work in C++ that anticipated.

 

Also, I'm not sure how C# would work on the Mac, if there is a requirement to work on the Mac.

 

Depending on the complexity on your project, it might be better to stick with C++. But if it is complicated, it might worth it to build your own C++/C# transition layer.

Link to comment

Thanks for the help! I have another question but this time regarding the UUID and how to exchange data between Vectorworks and the SDK. Specifically regarding symbol data such as speakers and lights. Is there a specific method or function in the SDK that facilitates this transaction? 

 

Thanks!
 

Link to comment
  • Vectorworks, Inc Employee
15 hours ago, Myke said:

but this time regarding the UUID

This is a unique identifier, used to uniquely represent an interface, or implementation of an interface.

You can generate unique identifiers for your plugins, here is some information on how:

https://developer.vectorworks.net/index.php/SDK:Generate_UUID_for_Extensions

 

15 hours ago, Myke said:

how to exchange data between Vectorworks and the SD

The SDK is an API that accesses the Vectorworks model.

I guess you should familiarize yourself with the Vectorworks model:

https://developer.vectorworks.net/index.php/SDK:The_Vectorworks_Environment

 

Then look at the VWFC::VWObjects namespace, and you'll see wrapper classes for the various types in the model.

 

Link to comment

Hmm,

 

I doubt this will be my last question, but I seem to be having trouble getting a simple std::coat << "Hello, World" << std::end; out of the program (with an int main() function around it. Everything builds successfully, but nothing is outputted to the terminal. I usually use the command line interface to test and check functionality before I scale it to a proper GUI. If you have any tips regarding this I would appreciate it.

 

Thanks

Edited by Myke
Link to comment

The standard build target isn’t an executable, so you’re not going to get any output when you build. Simple testing isn’t quite so straightforward. 
 

You can set up a separate target just for testing, but you have to make sure that vwmm is accessible as well as have a good sense for when you need to mock any data that comes from interacting with Vectorworks. You can also set your plug-in to generate test output within Vectorworks, but it needs to output to a log or dialog or use the VW testing interface. There’s not really such thing as a standard output. 

Link to comment

 

I think I managed to figure something out regarding the testing, although there are some kinks to workout. Building the plugin for data exchange is my next move and I have some more questions.

 

I took a bit of deep dive into some of the SDK files looking for method(s) that would allow me to build a plugin that can dynamically send LightFixtureSymbol data (Symbol_Name, Channel_Num, etc) to an external program that I would build and then send that data back.

 

If you know of a specific method in the SDK I would very much like to know.

 

Some methods/functions I have questions about:

 

ForEachObject()
The documentation seems to be clearer on this method but the return type is virtual void. Is this to be overridden in a user created derived class and then specified with a return type?  If a user is going to implement this method are there any guidelines to structuring it?

 

ForEachObjectInList()

Unfortunately there is less information on this method, the name suggest that it deals with objects in a list. Should I assume that the use of ForEachObject() would generate the list and then

 

GetObjectVariable(..)

I am not sure what the return type is. If its just a list of strings then that’s more than enough. Also within its parameters can you specify what type of object your looking for? Such as passing 2 to see if its a lineNode?

 

GetObjectPropertyChar(…)

Continuing on from the aforementioned, am I correct in assuming that this is more specific? Such as returning line thickness or length. Is there a list of inPropID’s

 

traverseWhat;

What is the difference between: allDrawing and allSymbolDef and which, if either, would give me access to the properties?

 

 

This might be a bit early, but find holes in my logic earlier in the process is preferable to later. Assuming what I’ve searched building a method for retrieving LightFixutureSymbol data might look like

 

private ArrayList<AnotherClass> instrumentData

 

 

struct InstrumentData

{

string symbol_Name; //or const char*

short channel_Num;

}

 

void MyCallBack( Handle h, CallBackPtr cbp, void* placeholder){ // Correct me if I’m wrong but the void* seems like a placeholder for a chunk of data that’s doesn’t have a specified type, hence why I changed it from env to placeholder

InstrumentData* instData = (InstrumentData) placeholder;

…. //Not sure what comes after

}

 

ArrayList<AnotherClass> traverseObjectsForLights()

{

InstrumentData data;

gSDK->ForEachObject( allDrawing , MyCallBack, & data);  // What is the gSDK and why does the traversal need to be passed. Or does it call functionality from an interface.

// is the data now in my data object? Assuming it it

 

gSDK->ForEachObjectInList(81 [kLightNode], MyCallBack, callBackLamda) = 0; // Not to familiar with lambdas, but should I attempt to make one in the above struct class or is there another approach

// Presumably it returns something along the lines of

 

fixtureData = ForEachObjectInList().toArray()

 

for(int i = 0; i =< fixtureData.size; i++)

{

instrumentData.add(fixutreData.get(i));

// std::cout << instrumentData.get(i) << std::end; //Checking

}

return instrumentData;

}

 

 

I hope this isn’t too much, and if I haven’t mentioned already I am a bit of a novice when it comes to programming.

 

Thanks

Link to comment

Are you looking to export data based on a manual menu command? If you're not looking to have the data exchange based on automatic triggers, you may want to try scripting with Python instead of the SDK. If you're new to the VW file structure and want to check your work with frequent console-like feedback, you'll find the process much easier. Plus, you have the added benefit of not having to wait for your new code to compile and VW to restart.

 

If you are committed to the SDK, I recommend learning how to use the debugger and viewing console output that way. Pure testing requires you to mock object data, and your code seems to be looking to test data retrieval, which you can't really do with a pure test.

 

Are you looking to retrieve information from Lighting Devices? A Lighting Device is a parametric object with the universal name "Lighting Device." That would be a kParametricNode, not a kLightNode, the latter giving you a render light object.

 

My sense is your code is adding too many layers of complexity.

 

Take a look at the VWParametricObj class. That will allow you both to test if the object is the desired PIO as well as retrieve parameter data the GetParam… calls. 

 

Use the "N" versions of ForEachObject… Those allow you to use lambdas, which is a much simpler way of exchanging data with the handler routine. They have the added benefit of allowing you to construct the handler routine in-line. The handler routines are designed to take one parameter of type MCObjectHandle. You want to process all drawing objects, unless you're confining your export to objects in a certain layer, only selected objects. etc.

 

FYI, python also has ForEachObject routines. For Python, you would take advantage of GetRField( handleToPIO, 'Lighting Device', fieldToRetrieve)

 

I suggest familiarizing yourself with the concept of handles, here and elsewhere 

 

Also take a look at the discussions on Debug List View, like this one. That will help you how Vectorworks structures its data.

 

Link to comment

Yes I am looking to have the on an automatic trigger hence the use of the SDK. To be clear I specifically want to know how to send lighting information out of VW, edit it (within reason), and then send it back in dynamically. I am hoping to reduce complexity while still affording those three conditions. 

 

I will definitely look at the Debug List view since I'll get a better idea of how the data is structured. Thank you very much for that.

 

I'll do more research and testing.

 

Thanks a lot!

 

Link to comment
Posted (edited)

 

I may have come across a better solution to my data transfer requirement. 

Using two Json files where VW plugin writes a files with the lighting device data, to be read by my program.
And my program reads the data edits it and then writes to a different Json file to be read by the VW plugin. 

I am trying to think of some automatic triggers that could be used to know when to send the changed data out again. Are there some smart ways of doing it. Or should I take a simpler approach and use a timer to send changes from VW and my program while also checking for changes from the other?

Edited by Myke
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...