removing uvcalc_from_adjacent for review on Sunday's meeting.
image_dump2path is a stopgap util. We need to look into making Pack/Unpack use filenames, not IDnames. or have some other datamanagement utility.
This commit is contained in:
@@ -1,137 +0,0 @@
|
|||||||
#!BPY
|
|
||||||
"""
|
|
||||||
Name: 'Dump All Images to Path'
|
|
||||||
Blender: 242
|
|
||||||
Group: 'Image'
|
|
||||||
Tooltip: 'Copy and reference all images to a new path.'
|
|
||||||
"""
|
|
||||||
__author__= "Campbell Barton"
|
|
||||||
__url__= ["blender.org", "blenderartists.org"]
|
|
||||||
__version__= "1.0"
|
|
||||||
|
|
||||||
__bpydoc__= """
|
|
||||||
|
|
||||||
This script copies all the images used by 1 blend to a spesified path and references the new images from Blender
|
|
||||||
Usefull for moving projects between computers or when you reference many images. naming collisions and multiple images using the same image path are delt with properly only creating new image names when needed.
|
|
||||||
|
|
||||||
Blender images will reference the newly copied files - So be mindfull when you save your blend after running the script.
|
|
||||||
|
|
||||||
Notes, images with the path "Untitled will be ignored"
|
|
||||||
|
|
||||||
Image path collisions are managed by enumerating the path names so images will never be overwritten at the target path.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from Blender import Image, sys, Draw, Window
|
|
||||||
import BPyMessages
|
|
||||||
|
|
||||||
def copy_file(srcpath, destpath):
|
|
||||||
f=open(srcpath, 'rb')
|
|
||||||
data= f.read()
|
|
||||||
f.close()
|
|
||||||
f= open(destpath, 'wb')
|
|
||||||
f.write(data)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# Makes the pathe relative to the blend file path.
|
|
||||||
def makeRelative(path, blendBasePath):
|
|
||||||
if path.startswith(blendBasePath):
|
|
||||||
path = path.replace(blendBasePath, '//')
|
|
||||||
path = path.replace('//\\', '//')
|
|
||||||
return path
|
|
||||||
|
|
||||||
def makeUnique(path):
|
|
||||||
|
|
||||||
if not sys.exists(path):
|
|
||||||
return path
|
|
||||||
|
|
||||||
orig_path = path
|
|
||||||
orig_path_noext, ext= sys.splitext(path)
|
|
||||||
|
|
||||||
i= 1
|
|
||||||
while sys.exists(path):
|
|
||||||
path = '%s_%.3d%s' % (orig_path_noext, i, ext)
|
|
||||||
i+= 1
|
|
||||||
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
#images= [(img, img.name, sys.expandpath(img.filename)) for img in Image.Get() if img.filename != 'Untitled' and img.name not in ("Render Result", "Compositor")]
|
|
||||||
|
|
||||||
# remove double paths so we dont copy twice
|
|
||||||
image_dict= {}
|
|
||||||
image_missing = []
|
|
||||||
|
|
||||||
|
|
||||||
# Make a dict of images with thir file name as a key
|
|
||||||
for img in Image.Get():
|
|
||||||
name= img.name
|
|
||||||
filename= sys.expandpath(img.filename)
|
|
||||||
|
|
||||||
if filename== 'Untitled' or name == "Render Result" or name == "Compositor":
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not sys.exists(filename):
|
|
||||||
#continue # ignore missing images.
|
|
||||||
image_missing.append(name)
|
|
||||||
|
|
||||||
|
|
||||||
try: image_dict[filename].append(img)
|
|
||||||
except: image_dict[filename]= [img]
|
|
||||||
|
|
||||||
|
|
||||||
if image_missing:
|
|
||||||
ret= Draw.PupMenu( 'Aborting, Image file(s) missing%t|' + '|'.join(image_missing) )
|
|
||||||
if ret != -1:
|
|
||||||
Image.Get(image_missing[ret-1]).makeCurrent()
|
|
||||||
return
|
|
||||||
|
|
||||||
# Chech done - select a dir
|
|
||||||
def dump_images(dump_path):
|
|
||||||
|
|
||||||
tot = len(image_dict)
|
|
||||||
count = 0
|
|
||||||
|
|
||||||
print 'starting the image dump'
|
|
||||||
|
|
||||||
dump_path = sys.dirname(dump_path)
|
|
||||||
base_blen_path = sys.expandpath('//')
|
|
||||||
|
|
||||||
if BPyMessages.Error_NoDir(dump_path): return
|
|
||||||
|
|
||||||
# ahh now were free to copy the images.
|
|
||||||
for filename, imgs in image_dict.iteritems():
|
|
||||||
count +=1
|
|
||||||
file= filename.split('\\')[-1].split('/')[-1]
|
|
||||||
new_filename= makeUnique( sys.join(dump_path, file) )
|
|
||||||
|
|
||||||
print ' copying image "%s" %d of %d' % (dump_path, count, tot)
|
|
||||||
print ' source path:', filename
|
|
||||||
print ' target path:', new_filename
|
|
||||||
|
|
||||||
copy_fail= False
|
|
||||||
try:
|
|
||||||
copy_file( filename, new_filename)
|
|
||||||
except:
|
|
||||||
copy_fail = True
|
|
||||||
|
|
||||||
if copy_fail or sys.exists(new_filename)==0:
|
|
||||||
print '\tERROR could not copy the file above!'
|
|
||||||
Draw.PupMenu('Error%t|Copy Failed, do not save this Blend file|"' + filename + '", see console for details.')
|
|
||||||
return
|
|
||||||
|
|
||||||
# account for
|
|
||||||
for img in imgs:
|
|
||||||
img.filename = makeRelative(new_filename, base_blen_path)
|
|
||||||
|
|
||||||
msg= 'Relinking %d images done' % len(image_dict)
|
|
||||||
Draw.PupMenu(msg)
|
|
||||||
|
|
||||||
Window.RedrawAll()
|
|
||||||
|
|
||||||
print 'done'
|
|
||||||
|
|
||||||
Window.FileSelector(dump_images, 'IMG DUMP DIR', '')
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
130
release/scripts/uvcalc_from_adjacent.py
Normal file
130
release/scripts/uvcalc_from_adjacent.py
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#!BPY
|
||||||
|
"""
|
||||||
|
Name: 'UVs from unselected adjacent'
|
||||||
|
Blender: 242
|
||||||
|
Group: 'UVCalculation'
|
||||||
|
Tooltip: 'Assign UVs to selected faces from surrounding unselected faces.'
|
||||||
|
"""
|
||||||
|
__author__ = "Campbell Barton"
|
||||||
|
__url__ = ("blender", "elysiun")
|
||||||
|
__version__ = "1.0 2006/02/07"
|
||||||
|
|
||||||
|
__bpydoc__ = """\
|
||||||
|
This script sets the UV mapping and image of selected faces from adjacent unselected faces.
|
||||||
|
|
||||||
|
Use this script in face select mode for texturing between textured faces.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
# Script copyright (C) Campbell J Barton
|
||||||
|
#
|
||||||
|
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# ***** END GPL LICENCE BLOCK *****
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
from Blender import *
|
||||||
|
|
||||||
|
|
||||||
|
def mostUsedImage(imageList): # Returns the image most used in the list.
|
||||||
|
if not imageList:
|
||||||
|
return None
|
||||||
|
elif len(imageList) < 3:
|
||||||
|
return imageList[0]
|
||||||
|
|
||||||
|
# 3+ Images, Get the most used image for surrounding faces.
|
||||||
|
imageCount = {}
|
||||||
|
for image in imageList:
|
||||||
|
if image:
|
||||||
|
image_key= image.name
|
||||||
|
else:
|
||||||
|
image_key = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
imageCount[image_key]['imageCount'] +=1 # an extra user of this image
|
||||||
|
except:
|
||||||
|
imageCount[image_key] = {'imageCount':1, 'blenderImage':image} # start with 1 user.
|
||||||
|
|
||||||
|
# Now a list of tuples, (imageName, {imageCount, image})
|
||||||
|
imageCount = imageCount.items()
|
||||||
|
|
||||||
|
try: imageCount.sort(key=lambda a: a[1])
|
||||||
|
except: imageCount.sort(lambda a,b: cmp(a[1], b[1]))
|
||||||
|
|
||||||
|
|
||||||
|
return imageCount[-1][1]['blenderImage']
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
scn = Scene.GetCurrent()
|
||||||
|
ob = scn.objects.active
|
||||||
|
if ob == None or ob.type != 'Mesh':
|
||||||
|
Draw.PupMenu('ERROR: No mesh object in face select mode.')
|
||||||
|
return
|
||||||
|
me = ob.getData(mesh=1)
|
||||||
|
|
||||||
|
if not me.faceUV:
|
||||||
|
Draw.PupMenu('ERROR: No mesh object in face select mode.')
|
||||||
|
return
|
||||||
|
SEL_FLAG = Mesh.FaceFlags['SELECT']
|
||||||
|
selfaces = [f for f in me.faces if f.flag & SEL_FLAG]
|
||||||
|
unselfaces = [f for f in me.faces if not f.flag & SEL_FLAG]
|
||||||
|
|
||||||
|
|
||||||
|
# Gather per Vert UV and Image, store in vertUvAverage
|
||||||
|
vertUvAverage = [[[],[]] for i in xrange(len(me.verts))]
|
||||||
|
|
||||||
|
for f in unselfaces: # Unselected faces only.
|
||||||
|
fuv = f.uv
|
||||||
|
for i,v in enumerate(f):
|
||||||
|
vertUvAverage[v.index][0].append(fuv[i])
|
||||||
|
vertUvAverage[v.index][1].append(f.image)
|
||||||
|
|
||||||
|
# Average per vectex UV coords
|
||||||
|
for vertUvData in vertUvAverage:
|
||||||
|
uvList = vertUvData[0]
|
||||||
|
if uvList:
|
||||||
|
# Convert from a list of vectors into 1 vector.
|
||||||
|
vertUvData[0] = reduce(lambda a,b: a+b, uvList, Mathutils.Vector(0,0)) * (1.0/len(uvList))
|
||||||
|
else:
|
||||||
|
vertUvData[0] = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Assign to selected faces
|
||||||
|
TEX_FLAG = Mesh.FaceModes['TEX']
|
||||||
|
for f in selfaces:
|
||||||
|
uvlist = []
|
||||||
|
imageList = []
|
||||||
|
for i,v in enumerate(f):
|
||||||
|
uv, vImages = vertUvAverage[v.index]
|
||||||
|
uvlist.append( uv )
|
||||||
|
imageList.extend(vImages)
|
||||||
|
|
||||||
|
if None not in uvlist:
|
||||||
|
# all the faces images used by this faces vert. some faces will be added twice but thats ok.
|
||||||
|
# Get the most used image and assign to the face.
|
||||||
|
image = mostUsedImage(imageList)
|
||||||
|
f.uv = uvlist
|
||||||
|
|
||||||
|
if image:
|
||||||
|
f.image = image
|
||||||
|
f.mode |= TEX_FLAG
|
||||||
|
Window.RedrawAll()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
#!BPY
|
|
||||||
|
|
||||||
""" Registration info for Blender menus: <- these words are ignored
|
|
||||||
Name: 'Click project from face'
|
|
||||||
Blender: 242
|
|
||||||
Group: 'UVCalculation'
|
|
||||||
Tooltip: '3 Clicks to project uvs onto selected faces.'
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = ["Campbell Barton"]
|
|
||||||
__url__ = ("blender", "elysiun", "http://members.iinet.net.au/~cpbarton/ideasman/")
|
|
||||||
__version__ = "0.1"
|
|
||||||
__bpydoc__=\
|
|
||||||
'''
|
|
||||||
http://mediawiki.blender.org/index.php/Scripts/Manual/UV_Calculate/Click_project_from_face
|
|
||||||
"
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
# Click project v0.1 by Campbell Barton (AKA Ideasman)
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
|
||||||
# ***** END GPL LICENCE BLOCK *****
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
import Blender
|
|
||||||
import BPyMesh
|
|
||||||
import BPyWindow
|
|
||||||
|
|
||||||
mouseViewRay= BPyWindow.mouseViewRay
|
|
||||||
from Blender import Mathutils, Window, Scene, Draw, sys
|
|
||||||
from Blender.Mathutils import CrossVecs, Vector, Matrix, LineIntersect, Intersect #, AngleBetweenVecs, Intersect
|
|
||||||
LMB= Window.MButs['L']
|
|
||||||
RMB= Window.MButs['R']
|
|
||||||
|
|
||||||
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()
|
|
||||||
sys.sleep(10)
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
scn = Scene.GetCurrent()
|
|
||||||
ob = scn.objects.active
|
|
||||||
if not ob or ob.type!='Mesh':
|
|
||||||
return
|
|
||||||
|
|
||||||
mousedown_wait() # so the menu items clicking dosnt trigger the mouseclick
|
|
||||||
|
|
||||||
Window.DrawProgressBar (0.0, '')
|
|
||||||
Window.DrawProgressBar (0.1, '(1 of 3) Click on a face corner')
|
|
||||||
|
|
||||||
# wait for a click
|
|
||||||
mouse_buttons = Window.GetMouseButtons()
|
|
||||||
while not mouse_buttons & LMB:
|
|
||||||
sys.sleep(10)
|
|
||||||
mouse_buttons = Window.GetMouseButtons()
|
|
||||||
|
|
||||||
# Allow for RMB cancel
|
|
||||||
if mouse_buttons & RMB:
|
|
||||||
Window.DrawProgressBar (1.0, '')
|
|
||||||
return
|
|
||||||
|
|
||||||
while mouse_buttons & LMB:
|
|
||||||
sys.sleep(10)
|
|
||||||
mouse_buttons = Window.GetMouseButtons()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Window.DrawProgressBar (0.2, '(2 of 3 ) Click confirms the U coords')
|
|
||||||
|
|
||||||
|
|
||||||
mousedown_wait()
|
|
||||||
|
|
||||||
obmat= ob.matrixWorld
|
|
||||||
screen_x, screen_y = Window.GetMouseCoords()
|
|
||||||
mouseInView, OriginA, DirectionA = mouseViewRay(screen_x, screen_y, obmat)
|
|
||||||
|
|
||||||
if not mouseInView or not OriginA:
|
|
||||||
Window.DrawProgressBar (1.0, '')
|
|
||||||
return
|
|
||||||
|
|
||||||
me = ob.getData(mesh=1)
|
|
||||||
|
|
||||||
# Get the face under the mouse
|
|
||||||
face_click, isect, side = BPyMesh.pickMeshRayFace(me, OriginA, DirectionA)
|
|
||||||
|
|
||||||
proj_z_component = face_click.no
|
|
||||||
if not face_click:
|
|
||||||
Window.DrawProgressBar (1.0, '')
|
|
||||||
return
|
|
||||||
|
|
||||||
# Find the face vertex thats closest to the mouse,
|
|
||||||
# this vert will be used as the corner to map from.
|
|
||||||
best_v= None
|
|
||||||
best_length = 10000000
|
|
||||||
vi1 = None
|
|
||||||
for i, v in enumerate(face_click.v):
|
|
||||||
l = (v.co-isect).length
|
|
||||||
if l < best_length:
|
|
||||||
best_v = v
|
|
||||||
best_length = l
|
|
||||||
vi1 = i
|
|
||||||
|
|
||||||
# now get the 2 edges in the face that connect to v
|
|
||||||
# we can work it out fairly easerly
|
|
||||||
if len(face_click)==4:
|
|
||||||
if vi1==0: vi2, vi3= 3,1
|
|
||||||
elif vi1==1: vi2, vi3= 0,2
|
|
||||||
elif vi1==2: vi2, vi3= 1,3
|
|
||||||
elif vi1==3: vi2, vi3= 2,0
|
|
||||||
else:
|
|
||||||
if vi1==0: vi2, vi3= 2,1
|
|
||||||
elif vi1==1: vi2, vi3= 0,2
|
|
||||||
elif vi1==2: vi2, vi3= 1,0
|
|
||||||
|
|
||||||
face_corner_main =face_click.v[vi1].co
|
|
||||||
face_corner_a =face_click.v[vi2].co
|
|
||||||
face_corner_b =face_click.v[vi3].co
|
|
||||||
|
|
||||||
line_a_len = (face_corner_a-face_corner_main).length
|
|
||||||
line_b_len = (face_corner_b-face_corner_main).length
|
|
||||||
|
|
||||||
orig_cursor = Window.GetCursorPos()
|
|
||||||
Window.SetCursorPos(face_corner_main.x, face_corner_main.y, face_corner_main.z)
|
|
||||||
|
|
||||||
SHIFT = Window.Qual.SHIFT
|
|
||||||
MODE = 0 # firstclick, 1, secondclick
|
|
||||||
mouse_buttons = Window.GetMouseButtons()
|
|
||||||
|
|
||||||
project_mat = Matrix([0,0,0], [0,0,0], [0,0,0])
|
|
||||||
|
|
||||||
|
|
||||||
SELECT_FLAG = Blender.Mesh.FaceFlags['SELECT']
|
|
||||||
|
|
||||||
def get_face_coords(f):
|
|
||||||
f_uv = f.uv
|
|
||||||
return [(v.co-face_corner_main, f_uv[i]) for i,v in enumerate(f.v)]
|
|
||||||
|
|
||||||
coords = [ (co,uv) for f in me.faces if f.flag & SELECT_FLAG for co, uv in get_face_coords(f)]
|
|
||||||
del SELECT_FLAG
|
|
||||||
|
|
||||||
coords_orig = [uv.copy() for co, uv in coords]
|
|
||||||
|
|
||||||
while 1:
|
|
||||||
if mouse_buttons & LMB:
|
|
||||||
if MODE == 0:
|
|
||||||
mousedown_wait()
|
|
||||||
Window.DrawProgressBar (0.8, '(3 of 3 ) Click confirms the V coords')
|
|
||||||
MODE = 1 # second click
|
|
||||||
|
|
||||||
# Se we cont continually set the length and get float error
|
|
||||||
proj_y_component_orig = proj_y_component.copy()
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
elif mouse_buttons & RMB:
|
|
||||||
# Restore old uvs
|
|
||||||
for i, uv_orig in enumerate(coords_orig):
|
|
||||||
coords[i][1][:] = uv_orig
|
|
||||||
break
|
|
||||||
|
|
||||||
mouse_buttons = Window.GetMouseButtons()
|
|
||||||
screen_x, screen_y = Window.GetMouseCoords()
|
|
||||||
mouseInView, OriginA, DirectionA = mouseViewRay(screen_x, screen_y, obmat)
|
|
||||||
|
|
||||||
if not mouseInView:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Do a ray tri intersection, not clipped by the tri
|
|
||||||
new_isect = Intersect(face_corner_main, face_corner_a, face_corner_b, DirectionA, OriginA, False)
|
|
||||||
new_isect_alt = new_isect + DirectionA*0.0001
|
|
||||||
|
|
||||||
|
|
||||||
# The distance from the mouse cursor ray vector to the edge
|
|
||||||
line_isect_a_pair = LineIntersect(new_isect, new_isect_alt, face_corner_main, face_corner_a)
|
|
||||||
line_isect_b_pair = LineIntersect(new_isect, new_isect_alt, face_corner_main, face_corner_b)
|
|
||||||
|
|
||||||
# SHIFT to flip the axis.
|
|
||||||
is_shift = Window.GetKeyQualifiers() & SHIFT
|
|
||||||
|
|
||||||
if MODE == 0:
|
|
||||||
line_dist_a = (line_isect_a_pair[0]-line_isect_a_pair[1]).length
|
|
||||||
line_dist_b = (line_isect_b_pair[0]-line_isect_b_pair[1]).length
|
|
||||||
|
|
||||||
if line_dist_a < line_dist_b:
|
|
||||||
proj_x_component = face_corner_a - face_corner_main
|
|
||||||
y_axis_length = line_b_len
|
|
||||||
x_axis_length = (line_isect_a_pair[1]-face_corner_main).length
|
|
||||||
else:
|
|
||||||
proj_x_component = face_corner_b - face_corner_main
|
|
||||||
y_axis_length = line_a_len
|
|
||||||
x_axis_length = (line_isect_b_pair[1]-face_corner_main).length
|
|
||||||
|
|
||||||
proj_y_component = CrossVecs(proj_x_component, proj_z_component)
|
|
||||||
|
|
||||||
proj_y_component.length = 1/y_axis_length
|
|
||||||
proj_x_component.length = 1/x_axis_length
|
|
||||||
|
|
||||||
if is_shift: proj_x_component.negate()
|
|
||||||
|
|
||||||
else:
|
|
||||||
proj_y_component[:] = proj_y_component_orig
|
|
||||||
if line_dist_a < line_dist_b:
|
|
||||||
proj_y_component.length = 1/(line_isect_a_pair[1]-new_isect).length
|
|
||||||
else:
|
|
||||||
proj_y_component.length = 1/(line_isect_b_pair[1]-new_isect).length
|
|
||||||
|
|
||||||
if is_shift: proj_y_component.negate()
|
|
||||||
|
|
||||||
# Use the existing matrix to make a new 3x3 projecton matrix
|
|
||||||
project_mat[0][:] = -proj_y_component
|
|
||||||
project_mat[1][:] = -proj_x_component
|
|
||||||
project_mat[2][:] = proj_z_component
|
|
||||||
|
|
||||||
# Apply the projection matrix
|
|
||||||
for proj_co, uv in coords:
|
|
||||||
uv[:] = (project_mat * proj_co)[0:2]
|
|
||||||
|
|
||||||
Window.Redraw(Window.Types.VIEW3D)
|
|
||||||
|
|
||||||
Window.DrawProgressBar (1.0, '')
|
|
||||||
Window.SetCursorPos(*orig_cursor)
|
|
||||||
Window.RedrawAll()
|
|
||||||
|
|
||||||
if __name__=='__main__':
|
|
||||||
main()
|
|
||||||
1164
release/scripts/uvcalc_smart_project.py
Normal file
1164
release/scripts/uvcalc_smart_project.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user