Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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
    • Login

    MakeEditable in C++

    SDK Help
    0
    11
    900
    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.
    • H
      Helper
      last edited by

      On 08/05/2013 at 14:36, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   12 
      Platform:      Mac OSX  ; 
      Language(s) :     C++  ;

      ---------
      The questions just won't stop....

      I created an Ocube primitive in my code. Now, how can I make it editable (as in Make Editable).

      I tried:
      doc->SetActiveObject(op, SELECTION_NEW);
      CallCommand(12236);

      But this crashed C4D.

      Then I experimented with this:
      op->ChangeNBit( NBIT_OM1_FOLD, NBITCONTROL_SET );

      but it didn't do anything.

      So what is the proper way to do this.
      This is in DescriptionToolData::Message.

      Peter

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 08/05/2013 at 15:06, xxxxxxxx wrote:

          
          ModelingCommandData cd;  
        cd.doc = doc;  
        cd.op = op;  
        if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, cd)) return FALSE;  
        
        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 08/05/2013 at 20:03, xxxxxxxx wrote:

          Thanks for the reply.
          This kept crashing C4D:

          ModelingCommandData cd;  
          cd.doc = doc;  
          cd.op = op;  
          if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, cd)) return FALSE;
          

          But after I added cd.flags = MODELINGCOMMANDFLAGS_CREATEUNDO;

          So this code works.

          ModelingCommandData mcd;
          opMachine = BaseObject::Alloc(Ocube);
          doc->InsertObject(opMachine, NULL, NULL);
                                         
          mcd.doc = doc;
          mcd.op = opMachine;
          mcd.flags = MODELINGCOMMANDFLAGS_CREATEUNDO;
          if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, mcd)) return FALSE;

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 08/05/2013 at 20:14, xxxxxxxx wrote:

            Oops, another observation:
            In my code I create three individual primitives. If I call

            if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, mcd)) return FALSE;

            after InsertObject() but before creating the next object I get a crash. If I create all needed objects and then use

            if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, mcd)) return FALSE;

            for each of the objects it's good.

            Is that a threading issue where the next object gets created before the previous one is done?

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 08/05/2013 at 20:34, xxxxxxxx wrote:

              And there I lied. If I use

              if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, mcd)) return FALSE;

              once after all objects are inserted it works fine but when I try to do this three times in a row for all three objects I get a crash. Is that because it's a Threaded Function? Forbidden?

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 08/05/2013 at 21:00, xxxxxxxx wrote:

                After doing a little more testing:
                The three objects I insert are hierarchal (ob3 is child of ob2 is child of ob1). All this happens in the 'Message' method of DescriptionToolData after I hit the Apply button

                Here then the question:
                I can insert three objects into my document in the proper hierarchy.
                But when I now try to use SendModelingCommand to make them editable I get a crash.

                I can insert the same three objects all at the top level of the doc.
                Then using the SendModelingCommand will work fine.
                But when I then try to rearrange my hierarchy I get the crash again.

                So either hierarchy or make editable.

                Are there restrictions I need to know of or other conflicts?

                Thanks

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 09/05/2013 at 01:43, xxxxxxxx wrote:

                  No, no, and more no.  Please post some code instead of making wild (and unfounded) guesses.  You are doing something wrong that leads to the crashes yet you haven't given us the required information to tell you what it is.

                  You can insert, hierarchy, and make editable without crashing.  But you have to know what you are doing.  For instance, after Make Editable, the new object is not the same one you are pointing to in your code (!).

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 09/05/2013 at 05:53, xxxxxxxx wrote:

                    Here is the code snippet:

                    case MDATA_APPLY:

                    // create the project object
                        opProject = BaseObject::Alloc(Onull);
                        opProject->SetName(data.GetString(GCHELPER_PROJECTNAME));
                        doc->InsertObject(opProject, NULL, NULL);

                    // create the machine object
                        opMachine = BaseObject::Alloc(Ocube);
                        opMachine->SetParameter(PRIM_CUBE_LEN, GeData(Vector(data.GetReal(GCHELPER_MACHINEWIDTH), DEFAULT_MACHINE_HEIGHT, data.GetReal(GCHELPER_MACHINEHEIGHT))), DESCFLAGS_SET_0);
                        opMachine->SetName(data.GetString(GCHELPER_MACHINENAME));
                        doc->InsertObject(opMachine, opProject, NULL);

                    mcd.doc = doc;
                        mcd.op = opMachine;
                        mcd.flags = MODELINGCOMMANDFLAGS_CREATEUNDO;
                        if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, mcd)) return FALSE;

                    // create the material object
                        opMaterial = BaseObject::Alloc(Oplane);
                        opMaterial->SetParameter(PRIM_PLANE_WIDTH, GeData(data.GetReal(GCHELPER_MATERIALWIDTH)), DESCFLAGS_SET_0);
                        opMaterial->SetParameter(PRIM_PLANE_HEIGHT, GeData(data.GetReal(GCHELPER_MATERIALHEIGHT)), DESCFLAGS_SET_0);
                        opMaterial->SetParameter(PRIM_PLANE_SUBW, GeData(1), DESCFLAGS_SET_0);
                        opMaterial->SetParameter(PRIM_PLANE_SUBH, GeData(1), DESCFLAGS_SET_0);
                        opMaterial->SetName(DEFAULT_MATERIAL_NAME);
                        opMaterial->SetAbsPos(Vector(opMaterial->GetAbsPos().x, (DEFAULT_MACHINE_HEIGHT/2)+2, opMaterial->GetAbsPos().y));
                        doc->InsertObject(opMaterial, opMachine, NULL);

                    mcd.doc = doc;
                        mcd.op = opMaterial;
                        mcd.flags = MODELINGCOMMANDFLAGS_CREATEUNDO;
                        if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, mcd)) return FALSE;

                    // create a default polygon with default name
                        opCuttingPath = BaseObject::Alloc(Oplane);
                        opCuttingPath->SetParameter(PRIM_PLANE_WIDTH, GeData(data.GetReal(GCHELPER_CUTTINGPATHWIDTH)), DESCFLAGS_SET_0);
                        opCuttingPath->SetParameter(PRIM_PLANE_HEIGHT, GeData(data.GetReal(GCHELPER_CUTTINGPATHHEIGHT)), DESCFLAGS_SET_0);
                        opCuttingPath->SetParameter(PRIM_PLANE_SUBW, GeData(1), DESCFLAGS_SET_0);
                        opCuttingPath->SetParameter(PRIM_PLANE_SUBH, GeData(1), DESCFLAGS_SET_0);
                        opCuttingPath->SetName(DEFAULT_CUTTINGPATH_NAME);
                        opCuttingPath->SetAbsPos(Vector(opCuttingPath->GetAbsPos().x, 2, opCuttingPath->GetAbsPos().y));

                    doc->InsertObject(opCuttingPath, opMaterial, NULL);

                    mcd.doc = doc;
                        mcd.op = opCuttingPath;
                        mcd.flags = MODELINGCOMMANDFLAGS_CREATEUNDO;
                        if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, mcd)) return FALSE;

                    DrawViews(DRAWFLAGS_NO_THREAD);

                    break;

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 09/05/2013 at 09:25, xxxxxxxx wrote:

                      As I said, there is your problem.  You are 'making editable' the objects that you add to the document and then reusing them for parenting new objects as if the pointer points to the same object afterwards.
                      _<_t_>_
                      MCOMMAND_MAKEEDITABLE
                      |
                      Make editable (returns object)
                      <_<_t_>_This command returns a 'new' object.  I do not remember if it replaces the document object directly or you have to insert it into the document, but you then proceed to create new objects that are dependent upon possibly non-existent objects (having been replaced by the SendModelingCommand(MCOMMANd_MAKEEDITABLE).  Your first course of action is to see if the original object is replaced in the document by the made-editable object (just do one MCOMMAND_MAKEEDITABLE and note the results in the document0.  If so, get the new object for parenting of the subsequent new objects you allocate.  The new object should be in AtomArray* arr or AtomArray* result in the ModelingCommandData structure.  Use that instead of the old object that you made editable to avoid the crashing.

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 09/05/2013 at 10:42, xxxxxxxx wrote:

                          
                        //-------------------------------------------------------------------------------------------------  
                        // Caller owns returning object !!!  
                        // Use PolygonObject::Free(poly); on the end !!!  
                        // or better call it like this:  
                        //  AutoFree<BaseObject> poly( GetEditableObject(op,doc) );  
                        inline BaseObject *GetEditableObject(BaseObject *obj, BaseDocument *doc = NULL)  
                        {  
                          // Get polygon object  
                          ModelingCommandData md1;   
                          md1.op = obj;   
                          if(doc) md1.doc = doc;  
                          else md1.doc = obj->GetDocument();  
                          if (!SendModelingCommand(MCOMMAND_MAKEEDITABLE, md1)){ return NULL; }  
                          
                          BaseObject *poly = static_cast<BaseObject*>(md1.result->GetIndex(0)); if (!poly) return NULL;  
                          return poly;  
                        }  
                        
                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          On 10/05/2013 at 16:42, xxxxxxxx wrote:

                          Thanks for clearing that up. I suspected something like that. As a rookie it's sometimes not quite clear what to search for in the SDK docs.

                          It works if I call 'GetEditableObject' like this:
                          opMaterial = GetEditableObject(op,doc);

                          If I try to use
                          AutoFree<BaseObject> poly( GetEditableObject(op,doc) );
                          it won't compile because of scope issues (it gets called in a Switch/Case block)
                          can I use AutoAlloc() to create my objects in the first place?

                          Thanks so much for your help.

                          Peter

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