Posts made by JohnThomas
-
Tags Under Cloners
Hello,
I'm working on a tag plugin that is using positional data of an object to drive parameters. This is simple and straightforward so it is working properly using the code below inside of the Execute function to drive the Radius value of a sphere object.
EXECUTIONRESULT TagParamRun::Execute(BaseTag* tag, BaseDocument* doc, BaseObject* op, BaseThread* bt, Int32 priority, EXECUTIONFLAGS flags) { if (tag->GetObject()) { BaseObject* parentObj = tag->GetObject(); if (parentObj->GetType() == Osphere) { ApplicationOutput("Parent object " + parentObj->GetName()); Matrix sphereMat = parentObj->GetMg(); Vector spherePos = sphereMat.off; Vector centerPos = Vector(0); Float distance = sqrt(pow(spherePos.x - centerPos.x, 2) + pow(spherePos.y - centerPos.y, 2) + pow(spherePos.z - centerPos.z, 2)); GeData setData; distance = distance / 2; if (distance > 50) distance = 50; setData.SetFloat(100 - distance); parentObj->SetParameter(ConstDescID(DescLevel(PRIM_SPHERE_RAD)), setData, DESCFLAGS_SET::NONE); } } return EXECUTIONRESULT::OK; }
My issue comes in when I have the object with my tag under a Cloner. As I drag the tag's object around the scene all of the cloned spheres are changing their radius based on that single object instead of their cloned positions. Shown below.
If I make the cloner edititable then the setup is working as I would expect.
Is there a way to make it so that my tag is running after the Cloner has run? In this case 9 separate spheres with attached tags running on their own positions.
Any help would be greatly appreciated.
John Thomas
-
RE: BitmapButton in Resource file
@i_mazlov Thanks for the response.
I tried utilizing the code and I am not getting any response when I try running it.
John Thomas
-
RE: BitmapButton in Resource file
Any ideas, my GetDParameter is defined with this code.
Bool ExampleFieldLayer::GetDParameter(const GeListNode* node, const DescID& id, GeData& t_data, DESCFLAGS_GET& flags) const { Int32 ID = id[0].id; if (ID == 1006) { Int32 dirty = 0; maxon::WeakRawPtr<const GeListNode> weakPtr(node); if (weakPtr.Get()) { GeListNode* convert = MAXON_REMOVE_CONST(weakPtr.Get()); BaseList2D* convertObject = static_cast<BaseList2D*>(convert); BitmapButtonStruct bbs(convertObject, id, dirty); t_data = GeData(bbs, CUSTOMDATATYPE_BITMAPBUTTON); flags |= DESCFLAGS_GET::PARAM_GET; } } return SUPER::GetDParameter(node, id, t_data, flags); }
-
RE: Python: Detect Plugins
Thanks for the response. I'll see if this does what I need it to
John Thomas
-
RE: Python: Detect Plugins
Thanks for the response.
Going through the code you have the line
assetDescription = repository.FindLatestAsset(maxon.AssetTypes.NodeTemplate(), assetId, maxon.Id(), maxon.ASSET_FIND_MODE.LATEST)
Looking at the sdk the NodeTemplate for AssetTypes first appears in 2024.2. Is there a way to tell if there is a Maxon One asset in 2023 or is this new functionality that isn't possible in older versions?
John Thomas
-
RE: BitmapButton in Resource file
Thanks for the response.
My SetDParamter function is defined with this code.
Bool ExampleFieldLayer::SetDParameter(GeListNode* node, const DescID& id, const GeData& t_data, DESCFLAGS_SET& flags) { switch (id[0].id) { case 1006: // ID_EXECUTERUN { if (flags & DESCFLAGS_SET::USERINTERACTION) { ApplicationOutput("Running SetDParameter"); } break; } } return SUPER::SetDParameter(node, id, t_data, flags); }
And at no point am I getting a print from the BitmapButton being pressed.
John Thomas
-
BitmapButton in Resource file
Hello.
I'm currently trying to create a FieldLayer plugin that is using a resource file for the creation of its description. Everything is working properly with the exception of a BitmapButton that does not seem to be sending any kind of message that it has been pressed.
Here is the line from the resource file that I am creating the BitmapButton.
BITMAPBUTTON ID_EXECUTERUN {BUTTON;}
Inside of Message I Have the MSG_DESCRIPTION_GETBITMAP to set the image for the bitmap.
if (type == MSG_DESCRIPTION_GETBITMAP) { DescriptionGetBitmap* dgb = static_cast<DescriptionGetBitmap*>(t_data); Int32 ID = dgb->_descId[0].id; AutoAlloc<BaseBitmap> bm; Filename bg; if (ID == ID_EXECUTERUN ) { bg = GeGetPluginPath() + Filename("res") + Filename("Icons") + Filename("Execute.png"); bm->Init(bg); AutoAlloc<BaseBitmap> bm2; bm2->Init(bm->GetBw() / 2, bm->GetBh() / 2); bm->ScaleIt(bm2, 256, TRUE, TRUE); dgb->_bmp = bm2.Release(); } }
There was a forum post that was dealing with the same issue, but the solution offered in the post does not seem to be working. I put prints in both the SetDParameter function as well as the MSG_DESCRIPTION_COMMAND message and neither one is ever being printed, all of the other controls I have are working properly.
Is there something fundamental that I'm missing that is preventing it from catching that the button is being pressed?
Any help would be greatly appreciated.
John Thomas
-
RE: Python: Detect Plugins
Thanks for the response, the code seems to work as hoped for detecting a plugin.
Have you had a chance to look into detecting a Maxon One capsule?
John Thomas
-
RE: Python: Detect Plugins
Thanks for the response.
Your code seems to work for Python plugins but is there a way to detect if something is a plugin for an xdl64 or xlib. I know that I could just check if the plugin ends with either of those but a Cube also counts as a plugin with either an xdl64 or xlib. Is there a way to tell if it is a Cinema plugin in this way or a user added one?
With the Maxon One question, is there a way to tell if a scene is Maxon One dependent without being able to detect a Maxon One object specifically?
John Thomas
-
Python: Detect Plugins
Hi.
I am working on a Python project that is browsing through all of the objects and tags in a scene. As part of this I am trying to detect which of the objects and tags are plugins. In addition to this I am trying to detect if any of the things in the scene are Maxon One exclusive content.
For a brute force method I know that I can compare the id of a given object or tag against a list of ids to tell if one of them is a plugin but I don't have a way of knowing if something is a plugin that I don't know the id of. I'm not overly familiar with Maxon One content but I assume that the same kind of method would apply for brute force detecting.
So in summary my question is, is there a way to detect if a given object or tag in the scene is a plugin or Maxon One content that is not just comparing a list of ids against all of the content in a scene?
Any help would be greatly appreciated,
John Thomas
-
RE: Spline Points with ModifyObject
@r_gigante Thanks for the response, that's what I thought the case would be.
John Thomas
-
Spline Points with ModifyObject
Hello,
I am trying to create a deformer plugin that will work on splines by modifying the positions of the points.
Using the code below I am getting the points from a spline and offsetting its position along the Z axis as a simple test.
Bool DeformPlugin::ModifyObject(BaseObject* mod, BaseDocument* doc, BaseObject* op, const Matrix& op_mg, const Matrix& mod_mg, Float lod, Int32 flags, BaseThread* thread) { // Check the input parameters validity. if (!mod || !op || !doc) return false; // Retrieve BaseContainer instance pointer and check for validity BaseContainer* bc = mod->GetDataInstance(); if (!bc) return false; // Verify the modifier inherits from PointObject and cast the pointer to the corresponding PointObject. if (!mod->IsInstanceOf(Opoint)) return false; // Verify the modified object inherits from PointObject and cast the pointer to the corresponding PointObject. if (!op->IsInstanceOf(Opoint)) return true; SplineObject *opSplineObj = static_cast<SplineObject*>(op); iferr(MovePoints(opSplineObj, modPointObj)) { return false; } return true; } maxon::Result<void> DeformPlugin::MovePoints(SplineObject* opSplineObj, PointObject* modPointObj) { if (!opSplineObj) return maxon::OK; const Vector* opPointsR = opSplineObj->GetPointR(); const Int32 opPointsCnt = opSplineObj->GetPointCount(); Vector* opPointsW = opSplineObj->GetPointW(); if (!opPointsCnt) return maxon::OK; for (Int32 opPointIdx = 0; opPointIdx < opPointsCnt; opPointIdx++) { opPointsW[opPointIdx] = opPointsR[opPointIdx]; opPointsW[opPointIdx].z = opPointsR[opPointIdx].z + 20; } return maxon::OK; }
The code is working to properly move the points, the problem is that I am getting the line points of the spline that I am deforming when I am trying to get the spline points.
This is the selection of points I am getting.
This is the selection of points I want to get.
I tried using the base SDK examples and they are also using the line points instead of the spline points.
Is there a way to get and use the spline points or do deformers only utilize the line points?
Any help would be greatly appreciated.
John Thomas
-
RE: Loft incorrectly returning input objects
Thanks for the response.
I'll spend some time looking into it.
John Thomas
-
RE: Loft incorrectly returning input objects
Thanks for the reply.
I went through the threads you linked but I've got a couple of clarification questions from them as I dig into them more.
I have concerns about the speed of some of the operations that are proposed.
From putting some prints in the GVO and GetContour of the OffsetYSpline, it seems like both GVO and GetContour are both getting called every time the plugin updates, so the entire spline is being rebuilt twice.
Is there a concern about the speed of the plugin given that it seems to be rebuilding twice?
From the code presented in https://developers.maxon.net/forum/topic/11408/getrealspline-not-returning-a-result/12
def GetCloneSpline(op): #Emulates the GetHierarchyClone in the GetContour by using the SendModelingCommand #:param op: The Object to clones and retrieves the current state (take care the whole hierarchy is join into one object. #:return: The merged object or None, if the retrieved object is not a Spline # Copies the original object childSpline = op.GetClone(c4d.COPYFLAGS_NO_ANIMATION) if childSpline is None: raise RuntimeError("Failed to copy the child spline.") # Retrieves the original document (so all links are kept) doc = op.GetDocument() if op.GetDocument() else c4d.documents.BaseDocument() if not doc: raise RuntimeError("Failed to retrieve a Doc") # Inserts the object into the document, this is needed for Current State To Object operation doc.InsertObject(childSpline) # Performs a Current State to Object resultCSTO = c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[childSpline], doc=doc) if not isinstance(resultCSTO, list) or not resultCSTO: raise RuntimeError("Failed to perform MCOMMAND_CURRENTSTATETOOBJECT.") # Removes the original clone object childSpline.Remove() childSpline = resultCSTO[0] # If the results is a Null, performs a Join command to retrieves only one object. if childSpline.CheckType(c4d.Onull): resultJoin = c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_JOIN, list=[childSpline], doc=doc) if not isinstance(resultJoin, list) or not resultJoin: raise RuntimeError("Failed to perform MCOMMAND_JOIN.") childSpline = resultJoin[0] if childSpline is None: raise RuntimeError("Failed to retrieves cached spline.") # Checks if childSpline can be interpreted as a Spline. if not childSpline.GetInfo() & c4d.OBJECT_ISSPLINE and not childSpline.IsInstanceOf(c4d.Ospline) and not childSpline.IsInstanceOf(c4d.Oline): return None return childSpline
It seems like cloning the object and inserting it back into the scene to CurrentStateToObject it and then removing it is going to be potentially really slow.
It seems like it would be a lot of overhead to just get the input points. Forgive my ignorance, but do native Cinema objects face this sort of overhead? Would this amount of overhead be a limiting factor?
John Thomas
-
RE: Loft incorrectly returning input objects
I still haven't had any success in getting my code to work as expected. Any help would be appreciated.
John Thomas
-
RE: Loft incorrectly returning input objects
Thanks for the response.
From my tests if GetHierarchyClone is commented out then the child object never disappears, as opposed to not appearing in the viewport. So it does seem to be doing something.
To be clear, my goal is to have the child objects correctly marked, (so they wouldn't appear when under the loft or at all), and to correctly retrieve the polygon/spline objects of the children for use in either GetContour(since sometimes I want to return a spline) or GetVirtualObject(since sometimes I want to return an polygon object).
From what I understand the ways to get the polygon/spline objects are CurrentStateToObject, GetCache, GetDeformCache, and GetHierarchyClone.
It seems like CurrentStateToObject doesn't seem like an option because cloning the object over to a new document and rebuilding it can be slow.
Using GetCache and GetDeformCache is faster but far more complicated given the number of exceptions that need to be handled. And these can't be used with AddDependence/TouchDependenceList clears the caches right?
GetHierarchyClone seems to work but that's only available in GetVirtualObjects, so what should be done in GetContour?
What would be the best approach to mark the children objects of my plugins and to retrieve the contents of those children in both GetContour and GetVirtualObject?
John Thomas
-
RE: Loft incorrectly returning input objects
I've spent more time working on it and have still not found a solution. Any help would be greatly appreciated.
John Thomas