[Bf-extensions-cvs] [4ef6bc77] master: xoffsets: merging in experimental snap code

NBurn noreply at git.blender.org
Thu Nov 9 22:37:29 CET 2017


Commit: 4ef6bc77365f762b144ddbf6dc6dd6124e1f05c9
Author: NBurn
Date:   Thu Nov 9 16:36:04 2017 -0500
Branches: master
https://developer.blender.org/rBAC4ef6bc77365f762b144ddbf6dc6dd6124e1f05c9

xoffsets: merging in experimental snap code

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

M	mesh_xoffsets.py

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

diff --git a/mesh_xoffsets.py b/mesh_xoffsets.py
index 8264e579..b5ebb1c4 100644
--- a/mesh_xoffsets.py
+++ b/mesh_xoffsets.py
@@ -19,7 +19,7 @@ END GPL LICENSE BLOCK
 
 #============================================================================
 
-mesh_xoffsets.py (alpha version 008)
+mesh_xoffsets.py (alpha version 008b with experimental snap code)
 
 Install instructions (if downloaded separately from Blender):
 1) Save the mesh_xoffsets.py file to your computer.
@@ -40,6 +40,10 @@ todo:
         launching addon, disabling perspective change for now
   [ ] better measurement input panel
   [ ] add hotkey reference info into 3D View ?
+  [?] snap_point not deleted after exit
+  [X] only free move during translate when in selected objects
+  [X] snap toggle button still drawn when dialog opened (jumps to dialog box)
+  [ ] 
 
 #============================================================================
 '''
@@ -63,6 +67,7 @@ from copy import deepcopy
 from math import fmod, sqrt, degrees, radians
 from mathutils import Vector, geometry, Quaternion, Euler
 from mathutils.geometry import intersect_line_line_2d
+from bpy_extras import view3d_utils
 from bpy_extras.view3d_utils import location_3d_to_region_2d
 #__import__('code').interact(local=dict(globals(), **locals()))
 
@@ -76,12 +81,15 @@ print("Exact Offsets loaded")
     XO_MOVE,
     XO_SCALE,
     XO_ROTATE,
-) = range(7)
+    XO_SLOW3DTO2D,
+    XO_GRABONLY
+) = range(9)
 
 curr_meas_stor = 0.0
 new_meas_stor = None
 popup_active = False
 reg_rv3d = ()
+pt_store = []
 
 
 def get_reg_rv3d():
@@ -165,6 +173,22 @@ class SceneSelectionInfo:
         self.update(ed_type)
 
 
+def backup_snap_settings():
+    backup = [
+        deepcopy(bpy.context.tool_settings.use_snap),
+        deepcopy(bpy.context.tool_settings.snap_element),
+        deepcopy(bpy.context.tool_settings.snap_target)
+    ]
+    return backup
+
+
+def restore_snap_settings(backup):
+    bpy.context.tool_settings.use_snap = deepcopy(backup[0])
+    bpy.context.tool_settings.snap_element = deepcopy(backup[1])
+    bpy.context.tool_settings.snap_target = deepcopy(backup[2])
+    return
+
+
 # vertex storage class, stores reference point info
 class VertObj:
     def __init__(self, obj_idx=-1, vert_idx=-1, co3D=(), co2D=(), dist2D=4000, ref_idx=-1):
@@ -457,7 +481,7 @@ def find_correct_rot(ref_pts, rot_dat):
             return t_co_neg, -ang_diff_rad
 
 
-# === Point finding code ===
+# === Original point finding code ===
 
 
 # Returns the closest vertex found to the supplied 2D location.
@@ -482,6 +506,94 @@ def find_closest_vert(loc, mesh_idx_ls):
         return None
 
 
+# === Experimental PointFind code ===
+
+
+def inside_bound_box(obj_num, co):
+    objs = bpy.context.scene.objects  # shorthand
+    m_w = objs[obj_num].matrix_world
+    bb = [m_w * Vector(v[:]) for v in objs[obj_num].bound_box]
+    bbx = [x[0] for x in bb]
+    bby = [y[1] for y in bb]
+    bbz = [z[2] for z in bb]
+    x_min = min(bbx); x_max = max(bbx)
+    y_min = min(bby); y_max = max(bby)
+    z_min = min(bbz); z_max = max(bbz)
+    tol = 0.0001
+    if co[0] < (x_min - tol) or co[0] > (x_max + tol): return False
+    if co[1] < (y_min - tol) or co[1] > (y_max + tol): return False
+    if co[2] < (z_min - tol) or co[2] > (z_max + tol): return False
+    return True
+
+
+# Returns the first vertex found at the supplied 3D location
+# Returns None if no vertex found.
+def find_snap_loc(loc, mesh_objs):
+    global pt_store
+    objs = bpy.context.scene.objects
+    #print("\nfind_snap_loc, loc:", loc)  # debug
+    for i in mesh_objs:
+        if inside_bound_box(i, loc):
+            test_loc = objs[i].matrix_world.inverted() * loc
+            v_idx = 0
+            for v in objs[i].data.vertices:
+                if flts_alm_eq( v.co[0], test_loc[0] ):
+                    if flts_alm_eq( v.co[1], test_loc[1] ):
+                        if flts_alm_eq( v.co[2], test_loc[2] ):
+                            world_loc = objs[i].matrix_world * v.co
+                            return VertObj(i, v_idx, world_loc)  # success!
+                v_idx += 1
+    # find_snap_loc failed to find loc match if it reaches here
+    return None
+
+
+def create_snap_pt(ms_loc, ed_type, sel_backup):
+    global reg_rv3d, pt_store
+    sel_backup.update(ed_type)
+    region, rv3d = reg_rv3d[0], reg_rv3d[1]
+    v_u = view3d_utils  # shorthand
+    persp_md_fix = v_u.region_2d_to_vector_3d(region, rv3d, ms_loc) / 5
+    enterloc = v_u.region_2d_to_origin_3d(region, rv3d, ms_loc) + persp_md_fix
+    if ed_type == 'OBJECT':
+        bpy.ops.object.add(type = 'MESH', location = enterloc)
+        pt_store = bpy.context.object
+    elif ed_type == 'EDIT_MESH':
+        # Make sure transform.translate only grabs newly created vert. Only
+        # need to do this in edit mode, object mode does this automatically.
+        bpy.ops.mesh.select_all(action='DESELECT')
+        inver_mw = bpy.context.edit_object.matrix_world.inverted()
+        bm = bmesh.from_edit_mesh(bpy.context.edit_object.data)
+        bm.verts.new(inver_mw * enterloc)
+        if hasattr(bm.verts, "ensure_lookup_table"):
+            bm.verts.ensure_lookup_table()
+        bmesh.update_edit_mesh(bpy.context.edit_object.data)
+        bm.select_history.add( bm.verts[-1] )
+        bm.verts[-1].select = True
+        pt_store = bm.select_history.active.co
+        #print("pt_store", pt_store)  # debug
+    # todo : move below to backup_snap_settings ?
+    bpy.context.tool_settings.use_snap = True
+    bpy.context.tool_settings.snap_element = 'VERTEX'
+    bpy.context.tool_settings.snap_target = 'ACTIVE'
+    bpy.ops.transform.translate('INVOKE_DEFAULT')
+
+
+# Makes sure only the "guide point" object or vert
+# added with create_snap_pt is deleted.
+def remove_snap_pt(ed_type, sel_backup):
+    if ed_type == 'OBJECT':
+        bpy.ops.object.select_all(action='DESELECT')
+        bpy.context.scene.objects[0].select = True
+        bpy.ops.object.delete()
+    elif ed_type == 'EDIT_MESH':
+        bpy.ops.mesh.select_all(action='DESELECT')
+        bm = bmesh.from_edit_mesh(bpy.context.edit_object.data)
+        bm.verts[-1].select = True
+        editmode_refresh(ed_type)
+        bpy.ops.mesh.delete(type='VERT')
+    sel_backup.restore_selected(ed_type)
+
+
 # === 3D View mouse location and button code ===
 # Functions outside_loop() and point_inside_loop() for creating the measure
 # change "button" in the 3D View taken from patmo141's Virtual Button script:
@@ -593,50 +705,79 @@ def draw_meas_btn(text, co2D, mouse_loc, color_off, color_on):
     return btn_co
 
 
+# Draw snap toggle button
+def draw_st_btn(text, co2D, mouse_loc, color_off, color_on):
+    color = color_off
+    offSet = 5
+    font_id = 0
+    blf.size(font_id, 18, 72)
+    w, h = blf.dimensions(font_id, text)
+    textCoor = (co2D[0] - w/2, (co2D[1] ))  #+ 5*offSet))
+    btn_co = get_btn_coor(textCoor, w, h, offSet, offSet)
+
+    bgl.glColor4f(*color)
+    blf.position(font_id, textCoor[0], textCoor[1] + 4, 0.0)
+    blf.draw(font_id, text)
+    if point_inside_loop(btn_co, mouse_loc):
+        color = color_on
+
+    draw_box(btn_co, color)
+    return btn_co
+
+
 # Draw User Interface
 def drawUI(self):
-    global curr_meas_stor
-    ref_pts, meas_btn_act = self.ref_pts, self.meas_btn_act
-    if ref_pts.cnt == 1:
-        ref_pts.rp_ls[0].set2D()
-        draw_pt_2D(ref_pts.rp_ls[0].co2D, ref_pts.colr_ls[0])
-    else:
-        midP = []
-        if ref_pts.cnt < 3:
-            midP = VertObj(-1, -1, get_midpoint(ref_pts.rp_ls[0].co3D,
-                    ref_pts.rp_ls[1].co3D))
-        else:
-            midP = VertObj( -1, -1, ref_pts.rp_ls[1].co3D.copy() )
-
-        lastPt = []
-        if ref_pts.ax_lock == '':
-            for i in range(ref_pts.cnt):
-                ref_pts.rp_ls[i].set2D()
-                draw_pt_2D(ref_pts.rp_ls[i].co2D, ref_pts.colr_ls[i])
-                if lastPt != []:
-                    draw_line_2D(lastPt, ref_pts.rp_ls[i].co2D, ref_pts.colr_ls[0])
-                lastPt = ref_pts.rp_ls[i].co2D
+    if self.ref_pts.cnt > 0:
+        global curr_meas_stor
+        ref_pts, meas_btn_act = self.ref_pts, self.meas_btn_act
+        if ref_pts.cnt == 1:
+            ref_pts.rp_ls[0].set2D()
+            draw_pt_2D(ref_pts.rp_ls[0].co2D, ref_pts.colr_ls[0])
         else:
-            if   ref_pts.ax_lock == 'X':
-                draw_font_at_pt(ref_pts.ax_lock, [80, 36], Colr.red)
-            elif ref_pts.ax_lock == 'Y':
-                draw_font_at_pt(ref_pts.ax_lock, [80, 36], Colr.green)
-            elif ref_pts.ax_lock == 'Z':
-                draw_font_at_pt(ref_pts.ax_lock, [80, 36], Colr.blue)
-            for i in range(ref_pts.cnt):
-                ref_pts.rp_ls[i].set2D()
-                draw_pt_2D(ref_pts.rp_ls[i].co2D, ref_pts.colr_ls[i])
-                ref_pts.lp_ls[i].set2D()
-                draw_pt_2D(ref_pts.lp_ls[i].co2D, ref_pts.colr_ls[i])
-                if lastPt != []:
-                    draw_line_2D(lastPt, ref_pts.lp_ls[i].co2D, ref_pts.colr_ls[0])
-                lastPt = ref_pts.lp_ls[i].co2D
-
-        if meas_btn_act:
-            midP.set2D()
-            meas_str = format(curr_meas_stor, '.2f')
-            self.meas_btn_co = draw_meas_btn(meas_str, midP.co2D,
-                        self.mouse_loc, Colr.white, Colr.red)
+            midP = []
+            if ref_pts.cnt < 3:
+                midP = VertObj(-1, -1, get_midpoint(ref_pts.rp_ls[0].co3D,
+                        ref_pts.rp_ls[1].co3D))
+            else:
+                midP = VertObj( -1, -1, ref_pts.rp_ls[1].co3D.copy() )
+
+            lastPt = []
+            if ref_pts.ax_lock == '':
+                for i in range(ref_pts.cnt):
+                    ref_pts.rp_ls[i].set2D()
+                    draw_pt_2D(ref_pts.rp_ls[i].co2D, ref_pts.colr_ls[i])
+                    if lastPt != []:
+                        draw_line_2D(lastPt, ref_pts.rp_ls[i].co2D, ref_pts.colr_ls[0])
+                    lastPt = ref_pts.rp_ls[i].co2D
+            else:
+                if   ref_pts.ax_lock == 'X':
+                    draw_font_at_pt(ref_pts.ax_lock, [80, 36], Colr.red)
+                

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list