diff options
author | mano-wii <germano.costa@ig.com.br> | 2019-06-25 02:58:45 +0300 |
---|---|---|
committer | mano-wii <germano.costa@ig.com.br> | 2019-06-25 03:03:54 +0300 |
commit | d45469416bfd1857c5cb3bde2e9c237547eb8a9c (patch) | |
tree | cadc3a38dc13324190ac2e1c28dd050b3f089ef3 /mesh_snap_utilities_line | |
parent | be57ea7b466f9574a49d811ee16a9e2212fa3425 (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.py | 133 | ||||
-rw-r--r-- | mesh_snap_utilities_line/op_line.py | 77 |
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) |