forked from bartvdbraak/blender
Added a vertex gradient tool. got the ok from willian to add if its well tested, can do vertex gradient and weight gradient- uses __vertex_gradient__.py which manages to do both.
This commit is contained in:
parent
d13ad8fe94
commit
14a67d2a3c
243
release/scripts/__vertex_gradient__.py
Executable file
243
release/scripts/__vertex_gradient__.py
Executable file
@ -0,0 +1,243 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Weight Gradient...'
|
||||
Blender: 241
|
||||
Group: 'VertPaint'
|
||||
Tooltip: 'Grad.'
|
||||
"""
|
||||
|
||||
__author__ = ["Campbell Barton"]
|
||||
__url__ = ("blender", "elysiun", "http://members.iinet.net.au/~cpbarton/ideasman/")
|
||||
__version__ = "0.1"
|
||||
import Blender
|
||||
import BPyMesh
|
||||
import BPyWindow
|
||||
|
||||
|
||||
reload(BPyWindow)
|
||||
reload(BPyMesh)
|
||||
mouseViewRay= BPyWindow.mouseViewRay
|
||||
from Blender import Mathutils, Window, Scene, Draw, sys
|
||||
from Blender.Mathutils import CrossVecs, Vector, Intersect, LineIntersect, AngleBetweenVecs
|
||||
LMB= Window.MButs['L']
|
||||
|
||||
def mouseup():
|
||||
# Loop until click
|
||||
mouse_buttons = Window.GetMouseButtons()
|
||||
while not mouse_buttons & LMB:
|
||||
sys.sleep(10)
|
||||
mouse_buttons = Window.GetMouseButtons()
|
||||
while mouse_buttons & LMB:
|
||||
sys.sleep(10)
|
||||
mouse_buttons = Window.GetMouseButtons()
|
||||
|
||||
def mousedown_wait():
|
||||
# If the menu has just been pressed dont use its mousedown,
|
||||
mouse_buttons = Window.GetMouseButtons()
|
||||
while mouse_buttons & LMB:
|
||||
mouse_buttons = Window.GetMouseButtons()
|
||||
|
||||
eps= 0.0001
|
||||
def vertexGradientPick(ob, MODE):
|
||||
#MODE 0 == VWEIGHT, 1 == VCOL
|
||||
|
||||
me= ob.getData(mesh=1)
|
||||
if not me.faceUV: me.faceUV= True
|
||||
|
||||
Window.DrawProgressBar (0.0, '')
|
||||
|
||||
mousedown_wait()
|
||||
|
||||
if MODE==0:
|
||||
act_group= me.activeGroup
|
||||
if act_group == None:
|
||||
mousedown_wait()
|
||||
Draw.PupMenu('Error, mesh has no active group.')
|
||||
return
|
||||
|
||||
# Loop until click
|
||||
Window.DrawProgressBar (0.25, 'Click to set gradient start')
|
||||
mouseup()
|
||||
|
||||
obmat= ob.matrixWorld
|
||||
screen_x, screen_y = Window.GetMouseCoords()
|
||||
mouseInView, OriginA, DirectionA = mouseViewRay(screen_x, screen_y, obmat)
|
||||
if not mouseInView or not OriginA:
|
||||
return
|
||||
|
||||
# get the mouse weight
|
||||
|
||||
if MODE==0:
|
||||
pickValA= BPyMesh.pickMeshGroupWeight(me, act_group, OriginA, DirectionA)
|
||||
if MODE==1:
|
||||
pickValA= BPyMesh.pickMeshGroupVCol(me, OriginA, DirectionA)
|
||||
|
||||
Window.DrawProgressBar (0.75, 'Click to set gradient end')
|
||||
mouseup()
|
||||
|
||||
TOALPHA= Window.GetKeyQualifiers() & Window.Qual.SHIFT
|
||||
|
||||
screen_x, screen_y = Window.GetMouseCoords()
|
||||
mouseInView, OriginB, DirectionB = mouseViewRay(screen_x, screen_y, obmat)
|
||||
if not mouseInView or not OriginB:
|
||||
return
|
||||
|
||||
if not TOALPHA: # Only get a second opaque value if we are not blending to alpha
|
||||
if MODE==0: pickValB= BPyMesh.pickMeshGroupWeight(me, act_group, OriginB, DirectionB)
|
||||
else:
|
||||
pickValB= BPyMesh.pickMeshGroupVCol(me, OriginB, DirectionB)
|
||||
else:
|
||||
if MODE==0: pickValB= 0.0
|
||||
else: pickValB= [0.0, 0.0, 0.0] # Dummy value
|
||||
|
||||
# Neither points touched a face
|
||||
if pickValA == pickValB == None:
|
||||
return
|
||||
|
||||
# clicking on 1 non face is fine. just set the weight to 0.0
|
||||
if pickValA==None:
|
||||
pickValA= 0.0
|
||||
|
||||
# swap A/B
|
||||
OriginA, OriginB= OriginB, OriginA
|
||||
DirectionA, DirectionB= DirectionB, DirectionA
|
||||
pickValA, pickValB= pickValA, pickValB
|
||||
|
||||
TOALPHA= True
|
||||
|
||||
if pickValB==None:
|
||||
pickValB= 0.0
|
||||
TOALPHA= True
|
||||
|
||||
|
||||
# set up 2 lines so we can measure their distances and calc the gradient
|
||||
|
||||
# make a line 90d to the grad in screenspace.
|
||||
if (OriginA-OriginB).length <= eps: # Persp view. same origin different direction
|
||||
cross_grad= CrossVecs(DirectionA, DirectionB)
|
||||
ORTHO= False
|
||||
|
||||
else: # Ortho - Same direction, different origin
|
||||
cross_grad= CrossVecs(DirectionA, OriginA-OriginB)
|
||||
ORTHO= True
|
||||
|
||||
cross_grad= cross_grad.normalize() * 100
|
||||
|
||||
lineA= (OriginA, OriginA+(DirectionA*100))
|
||||
lineB= (OriginB, OriginB+(DirectionB*100))
|
||||
|
||||
if not ORTHO:
|
||||
line_angle= AngleBetweenVecs(lineA[1], lineB[1])/2
|
||||
line_mid= (lineA[1]+lineB[1])*0.5
|
||||
|
||||
FSEL= Blender.Mesh.FaceFlags.SELECT
|
||||
|
||||
VSEL= [False] * (len(me.verts))
|
||||
|
||||
# Get the selected faces and apply the selection to the verts.
|
||||
for f in me.faces:
|
||||
if f.flag & FSEL:
|
||||
for v in f.v:
|
||||
VSEL[v.index]= True
|
||||
groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
|
||||
|
||||
|
||||
|
||||
def grad_weight_from_co(v):
|
||||
'''
|
||||
Takes a vert and retuens its gradient radio between A and B
|
||||
'''
|
||||
|
||||
if not VSEL[v.index]: # Not bart of a selected face?
|
||||
return None, None
|
||||
|
||||
v_co= v.co
|
||||
# make a line 90d to the 2 lines the user clicked.
|
||||
vert_line= (v_co - cross_grad, v_co + cross_grad)
|
||||
|
||||
xA= LineIntersect(vert_line[0], vert_line[1], lineA[0], lineA[1])
|
||||
xB= LineIntersect(vert_line[0], vert_line[1], lineB[0], lineB[1])
|
||||
|
||||
if not xA or not xB: # Should never happen but support it anyhow
|
||||
return None, None
|
||||
|
||||
wA= (xA[0]-xA[1]).length
|
||||
wB= (xB[0]-xB[1]).length
|
||||
|
||||
wTot= wA+wB
|
||||
if not wTot: # lines are on the same point.
|
||||
return None, None
|
||||
|
||||
'''
|
||||
Get the length of the line between both intersections on the
|
||||
2x view lines.
|
||||
if the dist between lineA+VertLine and lineB+VertLine is
|
||||
greater then the lenth between lineA and lineB intersection points, it means
|
||||
that the verts are not inbetween the 2 lines.
|
||||
'''
|
||||
lineAB_length= (xA[1]-xB[1]).length
|
||||
|
||||
# normalzie
|
||||
wA= wA/wTot
|
||||
wB= wB/wTot
|
||||
|
||||
if ORTHO: # Con only use line length method with parelelle lines
|
||||
if wTot > lineAB_length+eps:
|
||||
# vert is outside the range on 1 side. see what side of the grad
|
||||
if wA>wB: wA, wB= 1.0, 0.0
|
||||
else: wA, wB= 0.0, 1.0
|
||||
else:
|
||||
# PERSP, lineA[0] is the same origin as lineB[0]
|
||||
|
||||
# Either xA[0] or xB[0] can be used instead of a possible x_mid between the 2
|
||||
# as long as the point is inbetween lineA and lineB it dosent matter.
|
||||
a= AngleBetweenVecs(lineA[0]-xA[0], line_mid)
|
||||
if a>line_angle:
|
||||
# vert is outside the range on 1 side. see what side of the grad
|
||||
if wA>wB: wA, wB= 1.0, 0.0
|
||||
else: wA, wB= 0.0, 1.0
|
||||
|
||||
return wA, wB
|
||||
|
||||
|
||||
grad_weights= [grad_weight_from_co(v) for v in me.verts]
|
||||
|
||||
|
||||
if MODE==0:
|
||||
for v in me.verts:
|
||||
i= v.index
|
||||
if VSEL[i]:
|
||||
wA, wB = grad_weights[i]
|
||||
if wA != None: # and wB
|
||||
if TOALPHA:
|
||||
# Do alpha by using the exiting weight for
|
||||
try: pickValB= vWeightDict[i][act_group]
|
||||
except: pickValB= 0.0 # The weights not there? assume zero
|
||||
# Mix2 2 opaque weights
|
||||
vWeightDict[i][act_group]= pickValB*wA + pickValA*wB
|
||||
|
||||
else: # MODE==1 VCol
|
||||
for f in me.faces:
|
||||
if f.flag & FSEL:
|
||||
f_v= f.v
|
||||
for i in xrange(len(f_v)):
|
||||
v= f_v[i]
|
||||
wA, wB = grad_weights[v.index]
|
||||
|
||||
c= f.col[i]
|
||||
|
||||
if TOALPHA:
|
||||
pickValB= c.r, c.g, c.b
|
||||
|
||||
c.r = int(pickValB[0]*wA + pickValA[0]*wB)
|
||||
c.g = int(pickValB[1]*wA + pickValA[1]*wB)
|
||||
c.b = int(pickValB[2]*wA + pickValA[2]*wB)
|
||||
|
||||
|
||||
|
||||
|
||||
# Copy weights back to the mesh.
|
||||
BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
|
||||
Window.DrawProgressBar (1.0, '')
|
||||
|
||||
|
29
release/scripts/vertpaint_gradient_stub.py
Executable file
29
release/scripts/vertpaint_gradient_stub.py
Executable file
@ -0,0 +1,29 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'VCol Gradient...'
|
||||
Blender: 241
|
||||
Group: 'VertexPaint'
|
||||
Tooltip: 'Click on the start and end grad points for the mesh for selected faces.'
|
||||
"""
|
||||
|
||||
__author__ = ["Campbell Barton"]
|
||||
__url__ = ("blender", "elysiun", "http://members.iinet.net.au/~cpbarton/ideasman/")
|
||||
__version__ = "0.1"
|
||||
|
||||
import __vertex_gradient__
|
||||
reload(__vertex_gradient__)
|
||||
import Blender
|
||||
|
||||
def main():
|
||||
scn= Blender.Scene.GetCurrent()
|
||||
ob= scn.getActiveObject()
|
||||
|
||||
if not ob or ob.getType() != 'Mesh':
|
||||
Blender.Draw.PupMenu('Error, no active mesh object, aborting.')
|
||||
return
|
||||
|
||||
__vertex_gradient__.vertexGradientPick(ob, 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
42
release/scripts/weightpaint_gradient_stub.py
Executable file
42
release/scripts/weightpaint_gradient_stub.py
Executable file
@ -0,0 +1,42 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Weight Gradient...'
|
||||
Blender: 241
|
||||
Group: 'WeightPaint'
|
||||
Tooltip: 'Click on the start and end grad points for the mesh for selected faces.'
|
||||
"""
|
||||
|
||||
__author__ = ["Campbell Barton"]
|
||||
__url__ = ("blender", "elysiun", "http://members.iinet.net.au/~cpbarton/ideasman/")
|
||||
__version__ = "0.1"
|
||||
__bpydoc__=\
|
||||
'''
|
||||
This script is used to fill the selected faces with a gradient
|
||||
To use the script, switch to "Face Select" mode then "Vertex Paint" mode
|
||||
Select the faces you wish to apply the gradient to.
|
||||
Click twice on the mesh to set the start and end points of the gradient.
|
||||
The color under the mouse will be used for the start and end blend colors.
|
||||
Note:
|
||||
Holding Shift or clicking outside the mesh on the second click will blend the first colour to nothing.
|
||||
'''
|
||||
|
||||
import __vertex_gradient__
|
||||
reload(__vertex_gradient__)
|
||||
import Blender
|
||||
|
||||
def main():
|
||||
scn= Blender.Scene.GetCurrent()
|
||||
ob= scn.getActiveObject()
|
||||
|
||||
if not ob or ob.getType() != 'Mesh':
|
||||
Blender.Draw.PupMenu('Error, no active mesh object, aborting.')
|
||||
return
|
||||
# MODE 0 == VCOL
|
||||
# MODE 1 == WEIGHT
|
||||
MODE= 0
|
||||
__vertex_gradient__.vertexGradientPick(ob, MODE)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
Loading…
Reference in New Issue
Block a user