Jump to content

Calling a Python/VectorScript procedure from the SDK using CallUserProcedure


Recommended Posts

Posted (edited)

I have a (hopefully) simple question about the usage of VectorWorks::Scripting::IPythonScriptEngine and or IVectorScriptEngine. I want to call a procedure that is not available in the SDK but is available in both python and vss.

I want to call SaveSheet, which saves the current view, layer settings and more in a saved view (saved views used to be called sheets). The closest equivalent in the SDK that I could find was ISDK::CreateSavedViewWithUI, which does the same but instead opens up the dialogue that you would see when you manually create a saved view via the UI. Basically, I want to create a saved view without the UI.

 

An obvious starting point to achieve what I want seems to be VectorWorks::Scripting::IPythonScriptEngine and VectorWorks::Scripting::IVectorScriptEngine and I also got it to work quite fast:

VCOMPtr<VectorWorks::Scripting::IPythonScriptEngine> pythonScriptEngine{ VectorWorks::Scripting::IID_PythonScriptEngine };
VCOMError err = pythonScriptEngine->ExecuteScript("vs.SaveSheet(\"Test\", True, True, True)");


This might be easy to use but I don't like the fact that I have to concatenate a string if I want to change any of the parameters. For this case, both of the ScriptEngines seem to offer a function called CallUserProcedure. I think it does what I want but in a more type safe manner

 

Now finally for my questions. Can CallUserProcedure be used to call SaveSheet? Is this even the correct function that I'm trying to use or does this something completely different?

I'm also struggling to find out what the first parameter "procedureRef" has to be to achieve this call.

This is what I think it would look like with CallUserProcedure but it's missing the procedureRef

VCOMPtr<VectorWorks::Scripting::IPythonScriptEngine> pythonScriptEngine{ VectorWorks::Scripting::IID_PythonScriptEngine };
PluginLibraryArgTable argTable {
  .args = {
    {
      .argType = kStringArgType,
      .strValue = "Test"
    },
    {
      .argType = kBooleanArgType,
      .boolValue = true
    },
    {
      .argType = kBooleanArgType,
      .boolValue = true
    },
    {
      .argType = kBooleanArgType,
      .boolValue = true
    }
}};
void* procedureRef = nullptr; // ???
VCOMError err = pythonScriptEngine->CallUserProcedure(procedureRef, &argTable, 4);

 

Edited by JHangstoerfer
Link to comment

Take a look at VWFC::VWObjects::VWViewObj.

 

As for ExecuteScript, concatenating the string is not too hard — just use +. You can also use single quotes as your string qualified to avoid having to escape them.

 

I believe CallUserProcedure only works for procedures you have registered and can therefore get the callback pointer.

Link to comment
16 hours ago, JBenghiat said:

Take a look at VWFC::VWObjects::VWViewObj.


VWViewObj only is for temporary saved views like when you want to change camera, layers and then restore to how it was previously afterwards. For creating a saved view that shows up in the navigation palette there is ISDK::CreateSavedViewWithUI or the python/vss SaveSheet. To modify a saved view you also need to use the ISDK calls directly as VWViewObj operates on a duplicate.

 

16 hours ago, JBenghiat said:

As for ExecuteScript, concatenating the string is not too hard — just use +. You can also use single quotes as your string qualified to avoid having to escape them.

 

I believe CallUserProcedure only works for procedures you have registered and can therefore get the callback pointer.


I know it's not hard but I would have rather used a type safe way instead of converting everything to string myself.
Alright, if CallUserProcedure doesn't do what I expected then I guess I will be using the ExecuteScript method.

Link to comment
1 hour ago, JHangstoerfer said:

VWViewObj only is for temporary saved views like when you want to change camera, layers and then restore to how it was previously afterwards. For creating a saved view that shows up in the navigation palette there is ISDK::CreateSavedViewWithUI or the python/vss SaveSheet. To modify a saved view you also need to use the ISDK calls directly as VWViewObj operates on a duplicate.

 

It looks like the saved view is actually a script with a view object attached. Untested, but in theory:

- Use ISDK::CreateScriptResource to create a new script in the "Saved Views" palette. The name of the script is the name of the view.

- Use VWViewObj to create the view

- Set the parent of the view object to the aux list of the script object

Edited by JBenghiat
Link to comment
5 minutes ago, JBenghiat said:

 

It looks like the saved view is actually a script with a view object attached. Untested, but in theory:

- Use ISDK::CreateScriptResource to create a new script in the "Saved Views" palette. The name of the script is the name of the view.

- Use VWViewObj to create the view

- Set the parent of the view object to the aux list of the script object

 

I thought of manually creating the script object but there are way too many edge cases that I would want to deal with. Like "Saved Views" palette name being a localized text, or when someone renamed "Saved Views", or it already exists as a different object, doesn't exist yet at all and more. There's probably even more that happens in the background that I don't know of so I'd rather use the script function to do all of this for me.
 

Be careful with VWViewObj, because it deletes the view that it creates/duplicates in its dtor. That's why I mentioned that it's really only used for temporary views.

VWViewObj::VWViewObj()
{
	fhViewObj = gSDK->ViewCreateCurrent();
}

VWViewObj::VWViewObj(const VWViewObj& src)
{
	fhViewObj = gSDK->ViewDuplicate( src.fhViewObj );
}

VWViewObj::VWViewObj(MCObjectHandle hView)
{
	VWFC_ASSERT(VWViewObj::IsViewObject(hView));

	if (!VWViewObj::IsViewObject(hView))
		THROW_VWFC_EXCEPTION(VWBadObjectTypeException, 0, "bad handle type when creating");

	fhViewObj = gSDK->DuplicateObject( hView );
	fhObject = fhViewObj;
	VWFC_ASSERT(fhObject != nil);
}

VWViewObj::~VWViewObj()
{
	gSDK->ViewDelete( fhViewObj );
	fhViewObj = NULL;
	fhObject= NULL;
}

 

 

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