Left to right face select

Hi, i have been using blender 2.5 for awhile and starting to try making scripts. I’m trying to write a script that takes a plane made in top view that’s had a Multires applied to object so it has many faces, want to make it select each face one by one top left going right like a book. or am doing something already done? should i try selecting verts first?

Hi
get the ‘visualizer’ addon.
A plane several times subdivide gives this result
http://i54.tinypic.com/343t4x4.jpg

Maybe this helps?

You can use the interface to sort the faces based upon the viewport.

Put the mesh in edit mode.
Set the viewport to LEFT.
Press CTRL-F and choose Sort Faces from the popup menu.
Then choose ViewAxis.

You can re-arrange face order this way.

thank you both, that script seems like it should help out a lot.

I been trying to read the script Index Visualizer, I’m so new to python and the blender api right now so a lot of it is alil over my head right now. But I’m trying to add something that will take each face and from 0 to 1024 or more depending on the mesh, and separate each face into its own object. I’m right now using the bpy.ops.mesh.separate(type=‘SELECTED’) operator. I figure its going to be like a dicer tool.

Here is a script that separates each face of the active mesh into a separate object.

import bpy

# disable global undo, so we can undo all steps with a single ctrl+z
undo = bpy.context.user_preferences.edit.use_global_undo
bpy.context.user_preferences.edit.use_global_undo = False
# get object and make sure no faces are selected
ob = bpy.context.active_object
old_mode = ob.mode
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.mesh.select_all(action = 'DESELECT')
bpy.ops.object.mode_set(mode = 'OBJECT')
# get mesh data
mesh = ob.data
# set selection mode (we want face-selection mode)
select_mode = bpy.context.tool_settings.mesh_select_mode[:]
bpy.context.tool_settings.mesh_select_mode = [False, False, True]

# actual seperation loop
for i in range(len(mesh.faces)-1):
    mesh.faces[0].select = True # select face in object mode
    bpy.ops.object.mode_set(mode = 'EDIT')
    bpy.ops.mesh.separate(type = 'SELECTED') # separate face in edit mode
    bpy.ops.object.mode_set(mode = 'OBJECT')

# cleaning up, restoring all old setting
bpy.ops.object.mode_set(mode = old_mode)
bpy.context.tool_settings.mesh_select_mode = select_mode
bpy.context.user_preferences.edit.use_global_undo = undo

If you really need to do the separating in a specific order, for instance western reading order (top to bottom, left to right), you’ll run into a problem. Getting the faces in the correct order isn’t much of a problem. Simple example:

import bpy
import math

mesh = bpy.context.active_object.data

y_co = [[face.center[1], i] for i, face in enumerate(mesh.faces)]
y_co.sort()
grid_size = round(math.sqrt(len(mesh.faces)))

face_order = []
for row in range(grid_size):
    faces = [face[1] for face in y_co[row*grid_size : (row+1)*grid_size]]
    x_co = [[mesh.faces[i].center[0], i] for i in faces]
    x_co.sort()
    face_order += [face[1] for face in x_co]

print(face_order)

The problem is that once you separate a face, all remaining faces in the old mesh get a different index number and you’ll have to build face_order list again (and keep into account that you don’t have a square grid anymore).

Thanks so much Crouch this gives the results i need, just tested it out on some meshs. froze up when i tried 16000 faces maybe my computer cant take that many. didnt even know about bpy.context.selected_object till seeing your script and now this page http://wiki.blender.org/index.php/Dev:2.5/Py/API/Intro was just looking into the API earlier.

I was just thinking the order they were separated in edit mode might not be important, if the Objects after could be renamed like plane.001 plane.002 etc… in a second script.

The problem is that switching between edit and object mode for each separation step, is taking a lot of resources. You might be able to get better results by first adding a different material for each single face and then separating based on material. Afterwards you can delete the materials again. I’m not certain if this is faster though, as it might also take quite some resource to create a temporary material for each face. Not to mention that you loose material information.

Renaming the objects afterwards isn’t a problem. Just iterate over all objects and sort them as I did for the faces (2nd script, previous post of mine).

Nice thanks! yea I would try the material idea but the computer I’m on right now might not be able to handle that. I’m going to start working on a renaming part now for the script. thanks a lot for the help would have taken weeks maybe for me, being so new to scripting.

It is possible to save 1 selected object into its own separate .blend file under its own name like plane.001.blend? I’m thinking that might be very intense for it to handle a whole scene at once and do that, to put every object into its own file?

maybe can use the 2nd script for this also i only found how to export into other formats not .blend, like bpy.ops.export_scene.obj(). WIP!!!

hello : this is mine^^
import bpy
out=bpy.data.texts[‘out’]
out.clear()
context=bpy.context
sce=context.scene
actif=bpy.context.scene.objects.active
bpy.ops.object.mode_set(mode=‘EDIT’)
bpy.ops.object.mode_set(mode = ‘EDIT’)
bpy.context.tool_settings.mesh_select_mode = [False, False, True]
bpy.ops.mesh.select_all(action = ‘DESELECT’)
bpy.ops.object.mode_set(mode = ‘OBJECT’)
sm = actif.data

i=len(bpy.context.scene.objects.active.data.polygons[:])
out.write(str(sm)+’
_’+str(len(bpy.context.scene.objects.active.data.polygons[:]))+’
_’+str(range(i)))

for pol in range(len(bpy.context.scene.objects.active.data.polygons[:])-1) :
out.write(str(i-pol)+’
')
sm.polygons[i-pol-1].select=True
bpy.ops.object.mode_set(mode = ‘EDIT’)
bpy.ops.mesh.separate(type = ‘SELECTED’)
bpy.ops.object.mode_set(mode = ‘OBJECT’)

import bpy
if 'out' not in bpy.data.texts:
    bpy.data.texts.new('out')
out=bpy.data.texts['out']
out.clear()
context=bpy.context
sce=context.scene


list_obj=sce.objects[:]
actif=bpy.context.scene.objects.active
actif_name=actif.name
#out.write(str(actif)+'_____
')
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.context.tool_settings.mesh_select_mode = [False, False, True]
bpy.ops.mesh.select_all(action = 'DESELECT')
bpy.ops.object.mode_set(mode = 'OBJECT')
sm = actif.data


i=len(bpy.context.scene.objects.active.data.polygons[:])
#out.write(str(sm)+'
'+str(len(bpy.context.scene.objects.active.data.polygons[:]))+'
_'+str(range(i))+'
')


for pol in range(len(bpy.context.scene.objects.active.data.polygons[:])-1) :
    #out.write(str(i-pol)+'
')
    sm.polygons[i-pol-1].select=True
    bpy.ops.object.mode_set(mode = 'EDIT')
    bpy.ops.mesh.separate(type = 'SELECTED')
    bpy.ops.object.mode_set(mode = 'OBJECT')
    
    
new_list_obj=sce.objects[:]
#out.write(str(new_list_obj[:])+'
'+'
'+str(list_obj[:])+'
'+'
')
bpy.ops.object.select_all(action='DESELECT')
bpy.context.scene.objects.active=bpy.context.scene.objects[actif_name]
bpy.context.scene.objects.active.select=True
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN')
for obj in new_list_obj[:]:
   if obj not in list_obj[:]: 
       #out.write(str([obj.name])+':::repos:::
')
       bpy.ops.object.select_all(action='DESELECT')
       #out.write('.')
       bpy.context.scene.objects.active=obj
       #out.write('-')
       bpy.context.scene.objects.active.select=True
       #obj.select=true
       #out.write('_')
       #out.write(str(bpy.context.scene.objects.active)+'_____
')
       #bpy.context.scene.objects[obj.name].select=True
       
       
       #out.write('actif:'+str(bpy.context.scene.objects.active)+'
')
       bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN')
out.write('finished')