Applying outline selection by script ?



  • When using the tool: You need to physically click on the model in edge mode.
    I was wondering if there was a way to “apply” to selected object by script ?
    (Using phyton)
    If someone can help me out, let me know :)



  • Hi,

    technically this is possible via c4d.utils.SendModellingCommand(). However, the related specific command ID (c4d.ID_MODELING_OUTLINE_SELECTION_TOOL) is marked as private. So there is no documentation on how to use this properly.

    But it is not to hard to figure out the edges that are border edges. The example below will find all outlines, mimicing c4ds functionality of letting you select a specific loop is just a matter of additional filtering I left out to keep things short.

    import c4d
    # Welcome to the world of Python
    
    
    def set_outline_seleection(op):
        """ Sets the outline edge selection for op.
    
        Args:
            op (c4d.PolygonObject): The object to perform an outline selection on.
        """
        # Return if op is not a polygon object.
        if not isinstance(op, c4d.PolygonObject):
            return
    
        # This is Cinema's version of an edge neighbor data structure
        nbr = c4d.utils.Neighbor()
        nbr.Init(op)
    
        # Get the edge selection for our object.
        selection = op.GetEdgeS()
        selection.DeselectAll()
    
        # Loop over all polygons in our object.
        for pid, cpoly in enumerate(op.GetAllPolygons()):
            # All edge point pair indices of our polygon as a list of tuples with
            # their local edge index.
            edge_point_pairs = [(0, cpoly.a, cpoly.b), (1, cpoly.b, cpoly.c),
                                (2, cpoly.c, cpoly.d), (3, cpoly.d, cpoly.a)]
            # Loop over all edge point pairs in a polygon:
            for eid, a, b in edge_point_pairs:
                # Skip over "empty" triangle edges - c4d presents triangles as four
                # point polygons
                if a == b:
                    continue
                # Test if the current polygon ID is the only ID associated with
                # with the current edge, i. e. if the edge is an outline edge.
                if nbr.GetNeighbor(a, b, pid) == c4d.NOTOK:
                    # Global edge indices in Cinema are indexed as polygon
                    # ID * 4 + edge index in the polygon.
    
                    # Select the edge in our BaseSelect
                    selection.Select(pid * 4 + eid)
        # Update Cinema
        c4d.EventAdd()
    
    
    # Main function
    def main():
        """
        """
        set_outline_seleection(op)
    
    
    # Execute main()
    if __name__ == '__main__':
        main()
    

    Cheers
    zipit



  • Hi myosis, thanks for reaching us out.

    With regard to your request, I confirm that is not possible to script using our Python API the use of the Outline Selection tool.
    The options on your end are either to write your own outline selector by making use of the CPolygon, Neighbor and BaseSelect classes or take advantage of the selection scripts already developed by César Vonc.

    Best, Riccardo



  • @zipit said in Applying outline selection by script ?:

    D_MODELING_OUTLINE_SELECTION_TOO

    Indeed I saw it marked as private, which made me wonder about a modeling command.
    But wow what a response !
    I didn't even think about rewriting the entire function, and thank you for all the notes, very grateful for those. I am not that experienced, and this is teaching me loads.
    Its working like a charm!

    Cheers ;)
    Tim



  • Hi,

    I am glad it does help you. I forgot to mention one thing, which is worth pointing out, when somebody stumbles over this thread, searching for performing edge selections.

    The way I treat edge selections in this script only works because of the specific scenario - selecting edges that are only associated with one polygon. In all other cases you have to select two edge ids (one for each polygon) for each edge or use the convenience methods of c4d.BaseSelect for that. Otherwise you will end up with a corrupted edge selection.

    Cheers
    zipit


Log in to reply