[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1970] contrib/py/scripts/addons/ mesh_vertex_slide_chromoly.py: Added chromoly' s interactive vertex slide to contrib.
Brendon Murphy
meta.androcto1 at gmail.com
Thu May 26 14:08:23 CEST 2011
Revision: 1970
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=1970
Author: meta-androcto
Date: 2011-05-26 12:08:20 +0000 (Thu, 26 May 2011)
Log Message:
-----------
Added chromoly's interactive vertex slide to contrib.
thanks to chromoly & JMR
Added Paths:
-----------
contrib/py/scripts/addons/mesh_vertex_slide_chromoly.py
Added: contrib/py/scripts/addons/mesh_vertex_slide_chromoly.py
===================================================================
--- contrib/py/scripts/addons/mesh_vertex_slide_chromoly.py (rev 0)
+++ contrib/py/scripts/addons/mesh_vertex_slide_chromoly.py 2011-05-26 12:08:20 UTC (rev 1970)
@@ -0,0 +1,839 @@
+# -*- coding: utf-8 -*-
+
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# Modified by JMR to make it work on blender 2.57
+
+bl_info = {
+ 'name': 'Vertex Slide Chromoly',
+ 'author': 'chromoly, JMR',
+ 'version': (0, 2),
+ 'blender': (2, 5, 7),
+ 'api': 36887,
+ 'location': 'Search > vertex slide',
+ 'description': 'Interactive Vertex Slide',
+ 'warning': 'Tool Shelf functions may cause errors.',
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" \
+ "Scripts/Modeling/Vertex_Slide",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=27487&group_id=153&atid=468",
+ 'category': 'Mesh'}
+
+import math
+import sys
+import time
+#from functools import reduce
+#from collections import OrderedDict, Counter
+
+import bpy
+from bpy.props import *
+import mathutils as Math
+from mathutils import Euler, Matrix, Quaternion, Vector
+#import geometry as Geo
+import bgl
+from bgl import glEnable, glDisable, glBegin, glEnd, glColor4f, glVertex2f, \
+ GL_BLEND, GL_LINES, glRectf
+import blf
+'''
+from va.mesh import PyMesh #, path_vertices_list
+
+from va.view import convert_world_to_window, convert_window_to_world, \
+ MouseCoordinate
+from va.gl import draw_circle, draw_arrow
+from va.utils import InputExpression, print_event
+'''
+
+MIN_NUMBER = 1E-8
+GRID_MIN_PX = 6.0
+
+print_event_modal = False
+
+### Copy from Modules #########################################################
+class Vert():
+ # 簡易版
+ def __init__(self):
+ self.index = 0
+ self.select = False
+ self.hide = False
+ self.co = Vector()
+ self.vertices = []
+ self.worco = None # type:Vector. ob.matrix_world * self.co
+ self.winco = None # type:Vector. convert_world_to_window()
+ self.viewco = None # type:Vector viewmat * self.worco
+
+ def _get_selected(self):
+ return self.select and not self.hide
+ def _set_selected(self, val):
+ if not self.hide:
+ self.select = val
+ is_selected = property(_get_selected, _set_selected)
+
+class PyMesh():
+ # 簡易版
+ def __init__(self, me):
+ vertices = [Vert() for i in range(len(me.vertices))]
+ for i, v in enumerate(me.vertices):
+ vert = vertices[i]
+ vert.index = v.index
+ vert.select = v.select
+ vert.hide = v.hide
+ vert.co = v.co.copy()
+ for edge in me.edges:
+ i1, i2 = edge.key
+ vertices[i1].vertices.append(vertices[i2])
+ vertices[i2].vertices.append(vertices[i1])
+ self.vertices = vertices
+
+ def calc_world_coordinate(self, matrix_world):
+ for vert in self.vertices:
+ vert.worco = vert.co * matrix_world
+
+def convert_world_to_window(vec, persmat, sx, sy):
+ '''vec: sequence
+ return Vector
+ '''
+ #v = vec.copy().resize4D()
+ v = Vector([vec[0], vec[1], vec[2], 1.0])
+ v = v * persmat
+ if v[3] != 0.0:
+ v /= v[3]
+ x = sx / 2 + v[0] * sx / 2
+ y = sy / 2 + v[1] * sy / 2
+ return Vector([x, y, v[2]])
+
+
+def convert_window_to_world(vec, persmat, sx, sy):
+ '''vec: sequence
+ return Vector
+ '''
+ invpmat = persmat.copy()
+ invpmat.invert()
+ v1 = Math.Vector([float(vec[0]) * 2 / sx, float(vec[1]) * 2 / sy, vec[2]])
+ v2 = v1 - Math.Vector([1., 1., 0.])
+ v2.resize_4d()
+ v3 = v2 * invpmat
+ if v3[3] != 0.0:
+ v3 /= v3[3]
+ v3.resize_3d()
+ return v3
+
+
+def get_DPBU_dx_unit_pow(region, rv3d):
+ '''画面中心pと、そこからBlenderUnit分だけ画面と平行に移動したqを
+ それぞれwindow座標に変換(p,qは共にworld座標)
+ '''
+ sx = region.width
+ sy = region.height
+ persmat = rv3d.perspective_matrix
+ viewmat = rv3d.view_matrix
+ viewinvmat = viewmat.copy()
+ viewinvmat.invert()
+ viewloc = rv3d.view_location
+
+ p = viewloc
+ if sx >= sy:
+ q = viewloc + Vector(viewinvmat[0][:3])
+ else:
+ q = viewloc + Vector(viewinvmat[1][:3])
+ dp = convert_world_to_window(p, persmat, sx, sy)
+ dq = convert_world_to_window(q, persmat, sx, sy)
+ l = math.sqrt((dp[0] - dq[0]) ** 2 + (dp[1] - dq[1]) ** 2)
+ dot_per_blender_unit = dx = l
+
+ #unit = 1.0
+ unit_pow = 0
+ if dx < GRID_MIN_PX:
+ while dx < GRID_MIN_PX:
+ dx *= 10
+ unit_pow += 1
+ else:
+ while dx > GRID_MIN_PX * 10:
+ dx /= 10
+ unit_pow -= 1
+ return dot_per_blender_unit, dx, unit_pow
+
+
+class MouseCoordinate:
+ '''
+ origin, current, shiftからrelativeを求める。
+ relativeをorigin -> lockのベクトルに正射影。
+ スナップをを計算してdistに値を入れる。
+ '''
+ shift = None # *0.1. type:Vector. relativeに影響。
+ lock = None # lock direction. type:Vector. relativeに影響。
+ snap = False # type:Bool
+ origin = Vector() # Rキーで変更
+ current = Vector() # (event.mouse_region_x, event.mouse_region_y, 0)
+ relative = Vector() # shiftを考慮
+ dpbu = 1.0 # update時に可能なら再取得
+ unit_pow = 1.0 # update時に可能なら再取得
+ dist = 0.0 # relativesnapを考慮
+ dpf= 200 # dot per fac
+ fac = 0.0
+
+ def __init__(self, context=None, event=None, recalcDPBU=True, dpf=200):
+ if event:
+ self.origin = Vector((event.mouse_region_x, event.mouse_region_y, \
+ 0.0))
+ self.dpf = dpf
+ self.update(context, event, recalcDPBU)
+
+ def update(self, context=None, event=None, recalcDPBU=False):
+ shift = self.shift
+ snap = self.snap
+ lock = self.lock
+ origin = self.origin
+
+ if event:
+ current = Vector((event.mouse_region_x, event.mouse_region_y, 0.0))
+ else:
+ current = self.current
+ if shift:
+ relative = shift - origin + (current - shift) * 0.1
+ else:
+ relative = current - origin
+ if lock:
+ origin_lock = lock - origin
+ if origin_lock.length >= MIN_NUMBER:
+ if relative.length >= MIN_NUMBER:
+ relative = relative.project(origin_lock)
+ else:
+ self.lock = None
+ if context and recalcDPBU:
+ dpbu, dx, unit_pow = get_DPBU_dx_unit_pow(context.region, context.region_data)
+ else:
+ dpbu, unit_pow = self.dpbu, self.unit_pow
+
+ dist = relative.length / dpbu
+ fac = relative.length / self.dpf
+ if lock:
+ if relative.dot(origin_lock) < 0.0:
+ dist = -dist
+ fac = -fac
+ if snap:
+ grid = 10 ** unit_pow
+ gridf = 0.1
+ if shift:
+ grid /= 10
+ gridf /= 10
+ dist = grid * math.floor(0.5 + dist / grid)
+ fac = gridf * math.floor(0.5 + fac / gridf)
+
+ self.current = current
+ self.relative = relative
+ self.dpbu = dpbu
+ self.unit_pow = unit_pow
+ self.dist = dist
+ self.fac = fac
+
+ def draw_origin(self, radius=5):
+ draw_circle(self.origin[0], self.origin[1], radius, 16)
+
+ def draw_relative(self, radius=5):
+ #if self.shift:
+ draw_circle(self.origin[0] + self.relative[0], \
+ self.origin[1] + self.relative[1], radius, 16)
+
+ def draw_lock_arrow(self, length=10, angle=math.radians(110)):
+ if self.lock is not None:
+ lock = self.lock.copy().resize2D()
+ origin = self.origin.copy().resize2D()
+ vec = (origin - lock).normalize()
+ vec *= 20
+ vecn = lock + vec
+ draw_arrow(vecn[0], vecn[1], lock[0], lock[1], \
+ headlength=length, headangle=angle, headonly=True)
+
+
+def draw_circle(x, y, radius, subdivide):
+ '''e = Euler([0, 0, math.radians(360 / subdivide)])
+ m = e.to_matrix()
+ v = Vector([0, radius, 0])
+ bgl.glBegin(bgl.GL_LINE_LOOP)
+ for i in range(subdivide):
+ bgl.glVertex2f(x + v[0], y + v[1])
+ v = m * v
+ bgl.glEnd()
+ '''
+ bgl.glBegin(bgl.GL_LINE_LOOP)
+ r = 0.0
+ dr = math.pi * 2 / subdivide
+ for i in range(subdivide):
+ bgl.glVertex2f(x + radius * math.cos(r), y + radius * math.sin(r))
+ r += dr
+ bgl.glEnd()
+
+
+def draw_arrow(nockx, nocky, headx, heady, headlength=10, \
+ headangle=math.radians(70), headonly=False):
+ '''
+ nockx, nocky: 筈
+ headx, heady: 鏃
+ '''
+ if nockx == headx and nocky == heady or headonly and headlength == 0:
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list