Group Details Private

Global Moderators

Forum wide moderators

  • RE: SpecialEventAdd and structures / containers

    Hi @pim,

    In Python, SpecialEventAdd can only pass integer value, so the sender part can store the data into the document BaseContainer send the SpecialEventAdd/ Process this event read back the data from the active document BaseContainer.

    You can find valuable information on this topic https://plugincafe.maxon.net/topic/8219/10712_pluginmessage-and-pycobject-solved/5.

    Cheers,
    Maxime.

    posted in Cinema 4D Development
  • RE: Cinema 4D crashed without knowing it crashed

    Hi,

    I'm sorry you are having issues with Cinema 4D.
    You have ended up in MAXON's support forum for 3rd party developers.
    This is actually not a good place for user support requests. Instead I suggest to use the support form on our website.

    Cheers,
    Andreas

    posted in Cinema 4D Development
  • RE: Compute the Area of an Irregular Polygon?

    Hi Bentraje, thanks for following up and sorry for coming late here.

    I've checked your geometry and the issue is not with the algorithm, but in both cases with the geometries you're using to compute the area who don't shown vertexes being properly "ordered".
    The algorithm I've briefly presented requires the vertexes to be ordered as if you're visiting them by walking on the outer edge of your n-gon or polygon in CCW or CW. It is then mandatory to generate an ordered list of vertexes before passing the data to the function to get the correct result.

    62d2c929-154a-4c85-b558-af1536d3153d-image.png

    In order to come out with such an ordered list I warmly recommend you to visit the following old-threads:

    Best, Riccardo

    posted in General Programming & Plugin Discussions
  • RE: Transform mouse coordinates to c4d coordinates

    Yes you are right this is relative to the current frame being drawn (understand it as the current GeDialog, SubDialog, GeUserArea) and there is no way to retrieve the frame position in the screen. As I said cinema 4D does not work this way.

    May I ask you why SubDialog of a ToolData is not enough for your needs?

    posted in Cinema 4D Development
  • RE: Drag&Drop in Editor window

    Hi @pim, a dragging session only occurs in a 2D space (your screen, the viewport is a 2D representation of a 3D spaces).
    So retrieving such a Z coordinate don't make a lot of sense.
    If you want to retrieves the Z coordinate, you need to cast a ray in order to calculate intersections to retrieves a Z component but using the ViewPortSelect class could also help you, may ask you why you need to retrieve it?

    Please help us to help you by providing as much as possible information (the more we know the context the more precise we can answers)

    Cheers,
    Maxime.

    posted in Cinema 4D Development
  • RE: Transform mouse coordinates to c4d coordinates

    Hi @pim, I'm not sure a CommandData is the best place for doing this stuff, a ToolData offers the InputEvent which is far more suited for this.

    With that's said in a CommandData you actually get now way to be sure in which space you are currently retrieving the coordinate from.

    Finally, you can retrieve the active BaseDraw, then call BaseView.SW.

    If you have any questions, please let me know.
    Cheers,
    Maxime.

    posted in Cinema 4D Development
  • RE: Compute the Area of an Irregular Polygon?

    Hi Bentraje,

    with regard to computing the area of a non self-intersecting planar polygon you can use:

    # area of a polygon using 
    # shoelace formula 
      
    # (X[i], Y[i]) are coordinates of i'th point. 
    
    def polygonArea(X, Y, n): 
        # Initialze area 
        area = 0.0
    
        # Calculate value of shoelace formula 
        j = n - 1
        for i in range(0,n): 
            area += (X[j] + X[i]) * (Y[j] - Y[i]) 
            j = i   # j is previous vertex to i
        # Return absolute ;
        return int(abs(area / 2.0)) 
    

    Best, Riccardo

    posted in General Programming & Plugin Discussions
  • RE: How to output BaseBitmap with ShaderData plugin

    Hi Merkvilson, thanks for reaching out us.

    If the final intent is to simply get BaseBitmapinformation to be returned by your shader, rather than sampling a Xbitmap shader I suggest instead to simply query the color information by using BaseBitmap::GetPixel and eventually apply color space transformation.

        def Output(self, sh, cd) :
            x = int(cd.p.x * self.bitmap.GetBw())
            y = int(cd.p.y * self.bitmap.GetBh())
            col = self.bitmap.GetPixel(x, y)
            return c4d.Vector(float(col[0]/256.0), float(col[1]/256.0), float(col[2]/256.0))
    

    Best, Riccardo

    posted in Cinema 4D Development
  • RE: Get the "World Position" in "Deformed Space" of a point of the object.

    Hi,

    I'm glad you found something working for you. I just want to mention, this way of using the deform cache directly will only work for very specific setups, for arbitrary object configurations you will most likely need to iterate through the cache. So, I think, it's worth to give those manuals another read.
    Also Maxime has posted some snippets in Getting a polygonal version of an animated mesh, which might be useful for you.

    Cheers,
    Andreas

    posted in Cinema 4D Development
  • RE: Getting a polygonal version of an animated mesh

    Hi @rui_mac please make sure to post in the correct category, for anything related to Cinema 4D please post into the CINEMA 4D DEVELOPMENT category (I've moved your topic)
    Also, make sure to use the tagging system.

    In regards to your code, few things to say.
    First, there is no loop over time (so you never change the time of the current document)
    Moreover, when you clone the object, the returned object is not inserted into any document so even if you copy an object with these animation data they are lost since there is no document to define the time.

    Finally, a more suited approach is to use BaseObject.GetDeformCache which store the deformed state of an object.
    Find an example here, I also attached a scene, select the cloner run the script it will create a Null based on the position of each clone

    """
    Copyright: MAXON Computer GmbH
    Author: Maxime Adam
    
    Description:
        - Animates a BaseDocument from frame 5 to 20.
        - Retrieves all the deformed mesh from the selected object
        - Creates a Null for each frame at the position of point 88 of all deformed mesh
    
    Class/method highlighted:
        - BaseObject.GetDeformCache()
        - c4d.BaseTime()
        - BaseDocument.SetTime()
        - BaseDocument.ExecutePasses()
    
    Compatible:
        - Win / Mac
        - R16, R17, R18, R19, R20
    """
    import c4d
    
    
    def DeformedPolygonCacheIterator(op):
        """
        A Python Generator to iterate over all PolygonCache of passed BaseObject
        :param op: The BaseObject to retrieves all PolygonObject cache.
        """
        if not isinstance(op, c4d.BaseObject):
            raise TypeError("Expected a BaseObject or derived class got {0}".format(op.__class__.__name__))
    
        # Try to retrieves the deformed cache of the object
        temp = op.GetDeformCache()
        if temp is not None:
            # If there is a deformed cache we iterate over him, a deformed cache can also contain deformed cache
            # e.g. in case of a nested deformer
            for obj in DeformedPolygonCacheIterator(temp):
                yield obj
    
        # Try to retrieves the cache of the Object
        temp = op.GetCache()
        if temp is not None:
            # If there is a cache iterates over its, a cache can also contain deformed cache
            # e.g. an instance, have a cache of its linked object but if this object is deformed, then you have a deformed cache as well
            for obj in DeformedPolygonCacheIterator(temp):
                yield obj
    
        # If op is not a generator / modifier
        if not op.GetBit(c4d.BIT_CONTROLOBJECT):
            # If op is a PolygonObject we return it
            if op.IsInstanceOf(c4d.Opolygon):
                yield op
    
        # Then finally iterates over the child of the current object to retrieves all objects
        # e.g. in a cloner set to Instance mode, all clones is a new object.
        temp = op.GetDown()
        while temp:
            for obj in DeformedPolygonCacheIterator(temp):
                yield obj
            temp = temp.GetNext()
    
    
    def main():
        # Saves current time
        ctime = doc.GetTime()
    
        # Retrieves BaseTime of frame 5, 20
        start = 5
        end = 20
    
        # Marks the state of the document as the initial step of our undo process
        doc.StartUndo()
    
        # Loops through the frames
        for frame in xrange(start, end + 1):
            # Changes the time of the document
            doc.SetTime(c4d.BaseTime(frame, doc.GetFps()))
    
            # Executes the document, so animation, dynamics, expression are calculated and cached are build accordingly
            buildflag = c4d.BUILDFLAGS_NONE if c4d.GetC4DVersion() > 20000 else c4d.BUILDFLAGS_0
            doc.ExecutePasses(None, True, True, True, buildflag)
    
            # For each cache objects of our current selected object
            for obj in DeformedPolygonCacheIterator(op):
    
                # Calculates the position of the point 88 in world space
                pos = obj.GetPoint(88) * obj.GetMg()
    
                # Creates a null for each frame and each cache
                null = c4d.BaseObject(c4d.Onull)
                null.SetName(str(frame))
    
                # Inserts the objects into the documents
                doc.AddUndo(c4d.UNDOTYPE_NEW, null)
                doc.InsertObject(null)
    
                # Defines the position of the null with the position of the point from the deformed mesh
                null.SetAbsPos(pos)
    
        # Sets the time back to the original time.
        doc.SetTime(ctime)
    
        # Executes the document, so animation, dynamics, expression are calculated and cached are build accordingly
        buildflag = c4d.BUILDFLAGS_NONE if c4d.GetC4DVersion() > 20000 else c4d.BUILDFLAGS_0
        doc.ExecutePasses(None, True, True, True, buildflag)
    
        # Marks the state of the document as the final step of our undo process
        doc.EndUndo()
    
        # Updates Cinema 4D
        c4d.EventAdd(c4d.EVENT_ANIMATE)
    
    
    if __name__ == "__main__":
        main()
    

    test_scene.c4d

    If you have any question, please let me know.
    Cheers,
    Maxime.

    posted in Cinema 4D Development