PDA

View Full Version : Reload / update deformer plugin in a scene


zoharl
06-12-2012, 11:43 AM
Hi,

I started playing with deformer nodes, and I assume that what I'm looking for already lies around. The problem from the doc:

If you force the unload of a plug-in while it is in use, it will not be possible to reload node plug-ins. This is because existing nodes in the scene will have to be converted to "Unknown" nodes, and on plug-in reload, you will not be allowed to change the type of these existing nodes.


In practice if I use force, I need to restart maya afterwards, since I can't create a deformer node afterwards even in a new scene.

I'm looking for a two part script, which I can run with commandPort.exe in the pre/post build events in VS. The first part would locate all my deformer object in the scene, save their connections to a temporary file, delete them, and unload the plugin.
The second part would copy the new .mll, load it, create the deformer nodes, and reconnect them according to the temp file.

I assume that instead of saving the connections and restoring them, it would be easier to save the current scene in a temp file and reload it. But if the scene is big, it would be quite slow.

Also if anyone has other suggestions I would be happy to hear them out.

tontonsuspect
06-12-2012, 02:53 PM
Save your scene --> create a new empty scene( opening an empty scene/other scene flush the undo queue : you cant unload a plugin if an object in the undo queue needs it....). unload your plugin. Then you can transfer your new mll, load it in maya and reopen your test scene( though if your scene was saved while using a plugin the "requires" command in the header will normally load it ).

zoharl
06-12-2012, 03:10 PM
Yes, this is the method I was referring to towards the end of my post, but as I mentioned there's the limitation with big scenes that it takes time to reload them.

tontonsuspect
06-12-2012, 03:43 PM
Perhaps try to delete your node, flushUndo and then unload--> copy mll--> rehash script/plugins directory--> loadplugin. Maybe, just flushing undo will be enough

zoharl
06-12-2012, 03:57 PM
No need to rehash, since there are no new files.

Tonton, I think that you are missing here. If I delete my node, then it's deleted with all its connections. Who would restore them, and would reapply the node to all the scene objects it was attached to?

tontonsuspect
06-12-2012, 04:49 PM
Not really, your action are stored in maya undo list( in the API look around the MDAGModifier+MDGModifier)(unless you have disable it ): some memory is assigned for this purpose.

Once your history is erase you can proceed to update your plugin.

I just have done a test and on my computer it works .

procanic
06-12-2012, 05:32 PM
EDIT:
sry, fallacy on my side - post deleted ...

@zoharl:
what exactly is the problem with writing a script that writes all nodes and connections to a file and restores them after reloading the plug?

zoharl
06-13-2012, 12:43 AM
@tonton, sorry I misunderstood you then when you said "flush undo... flush undo would be enough". I tried instead of flushUndo "delete -ch -all", but it didn't work for me (maya2010). Actually as I remember from previous posts flushUndo is a necessary step, else maya still needs the plugin in memory for the undo. Could you please elaborate exactly what you did, if you used a deformer node (can you try offsetNode.cpp from devkit?), and which maya version did you use it on?

@procanic, no problem at all. But before I am wasting up to an hour, usually I check around if something already exists or if there are better ideas such as the one @tonton is trying to suggest.

tontonsuspect
06-13-2012, 08:08 AM
sorry for the late reply, delete -ch means delete construction history: basically removes "nodes" involved in the creation and modification of an object: this doesnt clear your physical ram memory( and it makes sense once all the piece start to fit together):

I use maya 2011 on a 32bit machine and did a test with python dependecy node then with a custom C++ deformer: my node are simple: no accessory setup, callback etc: I delete the culprit node flushUndo and then unload the plugin

zoharl
06-13-2012, 10:24 AM
Tonton, let me elaborate more and emphasize what I said before:


Tonton, I think that you are missing here. If I delete my node, then it's deleted with all its connections. Who would restore them, and would reapply the node to all the scene objects it was attached to?

I execute two batches in the pre-link and post-build events in VS:

1. pre-link2.bat $(TargetName):

commandPort.exe if ( `pluginInfo -q -l %1`) { delete `ls -typ %1`; }
commandPort.exe flushUndo
rem commandPort delete -ch -all
commandPort.exe unloadPlugin %1
echo commandPort.exe unloadPlugin %1


2. post-build2.bat $(OutDir)$(TargetName)$(TargetExt) $(TargetName)

echo copy %1 "\prj\plug-ins\"
copy %1 "\prj\plug-ins\"
commandPort.exe loadPlugin %2
commandPort.exe { $maxNum = `optionVar -q "RecentFilesMaxSize"`; $list = `optionVar -q "RecentFilesList"`; file -o -f $list[$maxNum-1]; }


I emphasize again, these are working fine, the plugin is unloaded successfully, updated successfully, and loaded again successfully. And the flushUndo() is crucial.
There is one limitation tough that I pointed out. If you notice, the last line reloads the last scene, since I broke the current. If I have a large scene, this step would take time. So my problem again is not to unload and update the plugin, my problem is to restore the scene to the previous state it has been. Namely I want the script to create deformer nodes and reconnect them to objects in the scene automatically.

So again, I don't have a problem to update the plugin, I have a problem to restore the scene to its previous state efficiently. I'm still not sure if you want to use the flushUndo or not. At this stage I appreciate if you show me the piece of script that you had in mind for accomplishing the task (and preferably test it on the offsetNode.cpp from the devkit).

tontonsuspect
06-13-2012, 12:51 PM
I would rather not delete history: in your case you say that you have huge data to operate on:

I usually have a self button in maya : plugin are unload,the build directory is scanned then the plugin files copied into maya directory, a new scene opened then the deformer is applied on object with no more than 10000 vertice...

I would rather invoke a script with your commandPort post build : ( in my eye there is no such thing as automatic: someone must sweat before to write things )

In your plugin: is your attribute disconnect behavior set on kNothing?.
for each node you list its attribute:

attributeList = cmds.listAttr('yourNodeInstanceInMaya1')

a deformer is a dependencyNode: so it inherits attribute from its parent class:like
message,nodeState,binMembership etc..( see the node domumentation of dependNode)
your can remove this from your attribute list than you simply store a MPluglist in order to restore your scene later.

destinationList = cmds.connectionInfo(attributeList[k],destinationFromSource=True)
sourceList = cmds.connectionInfo(attributeList[k],sourceFromDestination=True)

then you can disconnect attributes and hoping nodes will not be deleted if nothing is connected to it
Once your plugin is updated your reconnect stuff...

procanic
06-13-2012, 01:05 PM
ok, i'll give it another try ... hope this works for you!
it's two mel files (+the two bat files and a test scene).

preLink.mel
- stores all nodes of a given type with all their connections in a temporary file
- kicks all connections to and from these nodes
- deletes the nodes
- flushes cache
- unloads plugin

postBuild.mel
- copies new pluin file
- loads plugin
- recreates nodes from tmp file
- recreates connections from tmp file

you will have to change the contents of some string variables in the preLink.mel (path, plugin file and name). i'm not sure if the bat files are correct this way. you will at least have to change the path of the mel files in there.

couldn't test with commandPort.exe, but i tested the mel files with a simple nearestPointOnMesh setup (scene included) and it seemed to work ...

hope this is kinda what you need! cheers! :)

zoharl
06-13-2012, 01:24 PM
Tonton, that actually an interesting idea!

Nevertheless, our friend here @procanic already gave an implementation of the more conventional algorithm I noted initially, so at this point we make the discussion academic, and I'll give his solution a try.

zoharl
06-13-2012, 10:37 PM
@procanic, I've made a few tweaks and it works great:

http://svn.code.sf.net/p/mymayaplugins/code-0/trunk/maya-scripts/update_plugin/

Thanks :beer:

procanic
06-15-2012, 10:32 AM
glad it worked. thanks for sharing back the whole package! - cheers! :beer:

BigRoyNL
11-18-2012, 09:22 PM
How would one exactly set up the workflow with the pre-link and post-link bat files? ;) Keep getting errors while setting it up.

Thanks in advance.

zoharl
11-19-2012, 01:48 AM
And the errors are...?

Setup:

1. Put commandPort.exe, pre-link3.bat, and post-build3.bat in windows path or where the .sln of your project resides.
2. Add to your maya's userSetup.mel

commandPort();

3. Put vs_build_events.mel in your mel script path.
4. In VS, set under your project property pages>conf prop> build events> pre-link event> command line:
pre-link3.bat <plugin_file_name_without_extension> <node_name_of_deformer>
Since my project name is the same as the .mll and the deformer I simply set:
pre-link3.bat $(TargetName) $(TargetName)
and the build events> post-link event> command line to:
post-build3.bat <plugin_file_name> <node_name_of_deformer> <VS_out_dir_of_mll> <your_plugins_dir> <mel_command_to_create_deformer>
I use:
post-build3.bat $(TargetName)$(TargetExt) $(TargetName) $(OutDir) "\prj\plug-ins\" "deformer -type"

BigRoyNL
11-19-2012, 01:06 PM
Awesome! I got it to work.

My node is working fine, but when I use this while Maya is open the following code returns the MS::kNotImplemented. Even though before recompiling it the node actually works. Happens every time.


if (dataBlock.inputValue(aInCurve).type() != MFnData::kNurbsCurve) stat = MS::kNotImplemented;
CHECK_MSTATUS_AND_RETURN_IT(stat);

So before I can actually start using this I'll have to figure out why it is doing this. Nevertheless learned something awesome new about Visual Studio and the commandPort.

Thanks!

-Roy

zoharl
11-19-2012, 01:31 PM
The mel code should reconnect all the accessories to the deformer, but in your case something didn't connect right. I'll need some more information on the deformer type and what/how do you connect to it. Also, you should simply check the connections in the connection editor from the accessories to the deformer, and test inside the plugin if these connections are valid (it's your plugin, right?).

commandPort is not limited to VS. It's an external interface to maya, and any app can connect to it.

BigRoyNL
11-19-2012, 01:35 PM
I checked all the connections and they were all fine. Even tried reconnecting it or connecting it to a new node. It's derived from MPxNode and I changed the deformer -type code to createNode.

I had probably some other thing that was giving me the problems beside just this script. ;)

I'll let you know once I figure out what it was. Currently developing without this sweet functionality. hehe. :)

It also reconnected these connections (according to the nodeCon.tmp file):
<nodeName>.message
hyperLayout1.hyperPosition[0].dependNode
<nodeName>.message
hyperLayout2.hyperPosition[2].dependNode

I'm not entirely sure what that's about?

zoharl
11-19-2012, 01:45 PM
I'm sorry that I can't assist you better. Since it's only a small utility that I use at home (and not in mass production), I'm not really sure about its quirks and limitations in other situations besides mine :D.

If this really interests you (I won't be offended if not ;) ), then I suggest you would start eliminating chunks of code from the plugin, until it would be bare-bones, and then it would be easier to debug the problem.

The temp file shows the connections that the plugin had. I'm not sure what they are in your case (your plugin, right?).

zoharl
11-19-2012, 02:03 PM
Did you try, perhaps, to comment the code in the mel script that restores the connections, and then connect the deformer with your standard script?
This should be the first test, and after you make this work, your should compare the connections the mel script it trying to make with the ones your script makes.

Actually the whole process here is not that complicated. The connections are saved, the deformer is deleted, a new deformer is created, and the connections are remade for the new deformer. You should try to make this process manually and see where it fails.

CGTalk Moderation
11-19-2012, 02:03 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.