diff options
author | meta-androcto <meta.androcto1@gmail.com> | 2017-03-20 02:33:38 +0300 |
---|---|---|
committer | meta-androcto <meta.androcto1@gmail.com> | 2017-03-20 02:33:38 +0300 |
commit | 8e3bfa5506ea110fe6793401b53da17c61061167 (patch) | |
tree | 8e53f830a72b434928b07b99befe8762431a4ed3 /mesh_extra_tools/pkhg_faces.py | |
parent | 9007bcd10713e55168235e9e8420b17172674638 (diff) |
initial commit mesh edit tools: T50680
Diffstat (limited to 'mesh_extra_tools/pkhg_faces.py')
-rw-r--r-- | mesh_extra_tools/pkhg_faces.py | 824 |
1 files changed, 824 insertions, 0 deletions
diff --git a/mesh_extra_tools/pkhg_faces.py b/mesh_extra_tools/pkhg_faces.py new file mode 100644 index 00000000..10b0ca97 --- /dev/null +++ b/mesh_extra_tools/pkhg_faces.py @@ -0,0 +1,824 @@ +# gpl author: PHKG + +bl_info = { + "name": "PKHG faces", + "author": "PKHG", + "version": (0, 0, 5), + "blender": (2, 7, 1), + "location": "View3D > Tools > PKHG (tab)", + "description": "Faces selected will become added faces of different style", + "warning": "", + "wiki_url": "", + "category": "Mesh", +} + +import bpy +import bmesh +from bpy.types import ( + Operator, + Panel + ) +from mathutils import Vector +from bpy.props import ( + BoolProperty, + StringProperty, + IntProperty, + FloatProperty, + EnumProperty, + ) + + +class MESH_OT_add_faces_to_object(Operator): + bl_idname = "mesh.add_faces_to_object" + bl_label = "Face Extrude" + bl_description = "Set parameters and build object with added faces" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + reverse_faces = BoolProperty( + name="Reverse Faces", + default=False, + description="Revert the normals of selected faces" + ) + name_source_object = StringProperty( + name="Mesh", + description="Choose a Source Mesh", + default="Cube" + ) + remove_start_faces = BoolProperty( + name="Remove Start Faces", + default=True, + description="Make a choice about removal of Original Faces" + ) + base_height = FloatProperty( + name="Base Height", + min=-20, + soft_max=10, max=20, + default=0.2, + description="Set general Base Height" + ) + use_relative_base_height = BoolProperty( + name="rel.base_height", + default=False, + description="Relative or absolute Base Height" + ) + second_height = FloatProperty( + name="2nd height", min=-5, + soft_max=5, max=20, + default=0.2, + description="Second height for various shapes" + ) + width = FloatProperty( + name="Width Faces", + min=-20, max=20, + default=0.5, + description="Set general width" + ) + repeat_extrude = IntProperty( + name="Repeat", + min=1, + soft_max=5, max=20, + description="For longer base" + ) + move_inside = FloatProperty( + name="Move Inside", + min=0.0, + max=1.0, + default=0.5, + description="How much move to inside" + ) + thickness = FloatProperty( + name="Thickness", + soft_min=0.01, min=0, + soft_max=5.0, max=20.0, + default=0 + ) + depth = FloatProperty( + name="Depth", + min=-5, + soft_max=5.0, max=20.0, + default=0 + ) + collapse_edges = BoolProperty( + name="Make Point", + default=False, + description="Collapse the vertices of edges" + ) + spike_base_width = FloatProperty( + name="Spike Base Width", + default=0.4, + min=-4.0, + soft_max=1, max=20, + description="Base width of a spike" + ) + base_height_inset = FloatProperty( + name="Base Height Inset", + default=0.0, + min=-5, max=5, + description="To elevate or drop the Base height Inset" + ) + top_spike = FloatProperty( + name="Top Spike", + default=1.0, + min=-10.0, max=10.0, + description="The Base Height of a spike" + ) + + top_extra_height = FloatProperty( + name="Top Extra Height", + default=0.0, + min=-10.0, max=10.0, + description="Add extra height" + ) + step_with_real_spike = BoolProperty( + name="Step with Real Spike", + default=False, + description="In stepped, use a real spike" + ) + use_relative = BoolProperty( + name="Use Relative", + default=False, + description="Change size using area, min or max" + ) + face_types = EnumProperty( + name="Face Types", + description="Different types of Faces", + default="no", + items=[ + ('no', "Pick an Option", "Choose one of the available options"), + ('open_inset', "Open Inset", "Inset without closing faces (holes)"), + ('with_base', "With Base", "Base and ..."), + ('clsd_vertical', "Closed Vertical", "Closed Vertical"), + ('open_vertical', "Open Vertical", "Open Vertical"), + ('spiked', "Spiked", "Spike"), + ('stepped', "Stepped", "Stepped"), + ('boxed', "Boxed", "Boxed"), + ('bar', "Bar", "Bar"), + ] + ) + strange_boxed_effect = BoolProperty( + name="Strange Effect", + default=False, + description="Do not show one extrusion" + ) + use_boundary = BoolProperty( + name="Use Boundary", + default=True + ) + use_even_offset = BoolProperty( + name="Even Offset", + default=True + ) + use_relative_offset = BoolProperty( + name="Relative Offset", + default=True + ) + use_edge_rail = BoolProperty( + name="Edge Rail", + default=False + ) + use_outset = BoolProperty( + name="Outset", + default=False + ) + use_select_inset = BoolProperty( + name="Inset", + default=False + ) + use_interpolate = BoolProperty( + name="Interpolate", + default=True + ) + + @classmethod + def poll(cls, context): + result = False + active_object = context.active_object + if active_object: + mesh_objects_name = [el.name for el in bpy.data.objects if el.type == "MESH"] + if active_object.name in mesh_objects_name: + result = True + + return result + + def draw(self, context): + layout = self.layout + col = layout.column() + + col.separator() + col.label(text="Using Active Object", icon="INFO") + col.separator() + col.label("Face Types:") + col.prop(self, "face_types", text="") + col.separator() + col.prop(self, "use_relative") + + if self.face_types == "open_inset": + col.prop(self, "move_inside") + col.prop(self, "base_height") + + elif self.face_types == "with_base": + col.prop(self, "move_inside") + col.prop(self, "base_height") + col.prop(self, "second_height") + col.prop(self, "width") + + elif self.face_types == "clsd_vertical": + col.prop(self, "base_height") + + elif self.face_types == "open_vertical": + col.prop(self, "base_height") + + elif self.face_types == "boxed": + col.prop(self, "move_inside") + col.prop(self, "base_height") + col.prop(self, "top_spike") + col.prop(self, "strange_boxed_effect") + + elif self.face_types == "spiked": + col.prop(self, "spike_base_width") + col.prop(self, "base_height_inset") + col.prop(self, "top_spike") + + elif self.face_types == "bar": + col.prop(self, "spike_base_width") + col.prop(self, "top_spike") + col.prop(self, "top_extra_height") + + elif self.face_types == "stepped": + col.prop(self, "spike_base_width") + col.prop(self, "base_height_inset") + col.prop(self, "top_extra_height") + col.prop(self, "second_height") + col.prop(self, "step_with_real_spike") + + def execute(self, context): + obj_name = self.name_source_object + face_type = self.face_types + + is_selected = check_is_selected() + + if not is_selected: + self.report({'WARNING'}, + "Operation Cancelled. No selected Faces found on the Active Object") + return {'CANCELLED'} + + if face_type == "spiked": + Spiked(spike_base_width=self.spike_base_width, + base_height_inset=self.base_height_inset, + top_spike=self.top_spike, top_relative=self.use_relative) + + elif face_type == "boxed": + startinfo = prepare(self, context, self.remove_start_faces) + bm = startinfo['bm'] + top = self.top_spike + obj = startinfo['obj'] + obj_matrix_local = obj.matrix_local + + distance = None + base_heights = None + t = self.move_inside + areas = startinfo['areas'] + base_height = self.base_height + + if self.use_relative: + distance = [min(t * area, 1.0) for i, area in enumerate(areas)] + base_heights = [base_height * area for i, area in enumerate(areas)] + else: + distance = [t] * len(areas) + base_heights = [base_height] * len(areas) + + rings = startinfo['rings'] + centers = startinfo['centers'] + normals = startinfo['normals'] + for i in range(len(rings)): + make_one_inset(self, context, bm=bm, ringvectors=rings[i], + center=centers[i], normal=normals[i], + t=distance[i], base_height=base_heights[i]) + bpy.ops.mesh.select_mode(type="EDGE") + bpy.ops.mesh.select_more() + bpy.ops.mesh.select_more() + bpy.ops.object.mode_set(mode='OBJECT') + # PKHG>INFO base extrusion done and set to the mesh + + # PKHG>INFO if the extrusion is NOT done ... it'll look strange soon! + if not self.strange_boxed_effect: + bpy.ops.object.mode_set(mode='EDIT') + obj = context.active_object + bm = bmesh.from_edit_mesh(obj.data) + bmfaces = [face for face in bm.faces if face.select] + res = extrude_faces(self, context, bm=bm, face_l=bmfaces) + ring_edges = [face.edges[:] for face in res] + + bpy.ops.object.mode_set(mode='OBJECT') + + # PKHG>INFO now the extruded facec have to move in normal direction + bpy.ops.object.mode_set(mode='EDIT') + obj = bpy.context.scene.objects.active + bm = bmesh.from_edit_mesh(obj.data) + todo_faces = [face for face in bm.faces if face.select] + for face in todo_faces: + bmesh.ops.translate(bm, vec=face.normal * top, space=obj_matrix_local, + verts=face.verts) + bpy.ops.object.mode_set(mode='OBJECT') + + elif face_type == "stepped": + Stepped(spike_base_width=self.spike_base_width, + base_height_inset=self.base_height_inset, + top_spike=self.second_height, + top_extra_height=self.top_extra_height, + use_relative_offset=self.use_relative, with_spike=self.step_with_real_spike) + + elif face_type == "open_inset": + startinfo = prepare(self, context, self.remove_start_faces) + bm = startinfo['bm'] + + # PKHG>INFO adjust for relative, via areas + t = self.move_inside + areas = startinfo['areas'] + base_height = self.base_height + base_heights = None + distance = None + if self.use_relative: + distance = [min(t * area, 1.0) for i, area in enumerate(areas)] + base_heights = [base_height * area for i, area in enumerate(areas)] + else: + distance = [t] * len(areas) + base_heights = [base_height] * len(areas) + + rings = startinfo['rings'] + centers = startinfo['centers'] + normals = startinfo['normals'] + for i in range(len(rings)): + make_one_inset(self, context, bm=bm, ringvectors=rings[i], + center=centers[i], normal=normals[i], + t=distance[i], base_height=base_heights[i]) + bpy.ops.object.mode_set(mode='OBJECT') + + elif face_type == "with_base": + startinfo = prepare(self, context, self.remove_start_faces) + bm = startinfo['bm'] + obj = startinfo['obj'] + object_matrix = obj.matrix_local + + # PKHG>INFO for relative (using areas) + t = self.move_inside + areas = startinfo['areas'] + base_height = self.base_height + distance = None + base_heights = None + + if self.use_relative: + distance = [min(t * area, 1.0) for i, area in enumerate(areas)] + base_heights = [base_height * area for i, area in enumerate(areas)] + else: + distance = [t] * len(areas) + base_heights = [base_height] * len(areas) + + next_rings = [] + rings = startinfo['rings'] + centers = startinfo['centers'] + normals = startinfo['normals'] + for i in range(len(rings)): + next_rings.append(make_one_inset(self, context, bm=bm, ringvectors=rings[i], + center=centers[i], normal=normals[i], + t=distance[i], base_height=base_heights[i])) + + prepare_ring = extrude_edges(self, context, bm=bm, edge_l_l=next_rings) + + second_height = self.second_height + width = self.width + vectors = [[ele.verts[:] for ele in edge] for edge in prepare_ring] + n_ring_vecs = [] + + for rings in vectors: + v = [] + for edgv in rings: + v.extend(edgv) + # PKHF>INFO no double verts allowed, coming from two adjacents edges! + bm.verts.ensure_lookup_table() + vv = list(set([ele.index for ele in v])) + + vvv = [bm.verts[i].co for i in vv] + n_ring_vecs.append(vvv) + + for i, ring in enumerate(n_ring_vecs): + make_one_inset(self, context, bm=bm, ringvectors=ring, + center=centers[i], normal=normals[i], + t=width, base_height=base_heights[i] + second_height) + bpy.ops.object.mode_set(mode='OBJECT') + + else: + if face_type == "clsd_vertical": + obj_name = context.active_object.name + ClosedVertical(name=obj_name, base_height=self.base_height, + use_relative_base_height=self.use_relative) + + elif face_type == "open_vertical": + obj_name = context.active_object.name + OpenVertical(name=obj_name, base_height=self.base_height, + use_relative_base_height=self.use_relative) + + elif face_type == "bar": + startinfo = prepare(self, context, self.remove_start_faces) + + result = [] + bm = startinfo['bm'] + rings = startinfo['rings'] + centers = startinfo['centers'] + normals = startinfo['normals'] + spike_base_width = self.spike_base_width + for i, ring in enumerate(rings): + result.append(make_one_inset(self, context, bm=bm, + ringvectors=ring, center=centers[i], + normal=normals[i], t=spike_base_width)) + + next_ring_edges_list = extrude_edges(self, context, bm=bm, + edge_l_l=result) + top_spike = self.top_spike + fac = top_spike + object_matrix = startinfo['obj'].matrix_local + for i in range(len(next_ring_edges_list)): + translate_ONE_ring(self, context, bm=bm, + object_matrix=object_matrix, + ring_edges=next_ring_edges_list[i], + normal=normals[i], distance=fac) + + next_ring_edges_list_2 = extrude_edges(self, context, bm=bm, + edge_l_l=next_ring_edges_list) + + top_extra_height = self.top_extra_height + for i in range(len(next_ring_edges_list_2)): + move_corner_vecs_outside(self, context, bm=bm, + edge_list=next_ring_edges_list_2[i], + center=centers[i], normal=normals[i], + base_height_erlier=fac + top_extra_height, + distance=fac) + bpy.ops.mesh.select_mode(type="VERT") + bpy.ops.mesh.select_more() + + bpy.ops.object.mode_set(mode='OBJECT') + + return {'FINISHED'} + + +class VIEW3D_Faces_Panel(Panel): + bl_label = "Face Extrude" + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + bl_category = "Tools" + bl_options = {"DEFAULT_CLOSED"} + + @classmethod + def poll(cls, context): + result = False + active_object = context.active_object + if active_object: + mesh_objects_name = [el.name for el in bpy.data.objects if el.type == "MESH"] + if active_object.name in mesh_objects_name: + if active_object.mode == "OBJECT": + result = True + return result + + def draw(self, context): + layout = self.layout + + row = layout.split(0.8, align=True) + row.operator("mesh.add_faces_to_object", "Selected Faces") + row.operator("mesh.extra_tools_help", + icon="LAYER_USED").help_ids = "pkhg_faces" + + +def find_one_ring(sel_vertices): + ring0 = sel_vertices.pop(0) + to_delete = [] + + for i, edge in enumerate(sel_vertices): + len_nu = len(ring0) + if len(ring0 - edge) < len_nu: + to_delete.append(i) + ring0 = ring0.union(edge) + + to_delete.reverse() + + for el in to_delete: + sel_vertices.pop(el) + + return (ring0, sel_vertices) + + +class Stepped: + def __init__(self, spike_base_width=0.5, base_height_inset=0.0, top_spike=0.2, + top_relative=False, top_extra_height=0, use_relative_offset=False, with_spike=False): + + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=True, use_relative_offset=False, + use_edge_rail=False, thickness=spike_base_width, depth=0, use_outset=True, + use_select_inset=False, use_individual=True, use_interpolate=True) + + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=True, use_relative_offset=use_relative_offset, + use_edge_rail=False, thickness=top_extra_height, depth=base_height_inset, + use_outset=True, use_select_inset=False, use_individual=True, use_interpolate=True) + + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=True, use_relative_offset=use_relative_offset, + use_edge_rail=False, thickness=spike_base_width, depth=0, use_outset=True, + use_select_inset=False, use_individual=True, use_interpolate=True) + + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=True, use_relative_offset=False, + use_edge_rail=False, thickness=0, depth=top_spike, use_outset=True, + use_select_inset=False, use_individual=True, use_interpolate=True) + if with_spike: + bpy.ops.mesh.merge(type='COLLAPSE') + + bpy.ops.object.mode_set(mode='OBJECT') + + +class Spiked: + def __init__(self, spike_base_width=0.5, base_height_inset=0.0, top_spike=0.2, top_relative=False): + + obj = bpy.context.active_object + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=True, use_relative_offset=False, + use_edge_rail=False, thickness=spike_base_width, depth=base_height_inset, + use_outset=True, use_select_inset=False, use_individual=True, use_interpolate=True) + + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=True, use_relative_offset=top_relative, + use_edge_rail=False, thickness=0, depth=top_spike, use_outset=True, + use_select_inset=False, use_individual=True, use_interpolate=True) + + bm = bmesh.from_edit_mesh(obj.data) + bpy.ops.mesh.merge(type='COLLAPSE') + bpy.ops.object.mode_set(mode='OBJECT') + + +class ClosedVertical: + def __init__(self, name="Plane", base_height=1, use_relative_base_height=False): + obj = bpy.data.objects[name] + + bm = bmesh.new() + bm.from_mesh(obj.data) + # PKHG>INFO deselect chosen faces + sel = [f for f in bm.faces if f.select] + for f in sel: + f.select = False + res = bmesh.ops.extrude_discrete_faces(bm, faces=sel) + # PKHG>INFO select extruded faces + for f in res['faces']: + f.select = True + + factor = base_height + for face in res['faces']: + if use_relative_base_height: + area = face.calc_area() + factor = area * base_height + else: + factor = base_height + for el in face.verts: + tmp = el.co + face.normal * factor + el.co = tmp + + me = bpy.data.meshes[name] + bm.to_mesh(me) + bm.free() + + +class OpenVertical: + def __init__(self, name="Plane", base_height=1, use_relative_base_height=False): + + obj = bpy.data.objects[name] + bm = bmesh.new() + bm.from_mesh(obj.data) + # PKHG>INFO deselect chosen faces + sel = [f for f in bm.faces if f.select] + for f in sel: + f.select = False + res = bmesh.ops.extrude_discrete_faces(bm, faces=sel) + # PKHG>INFO select extruded faces + for f in res['faces']: + f.select = True + + # PKHG>INFO adjust extrusion by a vector + factor = base_height + for face in res['faces']: + if use_relative_base_height: + area = face.calc_area() + factor = area * base_height + else: + factor = base_height + for el in face.verts: + tmp = el.co + face.normal * factor + el.co = tmp + + me = bpy.data.meshes[name] + bm.to_mesh(me) + bm.free() + + bpy.ops.object.editmode_toggle() + bpy.ops.mesh.delete(type='FACE') + bpy.ops.object.editmode_toggle() + + +class StripFaces: + def __init__(self, use_boundary=True, use_even_offset=True, use_relative_offset=False, + use_edge_rail=True, thickness=0.0, depth=0.0, use_outset=False, + use_select_inset=False, use_individual=True, use_interpolate=True): + + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.inset(use_boundary=use_boundary, use_even_offset=True, use_relative_offset=False, + use_edge_rail=True, thickness=thickness, depth=depth, use_outset=use_outset, + use_select_inset=use_select_inset, use_individual=use_individual, + use_interpolate=use_interpolate) + + bpy.ops.object.mode_set(mode='OBJECT') + + # PKHG>IMFO only 3 parameters inc execution context supported!! + if False: + bpy.ops.mesh.inset(use_boundary, use_even_offset, use_relative_offset, use_edge_rail, + thickness, depth, use_outset, use_select_inset, use_individual, use_interpolate) + elif type == 0: + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=True, use_relative_offset=False, + use_edge_rail=True, thickness=thickness, depth=depth, use_outset=False, + use_select_inset=False, use_individual=True, use_interpolate=True) + elif type == 1: + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=True, use_relative_offset=False, + use_edge_rail=True, thickness=thickness, depth=depth, use_outset=False, + use_select_inset=False, use_individual=True, use_interpolate=False) + + bpy.ops.mesh.delete(type='FACE') + + elif type == 2: + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=False, use_relative_offset=True, + use_edge_rail=True, thickness=thickness, depth=depth, use_outset=False, + use_select_inset=False, use_individual=True, use_interpolate=False) + + bpy.ops.mesh.delete(type='FACE') + + elif type == 3: + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=False, use_relative_offset=True, + use_edge_rail=True, thickness=depth, depth=thickness, use_outset=False, + use_select_inset=False, use_individual=True, use_interpolate=True) + + bpy.ops.mesh.delete(type='FACE') + elif type == 4: + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=False, use_relative_offset=True, + use_edge_rail=True, thickness=thickness, depth=depth, use_outset=True, + use_select_inset=False, use_individual=True, use_interpolate=True) + + bpy.ops.mesh.inset(use_boundary=True, use_even_offset=False, use_relative_offset=True, + use_edge_rail=True, thickness=thickness, depth=depth, use_outset=True, + use_select_inset=False, use_individual=True, use_interpolate=True) + + bpy.ops.mesh.delete(type='FACE') + + bpy.ops.object.mode_set(mode='OBJECT') + + +def check_is_selected(): + is_selected = False + for face in bpy.context.active_object.data.polygons: + if face.select: + is_selected = True + break + return is_selected + + +def prepare(self, context, remove_start_faces=True): + """ + Start for a face selected change of faces + select an object of type mesh, with activated several (all) faces + """ + obj = bpy.context.scene.objects.active + bpy.ops.object.mode_set(mode='OBJECT') + selectedpolygons = [el for el in obj.data.polygons if el.select] + + # PKHG>INFO copies of the vectors are needed, otherwise Blender crashes! + centers = [face.center for face in selectedpolygons] + centers_copy = [Vector((el[0], el[1], el[2])) for el in centers] + normals = [face.normal for face in selectedpolygons] + normals_copy = [Vector((el[0], el[1], el[2])) for el in normals] + vertindicesofpolgons = [[vert for vert in face.vertices] for face in selectedpolygons] + vertVectorsOfSelectedFaces = [[obj.data.vertices[ind].co for ind in vertIndiceofface] + for vertIndiceofface in vertindicesofpolgons] + vertVectorsOfSelectedFaces_copy = [[Vector((el[0], el[1], el[2])) for el in listofvecs] + for listofvecs in vertVectorsOfSelectedFaces] + + bpy.ops.object.mode_set(mode='EDIT') + bm = bmesh.from_edit_mesh(obj.data) + selected_bm_faces = [ele for ele in bm.faces if ele.select] + selected_edges_per_face_ind = [[ele.index for ele in face.edges] for face in selected_bm_faces] + indices = [el.index for el in selectedpolygons] + selected_faces_areas = [bm.faces[:][i] for i in indices] + tmp_area = [el.calc_area() for el in selected_faces_areas] + + # PKHG>INFO, selected faces are removed, only their edges are used! + if remove_start_faces: + bpy.ops.mesh.delete(type='ONLY_FACE') + bpy.ops.object.mode_set(mode='OBJECT') + obj.data.update() + bpy.ops.object.mode_set(mode='EDIT') + bm = bmesh.from_edit_mesh(obj.data) + bm.verts.ensure_lookup_table() + bm.faces.ensure_lookup_table() + + start_ring_raw = [[bm.verts[ind].index for ind in vertIndiceofface] + for vertIndiceofface in vertindicesofpolgons] + start_ring = [] + + for el in start_ring_raw: + start_ring.append(set(el)) + bm.edges.ensure_lookup_table() + + bm_selected_edges_l_l = [[bm.edges[i] for i in bm_ind_list] for bm_ind_list in selected_edges_per_face_ind] + + result = {'obj': obj, 'centers': centers_copy, 'normals': normals_copy, + 'rings': vertVectorsOfSelectedFaces_copy, 'bm': bm, + 'areas': tmp_area, 'startBMRingVerts': start_ring, + 'base_edges': bm_selected_edges_l_l} + return result + + +def make_one_inset(self, context, bm=None, ringvectors=None, center=None, + normal=None, t=None, base_height=0): + # a face will get 'inserted' faces to create (normaly) a hole if t is > 0 and < 1) + tmp = [] + + for el in ringvectors: + tmp.append((el * (1 - t) + center * t) + normal * base_height) + + tmp = [bm.verts.new(v) for v in tmp] # the new corner bmvectors + # PKHG>INFO so to say sentinells, to use ONE for ... + tmp.append(tmp[0]) + vectorsFace_i = [bm.verts.new(v) for v in ringvectors] + vectorsFace_i.append(vectorsFace_i[0]) + myres = [] + for ii in range(len(vectorsFace_i) - 1): + # PKHG>INFO next line: sequence is important! for added edge + bmvecs = [vectorsFace_i[ii], vectorsFace_i[ii + 1], tmp[ii + 1], tmp[ii]] + res = bm.faces.new(bmvecs) + myres.append(res.edges[2]) + myres[-1].select = True # PKHG>INFO to be used later selected! + return (myres) + + +def extrude_faces(self, context, bm=None, face_l=None): + # to make a ring extrusion + res = bmesh.ops.extrude_discrete_faces(bm, faces=face_l)['faces'] + + for face in res: + face.select = True + return res + + +def extrude_edges(self, context, bm=None, edge_l_l=None): + # to make a ring extrusion + all_results = [] + for edge_l in edge_l_l: + for edge in edge_l: + edge.select = False + res = bmesh.ops.extrude_edge_only(bm, edges=edge_l) + tmp = [ele for ele in res['geom'] if isinstance(ele, bmesh.types.BMEdge)] + for edge in tmp: + edge.select = True + all_results.append(tmp) + return all_results + + +def translate_ONE_ring(self, context, bm=None, object_matrix=None, ring_edges=None, + normal=(0, 0, 1), distance=0.5): + # translate a ring in given (normal?!) direction with given (global) amount + tmp = [] + for edge in ring_edges: + tmp.extend(edge.verts[:]) + # PKHG>INFO no double vertices allowed by bmesh! + tmp = set(tmp) + tmp = list(tmp) + bmesh.ops.translate(bm, vec=normal * distance, space=object_matrix, verts=tmp) + # PKHG>INFO relevant edges will stay selected + return ring_edges + + +def move_corner_vecs_outside(self, context, bm=None, edge_list=None, center=None, normal=None, + base_height_erlier=0.5, distance=0.5): + # move corners (outside meant mostly) dependent on the parameters + tmp = [] + for edge in edge_list: + tmp.extend([ele for ele in edge.verts if isinstance(ele, bmesh.types.BMVert)]) + # PKHG>INFO to remove vertices, they are all used twice in the ring! + tmp = set(tmp) + tmp = list(tmp) + + for i in range(len(tmp)): + vec = tmp[i].co + direction = vec + (vec - (normal * base_height_erlier + center)) * distance + tmp[i].co = direction + + +def register(): + bpy.utils.register_module(__name__) + + +def unregister(): + bpy.utils.unregister_module(__name__) + + +if __name__ == "__main__": + register() |