Select plane polygons within a sphere



  • On 05/05/2017 at 14:39, xxxxxxxx wrote:

    Hi,

    I have a plane and I have a sphere, and I'd like to select the plane's polygons within the sphere to apply some subdivision to the selected polygons. So far I only selected all polygons and applied the subdivision. What would be a good approach to make that selection based on the sphere?

    Thanks!

    import c4d
    from c4d import gui, utils
    #Welcome to the world of Python
      
      
    def main() :
        
        poly = op.GetAllPolygons()
        
        doc.StartUndo()
        
        settings = c4d.BaseContainer()                 # Settings
      
        [c4d.BOOLEOBJECT_TYPE]
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)
        res = utils.SendModelingCommand(command = c4d.MCOMMAND_SUBDIVIDE,
                                    list = [op],
                                    mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
                                    bc = settings,
                                    doc = doc)                        
                                    
                                    
        
        doc.EndUndo()
        c4d.EventAdd()
        
    if __name__=='__main__':
        main()
    


  • On 08/05/2017 at 12:22, xxxxxxxx wrote:

    I understand my previous question was extremely vague.

    I managed to delete polygons based on a object's proximity. Of course I want to subdivide them, not delete them. But I couldn't find a way to just subdivide once, it keeps subdividing ad infinitum. That's why I was using delete for the tests, to not freeze the machine. Any idea on how to just subdivide the polygons only once? Is there a way to flag them as "already subdivided"?

    Thanks!

    import c4d
    from c4d import utils
    #Welcome to the world of Python
      
      
    def main() :
        pass  #put in your code here   
        
        link = op[c4d.ID_USERDATA,1]
        obj = op.GetObject()
        
        nbr = utils.Neighbor()
        nbr.Init(obj)
        
        points = obj.GetAllPoints()
        PolyS = obj.GetPolygonS()
        point = link.GetAbsPos()
        matrix = obj.GetMg()
        
        lastDistance = 500000000
        mDistance = 0
        closetPoint = 0
        
        for i in range(len(points)) :
            
            mesh_point = points[i]
            result = [mesh_point, (mesh_point * matrix - point).GetLength(), 0]
            distance = result[1]                
            if distance < lastDistance:
                mDistance = distance
                lastDistance = distance
                closestPoint =  points.index(mesh_point)
            else:
                mDistance = lastDistance    
      
        
        polys = nbr.GetPointPolys(closestPoint)    
        for i in polys:
            PolyS.Select(i)
            c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_DELETE,
                                      list=[obj],
                                      mode=c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
                                      doc=doc)  
        
        result
    


  • On 09/05/2017 at 13:49, xxxxxxxx wrote:

    Hi,
    The support guys are gone this week. That's why you're not getting a reply.

    It sounds like you're running your code from a python tag. And that's why it subdivides more than once.
    You'll probably need to run your code in the script manger so it executes only once.
    If you want to dynamically subdivide the polygons while moving the sphere around. You'll probably need to use a tool plugin. Where it executes the subdivision code once when the LMB is released.

    -ScottA



  • On 10/05/2017 at 15:17, xxxxxxxx wrote:

    Thanks for your reply. I'll look into the tool plugin.

    So far I was trying to get a list with the polygons that were already subdivided, and subtract them from the selection in the next frame/update of the generator so they don't get subdivided again. I was hoping that c4d.MCOMMAND_SUBDIVIDE would return a list with the new subdivided polygons, but I think it is not the case.



  • On 12/05/2017 at 17:56, xxxxxxxx wrote:

    I made it work with the Generator, but I am lacking undo or the option to animate it because once applied I don't know how to go back to the un-subdivided state. You can check this example project:

    http://www.dropbox.com/sh/c5460s47hnhr9jx/AABwdd5u-3ixAlH4FXxYVluDa?dl=0

    import c4d
    from c4d import utils
    #Welcome to the world of Python
      
      
    def main() :
        pass  #put in your code here
        
        #I put a null for the link
        link = op[c4d.ID_USERDATA,1]
        obj = op.GetObject()
        
        nbr = utils.Neighbor()
        nbr.Init(obj)
        
        points = obj.GetAllPoints()
        PolyS = obj.GetPolygonS()
        
        point = link.GetAbsPos()
        matrix = obj.GetMg()    
      
        lenPoints = len(points)
      
        lastDistance = 500000000
        mDistance = 0
        
        for i in range(len(points)) :
            
            mesh_point = points[i]
            result = [mesh_point, (mesh_point * matrix - point).GetLength(), 0]
            distance = result[1]
                    
            if distance < lastDistance:
                mDistance = distance
                lastDistance = distance
                closestPoint =  points.index(mesh_point)
            else:
                mDistance = lastDistance    
        
        polys = nbr.GetPointPolys(closestPoint)
        print polys
        print range(len(polys))
        
        settings = c4d.BaseContainer()
        settings[c4d.MDATA_SUBDIVIDE_SUB] =1    
      
        for i in polys:
            PolyS.Select(i)
            print (PolyS.Select(i))        
      
        c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_SUBDIVIDE,
                                    list = [obj],
                                    mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
                                    bc = settings,
                                    doc = doc)
      
        PolyS.DeselectAll()    
        
        result
    


  • On 13/05/2017 at 07:15, xxxxxxxx wrote:

    This code runs every time the frame changes. So you will end up with a lot of undo operations on the undo stack. It's not the kind of thing you would typically undo.
    It would be better to just select the polygons as the sphere collides with them. And then once you have the path of selected polygons. Run the subdivide code on it.
    That way the subdivision can be undone with one undo call.
    A tool plugin is the typical way to do that.

    If you need the subdivision code to execute on every frame so it's animated. Then you'll probably need to first copy the object somewhere in case you want to restore it later on.

    -ScottA



  • On 15/05/2017 at 02:29, xxxxxxxx wrote:

    Hello,

    as Scott indicated, a tag or a generator are executed multiple times. They are executed every time the scene execution pipeline is called. This is the case when the current frame changes but also when the scene is changed (a new object is added, the camera is moved.). So a generator or a tag are used to create plugins that are executed all the time. But a proper ObjectData plugin generator object should be able to "read" a input polygon object to create the (partially) subdivided result on demand.

    Undo steps should only be added to user interaction. So when the user uses the GUI (a button or a tool) to edit the active document, an undo step should be added. Such user interaction can be a ToolData based plugin tool, or using some button in a GeDialog.

    best wishes,
    Sebastian



  • On 17/05/2017 at 10:12, xxxxxxxx wrote:

    Thanks very much for your replies. I will try to translate what I did in the generator to an ObjectData plugin and get back here with the result. But I am guessing this will take me a while... ;)


Log in to reply