Face Center in Bmesh

Hi,

some one know how to get the face center vector from the new Bmesh api??

i used calc_median_center, but i return no vector

1 Like

How are you using it.

I had a hack at your addon last week to try converting it to bmesh. Here is as far as i got. You’ll see that calc_median_center() works. Not sure how to extrude with bmesh so i used the op and had to reload the updated mesh into bmesh.



# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####


bl_info = {
    "name": "Branch Extrusion",
    "author": "Rebellion",
    "version": (1, 0),
    "blender": (2, 6, 2),
    "location": "View3D > Object_Edit > Mesh Tools ",
    "description": "Extrude and Resize the face",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Mesh"}


#set the next face to the set distance (min distance)
#set the taper value = difference between the first and next face


import bpy, mathutils
import bmesh
from bpy.props import IntProperty, FloatProperty
from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_location_3d

#breakpoint = bpy.types.bp.bp

def extrusion(coord,region,rv3d,vec,loc,face,face_center,taper_value, cons_x,cons_y,cons_z,orientation):
    
    
    #bpy.ops.mesh.extrude_region_move(MESH_OT_extrude={"type":'REGION'}, TRANSFORM_OT_translate={"value":(loc )})
  
    #bpy.context.active_object.data.update
    
    bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(loc), "constraint_axis":(cons_x, cons_y, cons_z), "constraint_orientation": orientation})

    bpy.ops.transform.translate(value =(-face_center ), constraint_axis=(cons_x, cons_y, cons_z))         
    #bpy.context.active_object.data.update
    #area = bpy.context.active_object.data.faces[face].area
    bpy.ops.transform.resize(value = (taper_value, taper_value, taper_value)) # to set manually
    

class BranchExtrusionOperator(bpy.types.Operator):
    
  
    bl_idname = "object.branch_extrusion"
    bl_label = "Branch Extrusion"
    bl_options = {'REGISTER', 'UNDO'}
    
    bpy.types.Scene.min_distance = FloatProperty(name='Min Distance', min=0, max=999, soft_min=0, \
        soft_max=20, default= 5, description='Minimun distance from a face to another')
    
    bpy.types.Scene.taper_value = bpy.props.FloatProperty(name= 'Taper Value', min=0, max=999, soft_min=0.001, \
        soft_max=2, default= 0.5, description='Difference in size from a face to another')
    
    bpy.types.Scene.cons_x = bpy.props.BoolProperty(name= 'X Axis', default = False)
    bpy.types.Scene.cons_y = bpy.props.BoolProperty(name= 'Y Axis', default = False)
    bpy.types.Scene.cons_z = bpy.props.BoolProperty(name= 'Z Axis', default = False)
    bpy.types.Scene.orientation = bpy.props.EnumProperty(items = [( 'GLOBAL','Global','kjhb'), ('LOCAL','Local','kjhb'), ('NORMAL','Normal','kjhb')],name = "")




    
    #bpy.types.Scene.orientation = bpy.props.EnumProperty(items = [('NORMAL', 'GLOBAL') ] , name="Transform Orientation", description="###", default="NORMAL")
    
    bpy.context.scene.min_distance = 5
    bpy.context.scene.taper_value = 0.5
    bpy.context.scene.cons_x = False
    bpy.context.scene.cons_y = False
    bpy.context.scene.cons_z = False
    bpy.context.scene['orientation'] = 1
    #vec_taper_value = mathutils.Vector((taper))
    
    LMB_Hold = False
    bmesh = bmesh.new()
    mw = None

    def modal(self, context, event):
        print(event.type,event.value)
        if event.type == 'LEFTMOUSE':
            if event.value == 'PRESS':
                #self.bmesh.clear()
                #self.bmesh.from_mesh(context.object.data)
                #bpy.context.active_object.data.update
                coord = event.mouse_region_x, event.mouse_region_y
                region = context.region
                rv3d = context.space_data.region_3d
                vec = region_2d_to_vector_3d(region, rv3d, coord)
                loc = region_2d_to_location_3d(region, rv3d, coord, vec)

                face = context.object.data.polygons.active
                face_center = self.mw * self.bmesh.faces[face].calc_center_median()

                increment = round((loc - face_center).length, 0) 
                print("BEFORE EXTRUDE")

                print(face,face_center,increment)
                scn = context.scene     


                extrusion(coord,region,rv3d,vec,loc,face,face_center,scn['taper_value'],scn.cons_x ,scn.cons_y,scn.cons_z,scn.orientation)
                #edit mode flip 
                bpy.ops.object.mode_set(mode='OBJECT')
                bpy.ops.object.mode_set(mode='EDIT')
                context.object.data.update()
                self.bmesh.clear()
                self.bmesh.from_mesh(context.object.data)
                #self.bmesh.select_flush(True)
                #self.bmesh.select_mode.update()
                print("AFTER EXTRUDE")
                face = context.object.data.polygons.active
                face_center = self.mw * self.bmesh.faces[face].calc_center_median()
                increment = round((loc - face_center).length, 0) 
                print(face,face_center,increment)

        elif event.type in ('RIGHTMOUSE', 'MIDDLEMOUSE', 'WHEELMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE') or event.type.find('NUMPAD_') == 0:
            print("PASS THRU")
            return {'PASS_THROUGH'}


        elif event.type in {'NUMPAD_ENTER', 'ESC'}:

            return {'FINISHED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        if context.object:
            #self.bmesh = bmesh.new()
            self.bmesh.from_mesh(context.object.data)
            self.mw = context.object.matrix_world
            context.window_manager.modal_handler_add(self)

            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "No active object, could not finish")
            return {'CANCELLED'}

class UI (bpy.types.Panel):
    bl_label = 'Branch Extrusion'
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_context = "mesh_edit"

    def draw(self, context):
        scn = context.scene 
        layout = self.layout
        column = layout.column(align=True)
        column.operator('object.branch_extrusion')  
        column.label(text='Extrusion set:')
        column.prop(scn,'min_distance' , slider=True)
        column.prop(scn, 'taper_value', slider=True) 
        column.label(text='Constraint_axis')
        column.prop(scn,'cons_x')   
        column.prop(scn,'cons_y') 
        column.prop(scn,'cons_z') 
        column.label(text='ORIENTATION')
        column.prop(scn,'orientation')   
            


def Menu_append(self, context):
    self.layout.separator()
    self.layout.operator(BranchExtrusionOperator.bl_idname, text="Branch Extrusion")
 

def register():
    bpy.utils.register_class(BranchExtrusionOperator)
    #bpy.types.VIEW3D_MT_edit_mesh_normals.append(Menu_append)
    #bpy.types.VIEW3D_PT_tools_meshedit_options.append(UI)
    bpy.utils.register_class(UI)
    
def unregister():
    bpy.utils.unregister_class(BranchExtrusionOperator)
    #bpy.types.VIEW3D_MT_edit_mesh_normals.remove(Menu_append)
    bpy.utils.unregister_class(UI)
    
if __name__ == "__main__":
    register()


ok thanks for the reply, i don’t have understand yet bmesh…
so what do you think about the script, i can try to put it in trunk?

i try the code, but there is a problem that occour when i extrude, the mesh is rendering in wireframe, or the face are not rendered, is a problem of my code or a bmesh screen update issues??

and another question: i see that you have moltiplicated the coords with the word matrix, i 'd like to know the difference :smiley:

So does this mean that bMesh does not actually store the value of the face center? Instead we have to calculate it via the new method?

I guess that is what I meant by method, i.e. function. So the value does not exist until we, as programmers, calculate it via a call to the function. Seems like this kind of implementation would be slower than our traditional mesh that had the value pre-calculated for us. I suppose face.area is the same way…?