Hi,
Is there a MB plugin developers forum anywhere?
I need to know how to write a plugin that executes when any of the sculpting brushes are active & the LMB is clicked.
The SDK examples only show how to execute plugins from menus.
Where do I go for MB plugin developer help?
-ScottA
try this link http://around-the-corner.typepad.com/adn/2013/06/accessing-unsubdivide-functionality-from-a-mudbox-p...
and maybe contact the author.
Also you can try contacting Wayne Robson? Hes the Mudbox Master that created Mudwalker and Reducto both plugins for mudbox before it had reduce mesh. He might be able to help you.
These are just suggestions.
Best of luck man. I would love to see more people getting in on making plugins for mudbox.
Thanks a lot for the link.
Unfortunately, It doesn't help me with what I'm trying to do.
But I'm interested in any SDK information there is to learn from at this point.
I did e-mail Wayane R. But he never replied back to me.
I can use the SDK to a limited extent by fumbling through it.
I can use many of the classes and functions in it. And I'm making notes as I figure things out.
But it doesn't say how to tell if the program is in sculpt|paint mode. And which mesh is currently active using a LMB click event.
I'm assuming that it's a fairly easy thing to do (it usually is). But the docs don't really explain this.
I'm also new to QT. And that makes this even harder to figure out.
I can't belive that there's nobody out there that I can learn the basics from.
That's just crazy.
-ScottA
Hi again,
After months of struggling on my own and getting no help at all from the MudBox developers. I've managed to figure out most of the issues in how to create a simple plugin that uses a checkmark to enable/disable it.
And since I could not find any information in the SDK about testing if the UI was in Sculpt |Paint mode. I grabbed all of the brushes that I would allow to work with my plugin. And used that array of brushes as a condition to run the plugin or not.
@Cyrille Fauvel,
If you happen to read this. Thank you very much for at least trying to get Autodesk to help me.
But the company you're working for (at least the MudBox team) don't care about their users at all.
Especially the plugin developers.
-ScottA
@Anonymous wrote:I've managed to figure out most of the issues in how to create a simple plugin that uses a checkmark to enable/disable it.
You've done better than me! I ended up giving up on the checkmark front (should have been so simple!!). I'm happy to share the knowledge I've gained over the last 2 months plodding through it... I also realised there are many many simple features that are squirrelled away, even to the point of resizing an image isnt actually obvious... (Now using QImage instead of mudbox::Image).
Have you found a way to update the vertex buffer?? I've found the Redraw() function doesn't actually update this.. (more details here: http://forums.autodesk.com/t5/community-help/moving-vertices-and-redrawing-the-scene-does-not-update-the-mesh/td-p/5515344 )
But I agree with you, it is pretty ludicrous that there is no support for any developers, not even an infrequently checked forum like this... Astounds me how they don't see the additional value potential from freelance devs.
James
I have no idea about the vertex buffer. Sorry.
I've spent most of my time just trying to figure out how to control the menus.
If you want my checkmark code I can send it to you. It's fairly short and simple.
Just give me your e-mail address where to send it.
My e-mail is: scottasba@hotmail.com
Now I'm trying to figure out other simple things that are poorly documented. Like iterating through the OM (the TreeNode) and doing basic things like selecting, deleting, and creating new tree items.
None of which is properly documented or in the examples either.
As you've found out with the cameras. We can't just delete things using a simple remove() function from the SDK.
We have to delete them from memory ourselves. And then update the ui. But they don't tell us how to do that in the SDK!! 😠
It's very frustating.
If we all pooled our resources I think we could get all of these basic things documented.
We can't rely on Autodesk for anything SDK related. We have to help each other figure this stuff out.
-ScottA
Thanks for the offer, however I spoke with my supervisor and found that I needn't worry about clean removal after describing the issues with the SDK.
In regards to iterating through the nodes in the scene:
for(mb::Node *nodes = mb::Node::First() ; nodes ; nodes = nodes->Next()) {
if(nodes->IsKindOf(mb::Geometry::StaticClass())) {
mb::Geometry *geoPotential = dynamic_cast<mb::Geometry *>(nodes);
MB_SAFELY(geoPotential) {
}
}
}
That's how I've been iterating through the scene to grab objects, then searching by name, its slow, but as I only need to do this once at the start (when creating my control geometry).
I believe similar things are capable with TreeNodes using TreeNode->FirstChild() then TreeNode->NextSibling, this method might be more efficient than iterating through all the nodes, as you'd hopefully (not sure how its all implemented behind the scenes) only iterate through a subset (the TreeNodes)
This is how I'm doing it:
//Starting from the first child object in the OM under the "scene" parent object
TreeNode *sceneChild = Kernel()->Scene()->FirstChild();
//Iterate through the objects is the OM
while(sceneChild)
{
QString name = sceneChild->Name();
Kernel()->Log(name); //Print the names of all the objects
if(name == "cube")
{
Kernel()->Interface()->HUDMessageShow(name);
QString active = Kernel()->Scene()->ActiveGeometry()->Name();
Kernel()->Interface()->HUDMessageShow(active);
Kernel()->Scene()->RemoveGeometry(Kernel()->Scene()->ActiveGeometry()); //<---Crashes!!?
Kernel()->Scene()->RemoveChild(sceneChild); //<---wrong!!!
}
sceneChild = sceneChild->NextSibling();
}
It gets all of the objects in the manager fine.
I think I can expand of this and check for object types and whatnot.
However.
Deleting objects from the tree crashes MB.
-ScottA
Maybe worth storing a pointer to the active geo and then deselecting it before deletion:
Kernel()->Interface()->HUDMessageShow(active);
mb::Geometry *GeoPtr = Kernel()->Scene()->ActiveGeometry();
Kernel()->Scene()->SetActiveGeometry(NULL);
Kernel()->Scene()->RemoveGeometry(GeoPtr);
James
Thanks for your input. It really is helping me to get someone else's P.O.V.
This seems to be working and deleting properly now:
//Starting from the first child object in the OM under the "scene" parent object
TreeNode *sceneChild = Kernel()->Scene()->FirstChild();
//Iterate through the objects is the OM
while(sceneChild)
{
QString name = sceneChild->Name();
Kernel()->Log(name); //Print the names of all the objects
if(name == "cube")
{
Kernel()->Interface()->HUDMessageShow(name);
mudbox::Geometry *obj = Kernel()->Scene()->ActiveGeometry();
Kernel()->Scene()->RemoveGeometry(Kernel()->Scene()->ActiveGeometry());
//This is very important!!
//MB is still pointing to the object that was deleted so we need to set SetActiveGeometry(NULL)
Kernel()->Scene()->SetActiveGeometry(NULL);
}
sceneChild = sceneChild->NextSibling();
}
I just need to find a way to get the object types for each TreeNode. So it doesn't crash if something other than a Geometry type object happens to be named "cube".
I think ChildByClass() might possibly be what I need here. But I'm having trouble figuring out how to write it.
-ScottA
Nice to see its going somewhere!
The TreeNode class inherits the "IsKindOf" function from the Node class, so you can use that to ensure it is always a Geometry Node
if( sceneChild->IsKindOf( mudbox::Geometry:: StaticClass() ) ) { (Take out the space before Static Class, made an emoticon on the forums!)
QString name = sceneChild->Name();
Kernel()->Log(name); //Print the names of all the objects
if(name == "cube")
{
}
}
I'm not sure which way round would be quicker, but I assume check for Geometry class type then check for name comparison, as string comparisons are normally "slow" (in comparison to other comparisons) .
Yeah. I tried that one but it doesn't seem to work with the TreeNode type for some reason?
It does work with the Node type though:
for(mudbox::Node *nodes = mudbox::Node::First(); nodes; nodes = nodes->Next())
{
if(nodes->IsKindOf(mudbox::Geometry::StaticClass()))
{
mudbox::Geometry *geo = dynamic_cast<mudbox::Geometry *>(nodes);
MB_SAFELY(geo)
{
QString name = geo->Name();
Kernel()->Log(name);
if(name == "cube")
{
Kernel()->Scene()->RemoveGeometry(geo);
Kernel()->Scene()->SetActiveGeometry(NULL); //<--- very important!!
}
}
}
}
The Node and TreeNode types seem to do the same things here (child objects of "scene" in the OM heirarchy).
Yet TreeNode seems to have some limitations like not using the IsKindOf() method.
I guess I need to figure out the differnces between them.
-ScottA
I think I figured out how to use ChildByClass function with TreeNodes.
But It crashes MB when the result is false!?
How do we make a plugin stop running if there is an error in the code?
In other SDK's I use return; for void() methods. And return false; for returnable type methods.
This doesn't seem to work with MB?
//Get the first child and check if it's a Geometry type or not TreeNode *sceneChild = Kernel()->Scene()->FirstChild(); Geometry *obj = sceneChild->ChildByClass<Geometry>( false ); if( obj == 0 ) { MB_ERROR( QObject::tr("Wrong Type") ); Geometry *obj = nullptr; sceneChild = nullptr; return; //<---Crashes!!? }
-ScottA
Doh! Never mind.
The crash was coming from the MB_ERROR() message box. Using a regular style message box fixed the crashing.
Here is an example of testing a TreeNode's type while iterating through the OM.
Then deleting the object if both it's name and class type matches the condition:
//Get the first child TreeNode *sceneChild = Kernel()->Scene()->FirstChild(); //Iterate through the objects is the OM while(sceneChild) { QString name = sceneChild->Name(); //Check if it's a Geometry type or not Geometry *obj = sceneChild->ChildByClass<Geometry>( false ); if(obj != 0 && name == "cube") { Kernel()->Interface()->HUDMessageShow(name); Kernel()->Log(name); sceneChild->SetVisible(false); //Controls the visibilty option Kernel()->Scene()->SetActiveGeometry(obj); Kernel()->Scene()->RemoveGeometry(Kernel()->Scene()->ActiveGeometry()); //This is very important!! //MB is still pointing to the object that was deleted so we need to set SetActiveGeometry(NULL) Kernel()->Scene()->SetActiveGeometry(NULL); } sceneChild = sceneChild->NextSibling(); } Kernel()->Interface()->RefreshUI();
This is exactly why we need a MB developers forum. With Autodesk's participation.
So we can ask questions. And post our solutions with each other.
-ScottA
Can't find what you're looking for? Ask the community or share your knowledge.