[Bf-extensions-cvs] [febdff33] master: export paper model: fix bugs in UI and export (upstream edc29e0)

Adam Dominec noreply at git.blender.org
Tue Nov 12 15:16:08 CET 2019


Commit: febdff331afd47d5c4c6d2ab3c64f3ea1610ad71
Author: Adam Dominec
Date:   Tue Nov 12 13:22:07 2019 +0100
Branches: master
https://developer.blender.org/rBAfebdff331afd47d5c4c6d2ab3c64f3ea1610ad71

export paper model: fix bugs in UI and export (upstream edc29e0)

* Fix `Mesh.copy_freestyle_marks` to properly read from Mesh modified in Edit Mode;
* Add UI panels to 3D View, in own category;
* Report an error if exporting object with negative scale;
* tidy up `Mesh.check_correct`.

Reviewed By: dfelinto

Differential Revision: https://developer.blender.org/D6232

===================================================================

M	io_export_paper_model.py

===================================================================

diff --git a/io_export_paper_model.py b/io_export_paper_model.py
index 4edbea42..fab7db14 100644
--- a/io_export_paper_model.py
+++ b/io_export_paper_model.py
@@ -184,7 +184,6 @@ class Unfolder:
         self.do_create_uvmap = False
         bm = bmesh.from_edit_mesh(ob.data)
         self.mesh = Mesh(bm, ob.matrix_world)
-        self.mesh.copy_freestyle_marks(ob.data)
         self.mesh.check_correct()
     
     def __del__(self):
@@ -302,13 +301,18 @@ class Mesh:
             edge.choose_main_faces()
             if edge.main_faces:
                 edge.calculate_angle()
+        self.copy_freestyle_marks()
     
     def delete_uvmap(self):
         self.data.loops.layers.uv.remove(self.looptex) if self.looptex else None
     
-    def copy_freestyle_marks(self, mesh):
+    def copy_freestyle_marks(self):
+        # NOTE: this is a workaround for NotImplementedError on bmesh.edges.layers.freestyle
+        mesh = bpy.data.meshes.new("unfolder_temp")
+        self.data.to_mesh(mesh)
         for bmedge, edge in self.edges.items():
             edge.freestyle = mesh.edges[bmedge.index].use_freestyle_mark
+        bpy.data.meshes.remove(mesh)
     
     def mark_cuts(self):
         for bmedge, edge in self.edges.items():
@@ -318,21 +322,23 @@ class Mesh:
     def check_correct(self, epsilon=1e-6):
         """Check for invalid geometry"""
         def is_twisted(face):
-            if len(face.verts) > 3:
-                center = sum((vertex.co for vertex in face.verts), M.Vector((0, 0, 0))) / len(face.verts)
-                plane_d = center.dot(face.normal)
-                diameter = max((center - vertex.co).length for vertex in face.verts)
-                for vertex in face.verts:
-                    # check coplanarity
-                    if abs(vertex.co.dot(face.normal) - plane_d) > diameter * 0.01:
-                        return True
-            return False
+            if len(face.verts) <= 3:
+                return False
+            center = face.calc_center_median()
+            plane_d = center.dot(face.normal)
+            diameter = max((center - vertex.co).length for vertex in face.verts)
+            threshold = 0.01 * diameter
+            return any(abs(v.co.dot(face.normal) - plane_d) > threshold for v in face.verts)
         
         null_edges = {e for e in self.edges.keys() if e.calc_length() < epsilon and e.link_faces}
         null_faces = {f for f in self.data.faces if f.calc_area() < epsilon}
         twisted_faces = {f for f in self.data.faces if is_twisted(f)}
-        if not (null_edges or null_faces or twisted_faces):
-            return
+        inverted_scale = self.matrix.determinant() <= 0
+        if not (null_edges or null_faces or twisted_faces or inverted_scale):
+            return True
+        if inverted_scale:
+            raise UnfoldError("The object is flipped inside-out.\n"
+            "You can use Object -> Apply -> Scale to fix it. Export failed.")
         disease = [("Remove Doubles", null_edges or null_faces), ("Triangulate", twisted_faces)]
         cure = " and ".join(s for s, k in disease if k)
         raise UnfoldError(
@@ -1041,7 +1047,7 @@ def join(uvedge_a, uvedge_b, size_limit=None, epsilon=1e-6):
         uvedge.vb = phantoms[uvedge.vb]
         uvedge.update()
     if is_merged_mine:
-        for uvedge in island_a.edges:
+        for uvedge in island_a.edges.values():
             uvedge.va = phantoms.get(uvedge.va, uvedge.va)
             uvedge.vb = phantoms.get(uvedge.vb, uvedge.vb)
     island_a.edges.update(island_b.edges)
@@ -2027,7 +2033,7 @@ class ExportPaperModel(bpy.types.Operator):
         ])
     scale: bpy.props.FloatProperty(
         name="Scale", description="Divisor of all dimensions when exporting",
-        default=1, soft_min=1.0, soft_max=10000.0, step=100, subtype='UNSIGNED', precision=1)
+        default=1, soft_min=1.0, soft_max=100.0, subtype='FACTOR', precision=1)
     do_create_uvmap: bpy.props.BoolProperty(
         name="Create UVMap", description="Create a new UV Map showing the islands and page layout",
         default=False, options={'SKIP_SAVE'})
@@ -2109,8 +2115,7 @@ class ExportPaperModel(bpy.types.Operator):
         row.operator("export_mesh.paper_model_preset_add", text="", icon='ADD')
         row.operator("export_mesh.paper_model_preset_add", text="", icon='REMOVE').remove_active = True
 
-        # a little hack: this prints out something like "Scale: 1: 72"
-        layout.prop(self.properties, "scale", text="Scale: 1")
+        layout.prop(self.properties, "scale", text="Scale: 1/")
         scale_ratio = self.get_scale_ratio(context.scene)
         if scale_ratio > 1:
             layout.label(
@@ -2293,10 +2298,10 @@ class AddPresetPaperModel(bl_operators.presets.AddPresetBase, bpy.types.Operator
 
 
 class VIEW3D_PT_paper_model_tools(bpy.types.Panel):
-    bl_label = "Tools"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_category = "Paper Model"
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'UI'
+    bl_category = 'Paper'
+    bl_label = "Unfold"
 
     def draw(self, context):
         layout = self.layout
@@ -2304,11 +2309,7 @@ class VIEW3D_PT_paper_model_tools(bpy.types.Panel):
         obj = context.active_object
         mesh = obj.data if obj and obj.type == 'MESH' else None
 
-        layout.operator("export_mesh.paper_model")
-
-        col = layout.column(align=True)
-        col.label(text="Customization:")
-        col.operator("mesh.unfold")
+        layout.operator("mesh.unfold")
 
         if context.mode == 'EDIT_MESH':
             row = layout.row(align=True)
@@ -2317,8 +2318,22 @@ class VIEW3D_PT_paper_model_tools(bpy.types.Panel):
         else:
             layout.operator("mesh.clear_all_seams")
 
+
+class VIEW3D_PT_paper_model_settings(bpy.types.Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'UI'
+    bl_category = 'Paper'
+    bl_label = "Export"
+
+    def draw(self, context):
+        layout = self.layout
+        sce = context.scene
+        obj = context.active_object
+        mesh = obj.data if obj and obj.type == 'MESH' else None
+
+        layout.operator("export_mesh.paper_model")
         props = sce.paper_model
-        layout.prop(props, "scale", text="Model Scale: 1")
+        layout.prop(props, "scale", text="Model Scale:  1/")
 
         layout.prop(props, "limit_by_page")
         col = layout.column()
@@ -2447,7 +2462,7 @@ class PaperModelSettings(bpy.types.PropertyGroup):
         default=0.29, soft_min=0.148, soft_max=1.189, subtype="UNSIGNED", unit="LENGTH")
     scale: bpy.props.FloatProperty(
         name="Scale", description="Divisor of all dimensions when exporting",
-        default=1, soft_min=1.0, soft_max=10000.0, step=100, subtype='UNSIGNED', precision=1)
+        default=1, soft_min=1.0, soft_max=100.0, subtype='FACTOR', precision=1)
 
 
 module_classes = (
@@ -2461,7 +2476,8 @@ module_classes = (
     PaperModelSettings,
     VIEW3D_MT_paper_model_presets,
     DATA_PT_paper_model_islands,
-    #VIEW3D_PT_paper_model_tools,
+    VIEW3D_PT_paper_model_tools,
+    VIEW3D_PT_paper_model_settings,
 )



More information about the Bf-extensions-cvs mailing list