Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2006-01-18 02:47:45 +0300
committerCampbell Barton <ideasman42@gmail.com>2006-01-18 02:47:45 +0300
commitf90b7a69065b14cb1d5bb896a52a0d0c5783b8de (patch)
tree339253efc92889cdb572f60fc92eec2759cc0ae9
parent9f47286673a3c236813604f58bdff78a49a86c74 (diff)
moving to bpydata because it cant be accessed from the menus
-rw-r--r--release/scripts/mesh_bbrush.py898
1 files changed, 0 insertions, 898 deletions
diff --git a/release/scripts/mesh_bbrush.py b/release/scripts/mesh_bbrush.py
deleted file mode 100644
index e174a52d515..00000000000
--- a/release/scripts/mesh_bbrush.py
+++ /dev/null
@@ -1,898 +0,0 @@
-# SPACEHANDLER.VIEW3D.EVENT
-# Dont run, event handelers are accessed in the from the 3d View menu.
-
-import Blender
-from Blender import Mathutils, Window, Scene, Draw, Mesh, NMesh
-from Blender.Mathutils import CrossVecs, Matrix, Vector, Intersect, LineIntersect
-
-
-# DESCRIPTION:
-# screen_x, screen_y the origin point of the pick ray
-# it is either the mouse location
-# localMatrix is used if you want to have the returned values in an objects localspace.
-# this is usefull when dealing with an objects data such as verts.
-# or if useMid is true, the midpoint of the current 3dview
-# returns
-# Origin - the origin point of the pick ray
-# Direction - the direction vector of the pick ray
-# in global coordinates
-epsilon = 1e-3 # just a small value to account for floating point errors
-
-def getPickRay(screen_x, screen_y, localMatrix=None, useMid = False):
-
- # Constant function variables
- p = getPickRay.p
- d = getPickRay.d
-
- for win3d in Window.GetScreenInfo(Window.Types.VIEW3D): # we search all 3dwins for the one containing the point (screen_x, screen_y) (could be the mousecoords for example)
- win_min_x, win_min_y, win_max_x, win_max_y = win3d['vertices']
- # calculate a few geometric extents for this window
-
- win_mid_x = (win_max_x + win_min_x + 1.0) * 0.5
- win_mid_y = (win_max_y + win_min_y + 1.0) * 0.5
- win_size_x = (win_max_x - win_min_x + 1.0) * 0.5
- win_size_y = (win_max_y - win_min_y + 1.0) * 0.5
-
- #useMid is for projecting the coordinates when we subdivide the screen into bins
- if useMid: # == True
- screen_x = win_mid_x
- screen_y = win_mid_y
-
- # if the given screencoords (screen_x, screen_y) are within the 3dwin we fount the right one...
- if (win_max_x > screen_x > win_min_x) and ( win_max_y > screen_y > win_min_y):
- # first we handle all pending events for this window (otherwise the matrices might come out wrong)
- Window.QHandle(win3d['id'])
-
- # now we get a few matrices for our window...
- # sorry - i cannot explain here what they all do
- # - if you're not familiar with all those matrices take a look at an introduction to OpenGL...
- pm = Window.GetPerspMatrix() # the prespective matrix
- pmi = Matrix(pm); pmi.invert() # the inverted perspective matrix
-
- if (1.0 - epsilon < pmi[3][3] < 1.0 + epsilon):
- # pmi[3][3] is 1.0 if the 3dwin is in ortho-projection mode (toggled with numpad 5)
- hms = getPickRay.hms
- ortho_d = getPickRay.ortho_d
-
- # ortho mode: is a bit strange - actually there's no definite location of the camera ...
- # but the camera could be displaced anywhere along the viewing direction.
-
- ortho_d.x, ortho_d.y, ortho_d.z = Window.GetViewVector()
- ortho_d.w = 0
-
- # all rays are parallel in ortho mode - so the direction vector is simply the viewing direction
- hms.x, hms.y, hms.z, hms.w = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0
-
- # these are the homogenious screencoords of the point (screen_x, screen_y) ranging from -1 to +1
- p=(hms*pmi) + (1000*ortho_d)
- p.resize3D()
- d.x, d.y, d.z = ortho_d.x, ortho_d.y, ortho_d.z
-
-
- # Finally we shift the position infinitely far away in
- # the viewing direction to make sure the camera if outside the scene
- # (this is actually a hack because this function
- # is used in sculpt_mesh to initialize backface culling...)
- else:
- # PERSPECTIVE MODE: here everything is well defined - all rays converge at the camera's location
- vmi = Matrix(Window.GetViewMatrix()); vmi.invert() # the inverse viewing matrix
- fp = getPickRay.fp
-
- dx = pm[3][3] * (((screen_x-win_min_x)/win_size_x)-1.0) - pm[3][0]
- dy = pm[3][3] * (((screen_y-win_min_y)/win_size_y)-1.0) - pm[3][1]
-
- fp.x, fp.y, fp.z = \
- pmi[0][0]*dx+pmi[1][0]*dy,\
- pmi[0][1]*dx+pmi[1][1]*dy,\
- pmi[0][2]*dx+pmi[1][2]*dy
-
- # fp is a global 3dpoint obtained from "unprojecting" the screenspace-point (screen_x, screen_y)
- #- figuring out how to calculate this took me quite some time.
- # The calculation of dxy and fp are simplified versions of my original code
- #- so it's almost impossible to explain what's going on geometrically... sorry
-
- p.x, p.y, p.z = vmi[3][:3]
-
- # the camera's location in global 3dcoords can be read directly from the inverted viewmatrix
- #d.x, d.y, d.z =normalize_v3(sub_v3v3(p, fp))
- d.x, d.y, d.z = p.x-fp.x, p.y-fp.y, p.z-fp.z
-
- #print 'd', d, 'p', p, 'fp', fp
-
-
- # the direction vector is simply the difference vector from the virtual camera's position
- #to the unprojected (screenspace) point fp
-
- # Do we want to return a direction in object's localspace?
-
- if localMatrix:
- localInvMatrix = Matrix(localMatrix)
- localInvMatrix.invert()
- p = p*localInvMatrix
- d = d*localInvMatrix # normalize_v3
- p.x += localInvMatrix[3][0]
- p.y += localInvMatrix[3][1]
- p.z += localInvMatrix[3][2]
-
- #else: # Worldspace, do nothing
-
- d.normalize()
- return True, p, d # Origin, Direction
-
- # Mouse is not in any view, return None.
- return False, None, None
-
-# Constant function variables
-getPickRay.d = Vector(0,0,0) # Perspective, 3d
-getPickRay.p = Vector(0,0,0)
-getPickRay.fp = Vector(0,0,0)
-
-getPickRay.hms = Vector(0,0,0,0) # ortho only 4d
-getPickRay.ortho_d = Vector(0,0,0,0) # ortho only 4d
-
-
-
-def ui_set_preferences(user_interface=1):
-
- # Create data and set defaults.
- ADAPTIVE_GEOMETRY_but = Draw.Create(1)
- BRUSH_MODE_but = Draw.Create(1)
- BRUSH_PRESSURE_but = Draw.Create(0.05)
- BRUSH_RADIUS_but = Draw.Create(0.25)
- RESOLUTION_MIN_but = Draw.Create(0.1)
- DISPLACE_NORMAL_MODE_but = Draw.Create(2)
- STATIC_NORMAL_but = Draw.Create(1)
- XPLANE_CLIP_but = Draw.Create(0)
- STATIC_MESH_but = Draw.Create(1)
- FIX_TOPOLOGY_but = Draw.Create(0)
-
- # Remember old variables if alredy set.
- try:
- ADAPTIVE_GEOMETRY_but.val = Blender.bbrush['ADAPTIVE_GEOMETRY']
- BRUSH_MODE_but.val = Blender.bbrush['BRUSH_MODE']
- BRUSH_PRESSURE_but.val = Blender.bbrush['BRUSH_PRESSURE']
- BRUSH_RADIUS_but.val = Blender.bbrush['BRUSH_RADIUS']
- RESOLUTION_MIN_but.val = Blender.bbrush['RESOLUTION_MIN']
- DISPLACE_NORMAL_MODE_but.val = Blender.bbrush['DISPLACE_NORMAL_MODE']
- STATIC_NORMAL_but.val = Blender.bbrush['STATIC_NORMAL']
- XPLANE_CLIP_but.val = Blender.bbrush['XPLANE_CLIP']
- STATIC_MESH_but.val = Blender.bbrush['STATIC_MESH']
- FIX_TOPOLOGY_but.val = Blender.bbrush['FIX_TOPOLOGY']
- except:
- Blender.bbrush = {}
-
- if user_interface:
- pup_block = [\
- 'Brush Options',\
- ('Adaptive Geometry', ADAPTIVE_GEOMETRY_but, 'Add and remove detail as needed. Uses min/max resolution.'),\
- ('Brush Type: ', BRUSH_MODE_but, 1, 5, 'Push/Pull:1, Grow/Shrink:2, Spin:3, Relax:4, Goo:5'),\
- ('Pressure: ', BRUSH_PRESSURE_but, 0.0, 1.0, 'Pressure of the brush.'),\
- ('Size: ', BRUSH_RADIUS_but, 0.0, 2.0, 'Size of the brush.'),\
- ('Geometry Res: ', RESOLUTION_MIN_but, 0.01, 0.5, 'Size of the brush & Adaptive Subdivision.'),\
- ('Displace Vector: ', DISPLACE_NORMAL_MODE_but, 1, 4, 'Vertex Normal:1, Median Normal:2, Face Normal:3, View Normal:4'),\
- ('Static Normal', STATIC_NORMAL_but, 'Use the initial normal only.'),\
- ('No X Crossing', XPLANE_CLIP_but, 'Dont allow verts to have a negative X axis (use for x-mirror).'),\
- ('Static Mesh', STATIC_MESH_but, 'During mouse interaction, dont update the mesh.'),\
- #('Fix Topology', FIX_TOPOLOGY_but, 'Fix the mesh structure by rotating edges '),\
- ]
-
- Draw.PupBlock('BlenBrush Prefs (RMB)', pup_block)
-
- Blender.bbrush['ADAPTIVE_GEOMETRY'] = ADAPTIVE_GEOMETRY_but.val
- Blender.bbrush['BRUSH_MODE'] = BRUSH_MODE_but.val
- Blender.bbrush['BRUSH_PRESSURE'] = BRUSH_PRESSURE_but.val
- Blender.bbrush['BRUSH_RADIUS'] = BRUSH_RADIUS_but.val
- Blender.bbrush['RESOLUTION_MIN'] = RESOLUTION_MIN_but.val
- Blender.bbrush['DISPLACE_NORMAL_MODE'] = DISPLACE_NORMAL_MODE_but.val
- Blender.bbrush['STATIC_NORMAL'] = STATIC_NORMAL_but.val
- Blender.bbrush['XPLANE_CLIP'] = XPLANE_CLIP_but.val
- Blender.bbrush['STATIC_MESH'] = STATIC_MESH_but.val
- Blender.bbrush['FIX_TOPOLOGY'] = FIX_TOPOLOGY_but.val
-
-
-def triangulateNMesh(nm):
- '''
- Converts the meshes faces to tris, modifies the mesh in place.
- '''
-
- #============================================================================#
- # Returns a new face that has the same properties as the origional face #
- # but with no verts #
- #============================================================================#
- def copyFace(face):
- newFace = NMesh.Face()
- # Copy some generic properties
- newFace.mode = face.mode
- if face.image != None:
- newFace.image = face.image
- newFace.flag = face.flag
- newFace.mat = face.mat
- newFace.smooth = face.smooth
- return newFace
-
- # 2 List comprehensions are a lot faster then 1 for loop.
- tris = [f for f in nm.faces if len(f) == 3]
- quads = [f for f in nm.faces if len(f) == 4]
-
-
- if quads: # Mesh may have no quads.
- has_uv = quads[0].uv
- has_vcol = quads[0].col
- for quadFace in quads:
- # Triangulate along the shortest edge
- #if (quadFace.v[0].co - quadFace.v[2].co).length < (quadFace.v[1].co - quadFace.v[3].co).length:
- a1 = Mathutils.TriangleArea(quadFace.v[0].co, quadFace.v[1].co, quadFace.v[2].co)
- a2 = Mathutils.TriangleArea(quadFace.v[0].co, quadFace.v[2].co, quadFace.v[3].co)
- b1 = Mathutils.TriangleArea(quadFace.v[1].co, quadFace.v[2].co, quadFace.v[3].co)
- b2 = Mathutils.TriangleArea(quadFace.v[1].co, quadFace.v[3].co, quadFace.v[0].co)
- a1,a2 = min(a1, a2), max(a1, a2)
- b1,b2 = min(b1, b2), max(b1, b2)
- if a1/a2 < b1/b2:
-
- # Method 1
- triA = 0,1,2
- triB = 0,2,3
- else:
- # Method 2
- triA = 0,1,3
- triB = 1,2,3
-
- for tri1, tri2, tri3 in (triA, triB):
- newFace = copyFace(quadFace)
- newFace.v = [quadFace.v[tri1], quadFace.v[tri2], quadFace.v[tri3]]
- if has_uv: newFace.uv = [quadFace.uv[tri1], quadFace.uv[tri2], quadFace.uv[tri3]]
- if has_vcol: newFace.col = [quadFace.col[tri1], quadFace.col[tri2], quadFace.col[tri3]]
-
- nm.addEdge(quadFace.v[tri1], quadFace.v[tri3]) # Add an edge where the 2 tris are devided.
- tris.append(newFace)
-
- nm.faces = tris
-
-import mesh_tri2quad
-def fix_topolagy(mesh):
- ob = Scene.GetCurrent().getActiveObject()
-
- for f in mesh.faces:
- f.sel = 1
- mesh.quadToTriangle(0)
- nmesh = ob.getData()
-
- mesh_tri2quad.tri2quad(nmesh, 100, 0)
- triangulateNMesh(nmesh)
- nmesh.update()
-
- mesh = Mesh.Get(mesh.name)
- for f in mesh.faces:
- f.sel=1
- mesh.quadToTriangle()
- Mesh.Mode(Mesh.SelectModes['EDGE'])
-
-
-
-
-
-
-def event_main():
- #print Blender.event
- #mod =[Window.Qual.CTRL, Window.Qual.ALT, Window.Qual.SHIFT]
- mod =[Window.Qual.CTRL, Window.Qual.ALT]
-
- qual = Window.GetKeyQualifiers()
- SHIFT_FLAG = Window.Qual.SHIFT
- CTRL_FLAG = Window.Qual.CTRL
-
-
- # UNDO
- """
- is_editmode = Window.EditMode() # Exit Editmode.
- if is_editmode: Window.EditMode(0)
- if Blender.event == Draw.UKEY:
- if is_editmode:
- Blender.event = Draw.UKEY
- return
- else:
- winId = [win3d for win3d in Window.GetScreenInfo(Window.Types.VIEW3D)][0]
- Blender.event = None
- Window.QHandle(winId['id'])
- Window.EditMode(1)
- Window.QHandle(winId['id'])
- Window.QAdd(winId['id'],Draw.UKEY,1) # Change KeyPress Here for EditMode
- Window.QAdd(winId['id'],Draw.UKEY,0)
- Window.QHandle(winId['id'])
- Window.EditMode(0)
- Blender.event = None
- return
- """
-
- ob = Scene.GetCurrent().getActiveObject()
- if not ob or ob.getType() != 'Mesh':
- return
-
- # Mouse button down with no modifiers.
- if Blender.event == Draw.LEFTMOUSE and not [True for m in mod if m & qual]:
- # Do not exit (draw)
- pass
- elif Blender.event == Draw.RIGHTMOUSE and not [True for m in mod if m & qual]:
- ui_set_preferences()
- return
- else:
- return
-
- del qual
-
-
- try:
- Blender.bbrush
- except:
- # First time run
- ui_set_preferences() # No ui
- return
-
- ADAPTIVE_GEOMETRY = Blender.bbrush['ADAPTIVE_GEOMETRY'] # 1
- BRUSH_MODE = Blender.bbrush['BRUSH_MODE'] # 1
- BRUSH_PRESSURE_ORIG = Blender.bbrush['BRUSH_PRESSURE'] # 0.1
- BRUSH_RADIUS = Blender.bbrush['BRUSH_RADIUS'] # 0.5
- RESOLUTION_MIN = Blender.bbrush['RESOLUTION_MIN'] # 0.08
- STATIC_NORMAL = Blender.bbrush['STATIC_NORMAL'] # 0
- XPLANE_CLIP = Blender.bbrush['XPLANE_CLIP'] # 0
- DISPLACE_NORMAL_MODE = Blender.bbrush['DISPLACE_NORMAL_MODE'] # 'Vertex Normal%x1|Median Normal%x2|Face Normal%x3|View Normal%x4'
- STATIC_MESH = Blender.bbrush['STATIC_MESH']
- FIX_TOPOLOGY = Blender.bbrush['FIX_TOPOLOGY']
-
-
- # Angle between Vecs wrapper.
- AngleBetweenVecs = Mathutils.AngleBetweenVecs
- def ang(v1,v2):
- try:
- return AngleBetweenVecs(v1,v2)
- except:
- return 180
- """
- def Angle2D(x1, y1, x2, y2):
- import math
- RAD2DEG = 57.295779513082323
- '''
- Return the angle between two vectors on a plane
- The angle is from vector 1 to vector 2, positive anticlockwise
- The result is between -pi -> pi
- '''
- dtheta = math.atan2(y2,x2) - math.atan2(y1,x1) # theta1 - theta2
- while dtheta > math.pi:
- dtheta -= (math.pi*2)
- while dtheta < -math.pi:
- dtheta += (math.pi*2)
- return dtheta * RAD2DEG #(180.0 / math.pi)
- """
-
- def faceIntersect(f):
- isect = Intersect(f.v[0].co, f.v[1].co, f.v[2].co, Direction, Origin, 1) # Clipped.
- if isect:
- return isect
- elif len(f.v) == 4:
- isect = Intersect(f.v[0].co, f.v[2].co, f.v[3].co, Direction, Origin, 1) # Clipped.
- return isect
- """
- # Unused so farm, too slow.
- def removeDouble(v1,v2, me):
- v1List = [f for f in me.faces if v1 in f.v]
- v2List = [f for f in me.faces if v2 in f.v]
- #print v1List
- #print v2List
- remFaces = []
- newFaces = []
- for f2 in v2List:
- f2ls = list(f2.v)
- i = f2ls.index(v2)
- f2ls[i] = v1
- #remFaces.append(f2)
- if f2ls.count(v1) == 1:
- newFaces.append(tuple(f2ls))
- if remFaces:
- me.faces.delete(1, remFaces)
- #me.verts.delete(v2)
- if newFaces:
- me.faces.extend(newFaces)
- """
-
-
- me = ob.getData(mesh=1)
-
- is_editmode = Window.EditMode() # Exit Editmode.
- if is_editmode: Window.EditMode(0)
-
- Mesh.Mode(Mesh.SelectModes['EDGE'])
-
- # At the moment ADAPTIVE_GEOMETRY is the only thing that uses selection.
- if ADAPTIVE_GEOMETRY:
- # Deslect all
- SEL_FLAG = Mesh.EdgeFlags['SELECT']
- '''
- for ed in me.edges:
- #ed.flag &= ~SEL_FLAG # deselect. 34
- ed.flag = 32
- '''
- filter(lambda ed: setattr(ed, 'flag', 32), me.edges)
-
- '''for v in me.verts:
- v.sel = 0'''
- filter(lambda v: setattr(v, 'sel', 0), me.verts)
-
- i = 0
- time = Blender.sys.time()
- last_best_isect = None # used for goo only
- old_screen_x, old_screen_y = 1<<30, 1<<30
- goo_dir_vec = last_goo_dir_vec = gooRotMatrix = None # goo mode only.
-
- # Normal stuff
- iFaceNormal = medainNormal = None
-
- # Store all vert normals for now.
- if BRUSH_MODE == 1 and STATIC_NORMAL: # Push pull
- vert_orig_normals = dict([(v, v.no) for v in me.verts])
-
- elif BRUSH_MODE == 4: # RELAX, BUILD EDGE CONNECTIVITE DATA.
- # we need edge connectivity
- #vertEdgeUsers = [list() for i in xrange(len(me.verts))]
- verts_connected_by_edge = [list() for i in xrange(len(me.verts))]
-
- for ed in me.edges:
- i1, i2 = ed.v1.index, ed.v2.index
- #vertEdgeUsers[i1].append(ed)
- #vertEdgeUsers[i2].append(ed)
-
- verts_connected_by_edge[i1].append(ed.v2)
- verts_connected_by_edge[i2].append(ed.v1)
-
- if STATIC_MESH:
-
- # Try and find a static mesh to reuse.
- # this is because we dont want to make a new mesh for each stroke.
- mesh_static = None
- for _me_name_ in Blender.NMesh.GetNames():
- _me_ = Mesh.Get(_me_name_)
- #print _me_.users , len(me.verts)
- if _me_.users == 0 and len(_me_.verts) == 0:
- mesh_static = _me_
- #print 'using', _me_.name
- break
- del _me_name_
- del _me_
-
- if not mesh_static:
- mesh_static = Mesh.New()
- print 'Making new mesh', mesh_static.name
-
- mesh_static.verts.extend([v.co for v in me.verts])
- mesh_static.faces.extend([tuple([mesh_static.verts[v.index] for v in f.v]) for f in me.faces])
-
-
- best_isect = gooPlane = None
-
- while Window.GetMouseButtons() == 1:
- i+=1
- screen_x, screen_y = Window.GetMouseCoords()
-
- # Skip when no mouse movement, Only for Goo!
- if screen_x == old_screen_x and screen_y == old_screen_y:
- if BRUSH_MODE == 5: # Dont modify while mouse is not moved for goo.
- continue
- else: # mouse has moved get the new mouse ray.
- old_screen_x, old_screen_y = screen_x, screen_y
- mouseInView, Origin, Direction = getPickRay(screen_x, screen_y, ob.matrixWorld)
- if not mouseInView or not Origin:
- return
- Origin_SCALE = Origin * 100
-
- # Find an intersecting face!
- bestLen = 1<<30 # start with an assumed realy bad match.
- best_isect = None # last intersect is used for goo.
- best_face = None
-
- if not last_best_isect:
- last_best_isect = best_isect
-
- if not mouseInView:
- last_best_isect = None
-
- else:
- # Find Face intersection closest to the view.
- #for f in [f for f in me.faces if ang(f.no, Direction) < 90]:
-
- # Goo brush only intersects faces once, after that the brush follows teh view plain.
- if BRUSH_MODE == 5 and gooPlane != None and gooPlane:
- best_isect = Intersect( gooPlane[0], gooPlane[1], gooPlane[2], Direction, Origin, 0) # Non clipped
- else:
- if STATIC_MESH:
- intersectingFaces = [(f, ix) for f in mesh_static.faces for ix in (faceIntersect(f),) if ix]
- else:
- intersectingFaces = [(f, ix) for f in me.faces for ix in (faceIntersect(f),) if ix]
-
- for f, isect in intersectingFaces:
- l = (Origin_SCALE-isect).length
- if l < bestLen:
- best_face = f
- best_isect = isect
- bestLen = l
-
- if not best_isect:
- # Dont interpolate once the mouse moves off the mesh.
- lastGooVec = last_best_isect = None
-
- else: # mouseInView must be true also
-
- # Use the shift key to modify the pressure.
- if SHIFT_FLAG & Window.GetKeyQualifiers():
- BRUSH_PRESSURE = -BRUSH_PRESSURE_ORIG
- else:
- BRUSH_PRESSURE = BRUSH_PRESSURE_ORIG
-
- brush_verts = [(v,le) for v in me.verts for le in ((v.co-best_isect).length,) if le < BRUSH_RADIUS]
-
- # SETUP ONCE ONLY VARIABLES
- if STATIC_NORMAL: # Only set the normal once.
- if not iFaceNormal:
- iFaceNormal = best_face.no
- else:
- if best_face:
- iFaceNormal = best_face.no
-
-
- if DISPLACE_NORMAL_MODE == 2: # MEDIAN NORMAL
- if (STATIC_NORMAL and medainNormal == None) or not STATIC_NORMAL:
- medainNormal = Vector(0,0,0)
- for v, l in brush_verts:
- medainNormal += v.no*(BRUSH_RADIUS-l)
- medainNormal.normalize()
-
-
- # ================================================================#
- # == Tool code, loop on the verts and operate on them ============#
- # ================================================================#
- if BRUSH_MODE == 1: # NORMAL PAINT
- for v,l in brush_verts:
- if XPLANE_CLIP:
- origx = False
- if abs(v.co.x) < 0.001: origx = True
-
-
- v.sel = 1 # MARK THE VERT AS DIRTY.
- falloff = (BRUSH_RADIUS-l) / BRUSH_RADIUS # falloff between 0 and 1
-
- if DISPLACE_NORMAL_MODE == 1: # VERTEX NORMAL
- if STATIC_NORMAL:
- try:
- no = vert_orig_normals[v]
- except:
- no = vert_orig_normals[v] = v.no
- v.co += (no * BRUSH_PRESSURE) * falloff
- else:
- v.co += (v.no * BRUSH_PRESSURE) * falloff
- elif DISPLACE_NORMAL_MODE == 2: # MEDIAN NORMAL # FIXME
- v.co += (medainNormal * BRUSH_PRESSURE) * falloff
- elif DISPLACE_NORMAL_MODE == 3: # FACE NORMAL
- v.co += (iFaceNormal * BRUSH_PRESSURE) * falloff
- elif DISPLACE_NORMAL_MODE == 4: # VIEW NORMAL
- v.co += (Direction * BRUSH_PRESSURE) * falloff
-
- # Clamp back to original x if needs be.
- if XPLANE_CLIP and origx:
- v.co.x = 0
-
- elif BRUSH_MODE == 2: # SCALE
- for v,l in brush_verts:
-
- if XPLANE_CLIP:
- origx = False
- if abs(v.co.x) < 0.001: origx = True
-
- v.sel = 1 # MARK THE VERT AS DIRTY.
- falloff = (BRUSH_RADIUS-l) / BRUSH_RADIUS # falloff between 0 and 1
-
- vert_scale_vec = v.co - best_isect
- vert_scale_vec.normalize()
- # falloff needs to be scaled for this tool
- falloff = falloff / 10
- v.co += (vert_scale_vec * BRUSH_PRESSURE) * falloff # FLAT BRUSH
-
- # Clamp back to original x if needs be.
- if XPLANE_CLIP and origx:
- v.co.x = 0
-
- if BRUSH_MODE == 3: # ROTATE.
-
- if DISPLACE_NORMAL_MODE == 1: # VERTEX NORMAL
- ROTATE_MATRIX = Mathutils.RotationMatrix(BRUSH_PRESSURE*10, 4, 'r', iFaceNormal) # Cant use vertex normal, use face normal
- elif DISPLACE_NORMAL_MODE == 2: # MEDIAN NORMAL
- ROTATE_MATRIX = Mathutils.RotationMatrix(BRUSH_PRESSURE*10, 4, 'r', medainNormal) # Cant use vertex normal, use face normal
- elif DISPLACE_NORMAL_MODE == 3: # FACE NORMAL
- ROTATE_MATRIX = Mathutils.RotationMatrix(BRUSH_PRESSURE*10, 4, 'r', iFaceNormal) # Cant use vertex normal, use face normal
- elif DISPLACE_NORMAL_MODE == 4: # VIEW NORMAL
- ROTATE_MATRIX = Mathutils.RotationMatrix(BRUSH_PRESSURE*10, 4, 'r', Direction) # Cant use vertex normal, use face normal
- # Brush code
-
- for v,l in brush_verts:
-
- if XPLANE_CLIP:
- origx = False
- if abs(v.co.x) < 0.001: origx = True
-
- # MARK THE VERT AS DIRTY.
- v.sel = 1
- falloff = (BRUSH_RADIUS-l) / BRUSH_RADIUS # falloff between 0 and 1
-
- # Vectors handeled with rotation matrix creation.
- rot_vert_loc = (ROTATE_MATRIX * (v.co-best_isect)) + best_isect
- v.co = (v.co*(1-falloff)) + (rot_vert_loc*(falloff))
-
- # Clamp back to original x if needs be.
- if XPLANE_CLIP and origx:
- v.co.x = 0
-
- elif BRUSH_MODE == 4: # RELAX
- vert_orig_loc = [Vector(v.co) for v in me.verts ] # save orig vert location.
- #vertOrigNor = [Vector(v.no) for v in me.verts ] # save orig vert location.
-
- # Brush code
- for v,l in brush_verts:
-
- if XPLANE_CLIP:
- origx = False
- if abs(v.co.x) < 0.001: origx = True
-
- v.sel = 1 # Mark the vert as dirty.
- falloff = (BRUSH_RADIUS-l) / BRUSH_RADIUS # falloff between 0 and 1
- connected_verts = verts_connected_by_edge[v.index]
- relax_point = reduce(lambda a,b: a + vert_orig_loc[b.index], connected_verts, Mathutils.Vector(0,0,0)) * (1.0/len(connected_verts))
- falloff = falloff * BRUSH_PRESSURE
- # Old relax.
- #v.co = (v.co*(1-falloff)) + (relax_point*(falloff))
-
- ll = (v.co-relax_point).length
- newpoint = (v.co*(1-falloff)) + (relax_point*(falloff)) - v.co
- newpoint = newpoint * (1/(1+ll))
- v.co = v.co + newpoint
-
- '''
- # New relax
- relax_normal = vertOrigNor[v.index]
- v1,v2,v3,v4 = v.co, v.co+relax_normal, relax_point-(relax_normal*10), relax_point+(relax_normal*10)
- print v1,v2,v3,v4
- try:
- a,b = LineIntersect(v1,v2,v3,v4) # Scale the normal to make a line. we know we will intersect with.
- v.co = (v.co*(1-falloff)) + (a*(falloff))
- except:
- pass
- '''
-
- # Clamp back to original x if needs be.
- if XPLANE_CLIP and origx:
- v.co.x = 0
-
- elif BRUSH_MODE == 5: # GOO
- #print last_best_isect, best_isect, 'AA'
- if not last_best_isect:
- last_best_isect = best_isect
-
- # Set up a triangle orthographic to the view plane
- gooPlane = [best_isect, CrossVecs(best_isect, Direction), None]
-
-
- if DISPLACE_NORMAL_MODE == 4: # View Normal
- tempRotMatrix = Mathutils.RotationMatrix(90, 3, 'r', Direction)
- else:
- tempRotMatrix = Mathutils.RotationMatrix(90, 3, 'r', CrossVecs(best_face.no, Direction))
-
- gooPlane[2] = best_isect + (tempRotMatrix * gooPlane[1])
- gooPlane[1] = gooPlane[1] + best_isect
-
- continue # we need another point of reference.
-
- elif last_best_isect == best_isect:
- # Mouse has not moved, no point in trying to goo.
- continue
- else:
- if goo_dir_vec:
- last_goo_dir_vec = goo_dir_vec
- # The direction the mouse moved in 3d space. use for gooing
-
- # Modify best_isect so its not moving allong the view z axis.
- # Assume Origin hasnt changed since the view wont change while the mouse is drawing. ATM.
- best_isect = Intersect( gooPlane[0], gooPlane[1], gooPlane[2], Direction, Origin, 0) # Non clipped
- goo_dir_vec = (best_isect - last_best_isect) * 2
-
-
- # make a goo rotation matrix so the head of the goo rotates with the mouse.
- """
- if last_goo_dir_vec and goo_dir_vec != last_goo_dir_vec:
- '''
- vmi = Matrix(Window.GetViewMatrix()); vmi.invert() # the inverse viewing matrix
- a = last_goo_dir_vec * vmi
- b = goo_dir_vec * vmi
- c = Angle2D(a.x, a.y, b.x, b.y)
- gooRotMatrix = Mathutils.RotationMatrix((c * goo_dir_vec.length)*-20, 3, 'r', Direction)
- '''
- pass
- else:
- gooRotMatrix = None
- """
-
- if goo_dir_vec.x == 0 and goo_dir_vec.y == 0 and goo_dir_vec.z == 0:
- continue
-
- # Brush code
- for v,l in brush_verts:
-
- if XPLANE_CLIP:
- origx = False
- if abs(v.co.x) < 0.001: origx = True
-
- # MARK THE VERT AS DIRTY.
- v.sel = 1
-
- ''' # ICICLES!!!
- a = AngleBetweenVecs(goo_dir_vec, v.no)
- if a > 66:
- continue
-
- l = l * ((1+a)/67.0)
- l = max(0.00000001, l)
- '''
-
- falloff = (BRUSH_RADIUS-l) / BRUSH_RADIUS # falloff between 0 and 1
- goo_loc = (v.co*(1-falloff)) + ((v.co+goo_dir_vec) *falloff)
-
- v.co = (goo_loc*BRUSH_PRESSURE) + (v.co*(1-BRUSH_PRESSURE))
-
- '''
- if gooRotMatrix:
- rotatedVertLocation = (gooRotMatrix * (v.co-best_isect)) + best_isect
- v.co = (v.co*(1-falloff)) + (rotatedVertLocation*(falloff))
- # USe for goo only.
- '''
-
- # Clamp back to original x if needs be.
- if XPLANE_CLIP and origx:
- v.co.x = 0
-
-
- # Remember for the next sample
- last_best_isect = best_isect
- last_goo_dir_vec = goo_dir_vec
-
- # Post processing after the verts have moved
- # Subdivide any large edges, all but relax.
-
- MAX_SUBDIV = 10 # Maximum number of subdivisions per redraw. makes things useable.
- SUBDIV_COUNT = 0
- if ADAPTIVE_GEOMETRY and (BRUSH_MODE == 1 or BRUSH_MODE == 2 or BRUSH_MODE == 3 or BRUSH_MODE == 5):
- orig_len_edges = 0
- #print 'ADAPTIVE_GEOMETRY'
- while len(me.edges) != orig_len_edges and SUBDIV_COUNT < MAX_SUBDIV:
- #print 'orig_len_edges', len(me.edges)
- #me = ob.getData(mesh=1)
- orig_len_edges = len(me.edges)
- EDGE_COUNT = 0
- for ed in me.edges:
- if ed.v1.sel or ed.v2.sel:
- l = (ed.v1.co - ed.v2.co).length
- #if l > RESOLUTION_MAX:
- if l > BRUSH_RADIUS:
- #print 'adding edge'
- ed.flag |= SEL_FLAG
- #ed.flag = 35
- SUBDIV_COUNT += 1
- EDGE_COUNT +=1
- """
- elif l < RESOLUTION_MIN:
- '''
- print 'removing edge'
- v1 =e.v1
- v2 =e.v2
- v1.co = v2.co = (v1.co + v2.co) * 0.5
- v1.sel = v2.sel = 1
- me.remDoubles(0.001)
- me = ob.getData(mesh=1)
- break
- '''
- # Remove edge in python
- print 'removing edge'
- v1 =ed.v1
- v2 =ed.v2
- v1.co = v2.co = (v1.co + v2.co) * 0.5
-
- removeDouble(v1, v2, me)
- me = ob.getData(mesh=1)
- break
- """
-
- if EDGE_COUNT:
- me.subdivide(1)
-
-
- # Deselect all, we know theres only 2 selected
- '''
- for ee in me.edges:
- if ee.flag & SEL_FLAG:
- #ee.flag &= ~SEL_FLAG
- ee.flag = 32
- elif l < RESOLUTION_MIN:
- print 'removing edge'
- e.v1.co = e.v2.co = (e.v1.co + e.v2.co) * 0.5
- me.remDoubles(0.001)
- break
- '''
- # Done subdividing
- # Now remove doubles
- #print Mesh.SelectModes['VERT']
- #Mesh.Mode(Mesh.SelectModes['VERTEX'])
-
- filter(lambda v: setattr(v, 'sel', 1), me.verts)
- filter(lambda v: setattr(v[0], 'sel', 0), brush_verts)
-
- # Cycling editmode is too slow.
-
- remdoubles = False
- for ed in me.edges:
-
- if (not ed.v1.sel) and (not ed.v1.sel):
- l = (ed.v1.co - ed.v2.co).length
- if l < RESOLUTION_MIN:
- ed.v1.sel = ed.v2.sel = 1
- newco = (ed.v1.co + ed.v2.co)*0.5
- ed.v1.co.x = ed.v2.co.x = newco.x
- ed.v1.co.y = ed.v2.co.y = newco.y
- ed.v1.co.z = ed.v2.co.z = newco.z
- remdoubles = True
-
- #if remdoubles:
-
-
- filter(lambda v: setattr(v, 'sel', 0), me.verts)
- #Mesh.Mode(Mesh.SelectModes['EDGE'])
- # WHILE OVER
- # Clean up selection.
- #for v in me.verts:
- # v.sel = 0
- '''
- for ee in me.edges:
- if ee.flag & SEL_FLAG:
- ee.flag &= ~SEL_FLAG
- #ee.flag = 32
- '''
- filter(lambda ed: setattr(ed, 'flag', 32), me.edges)
-
-
- if XPLANE_CLIP:
- filter(lambda v: setattr(v.co, 'x', max(0, v.co.x)), me.verts)
-
-
- me.update()
- #Window.SetCursorPos(best_isect.x, best_isect.y, best_isect.z)
- Window.Redraw(Window.Types.VIEW3D)
- #Window.DrawProgressBar(1.0, '')
- if STATIC_MESH:
- #try:
- mesh_static.verts = None
- print len(mesh_static.verts)
- mesh_static.update()
- #except:
- # pass
- if FIX_TOPOLOGY:
- fix_topolagy(me)
-
- Mesh.Mode(Mesh.SelectModes['VERTEX'])
- filter(lambda v: setattr(v, 'sel', 1), me.verts)
- me.remDoubles(0.001)
- print 'removing doubles'
- me = ob.getData(mesh=1) # Get new vert data
-
- Blender.event = Draw.LEFTMOUSE
-
- if i:
- Window.EditMode(1)
- if not is_editmode: # User was in edit mode, so stay there.
- Window.EditMode(0)
- print '100 draws in %.6f' % (((Blender.sys.time()-time) / float(i))*100)
-
-if __name__ == '__main__':
- event_main() \ No newline at end of file