[Bf-extensions-cvs] [936e30e8] master: archipack: stability improvements

Stephen Leger noreply at git.blender.org
Fri Jun 30 17:48:16 CEST 2017


Commit: 936e30e841089750fdc22e107acb37234d2bcab4
Author: Stephen Leger
Date:   Fri Jun 30 17:47:48 2017 +0200
Branches: master
https://developer.blender.org/rBAC936e30e841089750fdc22e107acb37234d2bcab4

archipack: stability improvements

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

M	archipack/__init__.py
M	archipack/archipack_door.py
M	archipack/archipack_fence.py
M	archipack/archipack_manipulator.py
M	archipack/archipack_object.py
M	archipack/archipack_preset.py
M	archipack/archipack_reference_point.py
M	archipack/archipack_slab.py
M	archipack/archipack_snap.py
M	archipack/archipack_stair.py
M	archipack/archipack_wall2.py
M	archipack/archipack_window.py

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

diff --git a/archipack/__init__.py b/archipack/__init__.py
index c5706762..433c6b0d 100644
--- a/archipack/__init__.py
+++ b/archipack/__init__.py
@@ -713,3 +713,4 @@ def unregister():
 
 if __name__ == "__main__":
     register()
+
diff --git a/archipack/archipack_door.py b/archipack/archipack_door.py
index 7c8c8753..f29c44d1 100644
--- a/archipack/archipack_door.py
+++ b/archipack/archipack_door.py
@@ -33,7 +33,7 @@ from bpy.props import (
     FloatProperty, IntProperty, CollectionProperty,
     EnumProperty, BoolProperty, StringProperty
     )
-from mathutils import Vector, Matrix
+from mathutils import Vector
 # door component objects (panels, handles ..)
 from .bmesh_utils import BmeshEdit as bmed
 from .panel import Panel as DoorPanel
@@ -41,10 +41,10 @@ from .materialutils import MaterialUtils
 from .archipack_handle import create_handle, door_handle_horizontal_01
 from .archipack_manipulator import Manipulable
 from .archipack_preset import ArchipackPreset, PresetMenuOperator
-from .archipack_object import ArchipackCreateTool, ArchipackObject
+from .archipack_object import ArchipackObject, ArchipackCreateTool, ArchpackDrawTool
 from .archipack_gl import FeedbackPanel
 from .archipack_keymaps import Keymaps
-from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_origin_3d
+
 
 SPACING = 0.005
 BATTUE = 0.01
@@ -1615,7 +1615,7 @@ class ARCHIPACK_OT_door(ArchipackCreateTool, Operator):
             return {'CANCELLED'}
 
 
-class ARCHIPACK_OT_door_draw(Operator):
+class ARCHIPACK_OT_door_draw(ArchpackDrawTool, Operator):
     bl_idname = "archipack.door_draw"
     bl_label = "Draw Doors"
     bl_description = "Draw Doors over walls"
@@ -1626,32 +1626,6 @@ class ARCHIPACK_OT_door_draw(Operator):
     feedback = None
     stack = []
 
-    def mouse_to_matrix(self, context, event):
-        """
-            convert mouse pos to 3d point over plane defined by origin and normal
-        """
-        region = context.region
-        rv3d = context.region_data
-        co2d = (event.mouse_region_x, event.mouse_region_y)
-        view_vector_mouse = region_2d_to_vector_3d(region, rv3d, co2d)
-        ray_origin_mouse = region_2d_to_origin_3d(region, rv3d, co2d)
-        res, pt, y, i, o, tM = context.scene.ray_cast(
-            ray_origin_mouse,
-            view_vector_mouse)
-        if res and 'archipack_wall2' in o.data:
-            z = Vector((0, 0, 1))
-            d = o.data.archipack_wall2[0]
-            y = -y
-            pt += (0.5 * d.width) * y.normalized()
-            x = y.cross(z)
-            return True, Matrix([
-            [x.x, y.x, z.x, pt.x],
-            [x.y, y.y, z.y, pt.y],
-            [x.z, y.z, z.z, o.matrix_world.translation.z],
-            [0, 0, 0, 1]
-            ]), o
-        return False, Matrix(), None
-
     @classmethod
     def poll(cls, context):
         return True
@@ -1710,7 +1684,7 @@ class ARCHIPACK_OT_door_draw(Operator):
             o.hide = True
             hole.hide = True
 
-        res, tM, wall = self.mouse_to_matrix(context, event)
+        res, tM, wall, y = self.mouse_hover_wall(context, event)
 
         if hole is not None:
             o.hide = False
diff --git a/archipack/archipack_fence.py b/archipack/archipack_fence.py
index 5da5aee1..961b516e 100644
--- a/archipack/archipack_fence.py
+++ b/archipack/archipack_fence.py
@@ -509,7 +509,7 @@ class FenceGenerator():
         f = self.segs[0]
 
         # first step
-        if extend != 0:
+        if extend != 0 and f.p_line.length != 0:
             t = -extend / self.segs[0].p_line.length
             n = f.p_line.sized_normal(t, 1)
             # n.p = f.lerp(x_offset)
@@ -521,6 +521,8 @@ class FenceGenerator():
         sections.append((n, f.dz / f.p_line.length, f.z0))
 
         for s, f in enumerate(self.segs):
+            if f.p_line.length == 0:
+                continue
             if type(f).__name__ == 'CurvedFence':
                 n_s = int(max(1, abs(f.da) * 30 / pi - 1))
                 for i in range(1, n_s + 1):
@@ -533,7 +535,7 @@ class FenceGenerator():
                 # n.p = f.lerp(x_offset)
                 sections.append((n, f.dz / f.p_line.length, f.z0 + f.dz))
 
-        if extend != 0:
+        if extend != 0 and f.p_line.length != 0:
             t = 1 + extend / self.segs[-1].p_line.length
             n = f.p_line.sized_normal(t, 1)
             # n.p = f.lerp(x_offset)
@@ -1273,7 +1275,7 @@ class archipack_fence(ArchipackObject, Manipulable, PropertyGroup):
                 pts.append(pts[0])
             else:
                 pts.append(wM * points[-1].co)
-
+        auto_update = self.auto_update
         self.auto_update = False
 
         self.n_parts = len(pts) - 1
@@ -1295,7 +1297,7 @@ class archipack_fence(ArchipackObject, Manipulable, PropertyGroup):
             a0 += da
             p0 = p1
 
-        self.auto_update = True
+        self.auto_update = auto_update
 
         o.matrix_world = tM * Matrix([
             [1, 0, 0, pt.x],
@@ -1423,22 +1425,19 @@ class archipack_fence(ArchipackObject, Manipulable, PropertyGroup):
 
     def manipulable_setup(self, context):
         """
-            TODO: Implement the setup part as per parent object basis
-
-            self.manipulable_disable(context)
-            o = context.active_object
-            for m in self.manipulators:
-                self.manip_stack.append(m.setup(context, o, self))
-
+            NOTE:
+            this one assume context.active_object is the instance this
+            data belongs to, failing to do so will result in wrong
+            manipulators set on active object
         """
         self.manipulable_disable(context)
+
         o = context.active_object
-        d = self
 
         self.setup_manipulators()
 
-        for i, part in enumerate(d.parts):
-            if i >= d.n_parts:
+        for i, part in enumerate(self.parts):
+            if i >= self.n_parts:
                 break
 
             if i > 0:
diff --git a/archipack/archipack_manipulator.py b/archipack/archipack_manipulator.py
index 73439ed2..c3e0fc24 100644
--- a/archipack/archipack_manipulator.py
+++ b/archipack/archipack_manipulator.py
@@ -42,6 +42,39 @@ from .archipack_gl import (
 )
 
 
+# NOTE:
+# Snap aware manipulators use a dirty hack :
+# draw() as a callback to update values in realtime
+# as transform.translate in use to allow snap
+# does catch all events.
+# This however has a wanted side effect:
+# the manipulator take precedence over allready running
+# ones, and prevent select mode to start.
+#
+# TODO:
+# Other manipulators should use same technique to take
+# precedence over allready running ones when active
+#
+# NOTE:
+# Select mode does suffer from this stack effect:
+# the last running wins. The point is left mouse select mode
+# requiring left drag to be RUNNING_MODAL to prevent real
+# objects select and move during manipulators selection.
+#
+# TODO:
+# First run a separate modal dedicated to select mode.
+# Selecting in whole manips stack when required
+# (manips[key].manipulable.manip_stack)
+# Must investigate for a way to handle unselect after drag done.
+
+"""
+    @TODO:
+    Last modal running wins.
+    Manipulateurs without snap and thus not running own modal,
+    may loose events events caught by select mode of last
+    manipulable enabled
+"""
+
 # Arrow sizes (world units)
 arrow_size = 0.05
 # Handle area size (pixels)
@@ -60,6 +93,9 @@ manips = {}
 class ArchipackActiveManip:
     """
         Store manipulated object
+        - object_name: manipulated object name
+        - stack: array of Manipulators instances
+        - manipulable: Manipulable instance
     """
     def __init__(self, object_name):
         self.object_name = object_name
@@ -70,13 +106,23 @@ class ArchipackActiveManip:
 
     @property
     def dirty(self):
+        """
+            Check for manipulable validity
+            to disable modal when required
+        """
         return (
             self.manipulable is None or
-            len(self.stack) < 1 or
             bpy.data.objects.find(self.object_name) < 0
             )
 
     def exit(self):
+        """
+            Exit manipulation mode
+            - exit from all running manipulators
+            - empty manipulators stack
+            - set manipulable.manipulate_mode to False
+            - remove reference to manipulable
+        """
         for m in self.stack:
             if m is not None:
                 m.exit()
@@ -88,6 +134,9 @@ class ArchipackActiveManip:
 
 
 def remove_manipulable(key):
+    """
+        disable and remove a manipulable from stack
+    """
     global manips
     # print("remove_manipulable key:%s" % (key))
     if key in manips.keys():
@@ -116,6 +165,10 @@ def check_stack(key):
 
 def empty_stack():
     # print("empty_stack()")
+    """
+        kill every manipulators in stack
+        and cleanup stack
+    """
     global manips
     for key in manips.keys():
         manips[key].exit()
@@ -123,6 +176,12 @@ def empty_stack():
 
 
 def add_manipulable(key, manipulable):
+    """
+        add a ArchipackActiveManip into the stack
+        if not allready present
+        setup reference to manipulable
+        return manipulators stack
+    """
     global manips
     if key not in manips.keys():
         # print("add_manipulable() key:%s not found create new" % (key))
@@ -965,7 +1024,7 @@ class SizeManipulator(Manipulator):
 
     def mouse_move(self, context, event):
         self.mouse_position(event)
-        if self.handle_right.active:
+        if self.active:
             self.update(context, event)
             return True
         else:
@@ -1474,7 +1533,8 @@ class AngleManipulator(Manipulator):
 
     def mouse_move(self, context, event):
         self.mouse_position(event)
-        if self.handle_right.active:
+        if self.active:
+            # print("AngleManipulator.mouse_move")
             self.update(context, event)
             return True
         else:
@@ -1993,6 +2053,15 @@ class ARCHIPACK_OT_manipulate(Operator):
     def poll(self, context):
         return context.active_object is not None
 
+    def exit_selectmode(self, context, key):
+        """
+            Hide

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list