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

    Trying to programmatically create vertex color tag

    Cinema 4D SDK
    2
    2
    637
    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.
    • Z
      zauhar
      last edited by

      Hi,
      I am making a python script to import a mesh in OBJ format, and want to programmatically set the colors on a per-vertex basis.

      I am currently playing around, have imported the mesh using File->Merge Project, set a single material for all objects (there is only one object), and got a reference to the polygons by dragging into the python command line (op = Default below).

      I followed examples I found (code below) to make a vertex color tag, and just to experiment set the vertices to red. The issues :

      1. I have to select the vertex color tag in the Objects panel for the coloring to show up, otherwise the color is just default white

      2. When the tag is selected there is no shading, color is 'flat'

      3. Rendering just shows the white underlying material coloring

      Code is below, what am I missing?

      Thanks,

      Randy

      op = Default 
      red = c4d.Vector4d(1.0, 0.0, 0.0, 1.0)
      
      pointCount = op.GetPointCount()
      tag = c4d.VertexColorTag(pointCount)
      
      tag.SetPerPointMode(True)
      
      dataW = tag.GetDataAddressW()
      
      for idx in range(pointCount) :
      	c4d.VertexColorTag.SetPoint(dataW, None, None, idx, red)
      
      op.InsertTag(tag)
      tag.SetBit(c4d.BIT_ACTIVE)
      
      c4d.EventAdd()
      
      
      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @zauhar
        last edited by ferdinand

        Hello @zauhar,

        thank you for reaching out to us. Your code does look mostly fine and is working for me. The line op = Default makes little sense and you are of course missing things like imports, a context guard and a main function. Not all of them are absolutely necessary, but it is strongly advised to use them all, especially for novice users. Find a code example below.

        Vertex colors are also not automatically rendered as the diffuse color in Cinema 4D, one must use a VertexMap shader for that. Please consult the user manual or end-user support for end-user questions, we cannot deliver such support here.

        Cheers,
        Ferdinand

        The result for two polygon objects, the color of a vertex depends on its position in global space.
        0e9b3117-e70a-4495-8001-cbe0a6b0a2e4-image.png

        Code

        """Creates vertex-color tag on the currently selected polygon object and makes it the
        active tag.
        
        Must be run as a Script Manager scrip with a polygon object selected. The color of each vertex will
        depend on its position in global space.
        """
        
        import c4d
        import typing
        
        GRADIENT_MIN: float = -200.0 # The lower boundary of the gradient.
        GRADIENT_MAX: float =  200.0 # The upper boundary of the gradient.
        
        op: typing.Optional[c4d.BaseObject] # The active object, can be `None`.
        
        def main() -> None:
            """Runs the example.
            """
            # Check that there is indeed a selected object and that it is a polygon object.
            if not isinstance(op, c4d.PolygonObject):
                raise TypeError("Please select a polygon object.")
        
            # Get its point count and allocate a vertex color tag with that count.
            count: int = op.GetPointCount()
            tag: c4d.VertexColorTag = c4d.VertexColorTag(count)
            if not isinstance(tag, c4d.VertexColorTag):
                raise MemoryError("Could not allocate tag.")
        
            # We are going to make it a little bit more exciting and write a gradient based on the global
            # coordinate y-component of a vertex.
        
            # Set the tag to defining colors only once per vertex instead of having N colors per vertex,
            # where N is the number of polygons attached to it.
            tag.SetPerPointMode(True)
        
            # Get the global matrix of the polygon object and all its points in global space.
            mg: c4d.Matrix = op.GetMg()
            globalPoints: list[c4d.Vector] = [mg * p for p in op.GetAllPoints()]
        
            # Define a callable with which we can get the gradient color of a point over its index.
            GetGradientColor = lambda i : c4d.Vector4d(
                c4d.utils.RangeMap(globalPoints[i].y, GRADIENT_MIN, GRADIENT_MAX, 0, 1, True), 0, 0, 1)
        
            # Get the data pointer of the tag and start writing data.
            dataW: object = tag.GetDataAddressW()
            for i in range(count):
                c4d.VertexColorTag.SetPoint(dataW, None, None, i, GetGradientColor(i))
        
            # Insert the tag into the selected object, make it the active tag, and push an update event.
            op.InsertTag(tag)
            tag.SetBit(c4d.BIT_ACTIVE)
            c4d.EventAdd()
        
        if __name__ == "__main__":
            main()
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • ferdinandF ferdinand referenced this topic on
        • First post
          Last post