[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