def invoke(self, context, event): wm = context.window_manager ret = self.execute(context) generate_icons() generate_patterns_icons() if ret == {'FINISHED'}: wm.invoke_props_popup(self, event) return ret
def execute(self, context): object = context.object object.update_from_editmode() object_bm = bmesh.from_edit_mesh(object.data) selected_edges = [e for e in object_bm.edges if e.select] loops = get_loops(selected_edges[:]) if not loops: self.report({'WARNING'}, "Please select boundary loop of selected area.") return {'CANCELLED'} if len(loops) > 1: self.report({'WARNING'}, "Please select one loop.") return {'CANCELLED'} loop_verts = loops[0][0][0] if len(loop_verts) < 2: self.report({'WARNING'}, "Please select more edges.") return {'CANCELLED'} pattern_item = context.scene.perfect_shape.patterns.add() shape_bm = bmesh.new() for loop_vert in loop_verts: pattern_vert = pattern_item.verts.add() pattern_vert.co = loop_vert.co.copy() shape_bm.verts.new(loop_vert.co.copy()) shape_bm.verts.ensure_lookup_table() verts = shape_bm.verts[:] for i in range(len(verts) - 1): shape_bm.edges.new((verts[i], verts[i + 1 % len(verts)])) bmesh.ops.contextual_create(shape_bm, geom=shape_bm.edges) shape_bm.faces.ensure_lookup_table() center = shape_bm.faces[0].calc_center_median() bmesh.ops.triangulate(shape_bm, faces=shape_bm.faces[:]) forward = calculate_normal([v.co for v in loop_verts]) normal_forward = reduce( lambda v1, v2: v1.normal.copy() + v2.normal.copy() if isinstance(v1, bmesh.types.BMVert) else v1.copy() + v2.normal.copy(), loop_verts).normalized() if normal_forward.angle(forward) - math.pi / 2 > 1e-6: forward.negate() matrix_rotation = forward.to_track_quat('Z', 'Y').to_matrix().to_4x4() matrix_rotation.transpose() matrix = matrix_rotation * Matrix.Translation(-center) for pattern_vert in pattern_item.verts: pattern_vert.co = matrix * Vector(pattern_vert.co) pattern_faces = pattern_item.faces for face in shape_bm.faces: item = pattern_faces.add() item.indices = [v.index for v in face.verts] generate_patterns_icons() idx = context.scene.perfect_shape.patterns.values().index(pattern_item) context.scene.perfect_shape.active_pattern = str(idx) clear_cache() return {'FINISHED'}
def execute(self, context): object = context.object object.update_from_editmode() object_bm = bmesh.from_edit_mesh(object.data) selected_edges = [e for e in object_bm.edges if e.select] loops = get_loops(selected_edges[:]) if not loops: self.report({'WARNING'}, "Please select boundary loop of selected area.") return {'CANCELLED'} if len(loops) > 1: self.report({'WARNING'}, "Please select one loop.") return {'CANCELLED'} loop_verts = loops[0][0][0] if len(loop_verts) < 2: self.report({'WARNING'}, "Please select more edges.") return {'CANCELLED'} pattern_item = context.scene.perfect_shape.patterns.add() shape_bm = bmesh.new() for loop_vert in loop_verts: pattern_vert = pattern_item.verts.add() pattern_vert.co = loop_vert.co.copy() shape_bm.verts.new(loop_vert.co.copy()) shape_bm.verts.ensure_lookup_table() verts = shape_bm.verts[:] for i in range(len(verts) - 1): shape_bm.edges.new((verts[i], verts[i + 1 % len(verts)])) bmesh.ops.contextual_create(shape_bm, geom=shape_bm.edges) shape_bm.faces.ensure_lookup_table() center = shape_bm.faces[0].calc_center_median() bounds = shape_bm.faces[0].calc_center_bounds() dist = bounds.length - center.length # center = center + (bounds-center).normalized() * dist bmesh.ops.triangulate(shape_bm, faces=shape_bm.faces[:]) forward = calculate_normal([v.co for v in loop_verts]) normal_forward = reduce( lambda v1, v2: v1.normal.copy() + v2.normal.copy() if isinstance(v1, bmesh.types.BMVert) else v1.copy() + v2.normal.copy(), loop_verts).normalized() if normal_forward.angle(forward) - math.pi / 2 > 1e-6: forward.negate() matrix_rotation = forward.to_track_quat('Z', 'Y').to_matrix().to_4x4() matrix_rotation.transpose() matrix = matrix_rotation * Matrix.Translation(-center) for pattern_vert in pattern_item.verts: pattern_vert.co = matrix * Vector(pattern_vert.co) pattern_faces = pattern_item.faces for face in shape_bm.faces: item = pattern_faces.add() item.indices = [v.index for v in face.verts] generate_patterns_icons() idx = context.scene.perfect_shape.patterns.values().index(pattern_item) context.scene.perfect_shape.active_pattern = str(idx) clear_cache() return {'FINISHED'}