Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Leger <stephen@3dservices.ch>2018-11-16 17:31:26 +0300
committerStephen Leger <stephen@3dservices.ch>2018-11-16 17:34:51 +0300
commitbfbbd112c170d96e86838208b8781fd46df52514 (patch)
tree9fda29f608a32f8ac5a88e5873730bf6422dd280 /archipack/archipack_manipulator.py
parent64198b8817042962dcdedc71bb81ee9492b19a4d (diff)
archipack 2.8 compatibility (step1)
Diffstat (limited to 'archipack/archipack_manipulator.py')
-rw-r--r--archipack/archipack_manipulator.py345
1 files changed, 149 insertions, 196 deletions
diff --git a/archipack/archipack_manipulator.py b/archipack/archipack_manipulator.py
index 5ed7312b..06efefff 100644
--- a/archipack/archipack_manipulator.py
+++ b/archipack/archipack_manipulator.py
@@ -30,7 +30,13 @@ from mathutils import Vector, Matrix
from mathutils.geometry import intersect_line_plane, intersect_point_line, intersect_line_sphere
from bpy_extras import view3d_utils
from bpy.types import PropertyGroup, Operator
-from bpy.props import FloatVectorProperty, StringProperty, CollectionProperty, BoolProperty
+from bpy.props import (
+ FloatVectorProperty,
+ StringProperty,
+ CollectionProperty,
+ BoolProperty
+)
+
from bpy.app.handlers import persistent
from .archipack_snap import snap_point
from .archipack_keymaps import Keymaps
@@ -67,14 +73,16 @@ from .archipack_gl import (
# (manips[key].manipulable.manip_stack)
# Must investigate for a way to handle unselect after drag done.
+
+import logging
+logger = logging.getLogger("archipack")
+
+
"""
- @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
+ Change object location when moving 1 point
+ When False, change data.origin instead
"""
-
+USE_MOVE_OBJECT = True
# Arrow sizes (world units)
arrow_size = 0.05
# Handle area size (pixels)
@@ -469,7 +477,7 @@ class Manipulator():
view_vector_mouse = view3d_utils.region_2d_to_vector_3d(region, rv3d, self.mouse_pos)
ray_origin_mouse = view3d_utils.region_2d_to_origin_3d(region, rv3d, self.mouse_pos)
pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
- self.origin, rM * self.manipulator.normal, False)
+ self.origin, rM @ self.manipulator.normal, False)
# fix issue with parallel plane
if pt is None:
pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
@@ -495,18 +503,19 @@ class Manipulator():
"""
try:
if self.get_value(data, attr, index) != value:
+ o = self.o
# switch context so unselected object may be manipulable too
- old = context.active_object
- state = self.o.select
- self.o.select = True
- context.scene.objects.active = self.o
+ old = context.object
+ state = o.select_get()
+ o.select_set(state=True)
+ context.view_layer.objects.active = o
if index > -1:
getattr(data, attr)[index] = value
else:
setattr(data, attr, value)
- self.o.select = state
- old.select = True
- context.scene.objects.active = old
+ o.select_set(state=state)
+ old.select_set(state=True)
+ context.view_layer.objects.active = old
except:
pass
@@ -516,11 +525,7 @@ class Manipulator():
tM Matrix source
vec Vector translation
"""
- return tM * Matrix([
- [1, 0, 0, vec.x],
- [0, 1, 0, vec.y],
- [0, 0, 1, vec.z],
- [0, 0, 0, 1]])
+ return tM @ Matrix.Translation(vec)
def _move(self, o, axis, value):
if axis == 'x':
@@ -538,15 +543,15 @@ class Manipulator():
"""
old = context.active_object
bpy.ops.object.select_all(action='DESELECT')
- self.o.select = True
- context.scene.objects.active = self.o
+ self.o.select_set(state=True)
+ context.view_layer.objects.active = self.o
bpy.ops.object.select_linked(type='OBDATA')
for o in context.selected_objects:
if o != self.o:
self._move(o, axis, value)
bpy.ops.object.select_all(action='DESELECT')
- old.select = True
- context.scene.objects.active = old
+ old.select_set(state=True)
+ context.view_layer.objects.active = old
def move(self, context, axis, value):
"""
@@ -555,68 +560,6 @@ class Manipulator():
self._move(self.o, axis, value)
-# OUT OF ORDER
-class SnapPointManipulator(Manipulator):
- """
- np_station based snap manipulator
- dosent update anything by itself.
- NOTE : currently out of order
- and disabled in __init__
- """
- def __init__(self, context, o, datablock, manipulator, handle_size, snap_callback=None):
-
- raise NotImplementedError
-
- self.handle = SquareHandle(handle_size, 1.2 * arrow_size, draggable=True)
- Manipulator.__init__(self, context, o, datablock, manipulator, snap_callback)
-
- def check_hover(self):
- self.handle.check_hover(self.mouse_pos)
-
- def mouse_press(self, context, event):
- if self.handle.hover:
- self.handle.hover = False
- self.handle.active = True
- self.o.select = True
- # takeloc = self.o.matrix_world * self.manipulator.p0
- # print("Invoke sp_point_move %s" % (takeloc))
- # @TODO:
- # implement and add draw and callbacks
- # snap_point(takeloc, draw, callback)
- return True
- return False
-
- def mouse_release(self, context, event):
- self.check_hover()
- self.handle.active = False
- # False to callback manipulable_release
- return False
-
- def update(self, context, event):
- # NOTE:
- # dosent set anything internally
- return
-
- def mouse_move(self, context, event):
- """
-
- """
- self.mouse_position(event)
- if self.handle.active:
- # self.handle.active = np_snap.is_running
- # self.update(context)
- # True here to callback manipulable_manipulate
- return True
- else:
- self.check_hover()
- return False
-
- def draw_callback(self, _self, context, render=False):
- left, right, side, normal = self.manipulator.get_pts(self.o.matrix_world)
- self.handle.set_pos(context, left, Vector((1, 0, 0)), normal=normal)
- self.handle.draw(context, render)
-
-
# Generic snap tool for line based archipack objects (fence, wall, maybe stair too)
gl_pts3d = []
@@ -682,7 +625,7 @@ class WallSnapManipulator(Manipulator):
])
self.feedback.enable()
self.handle.hover = False
- self.o.select = True
+ self.o.select_set(state=True)
takeloc, right, side, dz = self.manipulator.get_pts(self.o.matrix_world)
dx = (right - takeloc).normalized()
dy = dz.cross(dx)
@@ -712,20 +655,20 @@ class WallSnapManipulator(Manipulator):
np station callback on moving, place, or cancel
"""
global gl_pts3d
+ logger.debug("WallSnapManipulator.sp_callback")
if state == 'SUCCESS':
-
- self.o.select = True
+ o = self.o
+ o.select_set(state=True)
+ context.view_layer.objects.active = o
# apply changes to wall
d = self.datablock
- d.auto_update = False
-
g = d.get_generator()
# rotation relative to object
- rM = self.o.matrix_world.inverted().to_3x3()
- delta = (rM * sp.delta).to_2d()
- # x_axis = (rM * Vector((1, 0, 0))).to_2d()
+ rM = o.matrix_world.inverted().to_3x3()
+ delta =rM @ sp.delta
+ # x_axis = (rM @ Vector((1, 0, 0))).to_2d()
# update generator
idx = 0
@@ -734,7 +677,7 @@ class WallSnapManipulator(Manipulator):
if selected:
# new location in object space
- pt = g.segs[idx].lerp(0) + delta
+ pt = g.segs[idx].lerp(0) + delta.to_2d()
# move last point of segment before current
if idx > 0:
@@ -747,6 +690,7 @@ class WallSnapManipulator(Manipulator):
# update properties from generator
idx = 0
+
for p0, p1, selected in gl_pts3d:
if selected:
@@ -759,7 +703,7 @@ class WallSnapManipulator(Manipulator):
if idx > 1:
part.a0 = w.delta_angle(g.segs[idx - 2])
else:
- part.a0 = w.straight(1, 0).angle
+ part.a0 = w.a0
if "C_" in part.type:
part.radius = w.r
@@ -773,10 +717,14 @@ class WallSnapManipulator(Manipulator):
if idx > 0:
part.a0 = w.delta_angle(g.segs[idx - 1])
else:
- part.a0 = w.straight(1, 0).angle
+ part.a0 = w.a0
# move object when point 0
- self.o.location += sp.delta
- self.o.matrix_world.translation += sp.delta
+ if USE_MOVE_OBJECT:
+ d.move_object(o, o.matrix_world.translation + sp.delta)
+ # self.o.location += sp.delta
+ # self.o.matrix_world.translation += sp.delta
+ else:
+ d.origin += sp.delta
if "C_" in part.type:
part.radius = w.r
@@ -790,15 +738,18 @@ class WallSnapManipulator(Manipulator):
idx += 1
self.mouse_release(context, event)
- d.auto_update = True
+ d.relocate_childs(context, o, g)
+ d.update(context)
if state == 'CANCEL':
self.mouse_release(context, event)
+ logger.debug("WallSnapManipulator.sp_callback done")
return
def sp_draw(self, sp, context):
# draw wall placeholders
+ logger.debug("WallSnapManipulator.sp_draw")
global gl_pts3d
@@ -842,6 +793,7 @@ class WallSnapManipulator(Manipulator):
self.label.set_pos(context, self.line.length, self.line.lerp(0.5), self.line.v, normal=Vector((0, 0, 1)))
self.line.draw(context, render=False)
self.label.draw(context, render=False)
+ logger.debug("WallSnapManipulator.sp_draw done")
def mouse_move(self, context, event):
self.mouse_position(event)
@@ -1002,7 +954,6 @@ class SizeManipulator(Manipulator):
])
gl_pts3d = [left, right]
snap_point(takemat=takemat,
- draw=self.sp_draw,
callback=self.sp_callback,
constraint_axis=(True, False, False))
self.handle_right.active = True
@@ -1085,32 +1036,31 @@ class SizeManipulator(Manipulator):
self.label.draw(context, render)
self.feedback.draw(context, render)
- def sp_draw(self, sp, context):
+ def sp_callback(self, context, event, state, sp):
+ logger.debug("SizeManipulator.sp_callback")
global gl_pts3d
- if self.o is None:
- return
+
p0 = gl_pts3d[0].copy()
p1 = gl_pts3d[1].copy()
- p1 += sp.delta
- self.sp_update(context, p0, p1)
- return
- def sp_callback(self, context, event, state, sp):
+ if state != 'CANCEL':
+ p1 += sp.delta
- if state == 'SUCCESS':
- self.sp_draw(sp, context)
- self.mouse_release(context, event)
+ length = (p0 - p1).length
- if state == 'CANCEL':
- p0 = gl_pts3d[0].copy()
- p1 = gl_pts3d[1].copy()
- self.sp_update(context, p0, p1)
- self.mouse_release(context, event)
+ if state != 'CANCEL' and event.alt:
+ if event.shift:
+ length = round(length, 2)
+ else:
+ length = round(length, 1)
- def sp_update(self, context, p0, p1):
- length = (p0 - p1).length
self.set_value(context, self.datablock, self.manipulator.prop1_name, length)
+ if state != 'RUNNING':
+ self.mouse_release(context, event)
+
+ logger.debug("SizeManipulator.sp_callback done")
+
class SizeLocationManipulator(SizeManipulator):
"""
@@ -1190,7 +1140,7 @@ class SizeLocationManipulator(SizeManipulator):
self.mouse_release(context, event)
# must move back to original location
itM = self.o.matrix_world.inverted()
- dl = self.get_value(itM * self.original_location, self.manipulator.prop2_name)
+ dl = self.get_value(itM @ self.original_location, self.manipulator.prop2_name)
self.move(context, self.manipulator.prop2_name, dl)
self.set_value(context, self.datablock, self.manipulator.prop1_name, self.original_size)
@@ -1263,7 +1213,6 @@ class SnapSizeLocationManipulator(SizeLocationManipulator):
])
gl_pts3d = [left, right]
snap_point(takemat=takemat,
- draw=self.sp_draw,
callback=self.sp_callback,
constraint_axis=(True, False, False))
@@ -1290,7 +1239,6 @@ class SnapSizeLocationManipulator(SizeLocationManipulator):
])
gl_pts3d = [left, right]
snap_point(takemat=takemat,
- draw=self.sp_draw,
callback=self.sp_callback,
constraint_axis=(True, False, False))
self.handle_left.active = True
@@ -1305,50 +1253,50 @@ class SnapSizeLocationManipulator(SizeLocationManipulator):
return False
- def sp_draw(self, sp, context):
+ def sp_callback(self, context, event, state, sp):
+ logger.debug("SnapSizeLocationManipulator.sp_callback")
global gl_pts3d
- if self.o is None:
- return
p0 = gl_pts3d[0].copy()
p1 = gl_pts3d[1].copy()
- if self.handle_right.active:
- p1 += sp.delta
- else:
- p0 += sp.delta
- self.sp_update(context, p0, p1)
-
- # snapping child objects may require base object update
- # eg manipulating windows requiring wall update
- if self.snap_callback is not None:
- snap_helper = context.active_object
- self.snap_callback(context, o=self.o, manipulator=self)
- context.scene.objects.active = snap_helper
-
- return
-
- def sp_callback(self, context, event, state, sp):
- if state == 'SUCCESS':
- self.sp_draw(sp, context)
- self.mouse_release(context, event)
-
- if state == 'CANCEL':
- p0 = gl_pts3d[0].copy()
- p1 = gl_pts3d[1].copy()
- self.sp_update(context, p0, p1)
- self.mouse_release(context, event)
+ if state != 'CANCEL':
+ if self.handle_right.active:
+ p1 += sp.delta
+ else:
+ p0 += sp.delta
- def sp_update(self, context, p0, p1):
l0 = self.get_value(self.datablock, self.manipulator.prop1_name)
length = (p0 - p1).length
+
+ if state != 'CANCEL' and event.alt:
+ if event.shift:
+ length = round(length, 2)
+ else:
+ length = round(length, 1)
+
dp = length - l0
+
if self.handle_left.active:
dp = -dp
dl = 0.5 * dp
+
+ # snap_helper = context.object
self.move(context, self.manipulator.prop2_name, dl)
self.set_value(context, self.datablock, self.manipulator.prop1_name, length)
self.move_linked(context, self.manipulator.prop2_name, dl)
+ # snapping child objects may require base object update
+ # eg manipulating windows requiring wall update
+ if self.snap_callback is not None:
+ snap_helper = context.active_object
+ self.snap_callback(context, o=self.o, manipulator=self)
+ snap_helper.select_set(state=True)
+
+ if state != 'RUNNING':
+ self.mouse_release(context, event)
+
+ logger.debug("SnapSizeLocationManipulator.sp_callback done")
+
class DeltaLocationManipulator(SizeManipulator):
"""
@@ -1388,7 +1336,6 @@ class DeltaLocationManipulator(SizeManipulator):
])
gl_pts3d = [p0]
snap_point(takemat=takemat,
- draw=self.sp_draw,
callback=self.sp_callback,
constraint_axis=(
self.manipulator.prop1_name == 'x',
@@ -1413,40 +1360,37 @@ class DeltaLocationManipulator(SizeManipulator):
self.check_hover()
return False
- def sp_draw(self, sp, context):
- global gl_pts3d
- if self.o is None:
- return
- p0 = gl_pts3d[0].copy()
- p1 = p0 + sp.delta
- itM = self.o.matrix_world.inverted()
- dl = self.get_value(itM * p1, self.manipulator.prop1_name)
- self.move(context, self.manipulator.prop1_name, dl)
-
- # snapping child objects may require base object update
- # eg manipulating windows requiring wall update
- if self.snap_callback is not None:
- snap_helper = context.active_object
- self.snap_callback(context, o=self.o, manipulator=self)
- context.scene.objects.active = snap_helper
-
- return
-
def sp_callback(self, context, event, state, sp):
-
- if state == 'SUCCESS':
- self.sp_draw(sp, context)
- self.mouse_release(context, event)
+ logger.debug("DeltaLocationManipulator.sp_callback")
if state == 'CANCEL':
self.cancel(context, event)
+ else:
+ global gl_pts3d
+ p0 = gl_pts3d[0].copy()
+ p1 = p0 + sp.delta
+ itM = self.o.matrix_world.inverted()
+ dl = self.get_value(itM @ p1, self.manipulator.prop1_name)
+ self.move(context, self.manipulator.prop1_name, dl)
+
+ # snapping child objects may require base object update
+ # eg manipulating windows requiring wall update
+ if self.snap_callback is not None:
+ snap_helper = context.active_object
+ self.snap_callback(context, o=self.o, manipulator=self)
+ snap_helper.select_set(state=True)
+
+ if state == 'SUCCESS':
+ self.mouse_release(context, event)
+
+ logger.debug("DeltaLocationManipulator.sp_callback done")
def cancel(self, context, event):
if self.active:
self.mouse_release(context, event)
# must move back to original location
itM = self.o.matrix_world.inverted()
- dl = self.get_value(itM * self.original_location, self.manipulator.prop1_name)
+ dl = self.get_value(itM @ self.original_location, self.manipulator.prop1_name)
self.move(context, self.manipulator.prop1_name, dl)
def draw_callback(self, _self, context, render=False):
@@ -1963,22 +1907,22 @@ class archipack_manipulator(PropertyGroup):
p0, p1, p2 3d Vectors as base points to represent manipulators on screen
normal Vector normal of plane on with draw manipulator
"""
- type_key = StringProperty(default='SIZE')
+ type_key : StringProperty(default='SIZE')
# How 3d points are stored in manipulators ?
# SIZE = 2 absolute positioned and a scaling vector
# RADIUS = 1 absolute positioned (center) and 2 relatives (sides)
# POLYGON = 2 absolute positioned and a relative vector (for rect polygons)
- pts_mode = StringProperty(default='SIZE')
- prop1_name = StringProperty()
- prop2_name = StringProperty()
- p0 = FloatVectorProperty(subtype='XYZ')
- p1 = FloatVectorProperty(subtype='XYZ')
- p2 = FloatVectorProperty(subtype='XYZ')
+ pts_mode : StringProperty(default='SIZE')
+ prop1_name : StringProperty()
+ prop2_name : StringProperty()
+ p0 : FloatVectorProperty(subtype='XYZ')
+ p1 : FloatVectorProperty(subtype='XYZ')
+ p2 : FloatVectorProperty(subtype='XYZ')
# allow orientation of manipulators by default on xy plane,
# but may be used to constrain heights on local object space
- normal = FloatVectorProperty(subtype='XYZ', default=(0, 0, 1))
+ normal : FloatVectorProperty(subtype='XYZ', default=(0, 0, 1))
def set_pts(self, pts, normal=None):
"""
@@ -1999,9 +1943,9 @@ class archipack_manipulator(PropertyGroup):
"""
rM = tM.to_3x3()
if self.pts_mode in ['SIZE', 'POLYGON']:
- return tM * self.p0, tM * self.p1, self.p2, rM * self.normal
+ return tM @ self.p0, tM @ self.p1, self.p2, rM @ self.normal
else:
- return tM * self.p0, rM * self.p1, rM * self.p2, rM * self.normal
+ return tM @ self.p0, rM @ self.p1, rM @ self.p2, rM @ self.normal
def get_prefs(self, context):
global __name__
@@ -2053,7 +1997,7 @@ class ARCHIPACK_OT_manipulate(Operator):
bl_description = "Manipulate"
bl_options = {'REGISTER', 'UNDO'}
- object_name = StringProperty(default="")
+ object_name : StringProperty(default="")
@classmethod
def poll(self, context):
@@ -2123,38 +2067,39 @@ class Manipulable():
Beware : prevent crash calling manipulable_disable()
before changing manipulated data structure
"""
- manipulators = CollectionProperty(
+ manipulators : CollectionProperty(
type=archipack_manipulator,
# options={'SKIP_SAVE'},
# options={'HIDDEN'},
description="store 3d points to draw gl manipulators"
)
- manipulable_refresh = BoolProperty(
+
+ # TODO: make simple instance vars
+ manipulable_refresh : BoolProperty(
default=False,
options={'SKIP_SAVE'},
description="Flag enable to rebuild manipulators when data model change"
)
- manipulate_mode = BoolProperty(
+ manipulate_mode : BoolProperty(
default=False,
options={'SKIP_SAVE'},
description="Flag manipulation state so we are able to toggle"
)
- select_mode = BoolProperty(
+ select_mode : BoolProperty(
default=False,
options={'SKIP_SAVE'},
description="Flag select state so we are able to toggle"
)
- manipulable_selectable = BoolProperty(
+ manipulable_selectable : BoolProperty(
default=False,
options={'SKIP_SAVE'},
description="Flag make manipulators selectable"
)
- keymap = None
- # selectable manipulators
- manipulable_area = GlCursorArea()
- manipulable_start_point = Vector((0, 0))
- manipulable_end_point = Vector((0, 0))
+ keymap = None
+ manipulable_area = None
+ manipulable_start_point = None
+ manipulable_end_point = None
manipulable_draw_handler = None
def setup_manipulators(self):
@@ -2171,6 +2116,13 @@ class Manipulable():
"""
disable gl draw handlers
"""
+
+ if self.keymap is None:
+ self.keymap = Keymaps(context)
+ self.manipulable_area = GlCursorArea()
+ self.manipulable_start_point = Vector((0, 0))
+ self.manipulable_end_point = Vector((0, 0))
+
o = context.active_object
if o is not None:
self.manipulable_exit_selectmode(context)
@@ -2259,6 +2211,7 @@ class Manipulable():
as it provide all needed
functionality out of the box
"""
+
# setup again when manipulators type change
if self.manipulable_refresh:
# print("manipulable_refresh")