From 9f7b301a9b0ac97de56854dec81d7be5f8900e12 Mon Sep 17 00:00:00 2001 From: Mikhail Rachinskiy Date: Wed, 18 Sep 2019 17:14:08 +0400 Subject: Print3D: PEP8 cleanup --- object_print3d_utils/__init__.py | 40 +++++------ object_print3d_utils/export.py | 69 +++++++++---------- object_print3d_utils/mesh_helpers.py | 58 ++++------------ object_print3d_utils/operators.py | 127 +++++++++++++++++------------------ object_print3d_utils/ui.py | 13 ++-- 5 files changed, 135 insertions(+), 172 deletions(-) (limited to 'object_print3d_utils') diff --git a/object_print3d_utils/__init__.py b/object_print3d_utils/__init__.py index 6bf2a8a7..b342bdfe 100644 --- a/object_print3d_utils/__init__.py +++ b/object_print3d_utils/__init__.py @@ -22,13 +22,13 @@ bl_info = { "name": "3D Print Toolbox", "author": "Campbell Barton", "blender": (2, 80, 0), - "location": "3D View > Toolbox", + "location": "3D View > Sidebar", "description": "Utilities for 3D printing", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" - "Scripts/Modeling/PrintToolbox", + # TODO + # "wiki_url": "", "support": 'OFFICIAL', "category": "Mesh", - } +} if "bpy" in locals(): @@ -40,22 +40,19 @@ else: import math import bpy + from bpy.types import PropertyGroup from bpy.props import ( - StringProperty, - BoolProperty, - FloatProperty, - EnumProperty, - PointerProperty, - ) - from bpy.types import ( - AddonPreferences, - PropertyGroup, - ) + StringProperty, + BoolProperty, + FloatProperty, + EnumProperty, + PointerProperty, + ) from . import ( - ui, - operators, - ) + ui, + operators, + ) class Print3D_Scene_Props(PropertyGroup): @@ -122,12 +119,13 @@ class Print3D_Scene_Props(PropertyGroup): classes = ( + Print3D_Scene_Props, + ui.VIEW3D_PT_Print3D_Object, ui.VIEW3D_PT_Print3D_Mesh, operators.MESH_OT_Print3D_Info_Volume, operators.MESH_OT_Print3D_Info_Area, - operators.MESH_OT_Print3D_Check_Degenerate, operators.MESH_OT_Print3D_Check_Distorted, operators.MESH_OT_Print3D_Check_Solid, @@ -136,20 +134,14 @@ classes = ( operators.MESH_OT_Print3D_Check_Sharp, operators.MESH_OT_Print3D_Check_Overhang, operators.MESH_OT_Print3D_Check_All, - operators.MESH_OT_Print3D_Clean_Isolated, operators.MESH_OT_Print3D_Clean_Distorted, # operators.MESH_OT_Print3D_Clean_Thin, operators.MESH_OT_Print3D_Clean_Non_Manifold, - operators.MESH_OT_Print3D_Select_Report, - operators.MESH_OT_Print3D_Scale_To_Volume, operators.MESH_OT_Print3D_Scale_To_Bounds, - operators.MESH_OT_Print3D_Export, - - Print3D_Scene_Props, ) diff --git a/object_print3d_utils/export.py b/object_print3d_utils/export.py index 9a9afb3a..5e9b71c0 100644 --- a/object_print3d_utils/export.py +++ b/object_print3d_utils/export.py @@ -65,7 +65,6 @@ def write_mesh(context, info, report_cb): path_mode = 'COPY' if print_3d.use_export_texture else 'AUTO' context_override = context.copy() - obj_tmp = None # PLY can only export single mesh objects! @@ -90,6 +89,7 @@ def write_mesh(context, info, report_cb): name = os.path.splitext(name)[0] else: name = "untitled" + # add object name name += "-%s" % bpy.path.clean_name(obj.name) @@ -118,55 +118,55 @@ def write_mesh(context, info, report_cb): addon_ensure("io_mesh_stl") filepath = bpy.path.ensure_ext(filepath, ".stl") ret = bpy.ops.export_mesh.stl( - context_override, - filepath=filepath, - ascii=False, - use_mesh_modifiers=True, - use_selection=True, - global_scale=global_scale, - ) + context_override, + filepath=filepath, + ascii=False, + use_mesh_modifiers=True, + use_selection=True, + global_scale=global_scale, + ) elif export_format == 'PLY': addon_ensure("io_mesh_ply") filepath = bpy.path.ensure_ext(filepath, ".ply") ret = bpy.ops.export_mesh.ply( - context_override, - filepath=filepath, - use_mesh_modifiers=True, - global_scale=global_scale, - ) + context_override, + filepath=filepath, + use_mesh_modifiers=True, + global_scale=global_scale, + ) elif export_format == 'X3D': addon_ensure("io_scene_x3d") filepath = bpy.path.ensure_ext(filepath, ".x3d") ret = bpy.ops.export_scene.x3d( - context_override, - filepath=filepath, - use_mesh_modifiers=True, - use_selection=True, - path_mode=path_mode, - global_scale=global_scale, - ) + context_override, + filepath=filepath, + use_mesh_modifiers=True, + use_selection=True, + path_mode=path_mode, + global_scale=global_scale, + ) elif export_format == 'WRL': addon_ensure("io_scene_vrml2") filepath = bpy.path.ensure_ext(filepath, ".wrl") ret = bpy.ops.export_scene.vrml2( - context_override, - filepath=filepath, - use_mesh_modifiers=True, - use_selection=True, - path_mode=path_mode, - global_scale=global_scale, - ) + context_override, + filepath=filepath, + use_mesh_modifiers=True, + use_selection=True, + path_mode=path_mode, + global_scale=global_scale, + ) elif export_format == 'OBJ': addon_ensure("io_scene_obj") filepath = bpy.path.ensure_ext(filepath, ".obj") ret = bpy.ops.export_scene.obj( - context_override, - filepath=filepath, - use_mesh_modifiers=True, - use_selection=True, - path_mode=path_mode, - global_scale=global_scale, - ) + context_override, + filepath=filepath, + use_mesh_modifiers=True, + use_selection=True, + path_mode=path_mode, + global_scale=global_scale, + ) else: assert 0 @@ -186,6 +186,7 @@ def write_mesh(context, info, report_cb): # restore context for ob in context_backup["selected_objects"]: ob.select_set(True) + layer.objects.active = context_backup["active_object"] if 'FINISHED' in ret: diff --git a/object_print3d_utils/mesh_helpers.py b/object_print3d_utils/mesh_helpers.py index cda8c005..d585d125 100644 --- a/object_print3d_utils/mesh_helpers.py +++ b/object_print3d_utils/mesh_helpers.py @@ -24,9 +24,7 @@ import bmesh def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifiers=False): - """ - Returns a transformed, triangulated copy of the mesh - """ + """Returns a transformed, triangulated copy of the mesh""" assert obj.type == 'MESH' @@ -61,47 +59,39 @@ def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifier def bmesh_from_object(obj): - """ - Object/Edit Mode get mesh, use bmesh_to_object() to write back. - """ + """Object/Edit Mode get mesh, use bmesh_to_object() to write back.""" me = obj.data - is_editmode = (obj.mode == 'EDIT') - if is_editmode: + + if obj.mode == 'EDIT': bm = bmesh.from_edit_mesh(me) else: bm = bmesh.new() bm.from_mesh(me) + return bm def bmesh_to_object(obj, bm): - """ - Object/Edit Mode update the object. - """ + """Object/Edit Mode update the object.""" me = obj.data - is_editmode = (obj.mode == 'EDIT') - if is_editmode: + + if obj.mode == 'EDIT': bmesh.update_edit_mesh(me, True) else: bm.to_mesh(me) + # grr... cause an update if me.vertices: me.vertices[0].co[0] = me.vertices[0].co[0] def bmesh_calc_area(bm): - """ - Calculate the surface area. - """ + """Calculate the surface area.""" return sum(f.calc_area() for f in bm.faces) def bmesh_check_self_intersect_object(obj): - """ - Check if any faces self intersect - - returns an array of edge index values. - """ + """Check if any faces self intersect returns an array of edge index values.""" import array import mathutils @@ -147,6 +137,7 @@ def bmesh_check_thick_object(obj, thickness): # Triangulate bm = bmesh_copy_from_object(obj, transform=True, triangulate=False) + # map original faces to their index. face_index_map_org = {f: i for i, f in enumerate(bm.faces)} ret = bmesh.ops.triangulate(bm, faces=bm.faces) @@ -166,27 +157,14 @@ def bmesh_check_thick_object(obj, thickness): bm.to_mesh(me_tmp) # bm.free() # delay free obj_tmp = bpy.data.objects.new(name=me_tmp.name, object_data=me_tmp) - # base = scene.objects.link(obj_tmp) scene_collection.objects.link(obj_tmp) - # Add new object to local view layer - # XXX28 - ''' - v3d = None - if context.space_data and context.space_data.type == 'VIEW_3D': - v3d = context.space_data - - if v3d and v3d.local_view: - base.layers_from_view(context.space_data) - ''' - layer.update() ray_cast = obj_tmp.ray_cast EPS_BIAS = 0.0001 faces_error = set() - bm_faces_new = bm.faces[:] for f in bm_faces_new: @@ -209,8 +187,7 @@ def bmesh_check_thick_object(obj, thickness): f_org_index = face_index_map_org[f_org] faces_error.add(f_org_index) - # finished with bm - bm.free() + bm.free() # finished with bm scene_collection.objects.unlink(obj_tmp) bpy.data.objects.remove(obj_tmp) @@ -222,9 +199,7 @@ def bmesh_check_thick_object(obj, thickness): def object_merge(context, objects): - """ - Caller must remove. - """ + """Caller must remove.""" import bpy @@ -279,10 +254,6 @@ def object_merge(context, objects): bpy.ops.object.join(fake_context) del base_new, obj_new - # remove object and its mesh, join does this - # scene_collection.objects.unlink(obj_new) - # bpy.data.objects.remove(obj_new) - obj_eval.to_mesh_clear() layer.update() @@ -291,7 +262,6 @@ def object_merge(context, objects): return obj_base - def face_is_distorted(ele, angle_distort): no = ele.normal angle_fn = no.angle diff --git a/object_print3d_utils/operators.py b/object_print3d_utils/operators.py index cfd2cec4..3934c9bd 100644 --- a/object_print3d_utils/operators.py +++ b/object_print3d_utils/operators.py @@ -213,12 +213,11 @@ class MESH_OT_Print3D_Check_Distorted(Operator): bm.normal_update() faces_distort = array.array( - 'i', - (i for i, ele in enumerate(bm.faces) if mesh_helpers.face_is_distorted(ele, angle_distort)) - ) + 'i', + (i for i, ele in enumerate(bm.faces) if mesh_helpers.face_is_distorted(ele, angle_distort)) + ) - info.append(("Non-Flat Faces: %d" % len(faces_distort), - (bmesh.types.BMFace, faces_distort))) + info.append(("Non-Flat Faces: %d" % len(faces_distort), (bmesh.types.BMFace, faces_distort))) bm.free() @@ -238,9 +237,7 @@ class MESH_OT_Print3D_Check_Thick(Operator): print_3d = scene.print_3d faces_error = mesh_helpers.bmesh_check_thick_object(obj, print_3d.thickness_min) - - info.append(("Thin Faces: %d" % len(faces_error), - (bmesh.types.BMFace, faces_error))) + info.append(("Thin Faces: %d" % len(faces_error), (bmesh.types.BMFace, faces_error))) def execute(self, context): return execute_check(self, context) @@ -260,11 +257,12 @@ class MESH_OT_Print3D_Check_Sharp(Operator): bm = mesh_helpers.bmesh_copy_from_object(obj, transform=True, triangulate=False) bm.normal_update() - edges_sharp = [ele.index for ele in bm.edges - if ele.is_manifold and ele.calc_face_angle_signed() > angle_sharp] + edges_sharp = [ + ele.index for ele in bm.edges + if ele.is_manifold and ele.calc_face_angle_signed() > angle_sharp + ] - info.append(("Sharp Edge: %d" % len(edges_sharp), - (bmesh.types.BMEdge, edges_sharp))) + info.append(("Sharp Edge: %d" % len(edges_sharp), (bmesh.types.BMEdge, edges_sharp))) bm.free() def execute(self, context): @@ -296,11 +294,12 @@ class MESH_OT_Print3D_Check_Overhang(Operator): z_down_angle = z_down.angle # 4.0 ignores zero area faces - faces_overhang = [ele.index for ele in bm.faces - if z_down_angle(ele.normal, 4.0) < angle_overhang] + faces_overhang = [ + ele.index for ele in bm.faces + if z_down_angle(ele.normal, 4.0) < angle_overhang + ] - info.append(("Overhang Face: %d" % len(faces_overhang), - (bmesh.types.BMFace, faces_overhang))) + info.append(("Overhang Face: %d" % len(faces_overhang), (bmesh.types.BMFace, faces_overhang))) bm.free() def execute(self, context): @@ -320,7 +319,7 @@ class MESH_OT_Print3D_Check_All(Operator): MESH_OT_Print3D_Check_Thick, MESH_OT_Print3D_Check_Sharp, MESH_OT_Print3D_Check_Overhang, - ) + ) def execute(self, context): obj = context.active_object @@ -368,8 +367,7 @@ class MESH_OT_Print3D_Clean_Isolated(Operator): for ele in elems_remove: remove(ele) change |= bool(elems_remove) - info.append(("Faces Removed: %d" % len(elems_remove), - None)) + info.append(("Faces Removed: %d" % len(elems_remove), None)) del elems_remove # --- edge elems_remove = [ele for ele in bm.edges if edge_is_isolated(ele)] @@ -377,8 +375,7 @@ class MESH_OT_Print3D_Clean_Isolated(Operator): for ele in elems_remove: remove(ele) change |= bool(elems_remove) - info.append(("Edge Removed: %d" % len(elems_remove), - None)) + info.append(("Edge Removed: %d" % len(elems_remove), None)) del elems_remove # --- vert elems_remove = [ele for ele in bm.verts if vert_is_isolated(ele)] @@ -386,8 +383,7 @@ class MESH_OT_Print3D_Clean_Isolated(Operator): for ele in elems_remove: remove(ele) change |= bool(elems_remove) - info.append(("Verts Removed: %d" % len(elems_remove), - None)) + info.append(("Verts Removed: %d" % len(elems_remove), None)) del elems_remove # --- @@ -463,12 +459,14 @@ class MESH_OT_Print3D_Clean_Non_Manifold(Operator): bpy.ops.object.mode_set(mode='OBJECT') self.report( - {'INFO'}, - "Modified Verts:%+d, Edges:%+d, Faces:%+d" % - (bm_key[0] - bm_key_orig[0], - bm_key[1] - bm_key_orig[1], - bm_key[2] - bm_key_orig[2], - )) + {'INFO'}, + "Modified Verts:%+d, Edges:%+d, Faces:%+d" % + ( + bm_key[0] - bm_key_orig[0], + bm_key[1] - bm_key_orig[1], + bm_key[2] - bm_key_orig[2], + ) + ) return {'FINISHED'} @@ -522,7 +520,6 @@ class MESH_OT_Print3D_Clean_Non_Manifold(Operator): while True: cls.fill_non_manifold(sides) - cls.delete_newly_generated_non_manifold_verts() bm_key = cls.elem_count(context) @@ -533,30 +530,26 @@ class MESH_OT_Print3D_Clean_Non_Manifold(Operator): @staticmethod def select_non_manifold_verts( - use_wire=False, - use_boundary=False, - use_multi_face=False, - use_non_contiguous=False, - use_verts=False, - ): + use_wire=False, + use_boundary=False, + use_multi_face=False, + use_non_contiguous=False, + use_verts=False + ): """select non-manifold vertices""" bpy.ops.mesh.select_non_manifold( - extend=False, - use_wire=use_wire, - use_boundary=use_boundary, - use_multi_face=use_multi_face, - use_non_contiguous=use_non_contiguous, - use_verts=use_verts, - ) + extend=False, + use_wire=use_wire, + use_boundary=use_boundary, + use_multi_face=use_multi_face, + use_non_contiguous=use_non_contiguous, + use_verts=use_verts, + ) @classmethod def count_non_manifold_verts(cls, context): """return a set of coordinates of non-manifold vertices""" - cls.select_non_manifold_verts( - use_wire=True, - use_boundary=True, - use_verts=True, - ) + cls.select_non_manifold_verts(use_wire=True, use_boundary=True, use_verts=True) bm = bmesh.from_edit_mesh(context.edit_object.data) return sum((1 for v in bm.verts if v.select)) @@ -606,13 +599,13 @@ class MESH_OT_Print3D_Select_Report(Operator): bmesh.types.BMVert: 'VERT', bmesh.types.BMEdge: 'EDGE', bmesh.types.BMFace: 'FACE', - } + } _type_to_attr = { bmesh.types.BMVert: "verts", bmesh.types.BMEdge: "edges", bmesh.types.BMFace: "faces", - } + } def execute(self, context): obj = context.edit_object @@ -689,8 +682,7 @@ class MESH_OT_Print3D_Scale_To_Volume(Operator): if context.mode == 'EDIT_MESH': volume = calc_volume(context.edit_object) else: - volume = sum(calc_volume(obj) for obj in context.selected_editable_objects - if obj.type == 'MESH') + volume = sum(calc_volume(obj) for obj in context.selected_editable_objects if obj.type == 'MESH') if volume == 0.0: self.report({'WARNING'}, "Object has zero volume") @@ -717,14 +709,17 @@ class MESH_OT_Print3D_Scale_To_Bounds(Operator): length: FloatProperty( name="Length Limit", unit='LENGTH', - min=0.0, max=100000.0, + min=0.0, + max=100000.0, ) def execute(self, context): scale = self.length / self.length_init - _scale(scale, - report=self.report, - report_suffix=", Clamping %s-Axis" % "XYZ"[self.axis_init]) + _scale( + scale, + report=self.report, + report_suffix=", Clamping %s-Axis" % "XYZ"[self.axis_init] + ) return {'FINISHED'} def invoke(self, context, event): @@ -734,13 +729,17 @@ class MESH_OT_Print3D_Scale_To_Bounds(Operator): return max(((max(v[i] for v in vecs) - min(v[i] for v in vecs)), i) for i in range(3)) if context.mode == 'EDIT_MESH': - length, axis = calc_length([Vector(v) @ obj.matrix_world - for obj in [context.edit_object] - for v in obj.bound_box]) + length, axis = calc_length( + [Vector(v) @ obj.matrix_world for obj in [context.edit_object] for v in obj.bound_box] + ) else: - length, axis = calc_length([Vector(v) @ obj.matrix_world - for obj in context.selected_editable_objects - if obj.type == 'MESH' for v in obj.bound_box]) + length, axis = calc_length( + [ + Vector(v) @ obj.matrix_world for obj in context.selected_editable_objects + if obj.type == 'MESH' + for v in obj.bound_box + ] + ) if length == 0.0: self.report({'WARNING'}, "Object has zero bounds") @@ -770,5 +769,5 @@ class MESH_OT_Print3D_Export(Operator): if ret: return {'FINISHED'} - else: - return {'CANCELLED'} + + return {'CANCELLED'} diff --git a/object_print3d_utils/ui.py b/object_print3d_utils/ui.py index 9f950c09..afb8a58c 100644 --- a/object_print3d_utils/ui.py +++ b/object_print3d_utils/ui.py @@ -35,7 +35,7 @@ class Print3D_ToolBar: bmesh.types.BMVert: 'VERTEXSEL', bmesh.types.BMEdge: 'EDGESEL', bmesh.types.BMFace: 'FACESEL', - } + } @classmethod def poll(cls, context): @@ -52,18 +52,19 @@ class Print3D_ToolBar: layout.label(text="Output:") box = layout.box() col = box.column(align=False) - # box.alert = True + for i, (text, data) in enumerate(info): if obj and data and data[1]: bm_type, bm_array = data - col.operator("mesh.print3d_select_report", - text=text, - icon=Print3D_ToolBar._type_to_icon[bm_type]).index = i + col.operator( + "mesh.print3d_select_report", + text=text, + icon=Print3D_ToolBar._type_to_icon[bm_type], + ).index = i layout.operator("mesh.select_non_manifold", text='Non Manifold Extended') else: col.label(text=text) - def draw(self, context): layout = self.layout -- cgit v1.2.3