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.