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 - every object [SOLVED]

    Scheduled Pinned Locked Moved PYTHON Development
    6 Posts 0 Posters 845 Views
    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 Offline
      Helper
      last edited by

      On 30/04/2017 at 16:01, xxxxxxxx wrote:

      Hello,

      coming from C++ i need your help in Python:
      I need a funktion to return a object as a PointObject - for e.g. GeRayCollider.
      In C++ i successfully used:

        
      PolygonObject *Dobj;   
           Bool Dobj_isclone     = FALSE;   
           if (op->GetDeformCache() || !op->IsInstanceOf(Opoint))   
           {   
                // convert Object to Polygonobject   
                ModelingCommandData bmd1; bmd1.op = op; bmd1.doc = op->GetDocument();   
                if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, bmd1)) return FALSE;   
                // Triangulate it   
                ModelingCommandData bmd2; bmd2.op = static_cast<BaseObject*>(bmd1.result->GetIndex(0));   
                if (!SendModelingCommand(MCOMMAND_TRIANGULATE, bmd2)) return FALSE;   
                Dobj               = static_cast<PolygonObject*>(bmd2.op);   
                Dobj_isclone     = TRUE;   
           }   
           else   
           {        
                Dobj               = ToPoly(op);   
           }   
      

      This works for me in all cases, but now in Python i try:

        
          def MakeEditable(self, op) :   
              if (not op) or op.CheckType(c4d.Opolygon) or op.CheckType(c4d.Ospline) :   
                  return op   
                
              doc = c4d.documents.BaseDocument()   
              #doc = op.GetDocument().GetClone() for animated deformers   
                
              clone = op.GetClone()   
              doc.InsertObject(clone, None, None)   
              clone.SetMg(op.GetMg())   
                
              op = c4d.utils.SendModelingCommand(   
                  command = c4d.MCOMMAND_CURRENTSTATETOOBJECT,   
                  list = [clone],   
                  mode = c4d.MODELINGCOMMANDMODE_ALL,   
                  doc = doc   
              )   
        
              if op:   
                  return op[0]   
              else:   
                  return None   
      

      But this code doesn't work with deformed PointObjects (deformed BaseObjects are okay)
      So, general question - is there a workaround, to "convert" EVERY object (BaseObject, PolygonObject, PointObject) including animated deformers to a (not in a hierachy) polygon- or point-object for eg. GeRayCollider or op.GetPoint() via SendModelingCommand? Is there a equivalent for "ToPoly()" - or how can a BaseObject(c4d.Opolygon) can be cast as PolygonObject to get e.g. GetPointCount()?
      Or exists a alternative stable way with GetDeformCache()/GetCache()?

      Thank you for any advice!
      Cheers,
      Mark.

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

        On 02/05/2017 at 05:57, xxxxxxxx wrote:

                doc = c4d.documents.BaseDocument()
        

        I have not tested your code. And Gonna do some tests more later on the days. But with that, you get an empty fresh new doc while in your c++ code you do everything into the same doc. Is tehre any reason for doing so?

        If you want the current doc use instead:

        doc = c4d.documents.GetActiveDocument()
        

        Or as you did in your c++ code
        doc = op.GetDocument()

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

          On 02/05/2017 at 09:00, xxxxxxxx wrote:

          Hi Adam!

          Thank you for your reply!

          Yes you're right with the document. Meanwhile i use

            
          doc = op.GetDocument().GetClone()   
          

          because of the animation-time (of eg. animated deformer) and remove it after SendModelingCommand. Seems to work good...

          The main problem i figured finally out: if already a point object and with a deactivated deformer as child, MCOMMAND_CURRENTSTATETOOBJECT returns the "polygon object" as parent of a null object - so i got only the null object back! Now i use op[0].GetDown() if exist.
          This now works for me 🙂

          Independently of this i found BaseDocument.Polygonize() and i'm asking me, if this could be a more elegant alternative to SendModelingCommand?

          Cheers,
          Mark.

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

            On 02/05/2017 at 09:32, xxxxxxxx wrote:

            Don't know about performance and Polygonize. But I'm pretty sure if you want to polygonize a huge scene it will be faster. But I have never use it. Then don't trust me and test.

            I'm happy you finally fixed your problem. Anyway take a look a thoses script from nicklas.
            https://github.com/NiklasRosenstein/py-c4dtools/blob/v1.3.0/c4dtools/utils.py#L279-L326
            https://github.com/NiklasRosenstein/py-c4dtools/blob/v1.3.0/c4dtools/utils.py#L328-L388

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

              On 02/05/2017 at 13:57, xxxxxxxx wrote:

              Hi Mark, thanks for writing us.

              If i understand correctly your request, you're basically aiming to access the inner data (like points position and polygon index) of a generic BaseObject. If that's the intent, although you've already address the issue, the way to go is to have a look at the BaseObject class in the Python API documentation and to the BaseObject.GetCache() and BaseObject.GetDeformCache() methods which are those really tackling your needs.

              To streamline the learning experience i suggest you to have a look at this recent thread where NNenov was asking how to access the deformed points of an object and look for the with the further negative Y-value.

              Best, Riccardo

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

                On 03/05/2017 at 07:27, xxxxxxxx wrote:

                Hello!

                Thanks, Adam! 🙂

                Yes, Riccardo, that's the intent. But with the cache i was afraid if it's already build or not. So thank you for the example, will study it 🙂

                Cheers,
                Mark.

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