auto fgons script?

Does anyone have an auto fgons script? I know ideasman wrote one 2 years ago, but it has disappeared.


#!BPY

""" 
Name: 'Poly Reduce (Planer)'
Blender: 241
Group: 'Mesh'
Tooltip: 'Reduce a mesh into its planes'
"""

import Blender
import BPyMesh
reload(BPyMesh)
Vector= Blender.Mathutils.Vector
Create= Blender.Draw.Create

def planer_redux(me):
    Blender.Mesh.Mode(Blender.Mesh.SelectModes['VERTEX'])
    scn= Blender.Scene.GetCurrent()
    all_obs= []
    islands= BPyMesh.facesPlanerIslands(me)
    print 'found,', len(islands), 'islands'

    # get edge users:
    FGON =Blender.Mesh.EdgeFlags.FGON
    
    for island_count, faces in enumerate(islands):
        ed_users= BPyMesh.edgeFaceUserCount(me, faces)
        boundry_edges= [  [me.edges[i].v1.index, me.edges[i].v2.index]  for i, users in enumerate(ed_users) if users == 1 ]
        
        # Cull Co-Linear Boundry edges!
        vert2edge= dict([(i, []) for be in boundry_edges for i in be]) # a dict with vert idx's as keys and 2 lists of  edge pair lists as values.
        
        
        for ed_ls in boundry_edges:
            for i in ed_ls:
                vert2edge[i].append(ed_ls)
        
        # Now we have info as to what verts join to what edges. lets cull!
        has_rem= True
        while has_rem:
            has_rem= False
            for v2idx, ed_users in vert2edge.iteritems():
                if ed_users:
                    # work out v1, v2, and v3   - v2 is us, the others join onto us. v2 is the elbo
                    ed_ls1= ed_users[0]
                    ed_ls2= ed_users[1]
                    
                    if v2idx==ed_ls1[0]:
                        v1idx= ed_ls1[1]
                        v2_ed1_idx= 0
                    else:    
                        v1idx= ed_ls1[0]
                        v2_ed1_idx= 1
                        
                    if v2idx==ed_ls2[0]:    v3idx= ed_ls2[1]
                    else:                v3idx= ed_ls2[0]
                    
                    # now we have v1,2 and 3 - lets see if there co-linear.
                    
                    v1co= me.verts[v1idx].co
                    v2co= me.verts[v2idx].co
                    v3co= me.verts[v3idx].co
                    if abs(((v1co-v2co).length+(v2co-v3co).length) - (v1co-v3co).length  ) < 0.0001:
                        # They are co-lin.
                        # remove and re-reference.
                        has_rem= True
                        
                        # Dont look at this vert again. - should always pop twice.
                        while ed_users:    ed_users.pop()
                        while ed_ls2:    ed_ls2.pop()
                        
                        # re-assign ed_ls1, forget about ed_ls2
                        ed_ls1[v2_ed1_idx]= v3idx
                        
                        # make v3 reference ed_ls1 instead of ed_ls2
                        v3_ed_users= vert2edge[v3idx]
                        for i, ed_ls_v3 in enumerate(v3_ed_users):
                            if not ed_ls_v3:
                                v3_ed_users[i]= ed_ls1
        # DONE CULLING COLINEAR EDGES!
                
        new_verts= [] # A list of verts to add to a mesh.
        new_edges= [] # store pairs of indicies to be added to the new mesh.
        vert_mapping= {}
        for ed in boundry_edges:
            if ed:
                v1i= ed[0]
                v2i= ed[1]
                
                v1= me.verts[v1i]
                v2= me.verts[v2i]
                
                try:
                    i1= vert_mapping[v1i]
                except:
                    i1= len(new_verts)
                    vert_mapping[v1i]= i1
                    new_verts.append(v1.co)
                
                try:
                    i2= vert_mapping[v2i]
                except:
                    i2= len(new_verts)
                    vert_mapping[v2i]= i2
                    new_verts.append(v2.co)
                
                new_edges.append( (i1, i2) )
            
        new_me= Blender.Mesh.New()
        new_me.verts.extend(new_verts)
        new_me.edges.extend(new_edges)
        
        new_me.sel= 1
        new_ob= Blender.Object.New('Mesh')
        new_ob.link(new_me)
        scn.link(new_ob)
        new_me.fill()
        
        edge_users= BPyMesh.edge_face_users(new_me)
        for i, ed in enumerate(new_me.edges):
            if len(edge_users[i])>1:
                ed.flag |= FGON
            else:
                ed.flag &= ~FGON
        
        
        # Make sure the new faces are flipped correctly,
        if len(new_me.faces):
            if (new_me.faces[0].no-faces[0].no).length > 0.5:
                new_me.flipNormals()
        
        #scn.unlink(new_ob) # noy currently supported by join
        all_obs.append(new_ob)
        if island_count % 10:
            print len(islands)-island_count
        
    
    new_me= Blender.Mesh.New()
    join_ob= Blender.Object.New('Mesh')
    join_ob.link(new_me)
    scn.link(join_ob)
    join_ob.Layers= scn.Layers
    join_ob.join(all_obs)
    for ob in all_obs:
        scn.unlink(ob)
    new_me.sel= 1
    new_me.remDoubles(0.00001)
    new_me.sel= 1
    '''
    # Assign image EVIL HACK!
    if new_me.faces and me.faceUV and me.faces[0].image:
        image= me.faces[0].image
        for f in new_me.faces:
            f.image= image
    '''
    join_ob.makeDisplayList()
    return join_ob
    

def main():
        # Create the variables.
    # Filename without path or extension.
    Blender.Window.EditMode(0)
    scn= Blender.Scene.GetCurrent()
    '''
    act_ob= scn.getActiveObject()
    if not act_ob or act_ob.getType() != 'Mesh':
        Blender.Draw.PupMenu('Error, no active mesh selected.')
        return
    
    me= act_ob.getData(mesh=1)
    new_ob= planer_redux(me)
    new_ob.setMatrix(act_ob.matrixWorld)
    
    for ob in scn.getChildren():
        ob.sel= 0
    
    new_ob.sel= 1
    '''
    
    meshes= [ob for ob in scn.objects.selected if ob.type=='Mesh']
    
    for ob in scn.objects.selected:
        ob.sel= 0
    
    for ob in meshes:
        me= ob.getData(mesh=1)
        new_ob= planer_redux(me)
        new_ob.setMatrix(ob.matrixWorld)
    
    Blender.Window.RedrawAll()


if __name__ == '__main__': 
    main()

Thanks!!! And also a big thanx for the recode in the UV editor. Is there a place to talk about the features? I’ve seen the wiki page, and I think your todo is actually everything I ever wished in UV editing. Just think the selection syncing could be switched sometimes just in 1 direction, so that you could e.g. select only 1 uv corner of a vertex, and still have the vertex selected in 3d view…

Hey pildanovak, for chit chat #blendercoders on freenode is good but for discussion for many to be involved with the best place is this mailing list…
http://lists.blender.org/mailman/listinfo/bf-funboard

Id not mind if you wanted to start the discussion.

regarding mixing MeshSyncSel with partial selection, At first I didnt think it could work, but if the rules logic was setup right it could…

though it would require flushing, (means when the vert selection is changes, the UV selection needs to be re-evaluated) with flushing functions that operate UV->mesh and mesh->UV

  • a vert is selected == at least one UV is selected, no UV’s selected, no verts selected.
  • selecting a vert will select all UV’s using that vert. selecting a corner can only be done in UV mode.

and that kind of stuff, but at the moment Im trying to get the basics in there, and it works ok this way.