Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Register
    • Login

    How to enable object X-Ray option - C++

    Cinema 4D SDK
    c++ sdk
    5
    19
    2.4k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • r_giganteR
      r_gigante
      last edited by

      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

      mfersaouiM 1 Reply Last reply Reply Quote 1
      • mfersaouiM
        mfersaoui @r_gigante
        last edited by

        @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

        CairynC 1 Reply Last reply Reply Quote 0
        • CairynC
          Cairyn @mfersaoui
          last edited by

          @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? So DescID(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()
          
          mfersaouiM 1 Reply Last reply Reply Quote 0
          • mfersaouiM
            mfersaoui @Cairyn
            last edited by mfersaoui

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

            S 1 Reply Last reply Reply Quote 0
            • S
              spedler @mfersaoui
              last edited by

              Try using the ObjectColorProperties like so:

              	BaseObject *obj;
              	ObjectColorProperties ocp;
              	obj->GetColorProperties(&ocp);
              	ocp.xray = true;
              	obj->SetColorProperties(&ocp);
              
              
              1 Reply Last reply Reply Quote 0
              • r_giganteR
                r_gigante
                last edited by

                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

                mfersaouiM 1 Reply Last reply Reply Quote 0
                • mfersaouiM
                  mfersaoui @r_gigante
                  last edited by

                  @r_gigante
                  Hi Riccardo, Yes I'm using it inside a GVO.

                  mfersaouiM 1 Reply Last reply Reply Quote 0
                  • r_giganteR
                    r_gigante
                    last edited by

                    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

                    mfersaouiM 1 Reply Last reply Reply Quote 0
                    • mfersaouiM
                      mfersaoui @r_gigante
                      last edited by

                      @r_gigante
                      Hi Riccardo, Thank you I will try this.
                      Best.

                      1 Reply Last reply Reply Quote 0
                      • mfersaouiM
                        mfersaoui @mfersaoui
                        last edited by mfersaoui

                        @mfersaoui

                        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;
                        	}
                        	}
                        }
                        
                        1 Reply Last reply Reply Quote 0
                        • r_giganteR
                          r_gigante
                          last edited by

                          Hi @mfersaoui, assuming you need to access the object pinned under your generator (actually the children), you should use op->GetDown() not op->GetCache()->GetDown().

                          Best, Riccardo

                          mfersaouiM 1 Reply Last reply Reply Quote 0
                          • mfersaouiM
                            mfersaoui @r_gigante
                            last edited by mfersaoui

                            @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;
                            		}
                            	}
                            }
                            
                            r_giganteR 1 Reply Last reply Reply Quote 0
                            • r_giganteR
                              r_gigante @mfersaoui
                              last edited by

                              @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

                              mfersaouiM 1 Reply Last reply Reply Quote 0
                              • mfersaouiM
                                mfersaoui @r_gigante
                                last edited by

                                @r_gigante I try it but nothing happen, it not detect any child object.

                                ferdinandF 1 Reply Last reply Reply Quote 0
                                • ferdinandF
                                  ferdinand @mfersaoui
                                  last edited by

                                  @mfersaoui

                                  Hm, stupid question: Does you object have actually any children? The parameter node passed to Message() is the actual GeListNode sitting in your object manager, representing your plugin instance. If this node has no children, this code does not make any sense.

                                  Cheers
                                  zipit

                                  MAXON SDK Specialist
                                  developers.maxon.net

                                  mfersaouiM 1 Reply Last reply Reply Quote 0
                                  • mfersaouiM
                                    mfersaoui @ferdinand
                                    last edited by mfersaoui

                                    @zipit
                                    My object contain a lot of child object, it is similar to the SDK Greek Temple Generator Example.

                                    1 Reply Last reply Reply Quote 0
                                    • ferdinandF
                                      ferdinand
                                      last edited by ferdinand

                                      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 your GVO. If you want to access objects in the ouput of your ObjectData plugin GetCache() 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 when Message() is being executed.

                                      Cheers
                                      zipit

                                      MAXON SDK Specialist
                                      developers.maxon.net

                                      1 Reply Last reply Reply Quote 0
                                      • r_giganteR
                                        r_gigante
                                        last edited by

                                        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

                                        1 Reply Last reply Reply Quote 0
                                        • First post
                                          Last post