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:
authormano-wii <germano.costa@ig.com.br>2019-06-25 02:58:45 +0300
committermano-wii <germano.costa@ig.com.br>2019-06-25 03:03:54 +0300
commitd45469416bfd1857c5cb3bde2e9c237547eb8a9c (patch)
treecadc3a38dc13324190ac2e1c28dd050b3f089ef3 /mesh_snap_utilities_line
parentbe57ea7b466f9574a49d811ee16a9e2212fa3425 (diff)
mesh_snap_utilities_line: new local constrain utilitie
Diffstat (limited to 'mesh_snap_utilities_line')
-rw-r--r--mesh_snap_utilities_line/common_classes.py133
-rw-r--r--mesh_snap_utilities_line/op_line.py77
2 files changed, 144 insertions, 66 deletions
diff --git a/mesh_snap_utilities_line/common_classes.py b/mesh_snap_utilities_line/common_classes.py
index e61d9354..7be2fa97 100644
--- a/mesh_snap_utilities_line/common_classes.py
+++ b/mesh_snap_utilities_line/common_classes.py
@@ -14,14 +14,18 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ##### END GPL LICENSE BLOCK #####
-
import bpy
-from mathutils import Vector
+from mathutils import (
+ Vector,
+ Matrix,
+ )
+from mathutils.geometry import intersect_point_line
from .drawing_utilities import SnapDrawn
from .common_utilities import (
convert_distance,
get_units_info,
+ location_3d_to_region_2d,
)
@@ -96,9 +100,6 @@ class SnapNavigation():
return True
if evkey in self._move:
- #if event.shift and self.vector_constrain and \
- # self.vector_constrain[2] in {'RIGHT_SHIFT', 'LEFT_SHIFT', 'shift'}:
- # self.vector_constrain = None
bpy.ops.view3d.move('INVOKE_DEFAULT')
return True
@@ -187,8 +188,7 @@ class CharMap:
self.line_pos = (pos + 1) % (len(self.length_entered) + 1)
try:
- self.length_entered_value = bpy.utils.units.to_value(
- self.unit_system, 'LENGTH', self.length_entered)
+ self.length_entered_value = bpy.utils.units.to_value(self.unit_system, 'LENGTH', self.length_entered)
except: # ValueError:
self.length_entered_value = 0.0 #invalid
#self.report({'INFO'}, "Operation not supported yet")
@@ -214,6 +214,110 @@ class CharMap:
self.line_pos = 0
+class Constrain:
+ def __init__(self, peferences, scene, obj):
+ self.last_type = None
+ self.last_vec = None
+ self.rotMat = None
+ self.preferences = peferences
+ trans_orient = scene.transform_orientation_slots[0]
+ self.orientation = [None, None]
+ if trans_orient.type == 'LOCAL':
+ self.orientation[0] = obj.matrix_world.to_3x3().transposed()
+ self.orientation[1] = Matrix.Identity(3)
+ else:
+ self.orientation[0] = Matrix.Identity(3)
+ self.orientation[1] = obj.matrix_world.to_3x3().transposed()
+
+ self.orientation_id = 0
+ self.center_2d = Vector((0.0, 0.0))
+ self.projected_vecs = Matrix(([0.0, 0.0], [0.0, 0.0], [0.0, 0.0]))
+
+ def _constrain_set(self, mcursor):
+ vec = (mcursor - self.center_2d)
+ vec.normalize()
+
+ dot_x = abs(vec.dot(self.projected_vecs[0]))
+ dot_y = abs(vec.dot(self.projected_vecs[1]))
+ dot_z = abs(vec.dot(self.projected_vecs[2]))
+
+ if dot_x > dot_y and dot_x > dot_z:
+ vec = self.orientation[self.orientation_id][0]
+ type = 'X'
+
+ elif dot_y > dot_x and dot_y > dot_z:
+ vec = self.orientation[self.orientation_id][1]
+ type = 'Y'
+
+ else: # dot_z > dot_y and dot_z > dot_x:
+ vec = self.orientation[self.orientation_id][2]
+ type = 'Z'
+
+ return vec, type
+
+ def modal(self, event, shift_callback):
+ type = event.type
+ if self.last_type == type:
+ self.orientation_id += 1
+
+ if type == 'X':
+ if self.orientation_id < 2:
+ self.last_vec = self.orientation[self.orientation_id][0]
+ else:
+ self.orientation_id = 0
+ self.last_vec = type = None
+ elif type == 'Y':
+ if self.orientation_id < 2:
+ self.last_vec = self.orientation[self.orientation_id][1]
+ else:
+ self.orientation_id = 0
+ self.last_vec = type = None
+ elif type == 'Z':
+ if self.orientation_id < 2:
+ self.last_vec = self.orientation[self.orientation_id][2]
+ else:
+ self.orientation_id = 0
+ self.last_vec = type = None
+ elif shift_callback and type in {'RIGHT_SHIFT', 'LEFT_SHIFT'}:
+ if self.orientation_id < 1:
+ type = 'shift'
+ self.last_vec = shift_callback()
+ else:
+ self.orientation_id = 0
+ self.last_vec = type = None
+ else:
+ return False
+
+ self.preferences.auto_constrain = False
+ self.last_type = type
+ return True
+
+ def toogle(self):
+ self.rotMat = None # update
+ if self.preferences.auto_constrain:
+ self.orientation_id = (self.orientation_id + 1) % 2
+ self.preferences.auto_constrain = self.orientation_id != 0
+ else:
+ self.preferences.auto_constrain = True
+
+ def update(self, region, rv3d, mcursor, location):
+ if rv3d.view_matrix != self.rotMat:
+ self.rotMat = rv3d.view_matrix.copy()
+
+ self.center_2d = location_3d_to_region_2d(region, rv3d, location)
+
+ orig = location_3d_to_region_2d(region, rv3d, Vector())
+ self.projected_vecs[0] = location_3d_to_region_2d(region, rv3d, self.orientation[self.orientation_id][0]) - orig
+ self.projected_vecs[1] = location_3d_to_region_2d(region, rv3d, self.orientation[self.orientation_id][1]) - orig
+ self.projected_vecs[2] = location_3d_to_region_2d(region, rv3d, self.orientation[self.orientation_id][2]) - orig
+
+ self.projected_vecs[0].normalize()
+ self.projected_vecs[1].normalize()
+ self.projected_vecs[2].normalize()
+
+ return self._constrain_set(mcursor)
+
+
class SnapUtilities:
"""
__slots__ = (
@@ -304,7 +408,7 @@ class SnapUtilities:
if obj.instance_type == 'COLLECTION':
mat = obj.matrix_world.copy()
for ob in obj.instance_collection.objects:
- snap_obj = self.sctx.add_obj(obj, mat @ ob.matrix_world)
+ snap_obj = self.sctx.add_obj(ob, mat @ ob.matrix_world)
if is_moving:
moving_snp_objects.add(snap_obj)
@@ -332,7 +436,7 @@ class SnapUtilities:
self.sctx.add_obj(obj, matrix)
- def snap_context_init(self, context, snap_edge_and_vert = True):
+ def snap_context_init(self, context, snap_edge_and_vert=True):
from .snap_context_l import global_snap_context_get
#Create Snap Context
@@ -352,8 +456,6 @@ class SnapUtilities:
self.draw_cache = widget.draw_cache
if hasattr(widget, "normal"):
self.normal = widget.normal
- #loc = widget.location
- #self.vector_constrain = [loc, loc + widget.normal, self.constrain]
else:
#init these variables to avoid errors
@@ -382,11 +484,9 @@ class SnapUtilities:
self.snap_vert = self.snap_edge = snap_edge_and_vert
shading = context.space_data.shading
- self.snap_face = not (snap_edge_and_vert and
- (shading.show_xray or shading.type == 'WIREFRAME'))
+ self.snap_face = not (snap_edge_and_vert and (shading.show_xray or shading.type == 'WIREFRAME'))
- self.sctx.set_snap_mode(
- self.snap_vert, self.snap_edge, self.snap_face)
+ self.sctx.set_snap_mode(self.snap_vert, self.snap_edge, self.snap_face)
#Configure the unit of measure
unit_system = context.scene.unit_settings.system
@@ -394,8 +494,7 @@ class SnapUtilities:
scale /= context.space_data.overlay.grid_scale
self.rd = bpy.utils.units.to_value(unit_system, 'LENGTH', str(1 / scale))
- self.incremental = bpy.utils.units.to_value(
- unit_system, 'LENGTH', str(self.preferences.incremental))
+ self.incremental = bpy.utils.units.to_value(unit_system, 'LENGTH', str(self.preferences.incremental))
def snap_to_grid(self):
if self.type == 'OUT' and self.preferences.increments_grid:
diff --git a/mesh_snap_utilities_line/op_line.py b/mesh_snap_utilities_line/op_line.py
index 7af0c684..20d5f0b8 100644
--- a/mesh_snap_utilities_line/op_line.py
+++ b/mesh_snap_utilities_line/op_line.py
@@ -25,6 +25,7 @@ from .drawing_utilities import SnapDrawn
from .common_utilities import snap_utilities
from .common_classes import (
CharMap,
+ Constrain,
SnapNavigation,
SnapUtilities,
)
@@ -206,7 +207,7 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
bl_label = "Line Tool"
bl_options = {'REGISTER'}
- wait_for_input: bpy.props.BoolProperty(name="Wait for Input", default=True)
+ wait_for_input : bpy.props.BoolProperty(name="Wait for Input", default=True)
def _exit(self, context):
#avoids unpredictable crashs
@@ -229,7 +230,7 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
self.list_verts = []
self.list_edges = []
self.list_verts_co = []
- self.bool_update = False
+ self.bool_update = True
self.vector_constrain = ()
self.len = 0
@@ -240,6 +241,12 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
self.main_snap_obj = self.snap_obj = self.sctx._get_snap_obj_by_obj(self.obj)
self.main_bm = self.bm
+ def _shift_contrain_callback(self):
+ if isinstance(self.geom, bmesh.types.BMEdge):
+ mat = self.main_snap_obj.mat
+ verts_co = [mat @ v.co for v in self.geom.verts]
+ return verts_co[1] - verts_co[0]
+
def modal(self, context, event):
if self.navigation_ops.run(context, event, self.prevloc if self.vector_constrain else self.location):
return {'RUNNING_MODAL'}
@@ -270,6 +277,8 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
is_making_lines = bool(self.list_verts_co)
if (event.type == 'MOUSEMOVE' or self.bool_update) and self.charmap.length_entered_value == 0.0:
+ mval = Vector((event.mouse_region_x, event.mouse_region_y))
+
if self.rv3d.view_matrix != self.rotMat:
self.rotMat = self.rv3d.view_matrix.copy()
self.bool_update = True
@@ -277,8 +286,6 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
else:
self.bool_update = False
- mval = Vector((event.mouse_region_x, event.mouse_region_y))
-
self.snap_obj, self.prevloc, self.location, self.type, self.bm, self.geom, self.len = snap_utilities(
self.sctx,
self.main_snap_obj,
@@ -289,25 +296,10 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
self.snap_to_grid()
- if is_making_lines and self.keyf8:
- lloc = self.list_verts_co[-1]
- view_vec, orig = self.sctx.last_ray
- location = intersect_point_line(lloc, orig, (orig + view_vec))
- vec = (location[0] - lloc)
- ax, ay, az = abs(vec.x), abs(vec.y), abs(vec.z)
- vec.x = ax > ay and ax > az
- vec.y = ay > ax and ay > az
- vec.z = az > ay and az > ax
- if not (vec.x or vec.y or vec.z):
- self.vector_constrain = None
- else:
- vc = lloc + vec
- if self.vector_constrain is None or vc != self.vector_constrain[1]:
- type = 'X' if vec.x else 'Y' if vec.y else 'Z' if vec.z else 'shift'
- self.vector_constrain = [lloc, vc, type]
- #del vc, type
-
- #del view_vec, orig, location, ax, ay, az, vec
+ if is_making_lines and self.preferences.auto_constrain:
+ loc = self.list_verts_co[-1]
+ vec, type = self.constrain.update(self.sctx.region, self.sctx.rv3d, mval, loc)
+ self.vector_constrain = [loc, loc + vec, type]
if event.value == 'PRESS':
if is_making_lines and self.charmap.modal_(context, event):
@@ -319,29 +311,17 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
self.location = self.list_verts_co[-1] + (vector * text_value)
del vector
- elif event.type in self.constrain_keys:
+ elif self.constrain.modal(event, self._shift_contrain_callback):
self.bool_update = True
- self.keyf8 = False
-
- if self.vector_constrain and self.vector_constrain[2] == event.type:
- self.vector_constrain = ()
+ if self.constrain.last_vec:
+ if self.list_verts_co:
+ loc = self.list_verts_co[-1]
+ else:
+ loc = self.location
+ self.vector_constrain = (loc, loc + self.constrain.last_vec, self.constrain.last_type)
else:
- if event.shift:
- if isinstance(self.geom, bmesh.types.BMEdge):
- mat = self.main_snap_obj.mat
- verts_co = [mat @ v.co for v in self.geom.verts]
- if is_making_lines:
- loc = self.list_verts_co[-1]
- self.vector_constrain = (loc, loc + verts_co[1] - verts_co[0], event.type)
- else:
- self.vector_constrain = verts_co + [event.type]
- else:
- if is_making_lines:
- loc = self.list_verts_co[-1]
- else:
- loc = self.location
- self.vector_constrain = [loc, loc + self.constrain_keys[event.type], event.type]
+ self.vector_constrain = None
elif event.type in {'LEFTMOUSE', 'RET', 'NUMPAD_ENTER'}:
if event.type == 'LEFTMOUSE' or self.charmap.length_entered_value != 0.0:
@@ -351,7 +331,6 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
mat_inv = self.main_snap_obj.mat.inverted_safe()
point = mat_inv @ self.location
- # with constraint the intersection can be in a different element of the selected one
geom2 = self.geom
if geom2:
geom2.select = False
@@ -369,7 +348,7 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
elif event.type == 'F8':
self.vector_constrain = None
- self.keyf8 = self.keyf8 is False
+ self.constrain.toogle()
elif event.type in {'RIGHTMOUSE', 'ESC'}:
if not self.wait_for_input or not is_making_lines or event.type == 'ESC':
@@ -406,6 +385,8 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
self.snap_context_init(context)
self.snap_context_update(context)
+ self.constrain = Constrain(self.preferences, context.scene, self.obj)
+
self.intersect = self.preferences.intersect
self.create_face = self.preferences.create_face
self.navigation_ops = SnapNavigation(context, True)
@@ -427,10 +408,8 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
#Store values from 3d view context
self.rv3d = context.region_data
self.rotMat = self.rv3d.view_matrix.copy()
- # self.obj_glmatrix = bgl.Buffer(bgl.GL_FLOAT, [4, 4], self.obj_matrix.transposed())
-
- #Init event variables
- self.keyf8 = False
+ # self.obj_glmatrix = bgl.Buffer(bgl.GL_FLOAT, [4, 4],
+ # self.obj_matrix.transposed())
#modals
context.window_manager.modal_handler_add(self)