How to enable object X-Ray option - C++
-
Hello,
How to enable the object X-Ray option using C++ (ID_BASEOBJECT_XRAY)AutoAlloc<BaseObject> extrudePtr(Oextrude); if (!extrudePtr) return false; extrudePtr->SetParameter(EXTRUDEOBJECT_MOVE, Vector(0,0,20), DESCFLAGS_SET_0); // How to do for the propriety: ID_BASEOBJECT_XRAY
Thank you.
-
Hi mfersaoui, thanks for reaching out us.
With regard to your question you can use the
C4DAtom::SetParameter()
method which in your case should look like :- pre R20:
extrudePtr->SetParameter(DescLevel(ID_BASEOBJECT_XRAY), Bool(true), DESCFLAGS_SET_0);
- post R20:
extrudePtr->SetParameter(DescLevel(ID_BASEOBJECT_XRAY), Bool(true), DESCFLAGS_SET::NONE);
Last but not least the
ID_BASEOBJECT_XRAY
is defined in obase.h.Best, Riccardo
- pre R20:
-
@r_gigante said in How to enable object X-Ray option - C++:
extrudePtr->SetParameter(DescLevel(ID_BASEOBJECT_XRAY), Bool(true), DESCFLAGS_SET_0);
Hi Riccardo, Sorry I just see your response. I forgot to enable notifications. I thank you for the detailed response.
I just test it but I don't know why it doesn't work for me.
Best regards, Mustapha -
@mfersaoui Do you get an error message? If yes, which one?
Perhaps you need to construct a DescID since that is the parameter SetParameter wants to have? SoDescID(DescLevel(ID_BASEOBJECT_XRAY))
?
Did you call EventAdd() to make the XRay visible?Sorry, can't fire up C++ right now but I tried it in Python for ***** and giggles, and it works:
import c4d def main(): op.SetParameter(c4d.DescID(c4d.DescLevel(c4d.ID_BASEOBJECT_XRAY)), True, c4d.DESCFLAGS_SET_NONE) c4d.EventAdd() if __name__=='__main__': main()
-
@Cairyn Hi,
I tryed your solution and it no thing happen. So, to be sure that there no problem in my code I tried with the ID_BASEOBJECT_GENERATOR_FLAG and work without any problem.// this work: extrudePtr->SetParameter(DescLevel(ID_BASEOBJECT_GENERATOR_FLAG), Bool(false), DESCFLAGS_SET_0); // this does't work: extrudePtr->SetParameter(DescLevel(ID_BASEOBJECT_XRAY), Bool(false), DESCFLAGS_SET_0);
With ID_BASEOBJECT_XRAY nothing happen.
-
Try using the ObjectColorProperties like so:
BaseObject *obj; ObjectColorProperties ocp; obj->GetColorProperties(&ocp); ocp.xray = true; obj->SetColorProperties(&ocp);
-
Hi mfersaoui,
I've tested the suggestion provided in a simple test code and it proved to work.
maxon::Result<void> PC_11804(BaseDocument *doc) { if (!doc) return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION); BaseObject* op = doc->GetActiveObject(); if (!op) return maxon::OK; Bool res = op->SetParameter(DescLevel(ID_BASEOBJECT_XRAY), Bool(true), DESCFLAGS_SET::NONE); if (res) DiagnosticOutput("ID_BASEOBJECT_XRAY set on @", maxon::String(op->GetName())); return maxon::OK; }
The sole question that pops in my mind... are you attempting to do it in a GVO?
Cheers, Riccardo
-
@r_gigante
Hi Riccardo, Yes I'm using it inside a GVO. -
Hi mfersaui, unfortunately Cinema has not been designed to set the X-Ray option directly inside a GVO.
What I instead recommend is to implement a NodeData::Message and react to MSG_MENUPREPARE.
Best, Riccardo
-
@r_gigante
Hi Riccardo, Thank you I will try this.
Best. -
Hi Riccardo,
I try to do this in NodeData::Message. that works on the parent op. But how can I apply the X-Ray option on child object of node. because I want to apply the X-Ray only on some of node child objects.
Best regards.
Bool MyObject::Message(GeListNode* node, Int32 type, void* data) { switch (type) { case (MSG_MENUPREPARE): { BaseObject* const op = static_cast<BaseObject*>(node); // op.GetCache()->GetDown() break; } } }
-
Hi @mfersaoui, assuming you need to access the object pinned under your generator (actually the children), you should use
op->GetDown()
notop->GetCache()->GetDown()
.Best, Riccardo
-
@r_gigante
Hi Riccardo,I have already tested to use op->GetDown(), but this crashing Cinema 4D.
See example below:Bool MyObject::Message(GeListNode* node, Int32 type, void* data) { switch (type) { case (MSG_MENUPREPARE): { BaseObject* const op = static_cast<BaseObject*>(node); GePrint(op->GetDown()->GetName()); break; } } }
-
@mfersaoui before calling any method belonging to a pointer it's highly recommended to check for the pointer validity, so i would rearrange it as
BaseObject* const op = static_cast<BaseObject*>(node); if (op->GetDown()) GePrint(op->GetDown()->GetName()); break;
This might prevent Cinema from crashing.
Cheers, R
-
@r_gigante I try it but nothing happen, it not detect any child object.
-
Hm, stupid question: Does you object have actually any children? The parameter
node
passed toMessage()
is the actualGeListNode
sitting in your object manager, representing your plugin instance. If this node has no children, this code does not make any sense.Cheers
zipit -
@zipit
My object contain a lot of child object, it is similar to the SDK Greek Temple Generator Example. -
Well,
everything you are showing here suggests ottherwise. It sounds like
GeListNode::GetDown()
returns the null pointer for your node (which would both explain the crashes and the non-execution of your print statement).Just to clarify again:
node
is the representation of your plugin instance in the editor, not the the root node of the object graph you did return in yourGVO
. If you want to access objects in the ouput of yourObjectData
pluginGetCache()
was the correct approach. But you also have to check the cache for null pointers, since there is no guarantee that any caches have been build whenMessage()
is being executed.Cheers
zipit -
Hi @mfersaoui, I thought you were referring to objects pinned under the generator and not children in the cache. In this case checking that the cache is valid before attempting to access any of its methods is mandatory.
Last but not least, I think we're running out of options here, cause even attempting to use SpecialEventAdd() / MessageData::CoreMessage() doesn't help too much and leads on some cases to unpredictable results.
Best, Riccardo