[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