MakeEditable - every object [SOLVED]



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



  • 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()



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



  • 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



  • 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



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


Log in to reply