diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-09-28 07:19:52 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-09-28 07:19:52 +0400 |
commit | 2d797f35d804fd86ef079b30f2c83a81a8e38cd5 (patch) | |
tree | f3354beea96c83a39c5d89d291d4429c8a69ec22 /release/scripts/bpymodules | |
parent | 0cbc87b42816711469cb63825ee826a837cc364a (diff) |
- removed 2.4x release/scripts
- moved release/io and release/ui into release/scripts/io, ui
- updated scons, cmake, make
When porting 2.4x scripts back, use a command like this so as not to loose the commit history...
svn cp https://svn.blender.org/svnroot/bf-blender/branches/blender2.4/release/scripts/raw_import.py release/scripts/io/import_raw.py
Diffstat (limited to 'release/scripts/bpymodules')
27 files changed, 0 insertions, 11296 deletions
diff --git a/release/scripts/bpymodules/BPyAddMesh.py b/release/scripts/bpymodules/BPyAddMesh.py deleted file mode 100644 index 901e68866cc..00000000000 --- a/release/scripts/bpymodules/BPyAddMesh.py +++ /dev/null @@ -1,159 +0,0 @@ -import Blender -from Blender.Window import EditMode, GetCursorPos, GetViewQuat -import bpy -import BPyMessages - -def add_mesh_simple(name, verts, edges, faces): - ''' - Adds a mesh from verts, edges and faces - - name - new object/mesh name - verts - list of 3d vectors - edges - list of int pairs - faces - list of int triplets/quads - ''' - - scn = bpy.data.scenes.active - if scn.lib: return - ob_act = scn.objects.active - - is_editmode = EditMode() - - cursor = GetCursorPos() - quat = None - if is_editmode or Blender.Get('add_view_align'): # Aligning seems odd for editmode, but blender does it, oh well - try: quat = Blender.Mathutils.Quaternion(GetViewQuat()) - except: pass - - # Exist editmode for non mesh types - if ob_act and ob_act.type != 'Mesh' and is_editmode: - EditMode(0) - - # We are in mesh editmode - if EditMode(): - me = ob_act.getData(mesh=1) - - if me.multires: - BPyMessages.Error_NoMeshMultiresEdit() - return - - # Add to existing mesh - # must exit editmode to modify mesh - EditMode(0) - - me.sel = False - - vert_offset = len(me.verts) - edge_offset = len(me.edges) - face_offset = len(me.faces) - - # transform the verts - txmat = Blender.Mathutils.TranslationMatrix(Blender.Mathutils.Vector(cursor)) - if quat: - mat = quat.toMatrix() - mat.invert() - mat.resize4x4() - txmat = mat * txmat - - txmat = txmat * ob_act.matrixWorld.copy().invert() - - - me.verts.extend(verts) - # Transform the verts by the cursor and view rotation - me.transform(txmat, selected_only=True) - - if vert_offset: - me.edges.extend([[i+vert_offset for i in e] for e in edges]) - me.faces.extend([[i+vert_offset for i in f] for f in faces]) - else: - # Mesh with no data, unlikely - me.edges.extend(edges) - me.faces.extend(faces) - else: - - # Object mode add new - - me = bpy.data.meshes.new(name) - me.verts.extend(verts) - me.edges.extend(edges) - me.faces.extend(faces) - me.sel = True - - # Object creation and location - scn.objects.selected = [] - ob_act = scn.objects.new(me, name) - scn.objects.active = ob_act - - if quat: - mat = quat.toMatrix() - mat.invert() - mat.resize4x4() - ob_act.setMatrix(mat) - - ob_act.loc = cursor - - me.calcNormals() - - if is_editmode or Blender.Get('add_editmode'): - EditMode(1) - - - - - -def write_mesh_script(filepath, me): - ''' - filepath - path to py file - me - mesh to write - ''' - - name = me.name - file = open(filepath, 'w') - - file.write('#!BPY\n') - file.write('"""\n') - file.write('Name: \'%s\'\n' % name) - file.write('Blender: 245\n') - file.write('Group: \'AddMesh\'\n') - file.write('"""\n\n') - file.write('import BPyAddMesh\n') - file.write('from Blender.Mathutils import Vector\n\n') - - file.write('verts = [\\\n') - for v in me.verts: - file.write('Vector(%f,%f,%f),\\\n' % tuple(v.co)) - file.write(']\n') - - file.write('edges = []\n') # TODO, write loose edges - - file.write('faces = [\\\n') - for f in me.faces: - file.write('%s,\\\n' % str(tuple([v.index for v in f]))) - file.write(']\n') - - file.write('BPyAddMesh.add_mesh_simple("%s", verts, edges, faces)\n' % name) - -# The script below can make a file from a mesh with teh above function... -''' -#!BPY -""" -Name: 'Mesh as AddMesh Script' -Blender: 242 -Group: 'Mesh' -Tip: '' -""" -import BPyAddMesh -reload(BPyAddMesh) - -import bpy - -def main(): - # Add error checking - scn = bpy.data.scenes.active - ob = scn.objects.active - me = ob.getData(mesh=1) - - BPyAddMesh.write_mesh_script('/test.py', me) - -main() -''' diff --git a/release/scripts/bpymodules/BPyArmature.py b/release/scripts/bpymodules/BPyArmature.py deleted file mode 100644 index 63df02d080c..00000000000 --- a/release/scripts/bpymodules/BPyArmature.py +++ /dev/null @@ -1,152 +0,0 @@ -# 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 -# Version History: -# 1.0 original release bakes an armature into a matrix -# 1.1 optional params (ACTION_BAKE, ACTION_BAKE_FIRST_FRAME, direct function to key and return the Action - -import Blender -from Blender import sys -import bpy -def getBakedPoseData(ob_arm, start_frame, end_frame, ACTION_BAKE = False, ACTION_BAKE_FIRST_FRAME = True): - ''' - If you are currently getting IPO's this function can be used to - ACTION_BAKE==False: return a list of frame aligned bone dictionary's - ACTION_BAKE==True: return an action with keys aligned to bone constrained movement - if ACTION_BAKE_FIRST_FRAME is not supplied or is true: keys begin at frame 1 - - The data in these can be swaped in for the IPO loc and quat - - If you want to bake an action, this is not as hard and the ipo hack can be removed. - ''' - - # --------------------------------- Dummy Action! Only for this functon - backup_action = ob_arm.action - backup_frame = Blender.Get('curframe') - - DUMMY_ACTION_NAME = '~DONT_USE~' - # Get the dummy action if it has no users - try: - new_action = bpy.data.actions[DUMMY_ACTION_NAME] - if new_action.users: - new_action = None - except: - new_action = None - - if not new_action: - new_action = bpy.data.actions.new(DUMMY_ACTION_NAME) - new_action.fakeUser = False - # ---------------------------------- Done - - Matrix = Blender.Mathutils.Matrix - Quaternion = Blender.Mathutils.Quaternion - Vector = Blender.Mathutils.Vector - POSE_XFORM= [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT] - - # Each dict a frame - bake_data = [{} for i in xrange(1+end_frame-start_frame)] - - pose= ob_arm.getPose() - armature_data= ob_arm.getData(); - pose_bones= pose.bones - - # --------------------------------- Build a list of arma data for reuse - armature_bone_data = [] - bones_index = {} - for bone_name, rest_bone in armature_data.bones.items(): - pose_bone = pose_bones[bone_name] - rest_matrix = rest_bone.matrix['ARMATURESPACE'] - rest_matrix_inv = rest_matrix.copy().invert() - armature_bone_data.append( [len(bones_index), -1, bone_name, rest_bone, rest_matrix, rest_matrix_inv, pose_bone, None ]) - bones_index[bone_name] = len(bones_index) - - # Set the parent ID's - for bone_name, pose_bone in pose_bones.items(): - parent = pose_bone.parent - if parent: - bone_index= bones_index[bone_name] - parent_index= bones_index[parent.name] - armature_bone_data[ bone_index ][1]= parent_index - # ---------------------------------- Done - - - - # --------------------------------- Main loop to collect IPO data - frame_index = 0 - NvideoFrames= end_frame-start_frame - for current_frame in xrange(start_frame, end_frame+1): - if frame_index==0: start=sys.time() - elif frame_index==15: print NvideoFrames*(sys.time()-start),"seconds estimated..." #slows as it grows *3 - elif frame_index >15: - percom= frame_index*100/NvideoFrames - print "Frame %i Overall %i percent complete\r" % (current_frame, percom), - ob_arm.action = backup_action - #pose.update() # not needed - Blender.Set('curframe', current_frame) - #Blender.Window.RedrawAll() - #frame_data = bake_data[frame_index] - ob_arm.action = new_action - ###for i,pose_bone in enumerate(pose_bones): - - for index, parent_index, bone_name, rest_bone, rest_matrix, rest_matrix_inv, pose_bone, ipo in armature_bone_data: - matrix= pose_bone.poseMatrix - parent_bone= rest_bone.parent - if parent_index != -1: - parent_pose_matrix = armature_bone_data[parent_index][6].poseMatrix - parent_bone_matrix_inv = armature_bone_data[parent_index][5] - matrix= matrix * parent_pose_matrix.copy().invert() - rest_matrix= rest_matrix * parent_bone_matrix_inv - - matrix=matrix * rest_matrix.copy().invert() - pose_bone.quat= matrix.toQuat() - pose_bone.loc= matrix.translationPart() - if ACTION_BAKE==False: - pose_bone.insertKey(ob_arm, 1, POSE_XFORM) # always frame 1 - - # THIS IS A BAD HACK! IT SUCKS BIGTIME BUT THE RESULT ARE NICE - # - use a temp action and bake into that, always at the same frame - # so as not to make big IPO's, then collect the result from the IPOs - - # Now get the data from the IPOs - if not ipo: ipo = armature_bone_data[index][7] = new_action.getChannelIpo(bone_name) - - loc = Vector() - quat = Quaternion() - - for curve in ipo: - val = curve.evaluate(1) - curve_name= curve.name - if curve_name == 'LocX': loc[0] = val - elif curve_name == 'LocY': loc[1] = val - elif curve_name == 'LocZ': loc[2] = val - elif curve_name == 'QuatW': quat[3] = val - elif curve_name == 'QuatX': quat[0] = val - elif curve_name == 'QuatY': quat[1] = val - elif curve_name == 'QuatZ': quat[2] = val - - bake_data[frame_index][bone_name] = loc, quat - else: - if ACTION_BAKE_FIRST_FRAME: pose_bone.insertKey(ob_arm, frame_index+1, POSE_XFORM) - else: pose_bone.insertKey(ob_arm, current_frame , POSE_XFORM) - frame_index+=1 - print "\nBaking Complete." - ob_arm.action = backup_action - if ACTION_BAKE==False: - Blender.Set('curframe', backup_frame) - return bake_data - elif ACTION_BAKE==True: - return new_action - else: print "ERROR: Invalid ACTION_BAKE %i sent to BPyArmature" % ACTION_BAKE - - - diff --git a/release/scripts/bpymodules/BPyBlender.py b/release/scripts/bpymodules/BPyBlender.py deleted file mode 100644 index 681dff63cf8..00000000000 --- a/release/scripts/bpymodules/BPyBlender.py +++ /dev/null @@ -1,36 +0,0 @@ -# $Id$ -# -# -------------------------------------------------------------------------- -# BPyBlender.py version 0.3 Mar 20, 2005 -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** 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 ***** -# -------------------------------------------------------------------------- - -# Basic set of modules Blender should have in all supported platforms. -# The second and third lines are the contents of the Python23.zip file -# included with Windows Blender binaries along with zlib.pyd. -# Other platforms are assumed to have Python installed. -basic_modules = [ -'Blender', -'chunk','colorsys','copy','copy_reg','gzip','os','random','repr','stat', -'string','StringIO','types','UserDict','webbrowser', 'zlib', 'math', -'BPyBlender', 'BPyRegistry' -] diff --git a/release/scripts/bpymodules/BPyCurve.py b/release/scripts/bpymodules/BPyCurve.py deleted file mode 100644 index 3dd5f1784f2..00000000000 --- a/release/scripts/bpymodules/BPyCurve.py +++ /dev/null @@ -1,79 +0,0 @@ -# -------------------------------------------------------------------------- -# BPyImage.py version 0.15 -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** 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 ***** -# -------------------------------------------------------------------------- - -from Blender import * - -def curve2vecs(ob, WORLDSPACE= True): - ''' - Takes a curve object and retuirns a list of vec lists (polylines) - one list per curve - - This is usefull as a way to get a polyline per curve - so as not to have to deal with the spline types directly - ''' - if ob.type != 'Curve': - raise 'must be a curve object' - - me_dummy = Mesh.New() - me_dummy.getFromObject(ob) - - if WORLDSPACE: - me_dummy.transform(ob.matrixWorld) - - # build an edge dict - edges = {} # should be a set - - def sort_pair(i1, i2): - if i1 > i2: return i2, i1 - else: return i1, i2 - - for ed in me_dummy.edges: - edges[sort_pair(ed.v1.index,ed.v2.index)] = None # dummy value - - # now set the curves - first_time = True - - current_vecs = [] - vec_list = [current_vecs] - - for v in me_dummy.verts: - if first_time: - first_time = False - current_vecs.append(v.co.copy()) - last_index = v.index - else: - index = v.index - if edges.has_key(sort_pair(index, last_index)): - current_vecs.append( v.co.copy() ) - else: - current_vecs = [] - vec_list.append(current_vecs) - - last_index = index - - me_dummy.verts = None - - return vec_list - - diff --git a/release/scripts/bpymodules/BPyImage.py b/release/scripts/bpymodules/BPyImage.py deleted file mode 100644 index 504e4ee29ba..00000000000 --- a/release/scripts/bpymodules/BPyImage.py +++ /dev/null @@ -1,318 +0,0 @@ -# -------------------------------------------------------------------------- -# BPyImage.py version 0.15 -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** 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 ***** -# -------------------------------------------------------------------------- - -#===========================================================================# -# Comprehensive image loader, will search and find the image # -# Will return a blender image or a new image if the image is missing # -#===========================================================================# -import bpy -from Blender import sys -try: - import os -except: - os=None - -#==============================================# -# Return directory, where the file is # -#==============================================# -def stripFile(path): - lastSlash = max(path.rfind('\\'), path.rfind('/')) - if lastSlash != -1: - path = path[:lastSlash] - newpath= '%s%s' % (path, sys.sep) - else: - newpath= path - return newpath - -#==============================================# -# Strips the slashes from the back of a string # -#==============================================# -def stripPath(path): - return path.split('/')[-1].split('\\')[-1] - -#====================================================# -# Strips the prefix off the name before writing # -#====================================================# -def stripExt(name): # name is a string - index = name.rfind('.') - if index != -1: - return name[ : index ] - else: - return name - -def getExt(name): - index = name.rfind('.') - if index != -1: - return name[index+1:] - return name - -#====================================================# -# Adds a slash to the end of a path if its not there # -#====================================================# -def addSlash(path): - if not path: - return '' - - elif path.endswith('\\') or path.endswith('/'): - return path - return path + sys.sep - - -def comprehensiveImageLoad(imagePath, filePath, PLACE_HOLDER= True, RECURSIVE=True, VERBOSE=False, CONVERT_CALLBACK=None): - ''' - imagePath: The image filename - If a path precedes it, this will be searched as well. - - filePath: is the directory where the image may be located - any file at teh end will be ignored. - - PLACE_HOLDER: if True a new place holder image will be created. - this is usefull so later you can relink the image to its original data. - - VERBOSE: If True debug info will be printed. - - RECURSIVE: If True, directories will be recursivly searched. - Be carefull with this if you have files in your root directory because it may take a long time. - - CASE_INSENSITIVE: for non win32 systems, find the correct case for the file. - - CONVERT_CALLBACK: a function that takes an existing path and returns a new one. - Use this when loading image formats blender may not support, the CONVERT_CALLBACK - can take the path for a GIF (for example), convert it to a PNG and return the PNG's path. - For formats blender can read, simply return the path that is given. - ''' - - # VERBOSE = True - - if VERBOSE: print 'img:', imagePath, 'file:', filePath - - if os == None and CASE_INSENSITIVE: - CASE_INSENSITIVE = True - - # When we have the file load it with this. try/except niceness. - def imageLoad(path): - #if path.endswith('\\') or path.endswith('/'): - # raise 'INVALID PATH' - - if CONVERT_CALLBACK: - path = CONVERT_CALLBACK(path) - - try: - img = bpy.data.images.new(filename=path) - if VERBOSE: print '\t\tImage loaded "%s"' % path - return img - except: - if VERBOSE: - if sys.exists(path): print '\t\tImage failed loading "%s", mabe its not a format blender can read.' % (path) - else: print '\t\tImage not found, making a place holder "%s"' % (path) - if PLACE_HOLDER: - img= bpy.data.images.new(stripPath(path),4,4) - img.filename= path - return img #blank image - else: - return None - - # Image formats blender can read - IMAGE_EXT = ['jpg', 'jpeg', 'png', 'tga', 'bmp', 'rgb', 'sgi', 'bw', 'iff', 'lbm', # Blender Internal - 'gif', 'psd', 'tif', 'tiff', 'pct', 'pict', 'pntg', 'qtif'] # Quacktime, worth a try. - - imageFileName = stripPath(imagePath) # image path only - imageFileName_lower = imageFileName.lower() # image path only - - if VERBOSE: print '\tSearchingExisting Images for "%s"' % imagePath - for i in bpy.data.images: - if stripPath(i.filename.lower()) == imageFileName_lower: - if VERBOSE: print '\t\tUsing existing image.' - return i - - - if VERBOSE: print '\tAttempting to load "%s"' % imagePath - if sys.exists(imagePath): - if VERBOSE: print '\t\tFile found where expected "%s".' % imagePath - return imageLoad(imagePath) - - - - imageFileName_noext = stripExt(imageFileName) # With no extension. - imageFileName_noext_lower = stripExt(imageFileName_lower) # With no extension. - imageFilePath = stripFile(imagePath) - - # Remove relative path from image path - if imageFilePath.startswith('./') or imageFilePath.startswith('.\\'): - imageFilePath = imageFilePath[2:] - - - # Attempt to load from obj path. - tmpPath = stripFile(filePath) + stripPath(imageFileName) - if sys.exists(tmpPath): - if VERBOSE: print '\t\tFile found in path (1)"%s".' % tmpPath - return imageLoad(tmpPath) - - - # os needed if we go any further. - if not os: - if VERBOSE: print '\t\tCreating a placeholder with a face path: "%s".' % imagePath - return imageLoad(imagePath) # Will jus treturn a placeholder. - - - # We have os. - # GATHER PATHS. - paths = {} # Store possible paths we may use, dict for no doubles. - tmpPath = addSlash(sys.expandpath('//')) # Blenders path - if sys.exists(tmpPath): - if VERBOSE: print '\t\tSearching in %s' % tmpPath - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - - tmpPath = imageFilePath - if sys.exists(tmpPath): - if VERBOSE: print '\t\tSearching in %s' % tmpPath - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - - tmpPath = stripFile(filePath) - if sys.exists(tmpPath): - if VERBOSE: print '\t\tSearching in %s' % tmpPath - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - - tmpPath = addSlash(bpy.config.textureDir) - if tmpPath and sys.exists(tmpPath): - if VERBOSE: print '\t\tSearching in %s' % tmpPath - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - - # Add path if relative image patrh was given. - tmp_paths= paths.keys() - for k in tmp_paths: - tmpPath = k + imageFilePath - if sys.exists(tmpPath): - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - # DONE - # - for path, files in paths.iteritems(): - if sys.exists(path + imageFileName): - if VERBOSE: print '\tFound image at path: "%s" file" "%s"' % (path, imageFileName) - return imageLoad(path + imageFileName) - - # If the files not there then well do a case insensitive seek. - filesOrigCase = files[0] - filesLower = files[1] - filesLowerNoExt = files[2] - - # We are going to try in index the file directly, if its not there just keep on - - index = None - try: - # Is it just a case mismatch? - index = filesLower.index(imageFileName_lower) - except: - try: - # Have the extensions changed? - index = filesLowerNoExt.index(imageFileName_noext_lower) - - ext = getExt( filesLower[index] ) # Get the extension of the file that matches all but ext. - - # Check that the ext is useable eg- not a 3ds file :) - if ext.lower() not in IMAGE_EXT: - index = None - - except: - index = None - - if index != None: - tmpPath = path + filesOrigCase[index] - img = imageLoad( tmpPath ) - if img != None: - if VERBOSE: print '\t\tImage Found "%s"' % tmpPath - return img - - if RECURSIVE: - # IMAGE NOT FOUND IN ANY OF THE DIRS!, DO A RECURSIVE SEARCH. - if VERBOSE: print '\t\tImage Not Found in any of the dirs, doing a recusrive search' - for path in paths.iterkeys(): - # Were not going to use files - if path == '/' or len(path) == 3 and path[1:] == ':\\': - continue - - # print path , 'ASS' - - #------------------ - # finds the file starting at the root. - # def findImage(findRoot, imagePath): - #W--------------- - - # ROOT, DIRS, FILES - pathWalk = os.walk(path) - pathList = [True] - - matchList = [] # Store a list of (match, size), choose the biggest. - while True: - try: - pathList = pathWalk.next() - except: - break - - for file in pathList[2]: - file_lower = file.lower() - # FOUND A MATCH - if (file_lower == imageFileName_lower) or\ - (stripExt(file_lower) == imageFileName_noext_lower and getExt(file_lower) in IMAGE_EXT): - name = pathList[0] + sys.sep + file - size = os.path.getsize(name) - if VERBOSE: print '\t\t\tfound:', name - matchList.append( (name, size) ) - - if matchList: - # Sort by file size - matchList.sort(lambda A, B: cmp(B[1], A[1]) ) - - if VERBOSE: print '\t\tFound "%s"' % matchList[0][0] - - # Loop through all we have found - img = None - for match in matchList: - img = imageLoad(match[0]) # 0 - first, 0 - pathname - if img != None: - break - return img - - # No go. - if VERBOSE: print '\t\tImage Not Found after looking everywhere! "%s"' % imagePath - return imageLoad(imagePath) # Will jus treturn a placeholder. diff --git a/release/scripts/bpymodules/BPyMathutils.py b/release/scripts/bpymodules/BPyMathutils.py deleted file mode 100644 index 4882e9aaf21..00000000000 --- a/release/scripts/bpymodules/BPyMathutils.py +++ /dev/null @@ -1,228 +0,0 @@ -# $Id$ -# -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** 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 -from Blender.Mathutils import * - -# ------ Mersenne Twister - start - -# Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. -# Any feedback is very welcome. For any question, comments, -# see http://www.math.keio.ac.jp/matumoto/emt.html or email -# matumoto@math.keio.ac.jp - -# The link above is dead, this is the new one: -# http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/emt.html -# And here the license info, from Mr. Matsumoto's site: -# Until 2001/4/6, MT had been distributed under GNU Public License, -# but after 2001/4/6, we decided to let MT be used for any purpose, including -# commercial use. 2002-versions mt19937ar.c, mt19937ar-cok.c are considered -# to be usable freely. -# -# So from the year above (1997), this code is under GPL. - -# Period parameters -N = 624 -M = 397 -MATRIX_A = 0x9908b0dfL # constant vector a -UPPER_MASK = 0x80000000L # most significant w-r bits -LOWER_MASK = 0x7fffffffL # least significant r bits - -# Tempering parameters -TEMPERING_MASK_B = 0x9d2c5680L -TEMPERING_MASK_C = 0xefc60000L - -def TEMPERING_SHIFT_U(y): - return (y >> 11) - -def TEMPERING_SHIFT_S(y): - return (y << 7) - -def TEMPERING_SHIFT_T(y): - return (y << 15) - -def TEMPERING_SHIFT_L(y): - return (y >> 18) - -mt = [] # the array for the state vector -mti = N+1 # mti==N+1 means mt[N] is not initialized - -# initializing the array with a NONZERO seed -def sgenrand(seed): - # setting initial seeds to mt[N] using - # the generator Line 25 of Table 1 in - # [KNUTH 1981, The Art of Computer Programming - # Vol. 2 (2nd Ed.), pp102] - - global mt, mti - - mt = [] - - mt.append(seed & 0xffffffffL) - for i in xrange(1, N + 1): - mt.append((69069 * mt[i-1]) & 0xffffffffL) - - mti = i -# end sgenrand - - -def genrand(): - global mt, mti - - mag01 = [0x0L, MATRIX_A] - # mag01[x] = x * MATRIX_A for x=0,1 - y = 0 - - if mti >= N: # generate N words at one time - if mti == N+1: # if sgenrand() has not been called, - sgenrand(4357) # a default initial seed is used - - for kk in xrange((N-M) + 1): - y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK) - mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1] - - for kk in xrange(kk, N): - y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK) - mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1] - - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK) - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1] - - mti = 0 - - y = mt[mti] - mti += 1 - y ^= TEMPERING_SHIFT_U(y) - y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B - y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C - y ^= TEMPERING_SHIFT_L(y) - - return ( float(y) / 0xffffffffL ) # reals - -#------ Mersenne Twister -- end - - - - -""" 2d convexhull -Based from Dinu C. Gherman's work, -modified for Blender/Mathutils by Campell Barton -""" -###################################################################### -# Public interface -###################################################################### -def convexHull(point_list_2d): - """Calculate the convex hull of a set of vectors - The vectors can be 3 or 4d but only the Xand Y are used. - returns a list of convex hull indicies to the given point list - """ - - ###################################################################### - # Helpers - ###################################################################### - - def _myDet(p, q, r): - """Calc. determinant of a special matrix with three 2D points. - - The sign, "-" or "+", determines the side, right or left, - respectivly, on which the point r lies, when measured against - a directed vector from p to q. - """ - return (q.x*r.y + p.x*q.y + r.x*p.y) - (q.x*p.y + r.x*q.y + p.x*r.y) - - def _isRightTurn((p, q, r)): - "Do the vectors pq:qr form a right turn, or not?" - #assert p[0] != q[0] and q[0] != r[0] and p[0] != r[0] - if _myDet(p[0], q[0], r[0]) < 0: - return 1 - else: - return 0 - - # Get a local list copy of the points and sort them lexically. - points = [(p, i) for i, p in enumerate(point_list_2d)] - - try: points.sort(key = lambda a: (a[0].x, a[0].y)) - except: points.sort(lambda a,b: cmp((a[0].x, a[0].y), (b[0].x, b[0].y))) - - # Build upper half of the hull. - upper = [points[0], points[1]] # cant remove these. - for i in xrange(len(points)-2): - upper.append(points[i+2]) - while len(upper) > 2 and not _isRightTurn(upper[-3:]): - del upper[-2] - - # Build lower half of the hull. - points.reverse() - lower = [points.pop(0), points.pop(1)] - for p in points: - lower.append(p) - while len(lower) > 2 and not _isRightTurn(lower[-3:]): - del lower[-2] - - # Concatenate both halfs and return. - return [p[1] for ls in (upper, lower) for p in ls] - - -def plane2mat(plane, normalize= False): - ''' - Takes a plane and converts to a matrix - points between 0 and 1 are up - 1 and 2 are right - assumes the plane has 90d corners - ''' - cent= (plane[0]+plane[1]+plane[2]+plane[3] ) /4.0 - - - up= cent - ((plane[0]+plane[1])/2.0) - right= cent - ((plane[1]+plane[2])/2.0) - z= up.cross(right) - - if normalize: - up.normalize() - right.normalize() - z.normalize() - - mat= Matrix(up, right, z) - - # translate - mat.resize4x4() - tmat= Blender.Mathutils.TranslationMatrix(cent) - return mat * tmat - - -# Used for mesh_solidify.py and mesh_wire.py - -# returns a length from an angle -# Imaging a 2d space. -# there is a hoz line at Y1 going to inf on both X ends, never moves (LINEA) -# down at Y0 is a unit length line point up at (angle) from X0,Y0 (LINEB) -# This function returns the length of LINEB at the point it would intersect LINEA -# - Use this for working out how long to make the vector - differencing it from surrounding faces, -# import math -from math import pi, sin, cos, sqrt - -def angleToLength(angle): - # Alredy accounted for - if angle < 0.000001: return 1.0 - else: return abs(1.0 / cos(pi*angle/180)); diff --git a/release/scripts/bpymodules/BPyMesh.py b/release/scripts/bpymodules/BPyMesh.py deleted file mode 100644 index 292f7a4b91e..00000000000 --- a/release/scripts/bpymodules/BPyMesh.py +++ /dev/null @@ -1,1326 +0,0 @@ -# ***** 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 bpy -import BPyMesh_redux # seperated because of its size. -# reload(BPyMesh_redux) -redux= BPyMesh_redux.redux - -# python 2.3 has no reversed() iterator. this will only work on lists and tuples -try: - reversed -except: - def reversed(l): return l[::-1] - - -# If python version is less than 2.4, try to get set stuff from module -try: - set -except: - try: - from sets import Set as set - except: - set= None - - - - - -def meshWeight2List(me): - ''' Takes a mesh and return its group names and a list of lists, one list per vertex. - aligning the each vert list with the group names, each list contains float value for the weight. - These 2 lists can be modified and then used with list2MeshWeight to apply the changes. - ''' - - # Clear the vert group. - groupNames= me.getVertGroupNames() - len_groupNames= len(groupNames) - - if not len_groupNames: - # no verts? return a vert aligned empty list - return [[] for i in xrange(len(me.verts))], [] - - else: - vWeightList= [[0.0]*len_groupNames for i in xrange(len(me.verts))] - - for group_index, group in enumerate(groupNames): - for vert_index, weight in me.getVertsFromGroup(group, 1): # (i,w) tuples. - vWeightList[vert_index][group_index]= weight - - # removed this because me may be copying teh vertex groups. - #for group in groupNames: - # me.removeVertGroup(group) - - return groupNames, vWeightList - - -def list2MeshWeight(me, groupNames, vWeightList): - ''' Takes a list of groups and a list of vertex Weight lists as created by meshWeight2List - and applys it to the mesh.''' - - if len(vWeightList) != len(me.verts): - raise 'Error, Lists Differ in size, do not modify your mesh.verts before updating the weights' - - act_group = me.activeGroup - - # Clear the vert group. - currentGroupNames= me.getVertGroupNames() - for group in currentGroupNames: - me.removeVertGroup(group) # messes up the active group. - - # Add clean unused vert groupNames back - currentGroupNames= me.getVertGroupNames() - for group in groupNames: - me.addVertGroup(group) - - add_ = Blender.Mesh.AssignModes.ADD - - vertList= [None] - for i, v in enumerate(me.verts): - vertList[0]= i - for group_index, weight in enumerate(vWeightList[i]): - if weight: - try: - me.assignVertsToGroup(groupNames[group_index], vertList, min(1, max(0, weight)), add_) - except: - pass # vert group is not used anymore. - - try: me.activeGroup = act_group - except: pass - - me.update() - - - - -def meshWeight2Dict(me): - ''' Takes a mesh and return its group names and a list of dicts, one dict per vertex. - using the group as a key and a float value for the weight. - These 2 lists can be modified and then used with dict2MeshWeight to apply the changes. - ''' - - vWeightDict= [dict() for i in xrange(len(me.verts))] # Sync with vertlist. - - # Clear the vert group. - groupNames= me.getVertGroupNames() - - for group in groupNames: - for vert_index, weight in me.getVertsFromGroup(group, 1): # (i,w) tuples. - vWeightDict[vert_index][group]= weight - - # removed this because me may be copying teh vertex groups. - #for group in groupNames: - # me.removeVertGroup(group) - - return groupNames, vWeightDict - - -def dict2MeshWeight(me, groupNames, vWeightDict): - ''' Takes a list of groups and a list of vertex Weight dicts as created by meshWeight2Dict - and applys it to the mesh.''' - - if len(vWeightDict) != len(me.verts): - raise 'Error, Lists Differ in size, do not modify your mesh.verts before updating the weights' - - act_group = me.activeGroup - - # Clear the vert group. - currentGroupNames= me.getVertGroupNames() - for group in currentGroupNames: - if group not in groupNames: - me.removeVertGroup(group) # messes up the active group. - else: - me.removeVertsFromGroup(group) - - # Add clean unused vert groupNames back - currentGroupNames= me.getVertGroupNames() - for group in groupNames: - if group not in currentGroupNames: - me.addVertGroup(group) - - add_ = Blender.Mesh.AssignModes.ADD - - vertList= [None] - for i, v in enumerate(me.verts): - vertList[0]= i - for group, weight in vWeightDict[i].iteritems(): - try: - me.assignVertsToGroup(group, vertList, min(1, max(0, weight)), add_) - except: - pass # vert group is not used anymore. - - try: me.activeGroup = act_group - except: pass - - me.update() - -def dictWeightMerge(dict_weights): - ''' - Takes dict weight list and merges into 1 weight dict item and returns it - ''' - - if not dict_weights: - return {} - - keys= [] - for weight in dict_weights: - keys.extend([ (k, 0.0) for k in weight.iterkeys() ]) - - new_wdict = dict(keys) - - len_dict_weights= len(dict_weights) - - for weight in dict_weights: - for group, value in weight.iteritems(): - new_wdict[group] += value/len_dict_weights - - return new_wdict - - -FLIPNAMES=[\ -('Left','Right'),\ -('_L','_R'),\ -('-L','-R'),\ -('.L','.R'),\ -] - -def dictWeightFlipGroups(dict_weight, groupNames, createNewGroups): - ''' - Returns a weight with flip names - dict_weight - 1 vert weight. - groupNames - because we may need to add new group names. - dict_weight - Weather to make new groups where needed. - ''' - - def flipName(name): - for n1,n2 in FLIPNAMES: - for nA, nB in ( (n1,n2), (n1.lower(),n2.lower()), (n1.upper(),n2.upper()) ): - if createNewGroups: - newName= name.replace(nA,nB) - if newName!=name: - if newName not in groupNames: - groupNames.append(newName) - return newName - - newName= name.replace(nB,nA) - if newName!=name: - if newName not in groupNames: - groupNames.append(newName) - return newName - - else: - newName= name.replace(nA,nB) - if newName!=name and newName in groupNames: - return newName - - newName= name.replace(nB,nA) - if newName!=name and newName in groupNames: - return newName - - return name - - if not dict_weight: - return dict_weight, groupNames - - - new_wdict = {} - for group, weight in dict_weight.iteritems(): - flipname= flipName(group) - new_wdict[flipname]= weight - - return new_wdict, groupNames - - -def mesh2linkedFaces(me): - ''' - Splits the mesh into connected parts, - these parts are returned as lists of faces. - used for seperating cubes from other mesh elements in the 1 mesh - ''' - - # Build vert face connectivity - vert_faces= [[] for i in xrange(len(me.verts))] - for f in me.faces: - for v in f: - vert_faces[v.index].append(f) - - # sort faces into connectivity groups - face_groups= [[f] for f in me.faces] - face_mapping = range(len(me.faces)) # map old, new face location - - # Now clump faces iterativly - ok= True - while ok: - ok= False - - for i, f in enumerate(me.faces): - mapped_index= face_mapping[f.index] - mapped_group= face_groups[mapped_index] - - for v in f: - for nxt_f in vert_faces[v.index]: - if nxt_f != f: - nxt_mapped_index= face_mapping[nxt_f.index] - - # We are not a part of the same group - if mapped_index != nxt_mapped_index: - - ok= True - - # Assign mapping to this group so they all map to this group - for grp_f in face_groups[nxt_mapped_index]: - face_mapping[grp_f.index] = mapped_index - - # Move faces into this group - mapped_group.extend(face_groups[nxt_mapped_index]) - - # remove reference to the list - face_groups[nxt_mapped_index]= None - - - # return all face groups that are not null - # this is all the faces that are connected in their own lists. - return [fg for fg in face_groups if fg] - - -def getFaceLoopEdges(faces, seams=[]): - ''' - Takes me.faces or a list of faces and returns the edge loops - These edge loops are the edges that sit between quads, so they dont touch - 1 quad, not not connected will make 2 edge loops, both only containing 2 edges. - - return a list of edge key lists - [ [(0,1), (4, 8), (3,8)], ...] - - optionaly, seams are edge keys that will be removed - ''' - - OTHER_INDEX = 2,3,0,1 # opposite face index - - edges = {} - - for f in faces: - if len(f) == 4: - edge_keys = f.edge_keys - for i, edkey in enumerate(f.edge_keys): - edges.setdefault(edkey, []).append(edge_keys[OTHER_INDEX[i]]) - - for edkey in seams: - edges[edkey] = [] - - # Collect edge loops here - edge_loops = [] - - for edkey, ed_adj in edges.iteritems(): - if 0 <len(ed_adj) < 3: # 1 or 2 - # Seek the first edge - context_loop = [edkey, ed_adj[0]] - edge_loops.append(context_loop) - if len(ed_adj) == 2: - other_dir = ed_adj[1] - else: - other_dir = None - - ed_adj[:] = [] - - flipped = False - - while 1: - # from knowing the last 2, look for th next. - ed_adj = edges[context_loop[-1]] - if len(ed_adj) != 2: - - if other_dir and flipped==False: # the original edge had 2 other edges - flipped = True # only flip the list once - context_loop.reverse() - ed_adj[:] = [] - context_loop.append(other_dir) # save 1 lookiup - - ed_adj = edges[context_loop[-1]] - if len(ed_adj) != 2: - ed_adj[:] = [] - break - else: - ed_adj[:] = [] - break - - i = ed_adj.index(context_loop[-2]) - context_loop.append( ed_adj[ not i] ) - - # Dont look at this again - ed_adj[:] = [] - - - return edge_loops - - - -def getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None): - ''' - ob - the object that you want to get the mesh from - container_mesh - a Blender.Mesh type mesh that is reused to avoid a new datablock per call to getMeshFromObject - apply_modifiers - if enabled, subsurf bones etc. will be applied to the returned mesh. disable to get a copy of the mesh. - vgroup - For mesh objects only, apply the vgroup to the the copied mesh. (slower) - scn - Scene type. avoids getting the current scene each time getMeshFromObject is called. - - Returns Mesh or None - ''' - - if not scn: - scn= bpy.data.scenes.active - if not container_mesh: - mesh = bpy.data.meshes.new(ob.name) - else: - mesh= container_mesh - mesh.verts= None - - ob_type = ob.type - dataname = ob.getData(1) - tempob= None - if apply_modifiers or ob_type != 'Mesh': - try: - mesh.getFromObject(ob) - except: - return None - - else: - ''' - Dont apply modifiers, copy the mesh. - So we can transform the data. its easiest just to get a copy of the mesh. - ''' - tempob= scn.objects.new(ob.getData(mesh=1)) - mesh.getFromObject(tempob) - scn.objects.unlink(tempob) - - if ob_type == 'Mesh': - if vgroups: - if tempob==None: - tempob= Blender.Object.New('Mesh') - - tempob.link(mesh) - try: - # Copy the influences if possible. - groupNames, vWeightDict= meshWeight2Dict(ob.getData(mesh=1)) - dict2MeshWeight(mesh, groupNames, vWeightDict) - except: - # if the modifier changes the vert count then it messes it up for us. - pass - - return mesh - - -def faceRayIntersect(f, orig, rdir): - ''' - Returns face, side - Side is the side of a quad we intersect. - side 0 == 0,1,2 - side 1 == 0,2,3 - ''' - f_v= f.v - isect= Blender.Mathutils.Intersect(f_v[0].co, f_v[1].co, f_v[2].co, rdir, orig, 1) # 1==clip - - if isect: - return isect, 0 - - if len(f_v)==4: - isect= Blender.Mathutils.Intersect(f_v[0].co, f_v[2].co, f_v[3].co, rdir, orig, 1) # 1==clip - if isect: - return isect, 1 - return False, 0 - - -def pickMeshRayFace(me, orig, rdir): - best_dist= 1000000 - best_isect= best_side= best_face= None - for f in me.faces: - isect, side= faceRayIntersect(f, orig, rdir) - if isect: - dist= (isect-orig).length - if dist<best_dist: - best_dist= dist - best_face= f - best_side= side - best_isect= isect - - return best_face, best_isect, best_side - - -def pickMeshRayFaceWeight(me, orig, rdir): - f, isect, side = pickMeshRayFace(me, orig, rdir) - - if f==None: - return None, None, None, None, None - - f_v= [v.co for v in f] - if side==1: # we can leave side 0 without changes. - f_v = f_v[0], f_v[2], f_v[3] - - l0= (f_v[0]-isect).length - l1= (f_v[1]-isect).length - l2= (f_v[2]-isect).length - - w0 = (l1+l2) - w1 = (l0+l2) - w2 = (l1+l0) - - totw= w0 + w1 + w2 - w0=w0/totw - w1=w1/totw - w2=w2/totw - - return f, side, w0, w1, w2 - - - -def pickMeshGroupWeight(me, act_group, orig, rdir): - f, side, w0, w1, w2= pickMeshRayFaceWeight(me, orig, rdir) - - if f==None: - return None - - f_v= f.v - if side==0: - f_vi= (f_v[0].index, f_v[1].index, f_v[2].index) - else: - f_vi= (f_v[0].index, f_v[2].index, f_v[3].index) - - vws= [0.0,0.0,0.0] - for i in xrange(3): - try: vws[i]= me.getVertsFromGroup(act_group, 1, [f_vi[i],])[0][1] - except: pass - - return w0*vws[0] + w1*vws[1] + w2*vws[2] - -def pickMeshGroupVCol(me, orig, rdir): - Vector= Blender.Mathutils.Vector - f, side, w0, w1, w2= pickMeshRayFaceWeight(me, orig, rdir) - - if f==None: - return None - - def col2vec(c): - return Vector(c.r, c.g, c.b) - - if side==0: - idxs= 0,1,2 - else: - idxs= 0,2,3 - f_c= f.col - f_colvecs= [col2vec(f_c[i]) for i in idxs] - return f_colvecs[0]*w0 + f_colvecs[1]*w1 + f_colvecs[2]*w2 - -def edge_face_users(me): - ''' - Takes a mesh and returns a list aligned with the meshes edges. - Each item is a list of the faces that use the edge - would be the equiv for having ed.face_users as a property - ''' - - face_edges_dict= dict([(ed.key, (ed.index, [])) for ed in me.edges]) - for f in me.faces: - fvi= [v.index for v in f]# face vert idx's - for edkey in f.edge_keys: - face_edges_dict[edkey][1].append(f) - - face_edges= [None] * len(me.edges) - for ed_index, ed_faces in face_edges_dict.itervalues(): - face_edges[ed_index]= ed_faces - - return face_edges - - -def face_edges(me): - ''' - Returns a list alligned to the meshes faces. - each item is a list of lists: that is - face_edges -> face indicies - face_edges[i] -> list referencs local faces v indicies 1,2,3 &| 4 - face_edges[i][j] -> list of faces that this edge uses. - crap this is tricky to explain :/ - ''' - face_edges= [ [-1] * len(f) for f in me.faces ] - - face_edges_dict= dict([(ed.key, []) for ed in me.edges]) - for fidx, f in enumerate(me.faces): - for i, edkey in enumerate(f.edge_keys): - edge_face_users= face_edges_dict[edkey] - edge_face_users.append(f) - face_edges[fidx][i]= edge_face_users - - return face_edges - - -def facesPlanerIslands(me): - - def roundvec(v): - return round(v[0], 4), round(v[1], 4), round(v[2], 4) - - face_props= [(cent, no, roundvec(no), cent.dot(no)) for f in me.faces for no, cent in ((f.no, f.cent),)] - - face_edge_users= face_edges(me) - islands= [] - - used_faces= [0] * len(me.faces) - while True: - new_island= False - for i, used_val in enumerate(used_faces): - if used_val==0: - island= [i] - new_island= True - used_faces[i]= 1 - break - - if not new_island: - break - - island_growing= True - while island_growing: - island_growing= False - for fidx1 in island[:]: - if used_faces[fidx1]==1: - used_faces[fidx1]= 2 - face_prop1= face_props[fidx1] - for ed in face_edge_users[fidx1]: - for f2 in ed: - fidx2= f2.index - if fidx1 != fidx2 and used_faces[fidx2]==0: - island_growing= True - face_prop2= face_props[fidx2] - # normals are the same? - if face_prop1[2]==face_prop2[2]: - if abs(face_prop1[3] - face_prop1[1].dot(face_prop2[0])) < 0.000001: - used_faces[fidx2]= 1 - island.append(fidx2) - islands.append([me.faces[i] for i in island]) - return islands - - - -def facesUvIslands(me, PREF_IMAGE_DELIMIT=True): - def roundvec(v): - return round(v[0], 4), round(v[1], 4) - - if not me.faceUV: - return [ list(me.faces), ] - - # make a list of uv dicts - face_uvs= [ [roundvec(uv) for uv in f.uv] for f in me.faces] - - # key - face uv || value - list of face idxs - uv_connect_dict= dict([ (uv, [] ) for f_uvs in face_uvs for uv in f_uvs]) - - for i, f_uvs in enumerate(face_uvs): - for uv in f_uvs: # loops through rounded uv values - uv_connect_dict[uv].append(i) - islands= [] - - used_faces= [0] * len(me.faces) - while True: - new_island= False - for i, used_val in enumerate(used_faces): - if used_val==0: - island= [i] - new_island= True - used_faces[i]= 1 - break - - if not new_island: - break - - island_growing= True - while island_growing: - island_growing= False - for fidx1 in island[:]: - if used_faces[fidx1]==1: - used_faces[fidx1]= 2 - for uv in face_uvs[fidx1]: - for fidx2 in uv_connect_dict[uv]: - if fidx1 != fidx2 and used_faces[fidx2]==0: - if not PREF_IMAGE_DELIMIT or me.faces[fidx1].image==me.faces[fidx2].image: - island_growing= True - used_faces[fidx2]= 1 - island.append(fidx2) - - islands.append([me.faces[i] for i in island]) - return islands - -#def faceUvBounds(me, faces= None): - - -def facesUvRotate(me, deg, faces= None, pivot= (0,0)): - ''' - Faces can be None an all faces will be used - pivot is just the x/y well rotated about - - positive deg value for clockwise rotation - ''' - if faces==None: faces= me.faces - pivot= Blender.Mathutils.Vector(pivot) - - rotmat= Blender.Mathutils.RotationMatrix(-deg, 2) - - for f in faces: - f.uv= [((uv-pivot)*rotmat)+pivot for uv in f.uv] - -def facesUvScale(me, sca, faces= None, pivot= (0,0)): - ''' - Faces can be None an all faces will be used - pivot is just the x/y well rotated about - sca can be wither an int/float or a vector if you want to - scale x/y seperately. - a sca or (1.0, 1.0) will do nothing. - ''' - def vecmulti(v1,v2): - '''V2 is unchanged''' - v1[:]= (v1.x*v2.x, v1.y*v2.y) - return v1 - - sca= Blender.Mathutils.Vector(sca) - if faces==None: faces= me.faces - pivot= Blender.Mathutils.Vector(pivot) - - for f in faces: - f.uv= [vecmulti(uv-pivot, sca)+pivot for uv in f.uv] - - -def facesUvTranslate(me, tra, faces= None, pivot= (0,0)): - ''' - Faces can be None an all faces will be used - pivot is just the x/y well rotated about - ''' - if faces==None: faces= me.faces - tra= Blender.Mathutils.Vector(tra) - - for f in faces: - f.uv= [uv+tra for uv in f.uv] - - - -def edgeFaceUserCount(me, faces= None): - ''' - Return an edge aligned list with the count for all the faces that use that edge. - - can spesify a subset of the faces, so only those will be counted. - ''' - if faces==None: - faces= me.faces - max_vert= len(me.verts) - else: - # find the lighest vert index - pass - - edge_users= [0] * len(me.edges) - - edges_idx_dict= dict([(ed.key, ed.index) for ed in me.edges]) - - for f in faces: - for edkey in f.edge_keys: - edge_users[edges_idx_dict[edkey]] += 1 - - return edge_users - - -#============================================================================# -# Takes a face, and a pixel x/y on the image and returns a worldspace x/y/z # -# will return none if the pixel is not inside the faces UV # -#============================================================================# -def getUvPixelLoc(face, pxLoc, img_size = None, uvArea = None): - TriangleArea= Blender.Mathutils.TriangleArea - Vector= Blender.Mathutils.Vector - - if not img_size: - w,h = face.image.size - else: - w,h= img_size - - scaled_uvs= [Vector(uv.x*w, uv.y*h) for uv in f.uv] - - if len(scaled_uvs)==3: - indicies= ((0,1,2),) - else: - indicies= ((0,1,2), (0,2,3)) - - for fidxs in indicies: - for i1,i2,i3 in fidxs: - # IS a point inside our triangle? - # UVArea could be cached? - uv_area = TriangleArea(scaled_uvs[i1], scaled_uvs[i2], scaled_uvs[i3]) - area0 = TriangleArea(pxLoc, scaled_uvs[i2], scaled_uvs[i3]) - area1 = TriangleArea(pxLoc, scaled_uvs[i1], scaled_uvs[i3]) - area2 = TriangleArea(pxLoc, scaled_uvs[i1], scaled_uvs[i2]) - if area0 + area1 + area2 > uv_area + 1: # 1 px bleed/error margin. - pass # if were a quad the other side may contain the pixel so keep looking. - else: - # We know the point is in the tri - area0 /= uv_area - area1 /= uv_area - area2 /= uv_area - - # New location - return Vector(\ - face.v[i1].co[0]*area0 + face.v[i2].co[0]*area1 + face.v[i3].co[0]*area2,\ - face.v[i1].co[1]*area0 + face.v[i2].co[1]*area1 + face.v[i3].co[1]*area2,\ - face.v[i1].co[2]*area0 + face.v[i2].co[2]*area1 + face.v[i3].co[2]*area2\ - ) - - return None - - -# Used for debugging ngon -""" -def draw_loops(loops): - - me= Blender.Mesh.New() - for l in loops: - #~ me= Blender.Mesh.New() - - - i= len(me.verts) - me.verts.extend([v[0] for v in l]) - try: - me.verts[0].sel= 1 - except: - pass - me.edges.extend([ (j-1, j) for j in xrange(i+1, len(me.verts)) ]) - # Close the edge? - me.edges.extend((i, len(me.verts)-1)) - - - #~ ob= Blender.Object.New('Mesh') - #~ ob.link(me) - #~ scn= Blender.Scene.GetCurrent() - #~ scn.link(ob) - #~ ob.Layers= scn.Layers - #~ ob.sel= 1 - - - - # Fill - #fill= Blender.Mathutils.PolyFill(loops) - #me.faces.extend(fill) - - - ob= Blender.Object.New('Mesh') - ob.link(me) - scn= Blender.Scene.GetCurrent() - scn.link(ob) - ob.Layers= scn.Layers - ob.sel= 1 - Blender.Window.RedrawAll() -""" - -def ngon(from_data, indices, PREF_FIX_LOOPS= True): - ''' - Takes a polyline of indices (fgon) - and returns a list of face indicie lists. - Designed to be used for importers that need indices for an fgon to create from existing verts. - - from_data: either a mesh, or a list/tuple of vectors. - indices: a list of indicies to use this list is the ordered closed polyline to fill, and can be a subset of the data given. - PREF_FIX_LOOPS: If this is enabled polylines that use loops to make multiple polylines are delt with correctly. - ''' - - if not set: # Need sets for this, otherwise do a normal fill. - PREF_FIX_LOOPS= False - - Vector= Blender.Mathutils.Vector - if not indices: - return [] - - # return [] - def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6) - def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length - - def vert_treplet(v, i): - return v, rvec(v), i, mlen(v) - - def ed_key_mlen(v1, v2): - if v1[3] > v2[3]: - return v2[1], v1[1] - else: - return v1[1], v2[1] - - - if not PREF_FIX_LOOPS: - ''' - Normal single concave loop filling - ''' - if type(from_data) in (tuple, list): - verts= [Vector(from_data[i]) for ii, i in enumerate(indices)] - else: - verts= [from_data.verts[i].co for ii, i in enumerate(indices)] - - for i in xrange(len(verts)-1, 0, -1): # same as reversed(xrange(1, len(verts))): - if verts[i][1]==verts[i-1][0]: - verts.pop(i-1) - - fill= Blender.Geometry.PolyFill([verts]) - - else: - ''' - Seperate this loop into multiple loops be finding edges that are used twice - This is used by lightwave LWO files a lot - ''' - - if type(from_data) in (tuple, list): - verts= [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)] - else: - verts= [vert_treplet(from_data.verts[i].co, ii) for ii, i in enumerate(indices)] - - edges= [(i, i-1) for i in xrange(len(verts))] - if edges: - edges[0]= (0,len(verts)-1) - - if not verts: - return [] - - - edges_used= set() - edges_doubles= set() - # We need to check if any edges are used twice location based. - for ed in edges: - edkey= ed_key_mlen(verts[ed[0]], verts[ed[1]]) - if edkey in edges_used: - edges_doubles.add(edkey) - else: - edges_used.add(edkey) - - # Store a list of unconnected loop segments split by double edges. - # will join later - loop_segments= [] - - v_prev= verts[0] - context_loop= [v_prev] - loop_segments= [context_loop] - - for v in verts: - if v!=v_prev: - # Are we crossing an edge we removed? - if ed_key_mlen(v, v_prev) in edges_doubles: - context_loop= [v] - loop_segments.append(context_loop) - else: - if context_loop and context_loop[-1][1]==v[1]: - #raise "as" - pass - else: - context_loop.append(v) - - v_prev= v - # Now join loop segments - - def join_seg(s1,s2): - if s2[-1][1]==s1[0][1]: # - s1,s2= s2,s1 - elif s1[-1][1]==s2[0][1]: - pass - else: - return False - - # If were stuill here s1 and s2 are 2 segments in the same polyline - s1.pop() # remove the last vert from s1 - s1.extend(s2) # add segment 2 to segment 1 - - if s1[0][1]==s1[-1][1]: # remove endpoints double - s1.pop() - - s2[:]= [] # Empty this segment s2 so we dont use it again. - return True - - joining_segments= True - while joining_segments: - joining_segments= False - segcount= len(loop_segments) - - for j in xrange(segcount-1, -1, -1): #reversed(xrange(segcount)): - seg_j= loop_segments[j] - if seg_j: - for k in xrange(j-1, -1, -1): # reversed(xrange(j)): - if not seg_j: - break - seg_k= loop_segments[k] - - if seg_k and join_seg(seg_j, seg_k): - joining_segments= True - - loop_list= loop_segments - - for verts in loop_list: - while verts and verts[0][1]==verts[-1][1]: - verts.pop() - - loop_list= [verts for verts in loop_list if len(verts)>2] - # DONE DEALING WITH LOOP FIXING - - - # vert mapping - vert_map= [None]*len(indices) - ii=0 - for verts in loop_list: - if len(verts)>2: - for i, vert in enumerate(verts): - vert_map[i+ii]= vert[2] - ii+=len(verts) - - fill= Blender.Geometry.PolyFill([ [v[0] for v in loop] for loop in loop_list ]) - #draw_loops(loop_list) - #raise 'done loop' - # map to original indicies - fill= [[vert_map[i] for i in reversed(f)] for f in fill] - - - if not fill: - print 'Warning Cannot scanfill, fallback on a triangle fan.' - fill= [ [0, i-1, i] for i in xrange(2, len(indices)) ] - else: - # Use real scanfill. - # See if its flipped the wrong way. - flip= None - for fi in fill: - if flip != None: - break - for i, vi in enumerate(fi): - if vi==0 and fi[i-1]==1: - flip= False - break - elif vi==1 and fi[i-1]==0: - flip= True - break - - if not flip: - for i, fi in enumerate(fill): - fill[i]= tuple([ii for ii in reversed(fi)]) - - - - - return fill - - - -# EG -''' -scn= Scene.GetCurrent() -me = scn.getActiveObject().getData(mesh=1) -ind= [v.index for v in me.verts if v.sel] # Get indices - -indices = ngon(me, ind) # fill the ngon. - -# Extand the faces to show what the scanfill looked like. -print len(indices) -me.faces.extend([[me.verts[ii] for ii in i] for i in indices]) -''' - -def meshCalcNormals(me, vertNormals=None): - ''' - takes a mesh and returns very high quality normals 1 normal per vertex. - The normals should be correct, indipendant of topology - - vertNormals - a list of vectors at least as long as the number of verts in the mesh - ''' - Ang= Blender.Mathutils.AngleBetweenVecs - Vector= Blender.Mathutils.Vector - SMALL_NUM=0.000001 - # Weight the edge normals by total angle difference - # EDGE METHOD - - if not vertNormals: - vertNormals= [ Vector() for v in xrange(len(me.verts)) ] - else: - for v in vertNormals: - v.zero() - - edges={} - for f in me.faces: - f_v = f.v - for edkey in f.edge_keys: - edges.setdefault(edkey, []).append(f.no) - - # Weight the edge normals by total angle difference - for fnos in edges.itervalues(): - - len_fnos= len(fnos) - if len_fnos>1: - totAngDiff=0 - for j in xrange(len_fnos-1, -1, -1): # same as reversed(xrange(...)) - for k in xrange(j-1, -1, -1): # same as reversed(xrange(...)) - #print j,k - try: - totAngDiff+= (Ang(fnos[j], fnos[k])) # /180 isnt needed, just to keeop the vert small. - except: - pass # Zero length face - - # print totAngDiff - if totAngDiff > SMALL_NUM: - ''' - average_no= Vector() - for no in fnos: - average_no+=no - ''' - average_no= reduce(lambda a,b: a+b, fnos, Vector()) - fnos.append(average_no*totAngDiff) # average no * total angle diff - #else: - # fnos[0] - else: - fnos.append(fnos[0]) - - for ed, v in edges.iteritems(): - vertNormals[ed[0]]+= v[-1] - vertNormals[ed[1]]+= v[-1] - for i, v in enumerate(me.verts): - v.no= vertNormals[i] - - - - -def pointInsideMesh(ob, pt): - Intersect = Blender.Mathutils.Intersect # 2 less dict lookups. - Vector = Blender.Mathutils.Vector - - def ptInFaceXYBounds(f, pt): - f_v = f.v - co= f_v[0].co - xmax= xmin= co.x - ymax= ymin= co.y - - co= f_v[1].co - xmax= max(xmax, co.x) - xmin= min(xmin, co.x) - ymax= max(ymax, co.y) - ymin= min(ymin, co.y) - - co= f_v[2].co - xmax= max(xmax, co.x) - xmin= min(xmin, co.x) - ymax= max(ymax, co.y) - ymin= min(ymin, co.y) - - if len(f_v)==4: - co= f_v[3].co - xmax= max(xmax, co.x) - xmin= min(xmin, co.x) - ymax= max(ymax, co.y) - ymin= min(ymin, co.y) - - # Now we have the bounds, see if the point is in it. - if\ - pt.x < xmin or\ - pt.y < ymin or\ - pt.x > xmax or\ - pt.y > ymax: - return False # point is outside face bounds - else: - return True # point inside. - #return xmax, ymax, xmin, ymin - - def faceIntersect(f): - f_v = f.v - isect = Intersect(f_v[0].co, f_v[1].co, f_v[2].co, ray, obSpacePt, 1) # Clipped. - if not isect and len(f) == 4: - isect = Intersect(f_v[0].co, f_v[2].co, f_v[3].co, ray, obSpacePt, 1) # Clipped. - - if isect and isect.z > obSpacePt.z: # This is so the ray only counts if its above the point. - return True - else: - return False - - obSpacePt = pt*ob.matrixWorld.copy().invert() - ray = Vector(0,0,-1) - me= ob.getData(mesh=1) - - # Here we find the number on intersecting faces, return true if an odd number (inside), false (outside) if its true. - return len([None for f in me.faces if ptInFaceXYBounds(f, obSpacePt) if faceIntersect(f)]) % 2 - - -def faceAngles(f): - ''' - Returns the angle between all corners in a tri or a quad - - ''' - AngleBetweenVecs = Blender.Mathutils.AngleBetweenVecs - def Ang(a1,a2): - try: return AngleBetweenVecs(a1,a2) - except: return 180 - - if len(f) == 3: - if type(f) in (tuple, list): v1,v2,v3 = f - else: v1,v2,v3 = [v.co for v in f] - a1= Ang(v2-v1,v3-v1) - a2= Ang(v1-v2,v3-v2) - a3 = 180 - (a1+a2) # a3= Mathutils.AngleBetweenVecs(v2-v3,v1-v3) - return a1,a2,a3 - - else: - if type(f) in (tuple, list): v1,v2,v3,v4 = f - else: v1,v2,v3,v4 = [v.co for v in f] - a1= Ang(v2-v1,v4-v1) - a2= Ang(v1-v2,v3-v2) - a3= Ang(v2-v3,v4-v3) - a4= Ang(v3-v4,v1-v4) - return a1,a2,a3,a4 - -# NMesh wrapper -Vector= Blender.Mathutils.Vector -class NMesh(object): - __slots__= 'verts', 'faces', 'edges', 'faceUV', 'materials', 'realmesh' - def __init__(self, mesh): - ''' - This is an NMesh wrapper that - mesh is an Mesh as returned by Blender.Mesh.New() - This class wraps NMesh like access into Mesh - - Running NMesh.update() - with this wrapper, - Will update the realmesh. - ''' - self.verts= [] - self.faces= [] - self.edges= [] - self.faceUV= False - self.materials= [] - self.realmesh= mesh - - def addFace(self, nmf): - self.faces.append(nmf) - - def Face(self, v=[]): - return NMFace(v) - def Vert(self, x,y,z): - return NMVert(x,y,z) - - def hasFaceUV(self, flag): - if flag: - self.faceUV= True - else: - self.faceUV= False - - def addMaterial(self, mat): - self.materials.append(mat) - - def update(self, recalc_normals=False): # recalc_normals is dummy - mesh= self.realmesh - mesh.verts= None # Clears the - - # Add in any verts from faces we may have not added. - for nmf in self.faces: - for nmv in nmf.v: - if nmv.index==-1: - nmv.index= len(self.verts) - self.verts.append(nmv) - - - mesh.verts.extend([nmv.co for nmv in self.verts]) - for i, nmv in enumerate(self.verts): - nmv.index= i - mv= mesh.verts[i] - mv.sel= nmv.sel - - good_faces= [nmf for nmf in self.faces if len(nmf.v) in (3,4)] - #print len(good_faces), 'AAA' - - - #mesh.faces.extend([nmf.v for nmf in self.faces]) - mesh.faces.extend([[mesh.verts[nmv.index] for nmv in nmf.v] for nmf in good_faces]) - if len(mesh.faces): - if self.faceUV: - mesh.faceUV= 1 - - #for i, nmf in enumerate(self.faces): - for i, nmf in enumerate(good_faces): - mf= mesh.faces[i] - if self.faceUV: - if len(nmf.uv) == len(mf.v): - mf.uv= [Vector(uv[0], uv[1]) for uv in nmf.uv] - if len(nmf.col) == len(mf.v): - for c, i in enumerate(mf.col): - c.r, c.g, c.b= nmf.col[i].r, nmf.col[i].g, nmf.col[i].b - if nmf.image: - mf.image= nmf.image - - mesh.materials= self.materials[:16] - -class NMVert(object): - __slots__= 'co', 'index', 'no', 'sel', 'uvco' - def __init__(self, x,y,z): - self.co= Vector(x,y,z) - self.index= None # set on appending. - self.no= Vector(0,0,1) # dummy - self.sel= 0 - self.uvco= None -class NMFace(object): - __slots__= 'col', 'flag', 'hide', 'image', 'mat', 'materialIndex', 'mode', 'normal',\ - 'sel', 'smooth', 'transp', 'uv', 'v' - - def __init__(self, v=[]): - self.col= [] - self.flag= 0 - self.hide= 0 - self.image= None - self.mat= 0 # materialIndex needs support too. - self.mode= 0 - self.normal= Vector(0,0,1) - self.uv= [] - self.sel= 0 - self.smooth= 0 - self.transp= 0 - self.uv= [] - self.v= [] # a list of nmverts. - -class NMCol(object): - __slots__ = 'r', 'g', 'b', 'a' - def __init__(self): - self.r= 255 - self.g= 255 - self.b= 255 - self.a= 255 - - -''' -# -verts_split= [dict() for i in xrange(len(me.verts))] - -tot_verts= 0 -for f in me.faces: - f_uv= f.uv - for i, v in enumerate(f.v): - vert_index= v.index # mesh index - vert_dict= verts_split[vert_index] # get the dict for this vert - - uv= f_uv[i] - # now we have the vert and the face uv well make a unique dict. - - vert_key= v.x, v.y, v.x, uv.x, uv.y # ADD IMAGE NAME HETR IF YOU WANT TO SPLIT BY THAT TOO - value= vert_index, tot_verts # ADD WEIGHT HERE IF YOU NEED. - try: - vert_dict[vert_key] # if this is missing it will fail. - except: - # this stores a mapping between the split and orig vert indicies - vert_dict[vert_key]= value - tot_verts+= 1 - -# a flat list of split verts - can add custom weight data here too if you need -split_verts= [None]*tot_verts - -for vert_split_dict in verts_split: - for key, value in vert_split_dict.iteritems(): - local_index, split_index= value - split_verts[split_index]= key - -# split_verts - Now you have a list of verts split by their UV. -''' diff --git a/release/scripts/bpymodules/BPyMesh_redux.py b/release/scripts/bpymodules/BPyMesh_redux.py deleted file mode 100644 index 5955d696fbd..00000000000 --- a/release/scripts/bpymodules/BPyMesh_redux.py +++ /dev/null @@ -1,652 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# (C) Copyright 2006 MetaVR, Inc. -# http://www.metavr.com -# Written by Campbell 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 ***** -# -------------------------------------------------------------------------- - -import Blender -import bpy -Vector= Blender.Mathutils.Vector -Ang= Blender.Mathutils.AngleBetweenVecs -MidpointVecs= Blender.Mathutils.MidpointVecs -import BPyMesh - -# If python version is less than 2.4, try to get set stuff from module - -try: - set -except: - try: - from sets import Set as set - except: - set= None - -def uv_key(uv): - return round(uv.x, 5), round(uv.y, 5) - -def uv_key_mix(uv1, uv2, w1, w2): - # Weighted mix. w1+w2==1.0 - return w1*uv1[0]+w2*uv2[0], w1*uv1[1]+w2*uv2[1] - -def col_key(col): - return col.r, col.g, col.b - -def col_key_mix(col1, col2, w1, w2): - # Weighted mix. w1+w2==1.0 - return int(w1*col1[0] + w2*col2[0]), int(w1*col1[1] + w2*col2[1]), int(w1*col1[2]+col2[2]*w2) - - -def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=2.0, REMOVE_DOUBLES=False, FACE_AREA_WEIGHT=1.0, FACE_TRIANGULATE=True, DO_UV=True, DO_VCOL=True, DO_WEIGHTS=True, VGROUP_INF_REDUX= None, VGROUP_INF_WEIGHT=0.5): - """ - BOUNDRY_WEIGHT - 0 is no boundry weighting. 2.0 will make them twice as unlikely to collapse. - FACE_AREA_WEIGHT - 0 is no weight. 1 is normal, 2.0 is higher. - """ - - if REDUX<0 or REDUX>1.0: - raise 'Error, factor must be between 0 and 1.0' - elif not set: - raise 'Error, this function requires Python 2.4 or a full install of Python 2.3' - - BOUNDRY_WEIGHT= 1+BOUNDRY_WEIGHT - - """ # DEBUG! - if Blender.Get('rt') == 1000: - DEBUG=True - else: - DEBUG= False - """ - - me= ob.getData(mesh=1) - me.hide= False # unhide all data,. - if len(me.faces)<5: - return - - - - if FACE_TRIANGULATE or REMOVE_DOUBLES: - me.sel= True - - if FACE_TRIANGULATE: - me.quadToTriangle() - - if REMOVE_DOUBLES: - me.remDoubles(0.0001) - - vgroups= me.getVertGroupNames() - - if not me.getVertGroupNames(): - DO_WEIGHTS= False - - if (VGROUP_INF_REDUX!= None and VGROUP_INF_REDUX not in vgroups) or\ - VGROUP_INF_WEIGHT==0.0: - VGROUP_INF_REDUX= None - - try: - VGROUP_INF_REDUX_INDEX= vgroups.index(VGROUP_INF_REDUX) - except: - VGROUP_INF_REDUX_INDEX= -1 - - # del vgroups - len_vgroups= len(vgroups) - - - - OLD_MESH_MODE= Blender.Mesh.Mode() - Blender.Mesh.Mode(Blender.Mesh.SelectModes.VERTEX) - - if DO_UV and not me.faceUV: - DO_UV= False - - if DO_VCOL and not me.vertexColors: - DO_VCOL = False - - current_face_count= len(me.faces) - target_face_count= int(current_face_count * REDUX) - # % of the collapseable faces to collapse per pass. - #collapse_per_pass= 0.333 # between 0.1 - lots of small nibbles, slow but high q. and 0.9 - big passes and faster. - collapse_per_pass= 0.333 # between 0.1 - lots of small nibbles, slow but high q. and 0.9 - big passes and faster. - - """# DEBUG! - if DEBUG: - COUNT= [0] - def rd(): - if COUNT[0]< 330: - COUNT[0]+=1 - return - me.update() - Blender.Window.RedrawAll() - print 'Press key for next, count "%s"' % COUNT[0] - try: input() - except KeyboardInterrupt: - raise "Error" - except: - pass - - COUNT[0]+=1 - """ - - class collapseEdge(object): - __slots__ = 'length', 'key', 'faces', 'collapse_loc', 'v1', 'v2','uv1', 'uv2', 'col1', 'col2', 'collapse_weight' - def __init__(self, ed): - self.init_from_edge(ed) # So we can re-use the classes without using more memory. - - def init_from_edge(self, ed): - self.key= ed.key - self.length= ed.length - self.faces= [] - self.v1= ed.v1 - self.v2= ed.v2 - if DO_UV or DO_VCOL: - self.uv1= [] - self.uv2= [] - self.col1= [] - self.col2= [] - - # self.collapse_loc= None # new collapse location. - # Basic weighting. - #self.collapse_weight= self.length * (1+ ((ed.v1.no-ed.v2.no).length**2)) - self.collapse_weight= 1.0 - - def collapse_locations(self, w1, w2): - ''' - Generate a smart location for this edge to collapse to - w1 and w2 are vertex location bias - ''' - - v1co= self.v1.co - v2co= self.v2.co - v1no= self.v1.no - v2no= self.v2.no - - # Basic operation, works fine but not as good as predicting the best place. - #between= ((v1co*w1) + (v2co*w2)) - #self.collapse_loc= between - - # normalize the weights of each vert - se we can use them as scalers. - wscale= w1+w2 - if not wscale: # no scale? - w1=w2= 0.5 - else: - w1/=wscale - w2/=wscale - - length= self.length - between= MidpointVecs(v1co, v2co) - - # Collapse - # new_location = between # Replace tricky code below. this code predicts the best collapse location. - - # Make lines at right angles to the normals- these 2 lines will intersect and be - # the point of collapsing. - - # Enlarge so we know they intersect: self.length*2 - cv1= v1no.cross(v1no.cross(v1co-v2co)) - cv2= v2no.cross(v2no.cross(v2co-v1co)) - - # Scale to be less then the edge lengths. - cv2.length = cv1.length = 1 - - cv1 = cv1 * (length* 0.4) - cv2 = cv2 * (length* 0.4) - - smart_offset_loc= between + (cv1 + cv2) - - # Now we need to blend between smart_offset_loc and w1/w2 - # you see were blending between a vert and the edges midpoint, so we cant use a normal weighted blend. - if w1 > 0.5: # between v1 and smart_offset_loc - #self.collapse_loc= v1co*(w2+0.5) + smart_offset_loc*(w1-0.5) - w2*=2 - w1= 1-w2 - new_loc_smart= v1co*w1 + smart_offset_loc*w2 - else: # w between v2 and smart_offset_loc - w1*=2 - w2= 1-w1 - new_loc_smart= v2co*w2 + smart_offset_loc*w1 - - if new_loc_smart.x != new_loc_smart.x: # NAN LOCATION, revert to between - new_loc_smart= None - - return new_loc_smart, between, v1co*0.99999 + v2co*0.00001, v1co*0.00001 + v2co*0.99999 - - - class collapseFace(object): - __slots__ = 'verts', 'normal', 'area', 'index', 'orig_uv', 'orig_col', 'uv', 'col' # , 'collapse_edge_count' - def __init__(self, f): - self.init_from_face(f) - - def init_from_face(self, f): - self.verts= f.v - self.normal= f.no - self.area= f.area - self.index= f.index - if DO_UV: - self.orig_uv= [uv_key(uv) for uv in f.uv] - self.uv= f.uv - if DO_VCOL: - self.orig_col= [col_key(col) for col in f.col] - self.col= f.col - - collapse_edges= collapse_faces= None - - # So meshCalcNormals can avoid making a new list all the time. - reuse_vertNormals= [ Vector() for v in xrange(len(me.verts)) ] - - while target_face_count <= len(me.faces): - BPyMesh.meshCalcNormals(me, reuse_vertNormals) - - if DO_WEIGHTS: - #groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me) - groupNames, vWeightList= BPyMesh.meshWeight2List(me) - - # THIS CRASHES? Not anymore. - verts= list(me.verts) - edges= list(me.edges) - faces= list(me.faces) - - # THIS WORKS - #verts= me.verts - #edges= me.edges - #faces= me.faces - - # if DEBUG: DOUBLE_CHECK= [0]*len(verts) - me.sel= False - - if not collapse_faces: # Initialize the list. - collapse_faces= [collapseFace(f) for f in faces] - collapse_edges= [collapseEdge(ed) for ed in edges] - else: - for i, ed in enumerate(edges): - collapse_edges[i].init_from_edge(ed) - - # Strip the unneeded end off the list - collapse_edges[i+1:]= [] - - for i, f in enumerate(faces): - collapse_faces[i].init_from_face(f) - - # Strip the unneeded end off the list - collapse_faces[i+1:]= [] - - - collapse_edges_dict= dict( [(ced.key, ced) for ced in collapse_edges] ) - - # Store verts edges. - vert_ed_users= [[] for i in xrange(len(verts))] - for ced in collapse_edges: - vert_ed_users[ced.key[0]].append(ced) - vert_ed_users[ced.key[1]].append(ced) - - # Store face users - vert_face_users= [[] for i in xrange(len(verts))] - - # Have decieded not to use this. area is better. - #face_perim= [0.0]* len(me.faces) - - for ii, cfa in enumerate(collapse_faces): - for i, v1 in enumerate(cfa.verts): - vert_face_users[v1.index].append( (i,cfa) ) - - # add the uv coord to the vert - v2 = cfa.verts[i-1] - i1= v1.index - i2= v2.index - - if i1>i2: ced= collapse_edges_dict[i2,i1] - else: ced= collapse_edges_dict[i1,i2] - - ced.faces.append(cfa) - if DO_UV or DO_VCOL: - # if the edge is flipped from its order in the face then we need to flip the order indicies. - if cfa.verts[i]==ced.v1: i1,i2 = i, i-1 - else: i1,i2 = i-1, i - - if DO_UV: - ced.uv1.append( cfa.orig_uv[i1] ) - ced.uv2.append( cfa.orig_uv[i2] ) - - if DO_VCOL: - ced.col1.append( cfa.orig_col[i1] ) - ced.col2.append( cfa.orig_col[i2] ) - - - # PERIMITER - #face_perim[ii]+= ced.length - - - - # How weight the verts by the area of their faces * the normal difference. - # when the edge collapses, to vert weights are taken into account - - vert_weights= [0.5] * len(verts) - - for ii, vert_faces in enumerate(vert_face_users): - for f in vert_faces: - try: - no_ang= (Ang(verts[ii].no, f[1].normal)/180) * f[1].area - except: - no_ang= 1.0 - - vert_weights[ii] += no_ang - - # Use a vertex group as a weighting. - if VGROUP_INF_REDUX!=None: - - # Get Weights from a vgroup. - """ - vert_weights_map= [1.0] * len(verts) - for i, wd in enumerate(vWeightDict): - try: vert_weights_map[i]= 1+(wd[VGROUP_INF_REDUX] * VGROUP_INF_WEIGHT) - except: pass - """ - vert_weights_map= [1+(wl[VGROUP_INF_REDUX_INDEX]*VGROUP_INF_WEIGHT) for wl in vWeightList ] - - - # BOUNDRY CHECKING AND WEIGHT EDGES. CAN REMOVE - # Now we know how many faces link to an edge. lets get all the boundry verts - if BOUNDRY_WEIGHT > 0: - verts_boundry= [1] * len(verts) - #for ed_idxs, faces_and_uvs in edge_faces_and_uvs.iteritems(): - for ced in collapse_edges: - if len(ced.faces) < 2: - for key in ced.key: # only ever 2 key indicies. - verts_boundry[key]= 2 - - for ced in collapse_edges: - b1= verts_boundry[ced.key[0]] - b2= verts_boundry[ced.key[1]] - if b1 != b2: - # Edge has 1 boundry and 1 non boundry vert. weight higher - ced.collapse_weight= BOUNDRY_WEIGHT - #elif b1==b2==2: # if both are on a seam then weigh half as bad. - # ced.collapse_weight= ((BOUNDRY_WEIGHT-1)/2) +1 - # weight the verts by their boundry status - del b1 - del b2 - - for ii, boundry in enumerate(verts_boundry): - if boundry==2: - vert_weights[ii] *= BOUNDRY_WEIGHT - - vert_collapsed= verts_boundry - del verts_boundry - else: - vert_collapsed= [1] * len(verts) - - - - - # Best method, no quick hacks here, Correction. Should be the best but needs tweaks. - def ed_set_collapse_error(ced): - # Use the vertex weights to bias the new location. - new_locs= ced.collapse_locations(vert_weights[ced.key[0]], vert_weights[ced.key[1]]) - - - # Find the connecting faces of the 2 verts. - i1, i2= ced.key - test_faces= set() - for i in (i1,i2): # faster then LC's - for f in vert_face_users[i]: - test_faces.add(f[1].index) - for f in ced.faces: - test_faces.remove(f.index) - - - v1_orig= Vector(ced.v1.co) - v2_orig= Vector(ced.v2.co) - - def test_loc(new_loc): - ''' - Takes a location and tests the error without changing anything - ''' - new_weight= ced.collapse_weight - ced.v1.co= ced.v2.co= new_loc - - new_nos= [faces[i].no for i in test_faces] - - # So we can compare the befire and after normals - ced.v1.co= v1_orig - ced.v2.co= v2_orig - - # now see how bad the normals are effected - angle_diff= 1.0 - - for ii, i in enumerate(test_faces): # local face index, global face index - cfa= collapse_faces[i] # this collapse face - try: - # can use perim, but area looks better. - if FACE_AREA_WEIGHT: - # Psudo code for wrighting - # angle_diff= The before and after angle difference between the collapsed and un-collapsed face. - # ... devide by 180 so the value will be between 0 and 1.0 - # ... add 1 so we can use it as a multiplyer and not make the area have no eefect (below) - # area_weight= The faces original area * the area weight - # ... add 1.0 so a small area face dosent make the angle_diff have no effect. - # - # Now multiply - (angle_diff * area_weight) - # ... The weight will be a minimum of 1.0 - we need to subtract this so more faces done give the collapse an uneven weighting. - - angle_diff+= ((1+(Ang(cfa.normal, new_nos[ii])/180)) * (1+(cfa.area * FACE_AREA_WEIGHT))) -1 # 4 is how much to influence area - else: - angle_diff+= (Ang(cfa.normal), new_nos[ii])/180 - - except: - pass - - - # This is very arbirary, feel free to modify - try: no_ang= (Ang(ced.v1.no, ced.v2.no)/180) + 1 - except: no_ang= 2.0 - - # do *= because we face the boundry weight to initialize the weight. 1.0 default. - new_weight *= ((no_ang * ced.length) * (1-(1/angle_diff)))# / max(len(test_faces), 1) - return new_weight - # End testloc - - - # Test the collapse locatons - collapse_loc_best= None - collapse_weight_best= 1000000000 - ii= 0 - for collapse_loc in new_locs: - if collapse_loc: # will only ever fail if smart loc is NAN - test_weight= test_loc(collapse_loc) - if test_weight < collapse_weight_best: - iii= ii - collapse_weight_best = test_weight - collapse_loc_best= collapse_loc - ii+=1 - - ced.collapse_loc= collapse_loc_best - ced.collapse_weight= collapse_weight_best - - - # are we using a weight map - if VGROUP_INF_REDUX: - v= vert_weights_map[i1]+vert_weights_map[i2] - ced.collapse_weight*= v - # End collapse Error - - # We can calculate the weights on __init__ but this is higher qualuity. - for ced in collapse_edges: - if ced.faces: # dont collapse faceless edges. - ed_set_collapse_error(ced) - - # Wont use the function again. - del ed_set_collapse_error - # END BOUNDRY. Can remove - - # sort by collapse weight - try: collapse_edges.sort(key = lambda ced: ced.collapse_weight) # edges will be used for sorting - except: collapse_edges.sort(lambda ced1, ced2: cmp(ced1.collapse_weight, ced2.collapse_weight)) # edges will be used for sorting - - - vert_collapsed= [0]*len(verts) - - collapse_edges_to_collapse= [] - - # Make a list of the first half edges we can collapse, - # these will better edges to remove. - collapse_count=0 - for ced in collapse_edges: - if ced.faces: - i1, i2= ced.key - # Use vert selections - if vert_collapsed[i1] or vert_collapsed[i2]: - pass - else: - # Now we know the verts havnyt been collapsed. - vert_collapsed[i2]= vert_collapsed[i1]= 1 # Dont collapse again. - collapse_count+=1 - collapse_edges_to_collapse.append(ced) - - # Get a subset of the entire list- the first "collapse_per_pass", that are best to collapse. - if collapse_count > 4: - collapse_count = int(collapse_count*collapse_per_pass) - else: - collapse_count = len(collapse_edges) - # We know edge_container_list_collapse can be removed. - for ced in collapse_edges_to_collapse: - """# DEBUG! - if DEBUG: - if DOUBLE_CHECK[ced.v1.index] or\ - DOUBLE_CHECK[ced.v2.index]: - raise 'Error' - else: - DOUBLE_CHECK[ced.v1.index]=1 - DOUBLE_CHECK[ced.v2.index]=1 - - tmp= (ced.v1.co+ced.v2.co)*0.5 - Blender.Window.SetCursorPos(tmp.x, tmp.y, tmp.z) - Blender.Window.RedrawAll() - """ - - # Chech if we have collapsed our quota. - collapse_count-=1 - if not collapse_count: - break - - current_face_count -= len(ced.faces) - - # Find and assign the real weights based on collapse loc. - - # Find the weights from the collapse error - if DO_WEIGHTS or DO_UV or DO_VCOL: - i1, i2= ced.key - # Dont use these weights since they may not have been used to make the collapse loc. - #w1= vert_weights[i1] - #w2= vert_weights[i2] - w1= (ced.v2.co-ced.collapse_loc).length - w2= (ced.v1.co-ced.collapse_loc).length - - # Normalize weights - wscale= w1+w2 - if not wscale: # no scale? - w1=w2= 0.5 - else: - w1/= wscale - w2/= wscale - - - # Interpolate the bone weights. - if DO_WEIGHTS: - - # add verts vgroups to eachother - wl1= vWeightList[i1] # v1 weight dict - wl2= vWeightList[i2] # v2 weight dict - for group_index in xrange(len_vgroups): - wl1[group_index]= wl2[group_index]= (wl1[group_index]*w1) + (wl2[group_index]*w2) - # Done finding weights. - - - - if DO_UV or DO_VCOL: - # Handel UV's and vert Colors! - for v, my_weight, other_weight, edge_my_uvs, edge_other_uvs, edge_my_cols, edge_other_cols in (\ - (ced.v1, w1, w2, ced.uv1, ced.uv2, ced.col1, ced.col2),\ - (ced.v2, w2, w1, ced.uv2, ced.uv1, ced.col2, ced.col1)\ - ): - uvs_mixed= [ uv_key_mix(edge_my_uvs[iii], edge_other_uvs[iii], my_weight, other_weight) for iii in xrange(len(edge_my_uvs)) ] - cols_mixed= [ col_key_mix(edge_my_cols[iii], edge_other_cols[iii], my_weight, other_weight) for iii in xrange(len(edge_my_cols)) ] - - for face_vert_index, cfa in vert_face_users[v.index]: - if len(cfa.verts)==3 and cfa not in ced.faces: # if the face is apart of this edge then dont bother finding the uvs since the face will be removed anyway. - - if DO_UV: - # UV COORDS - uvk= cfa.orig_uv[face_vert_index] - try: - tex_index= edge_my_uvs.index(uvk) - except: - tex_index= None - """ # DEBUG! - if DEBUG: - print 'not found', uvk, 'in', edge_my_uvs, 'ed index', ii, '\nwhat about', edge_other_uvs - """ - if tex_index != None: # This face uses a uv in the collapsing face. - do a merge - other_uv= edge_other_uvs[tex_index] - uv_vec= cfa.uv[face_vert_index] - uv_vec.x, uv_vec.y= uvs_mixed[tex_index] - - # TEXFACE COLORS - if DO_VCOL: - colk= cfa.orig_col[face_vert_index] - try: tex_index= edge_my_cols.index(colk) - except: pass - if tex_index != None: - other_col= edge_other_cols[tex_index] - col_ob= cfa.col[face_vert_index] - col_ob.r, col_ob.g, col_ob.b= cols_mixed[tex_index] - - # DEBUG! if DEBUG: rd() - - # Execute the collapse - ced.v1.sel= ced.v2.sel= True # Select so remove doubles removed the edges and faces that use it - ced.v1.co= ced.v2.co= ced.collapse_loc - - # DEBUG! if DEBUG: rd() - if current_face_count <= target_face_count: - break - - # Copy weights back to the mesh before we remove doubles. - if DO_WEIGHTS: - #BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) - BPyMesh.list2MeshWeight(me, groupNames, vWeightList) - - doubles= me.remDoubles(0.0001) - current_face_count= len(me.faces) - - if current_face_count <= target_face_count or not doubles: # not doubles shoule never happen. - break - - me.update() - Blender.Mesh.Mode(OLD_MESH_MODE) - - -# Example usage -def main(): - Blender.Window.EditMode(0) - scn= bpy.data.scenes.active - active_ob= scn.objects.active - t= Blender.sys.time() - redux(active_ob, 0.5) - print '%.4f' % (Blender.sys.time()-t) - -if __name__=='__main__': - main() diff --git a/release/scripts/bpymodules/BPyMessages.py b/release/scripts/bpymodules/BPyMessages.py deleted file mode 100644 index 8ee1aa6c707..00000000000 --- a/release/scripts/bpymodules/BPyMessages.py +++ /dev/null @@ -1,61 +0,0 @@ -from Blender import Draw, sys -def Error_NoMeshSelected(): - Draw.PupMenu('Error%t|No mesh objects selected') -def Error_NoActive(): - Draw.PupMenu('Error%t|No active object') -def Error_NoMeshActive(): - Draw.PupMenu('Error%t|Active object is not a mesh') -def Error_NoMeshUvSelected(): - Draw.PupMenu('Error%t|No mesh objects with texface selected') -def Error_NoMeshUvActive(): - Draw.PupMenu('Error%t|Active object is not a mesh with texface') -def Error_NoMeshMultiresEdit(): - Draw.PupMenu('Error%t|Unable to complete action with multires enabled') -def Error_NoMeshFaces(): - Draw.PupMenu('Error%t|Mesh has no faces') - -# File I/O messages -def Error_NoFile(path): - '''True if file missing, False if files there - - Use simply by doing... - if Error_NoFile(path): return - ''' - if not sys.exists(sys.expandpath(path)): - Draw.PupMenu("Error%t|Can't open file: " + path) - return True - return False - -def Error_NoDir(path): - '''True if dirs missing, False if dirs there - - Use simply by doing... - if Error_NoDir(path): return - ''' - if not sys.exists(sys.expandpath(path)): - Draw.PupMenu("Error%t|Path does not exist: " + path) - return True - return False - - -def Warning_MeshDistroyLayers(mesh): - '''Returns true if we can continue to edit the mesh, warn when using NMesh''' - if len(mesh.getUVLayerNames()) >1 and len(mesh.getColorLayerNames()) >1: - return True - - ret = Draw.PupMenu('Warning%t|This script will distroy inactive UV and Color layers, OK?') - if ret == -1: - return False - - return True - -def Warning_SaveOver(path): - '''Returns - True to save, False dont save''' - if sys.exists(sys.expandpath(path)): - ret= Draw.PupMenu('Save over%t|' + path) - if ret == -1: - return False - - return True - - diff --git a/release/scripts/bpymodules/BPyNMesh.py b/release/scripts/bpymodules/BPyNMesh.py deleted file mode 100644 index 043d8514db9..00000000000 --- a/release/scripts/bpymodules/BPyNMesh.py +++ /dev/null @@ -1,48 +0,0 @@ -# $Id$ -# -# -------------------------------------------------------------------------- -# BPyNMesh.py version 0.1 -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** 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 ***** -# -------------------------------------------------------------------------- - - -# -------------------------------------------------------------------------- -# "Apply size and rotation" function by Jonas Petersen -# -------------------------------------------------------------------------- -# This function does (hopefully) exactly what the -# "Apply size and rotation" command does (CTRL-A in Object Mode). -def ApplySizeAndRotation(obj): - if obj.getType() != "Mesh": return - if obj.SizeX==1.0 and obj.SizeY==1.0 and obj.SizeZ==1.0 and obj.RotX == 0.0 and obj.RotY == 0.0 and obj.RotZ == 0.0: return - mesh = obj.getData() - matrix = obj.matrix - v = [0,0,0] - for vert in mesh.verts: - co = vert.co - v[0] = co[0]*matrix[0][0] + co[1]*matrix[1][0] + co[2]*matrix[2][0] - v[1] = co[0]*matrix[0][1] + co[1]*matrix[1][1] + co[2]*matrix[2][1] - v[2] = co[0]*matrix[0][2] + co[1]*matrix[1][2] + co[2]*matrix[2][2] - co[0], co[1], co[2] = v - obj.SizeX = obj.SizeY = obj.SizeZ = 1.0 - obj.RotX = obj.RotY = obj.RotZ = 0.0 - mesh.update() - diff --git a/release/scripts/bpymodules/BPyObject.py b/release/scripts/bpymodules/BPyObject.py deleted file mode 100644 index 54ff949218d..00000000000 --- a/release/scripts/bpymodules/BPyObject.py +++ /dev/null @@ -1,108 +0,0 @@ -import Blender - -def getObjectArmature(ob): - ''' - This returns the first armature the mesh uses. - remember there can be more then 1 armature but most people dont do that. - ''' - if ob.type != 'Mesh': - return None - - arm = ob.parent - if arm and arm.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.ARMATURE: - return arm - - for m in ob.modifiers: - if m.type== Blender.Modifier.Types.ARMATURE: - arm = m[Blender.Modifier.Settings.OBJECT] - if arm: - return arm - - return None - - -def getDerivedObjects(ob, PARTICLES= True): - ''' - Takes an objects and returnes a list of (ob, maxrix4x4) pairs - that are derived from this object - - This will include the object its self if it would be rendered. - all dupli's for eg are not rendered themselves. - - currently supports - * dupligroups - * dupliverts - * dupliframes - * static particles as a mesh - - it is possible this function will return an empty list. - ''' - - ob_mtx_pairs = ob.DupObjects - effects= ob.effects - - # Ignore self if were a dupli* or our parent is a duplivert. - if ob.enableDupFrames or ob.enableDupGroup or ob.enableDupVerts: - pass - else: - parent= ob.parent - if parent and parent.enableDupVerts: - pass - else: - if effects and (not effects[0].flag & Blender.Effect.Flags.EMESH): - # Particles mesh wont render - pass - else: - ob_mtx_pairs.append((ob, ob.matrixWorld)) - - - if PARTICLES: - type_vec= type(Blender.Mathutils.Vector()) - type_tp= type((0,0)) - type_ls= type([]) - - # TODO, particles per child object. - # TODO Support materials - me= Blender.Mesh.New() - for eff in effects: - par= eff.getParticlesLoc() - - if par: - type_par= type(par[0]) - - if type_par == type_vec: - # point particles - me.verts.extend(par) - - elif type_par == type_tp: - # edge pairs - start_index= len(me.verts) - me.verts.extend([v for p in par for v in p]) - me.edges.extend( [(i, i+1) for i in xrange(start_index, start_index + len(par) - 1 )] ) - - elif type_par == type_ls: - # lines of edges - start_index= len(me.verts) - me.verts.extend([v for line in par for v in line]) - - edges= [] - for line in par: - edges.extend( [(i,i+1) for i in xrange(start_index, start_index+len(line)-1) ] ) - start_index+= len(line) - - me.edges.extend(edges) - - if me.verts: - # If we have verts, then add the mesh - ob_par = Blender.Object.New('Mesh') - ob_par.link( me ) - - LOOSE= Blender.Mesh.EdgeFlags.LOOSE - for ed in me.edges: - ed.flag |= LOOSE - - # Particle's are in worldspace so an identity matrix is fine. - ob_mtx_pairs.append( (ob_par, Blender.Mathutils.Matrix()) ) - - return ob_mtx_pairs - - diff --git a/release/scripts/bpymodules/BPyRegistry.py b/release/scripts/bpymodules/BPyRegistry.py deleted file mode 100644 index 4d681e15937..00000000000 --- a/release/scripts/bpymodules/BPyRegistry.py +++ /dev/null @@ -1,267 +0,0 @@ -# -------------------------------------------------------------------------- -# Module BPyRegistry version 0.1 -# Helper functions to store / restore configuration data. -# -------------------------------------------------------------------------- -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br -# -# 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, -# -------------------------------------------------------------------------- - -# The Registry is a Python dictionary that is kept in Blender for as long as -# the program is running, where scripts can store / restore persistent data -# (data that is not lost when the script exits). This module provides -# functions to save and restore Registry entries as config data in the -# bpydata/config folder. Scripts just need to give an extra parameter to -# the Blender.Registry.Get/Set() functions to have their data automatically -# saved and restored when needed. -# -# Note: entries starting with an underscore are not saved, so script authors -# can use that fact to define data that is not meant to be stored in a -# config file. Example: data to be passed to another script and references to -# invalid data, like Blender objects and any function or method. -# -# Check the Blender.Registry documentation for more information. - -import Blender -from Blender import Registry, sys as bsys - -_EXT = '.cfg' # file extension for saved config data - -# limits: -#MAX_ITEMS_NUM = 60 # max number of keys per dict and itens per list and tuple -#MAX_STR_LEN = 300 # max string length (remember this is just for config data) - -_CFG_DIR = '' -if Blender.Get('udatadir'): - _CFG_DIR = Blender.sys.join(Blender.Get('udatadir'), 'config') -if not _CFG_DIR or not bsys.exists(_CFG_DIR): - _CFG_DIR = Blender.sys.join(Blender.Get('datadir'), 'config') -if not bsys.exists(_CFG_DIR): - _CFG_DIR = '' - -# to compare against, so we don't write to a cvs tree: -_CVS_SUBPATH = 'release/scripts/bpydata/config/' -if bsys.dirsep == '\\': - _CVS_SUBPATH = _CVS_SUBPATH.replace('/', '\\') - -_KEYS = [k for k in Registry.Keys() if k[0] != '_'] - -# _ITEMS_NUM = 0 - -def _sanitize(o): - "Check recursively that all objects are valid, set invalid ones to None" - - # global MAX_ITEMS_NUM, MAX_STR_LEN, _ITEMS_NUM - - valid_types = [int, float, bool, long, type] - valid_checked_types = [str, unicode] - # Only very simple types are considered valid for configuration data, - # functions, methods and Blender objects (use their names instead) aren't. - - t = type(o) - - if t == dict: - ''' - _ITEMS_NUM += len(o) - if _ITEMS_NUM > MAX_ITEMS_NUM: - return None - ''' - for k, v in o.iteritems(): - o[k] = _sanitize(v) - elif t in [list, tuple]: - ''' - _ITEMS_NUM += len(o) - if _ITEMS_NUM > MAX_ITEMS_NUM: - return None - ''' - return [_sanitize(i) for i in o] - elif t in valid_types: - return o - elif t in valid_checked_types: - ''' - if len(o) > MAX_STR_LEN: - o = o[:MAX_STR_LEN] - ''' - return o - else: return None - - return o - - -def _dict_to_str(name, d): - "Return a pretty-print version of the passed dictionary" - if not d: return 'None' # d can be None if there was no config to pass - - if name: l = ['%s = {' % name] - else: l = ['{'] - #keys = d.keys() - for k,v in d.iteritems(): # .keys() - if type(v) == dict: - l.append("'%s': %s" % (k, _dict_to_str(None, v))) - else: - l.append("'%s': %s," % (k, repr(v))) - if name: l.append('}') - else: l.append('},') - return "\n".join(l) - -_HELP_MSG = """ -Please create a valid scripts config dir tree either by -copying release/scripts/ tree to your <blenderhome> dir -or by copying release/scripts/bpydata/ tree to a user -defined scripts dir that you can set in the -User Preferences -> Paths tab -> Python path input box. -""" - -def _check_dir(): - global _CFG_DIR, _CVS_SUBPATH, _HELP_MSG - - if not _CFG_DIR: - errmsg = "scripts config dir not found!\n%s" % _HELP_MSG - raise IOError, errmsg - elif _CFG_DIR.find(_CVS_SUBPATH) > 0: - errmsg = """ -Your scripts config dir:\n%s -seems to reside in your local Blender's cvs tree.\n%s""" % (_CFG_DIR, _HELP_MSG) - raise SystemError, errmsg - else: return - - -# API: - -BPY_KEY_MISSING = 0 -BPY_KEY_IN_REGISTRY = 1 -BPY_KEY_IN_FILE = 2 - -def HasConfigData (key): - """ - Check if the given key exists, either already loaded in the Registry dict or - as a file in the script data config dir. - @type key: string - @param key: a given key name. - @returns: - - 0: key does not exist; - - 1: key exists in the Registry dict only; - - 2: key exists as a file only; - - 3: key exists in the Registry dict and also as a file. - @note: for readability it's better to check against the constant bitmasks - BPY_KEY_MISSING = 0, BPY_KEY_IN_REGISTRY = 1 and BPY_KEY_IN_FILE = 2. - """ - - fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT)) - - result = BPY_KEY_MISSING - if key in Registry.Keys(): result |= BPY_KEY_IN_REGISTRY - if bsys.exists(fname): result |= BPY_KEY_IN_FILE - - return result - - -def LoadConfigData (key = None): - """ - Load config data from file(s) to the Registry dictionary. - @type key: string - @param key: a given key name. If None (default), all available keys are - loaded. - @returns: None - """ - - _check_dir() - - import os - - if not key: - files = \ - [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f.endswith(_EXT)] - else: - files = [] - fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT)) - if bsys.exists(fname): files.append(fname) - - for p in files: - try: - f = file(p, 'r') - lines = f.readlines() - f.close() - if lines: # Lines may be blank - mainkey = lines[0].split('=')[0].strip() - pysrc = "\n".join(lines) - exec(pysrc) - exec("Registry.SetKey('%s', %s)" % (str(mainkey), mainkey)) - except Exception, e: - raise Warning(e) # Resend exception as warning - - -def RemoveConfigData (key = None): - """ - Remove this key's config file from the <(u)datadir>/config/ folder. - @type key: string - @param key: the name of the key to be removed. If None (default) all - available config files are deleted. - """ - - _check_dir() - - if not key: - files = \ - [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f.endswith(_EXT)] - else: - files = [] - fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT)) - if bsys.exists(fname): files.append(fname) - - import os - - try: - for p in files: - os.remove(p) # remove the file(s) - except Exception, e: - raise Warning(e) # Resend exception as warning - - -def SaveConfigData (key = None): - """ - Save Registry key(s) as file(s) in the <(u)datadir>/config/ folder. - @type key: string - @param key: the name of the key to be saved. If None (default) all - available keys are saved. - """ - - global _KEYS, _CFG_DIR - - _check_dir() - - if key: keys = [key] - else: keys = _KEYS - - for mainkey in keys: - cfgdict = Registry.GetKey(mainkey).copy() - for k in cfgdict: # .keys() - if not k or k[0] == '_': - del cfgdict[k] - - if not cfgdict: continue - - try: - filename = bsys.join(_CFG_DIR, "%s%s" % (mainkey, _EXT)) - f = file(filename, 'w') - output = _dict_to_str(mainkey, _sanitize(cfgdict)) - if output!='None': - f.write(output) - f.close() - except Exception, e: - raise Warning(e) # Resend exception as warning diff --git a/release/scripts/bpymodules/BPyRender.py b/release/scripts/bpymodules/BPyRender.py deleted file mode 100644 index 951e1ae6300..00000000000 --- a/release/scripts/bpymodules/BPyRender.py +++ /dev/null @@ -1,633 +0,0 @@ -import Blender -from Blender import Scene, sys, Camera, Object, Image -from Blender.Scene import Render -Vector= Blender.Mathutils.Vector - - -def extFromFormat(format): - if format == Render.TARGA: return 'tga' - if format == Render.RAWTGA: return 'tga' - if format == Render.HDR: return 'hdr' - if format == Render.PNG: return 'png' - if format == Render.BMP: return 'bmp' - if format == Render.JPEG: return 'jpg' - if format == Render.HAMX: return 'ham' - if format == Render.TIFF: return 'tif' - if format == Render.CINEON: return 'cine' - if format == Render.DPX: return 'tif' - if format == Render.OPENEXR: return 'exr' - if format == Render.IRIS: return 'rgb' - return '' - - - -def imageFromObjectsOrtho(objects, path, width, height, smooth, alpha= True, camera_matrix= None, format=Render.PNG): - ''' - Takes any number of objects and renders them on the z axis, between x:y-0 and x:y-1 - Usefull for making images from a mesh without per pixel operations - - objects must be alredy placed - - smooth, anti alias True/False - - path renders to a PNG image - - alpha weather to render background as alpha - - returns the blender image - ''' - ext = '.' + extFromFormat(format) - print ext - # remove an extension if its alredy there - if path.lower().endswith(ext): - path= path[:-4] - - path_expand= sys.expandpath(path) + ext - - print path_expand, 'path' - - # Touch the path - try: - f= open(path_expand, 'w') - f.close() - except: - raise 'Error, could not write to path:' + path_expand - - - # RENDER THE FACES. - scn= Scene.GetCurrent() - render_scn= Scene.New() - render_scn.makeCurrent() - render_scn.Layers |= (1<<20)-1 # all layers enabled - - # Add objects into the current scene - for ob in objects: - render_scn.link(ob) - - render_context= render_scn.getRenderingContext() - render_context.setRenderPath('') # so we can ignore any existing path and save to the abs path. - - - render_context.imageSizeX(width) - render_context.imageSizeY(height) - - if smooth: - render_context.enableOversampling(True) - render_context.setOversamplingLevel(16) - else: - render_context.enableOversampling(False) - - render_context.setRenderWinSize(100) - render_context.setImageType(format) - render_context.enableExtensions(True) - #render_context.enableSky() # No alpha needed. - if alpha: - render_context.alphaMode= 1 - render_context.enableRGBAColor() - else: - render_context.alphaMode= 0 - render_context.enableRGBColor() - - render_context.displayMode= 0 # fullscreen - - # New camera and object - render_cam_data= Camera.New('ortho') - render_cam_ob= Object.New('Camera') - render_cam_ob.link(render_cam_data) - render_scn.link(render_cam_ob) - render_scn.objects.camera = render_cam_ob - - render_cam_data.type= 'ortho' - - - - # Position the camera - if camera_matrix: - render_cam_ob.setMatrix(camera_matrix) - # We need to take into account the matrix scaling when setting the size - # so we get the image bounds defined by the matrix - # first get the x and y factors from the matrix. - # To render the correct dimensions we must use the aspy and aspy to force the matrix scale to - # override the aspect enforced by the width and weight. - cent= Vector() * camera_matrix - xvec= Vector(1,0,0) * camera_matrix - yvec= Vector(0,1,0) * camera_matrix - # zvec= Vector(0,0,1) * camera_matrix - xlen = (cent-xvec).length # half height of the image - ylen = (cent-yvec).length # half width of the image - # zlen = (cent-zvec).length # dist to place the camera? - just use the loc for now. - - - # less then 1.0 portrate, 1.0 or more is portrate - asp_cam_mat= xlen/ylen # divide by zero? - possible but scripters fault. - asp_image_res= float(width)/height - #print 'asp quad', asp_cam_mat, 'asp_image', asp_image_res - #print 'xylen', xlen, ylen, 'w/h', width, height - # Setup the aspect - - if asp_cam_mat > asp_image_res: - # camera is wider then image res. - # to make the image wider, reduce the aspy - asp_diff= asp_image_res/asp_cam_mat - min_asp= asp_diff * 200 - #print 'X', min_asp - - elif asp_cam_mat < asp_image_res: # asp_cam_mat < asp_image_res - # camera is narrower then image res - # to make the image narrower, reduce the aspx - asp_diff= asp_cam_mat/asp_image_res - min_asp= asp_diff * 200 - #print 'Y', min_asp - else: - min_asp= 200 - - # set the camera size - if xlen > ylen: - if asp_cam_mat > asp_image_res: - render_context.aspectX= 200 # get the greatest range possible - render_context.aspectY= min_asp # get the greatest range possible - else: - render_context.aspectY= 200 # get the greatest range possible - render_context.aspectX= min_asp # get the greatest range possible - #print "xlen bigger" - render_cam_data.scale= xlen * 2 - elif xlen < ylen:# ylen is bigger - if asp_cam_mat > asp_image_res: - render_context.aspectX= 200 # get the greatest range possible - render_context.aspectY= min_asp # get the greatest range possible - else: - render_context.aspectY= 200 # get the greatest range possible - render_context.aspectX= min_asp # get the greatest range possible - #print "ylen bigger" - render_cam_data.scale= ylen *2 - else: - # asppect 1:1 - #print 'NOLEN Bigger' - render_cam_data.scale= xlen * 2 - - #print xlen, ylen, 'xlen, ylen' - - else: - if width > height: - min_asp = int((float(height) / width) * 200) - render_context.aspectX= min_asp - render_context.aspectY= 200 - else: - min_asp = int((float(width) / height) * 200) - render_context.aspectX= 200 - render_context.aspectY= min_asp - - - render_cam_data.scale= 1.0 - render_cam_ob.LocZ= 1.0 - render_cam_ob.LocX= 0.5 - render_cam_ob.LocY= 0.5 - - Blender.Window.RedrawAll() - - render_context.render() - render_context.saveRenderedImage(path) - Render.CloseRenderWindow() - #if not B.sys.exists(PREF_IMAGE_PATH_EXPAND): - # raise 'Error!!!' - - scn.makeCurrent() - Scene.Unlink(render_scn) - - # NOW APPLY THE SAVED IMAGE TO THE FACES! - #print PREF_IMAGE_PATH_EXPAND - try: - target_image= Image.Load(path_expand) - return target_image - except: - raise 'Error: Could not render or load the image at path "%s"' % path_expand - return - - - -#-----------------------------------------------------------------------------# -# UV Baking functions, make a picture from mesh(es) uvs # -#-----------------------------------------------------------------------------# - -def mesh2uv(me_s, PREF_SEL_FACES_ONLY=False): - ''' - Converts a uv mapped mesh into a 2D Mesh from UV coords. - returns a triple - - (mesh2d, face_list, col_list) - "mesh" is the new mesh and... - "face_list" is the faces that were used to make the mesh, - "material_list" is a list of materials used by each face - These are in alligned with the meshes faces, so you can easerly copy data between them - - ''' - render_me= Blender.Mesh.New() - render_me.verts.extend( [Vector(0,0,0),] ) # 0 vert uv bugm dummy vert - face_list= [] - material_list= [] - for me in me_s: - me_materials= me.materials - if PREF_SEL_FACES_ONLY: - me_faces= [f for f in me.faces if f.sel] - else: - me_faces= me.faces - - face_list.extend(me_faces) - - # Dittro - if me_materials: - material_list.extend([me_materials[f.mat] for f in me_faces]) - else: - material_list.extend([None]*len(me_faces)) - - # Now add the verts - render_me.verts.extend( [ Vector(uv.x, uv.y, 0) for f in face_list for uv in f.uv ] ) - - # Now add the faces - tmp_faces= [] - vert_offset= 1 - for f in face_list: - tmp_faces.append( [ii+vert_offset for ii in xrange(len(f))] ) - vert_offset+= len(f) - - render_me.faces.extend(tmp_faces) - render_me.faceUV=1 - return render_me, face_list, material_list - - -def uvmesh_apply_normals(render_me, face_list): - '''Worldspace normals to vertex colors''' - for i, f in enumerate(render_me.faces): - face_orig= face_list[i] - f_col= f.col - for j, v in enumerate(face_orig): - c= f_col[j] - nx, ny, nz= v.no - c.r= int((nx+1)*128)-1 - c.g= int((ny+1)*128)-1 - c.b= int((nz+1)*128)-1 - -def uvmesh_apply_image(render_me, face_list): - '''Copy the image and uvs from the original faces''' - for i, f in enumerate(render_me.faces): - f.uv= face_list[i].uv - f.image= face_list[i].image - - -def uvmesh_apply_vcol(render_me, face_list): - '''Copy the vertex colors from the original faces''' - for i, f in enumerate(render_me.faces): - face_orig= face_list[i] - f_col= f.col - for j, c_orig in enumerate(face_orig.col): - c= f_col[j] - c.r= c_orig.r - c.g= c_orig.g - c.b= c_orig.b - -def uvmesh_apply_matcol(render_me, material_list): - '''Get the vertex colors from the original materials''' - for i, f in enumerate(render_me.faces): - mat_orig= material_list[i] - f_col= f.col - if mat_orig: - for c in f_col: - c.r= int(mat_orig.R*255) - c.g= int(mat_orig.G*255) - c.b= int(mat_orig.B*255) - else: - for c in f_col: - c.r= 255 - c.g= 255 - c.b= 255 - -def uvmesh_apply_col(render_me, color): - '''Get the vertex colors from the original materials''' - r,g,b= color - for i, f in enumerate(render_me.faces): - f_col= f.col - for c in f_col: - c.r= r - c.g= g - c.b= b - - -def vcol2image(me_s,\ - PREF_IMAGE_PATH,\ - PREF_IMAGE_SIZE,\ - PREF_IMAGE_BLEED,\ - PREF_IMAGE_SMOOTH,\ - PREF_IMAGE_WIRE,\ - PREF_IMAGE_WIRE_INVERT,\ - PREF_IMAGE_WIRE_UNDERLAY,\ - PREF_USE_IMAGE,\ - PREF_USE_VCOL,\ - PREF_USE_MATCOL,\ - PREF_USE_NORMAL,\ - PREF_USE_TEXTURE,\ - PREF_SEL_FACES_ONLY): - - - def rnd_mat(): - render_mat= Blender.Material.New() - mode= render_mat.mode - - # Dont use lights ever - mode |= Blender.Material.Modes.SHADELESS - - if PREF_IMAGE_WIRE: - # Set the wire color - if PREF_IMAGE_WIRE_INVERT: - render_mat.rgbCol= (1,1,1) - else: - render_mat.rgbCol= (0,0,0) - - mode |= Blender.Material.Modes.WIRE - if PREF_USE_VCOL or PREF_USE_MATCOL or PREF_USE_NORMAL: # both vcol and material color use vertex cols to avoid the 16 max limit in materials - mode |= Blender.Material.Modes.VCOL_PAINT - if PREF_USE_IMAGE: - mode |= Blender.Material.Modes.TEXFACE - - # Copy back the mode - render_mat.mode |= mode - return render_mat - - - render_me, face_list, material_list= mesh2uv(me_s, PREF_SEL_FACES_ONLY) - - # Normals exclude all others - if PREF_USE_NORMAL: - uvmesh_apply_normals(render_me, face_list) - else: - if PREF_USE_IMAGE: - uvmesh_apply_image(render_me, face_list) - uvmesh_apply_vcol(render_me, face_list) - - elif PREF_USE_VCOL: - uvmesh_apply_vcol(render_me, face_list) - - elif PREF_USE_MATCOL: - uvmesh_apply_matcol(render_me, material_list) - - elif PREF_USE_TEXTURE: - # if we have more then 16 materials across all the mesh objects were stuffed :/ - # get unique materials - tex_unique_materials= dict([(mat.name, mat) for mat in material_list]).values()[:16] # just incase we have more then 16 - tex_me= Blender.Mesh.New() - - # Backup the original shadless setting - tex_unique_materials_shadeless= [ mat.mode & Blender.Material.Modes.SHADELESS for mat in tex_unique_materials ] - - # Turn shadeless on - for mat in tex_unique_materials: - mat.mode |= Blender.Material.Modes.SHADELESS - - # Assign materials - render_me.materials= tex_unique_materials - - - - tex_material_indicies= dict([(mat.name, i) for i, mat in enumerate(tex_unique_materials)]) - - tex_me.verts.extend([Vector(0,0,0),]) # dummy - tex_me.verts.extend( [ Vector(v.co) for f in face_list for v in f ] ) - - # Now add the faces - tmp_faces= [] - vert_offset= 1 - for f in face_list: - tmp_faces.append( [ii+vert_offset for ii in xrange(len(f))] ) - vert_offset+= len(f) - - tex_me.faces.extend(tmp_faces) - - # Now we have the faces, put materials and normal, uvs into the mesh - if len(tex_me.faces) != len(face_list): - # Should never happen - raise "Error face length mismatch" - - # Copy data to the mesh that could be used as texture coords - for i, tex_face in enumerate(tex_me.faces): - orig_face= face_list[i] - - # Set the material index - try: - render_face.mat= tex_material_indicies[ material_list[i].name ] - except: - # more then 16 materials - pass - - - # set the uvs on the texmesh mesh - tex_face.uv= orig_face.uv - - orig_face_v= orig_face.v - # Set the normals - for j, v in enumerate(tex_face): - v.no= orig_face_v[j].no - - # Set the texmesh - render_me.texMesh= tex_me - # END TEXMESH - - - # Handel adding objects - render_ob= Blender.Object.New('Mesh') - render_ob.link(render_me) - - if not PREF_USE_TEXTURE: # textures use the original materials - render_me.materials= [rnd_mat()] - - - obs= [render_ob] - - - if PREF_IMAGE_WIRE_UNDERLAY: - # Make another mesh with the material colors - render_me_under, face_list, material_list= mesh2uv(me_s, PREF_SEL_FACES_ONLY) - - uvmesh_apply_matcol(render_me_under, material_list) - - # Handel adding objects - render_ob= Blender.Object.New('Mesh') - render_ob.link(render_me_under) - render_ob.LocZ= -0.01 - - # Add material and disable wire - mat= rnd_mat() - mat.rgbCol= 1,1,1 - mat.alpha= 0.5 - mat.mode &= ~Blender.Material.Modes.WIRE - mat.mode |= Blender.Material.Modes.VCOL_PAINT - - render_me_under.materials= [mat] - - obs.append(render_ob) - - elif PREF_IMAGE_BLEED and not PREF_IMAGE_WIRE: - # EVIL BLEEDING CODE!! - Just do copys of the mesh and place behind. Crufty but better then many other methods I have seen. - Cam - BLEED_PIXEL= 1.0/PREF_IMAGE_SIZE - z_offset= 0.0 - for i in xrange(PREF_IMAGE_BLEED): - for diag1, diag2 in ((-1,-1),(-1,1),(1,-1),(1,1), (1,0), (0,1), (-1,0), (0, -1)): # This line extends the object in 8 different directions, top avoid bleeding. - - render_ob= Blender.Object.New('Mesh') - render_ob.link(render_me) - - render_ob.LocX= (i+1)*diag1*BLEED_PIXEL - render_ob.LocY= (i+1)*diag2*BLEED_PIXEL - render_ob.LocZ= -z_offset - - obs.append(render_ob) - z_offset += 0.01 - - - - image= imageFromObjectsOrtho(obs, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_IMAGE_SIZE, PREF_IMAGE_SMOOTH) - - # Clear from memory as best as we can - render_me.verts= None - - if PREF_IMAGE_WIRE_UNDERLAY: - render_me_under.verts= None - - if PREF_USE_TEXTURE: - tex_me.verts= None - # Restire Shadeless setting - for i, mat in enumerate(tex_unique_materials): - # we know there all on so turn it off of its not set - if not tex_unique_materials_shadeless[i]: - mat.mode &= ~Blender.Material.Modes.SHADELESS - - return image - -def bakeToPlane(sce, ob_from, width, height, bakemodes, axis='z', margin=0, depth=32): - ''' - Bakes terrain onto a plane from one object - sce - scene to bake with - ob_from - mesh object - width/height - image size - bakemodes - list of baking modes to use, Blender.Scene.Render.BakeModes.NORMALS, Blender.Scene.Render.BakeModes.AO ... etc - axis - axis to allign the plane to. - margin - margin setting for baking. - depth - bit depth for the images to bake into, (32 or 128 for floating point images) - Example: - import Blender - from Blender import * - import BPyRender - sce = Scene.GetCurrent() - ob = Object.Get('Plane') - BPyRender.bakeToPlane(sce, ob, 512, 512, [Scene.Render.BakeModes.DISPLACEMENT, Scene.Render.BakeModes.NORMALS], 'z', 8 ) - ''' - - # Backup bake settings - rend = sce.render - BACKUP_bakeDist = rend.bakeDist - BACKUP_bakeBias = rend.bakeBias - BACKUP_bakeMode = rend.bakeMode - BACKUP_bakeClear = rend.bakeClear - BACKUP_bakeMargin = rend.bakeMargin - BACKUP_bakeToActive = rend.bakeToActive - BACKUP_bakeNormalize = rend.bakeNormalize - - # Backup object selection - BACKUP_obsel = list(sce.objects.selected) - BACKUP_obact = sce.objects.active - - # New bake settings - rend.bakeClear = True - rend.bakeMargin = margin - rend.bakeToActive = True - rend.bakeNormalize = True - - # Assume a mesh - me_from = ob_from.getData(mesh=1) - - xmin = ymin = zmin = 10000000000 - xmax = ymax = zmax =-10000000000 - - # Dont trust bounding boxes :/ - #bounds = ob_from.boundingBox - #for v in bounds: - # x,y,z = tuple(v) - mtx = ob_from.matrixWorld - for v in me_from.verts: - x,y,z = tuple(v.co*mtx) - - xmax = max(xmax, x) - ymax = max(ymax, y) - zmax = max(zmax, z) - - xmin = min(xmin, x) - ymin = min(ymin, y) - zmin = min(zmin, z) - - if axis=='x': - xmed = (xmin+xmax)/2.0 - co1 = (xmed, ymin, zmin) - co2 = (xmed, ymin, zmax) - co3 = (xmed, ymax, zmax) - co4 = (xmed, ymax, zmin) - rend.bakeDist = ((xmax-xmin)/2.0) + 0.000001 # we need a euler value for this since it - elif axis=='y': - ymed = (ymin+ymax)/2.0 - co1 = (xmin, ymed, zmin) - co2 = (xmin, ymed, zmax) - co3 = (xmax, ymed, zmax) - co4 = (xmax, ymed, zmin) - rend.bakeDist = ((ymax-ymin)/2.0) + 0.000001 - elif axis=='z': - zmed = (zmin+zmax)/2.0 - co1 = (xmin, ymin, zmed) - co2 = (xmin, ymax, zmed) - co3 = (xmax, ymax, zmed) - co4 = (xmax, ymin, zmed) - rend.bakeDist = ((zmax-zmin)/2.0) + 0.000001 - else: - raise "invalid axis" - me_plane = Blender.Mesh.New() - ob_plane = Blender.Object.New('Mesh') - ob_plane.link(me_plane) - sce.objects.link(ob_plane) - ob_plane.Layers = ob_from.Layers - - ob_from.sel = 1 # make active - sce.objects.active = ob_plane - ob_plane.sel = 1 - - me_plane.verts.extend([co4, co3, co2, co1]) - me_plane.faces.extend([(0,1,2,3)]) - me_plane.faceUV = True - me_plane_face = me_plane.faces[0] - uvs = me_plane_face.uv - uvs[0].x = 0.0; uvs[0].y = 0.0 - uvs[1].x = 0.0; uvs[1].y = 1.0 - uvs[2].x = 1.0; uvs[2].y = 1.0 - uvs[3].x = 1.0; uvs[3].y = 0.0 - - images_return = [] - - for mode in bakemodes: - img = Blender.Image.New('bake', width, height, depth) - - me_plane_face.image = img - rend.bakeMode = mode - rend.bake() - images_return.append( img ) - - # Restore bake settings - #''' - rend.bakeDist = BACKUP_bakeDist - rend.bakeBias = BACKUP_bakeBias - rend.bakeMode = BACKUP_bakeMode - rend.bakeClear = BACKUP_bakeClear - rend.bakeMargin = BACKUP_bakeMargin - rend.bakeToActive = BACKUP_bakeToActive - rend.bakeNormalize = BACKUP_bakeNormalize - - - # Restore obsel - sce.objects.selected = BACKUP_obsel - sce.objects.active = BACKUP_obact - - me_plane.verts = None - sce.objects.unlink(ob_plane) - #''' - - return images_return - diff --git a/release/scripts/bpymodules/BPySys.py b/release/scripts/bpymodules/BPySys.py deleted file mode 100644 index a2d2120ebff..00000000000 --- a/release/scripts/bpymodules/BPySys.py +++ /dev/null @@ -1,74 +0,0 @@ - -## This was used to make V, but faster not to do all that -##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_' -##v = range(255) -##for c in valid: v.remove(ord(c)) -v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254] -invalid = ''.join([chr(i) for i in v]) -## del v, c, i, valid -del v, i - -def cleanName(name): - for ch in invalid: name = name.replace(ch, '_') - return name - -def caseInsensitivePath(path, RET_FOUND=False): - ''' - Get a case insensitive path on a case sensitive system - - RET_FOUND is for internal use only, to avoid too many calls to os.path.exists - # Example usage - getCaseInsensitivePath('/hOmE/mE/sOmEpAtH.tXt') - ''' - import os # todo, what happens with no os? - - if os==None: - if RET_FOUND: ret = path, True - else: ret = path - return ret - - if path=='' or os.path.exists(path): - if RET_FOUND: ret = path, True - else: ret = path - return ret - - f = os.path.basename(path) # f may be a directory or a file - d = os.path.dirname(path) - - suffix = '' - if not f: # dir ends with a slash? - if len(d) < len(path): - suffix = path[:len(path)-len(d)] - - f = os.path.basename(d) - d = os.path.dirname(d) - - if not os.path.exists(d): - d, found = caseInsensitivePath(d, True) - - if not found: - if RET_FOUND: ret = path, False - else: ret = path - return ret - - # at this point, the directory exists but not the file - - try: # we are expecting 'd' to be a directory, but it could be a file - files = os.listdir(d) - except: - if RET_FOUND: ret = path, False - else: ret = path - - f_low = f.lower() - - try: f_nocase = [fl for fl in files if fl.lower() == f_low][0] - except: f_nocase = None - - if f_nocase: - if RET_FOUND: ret = os.path.join(d, f_nocase) + suffix, True - else: ret = os.path.join(d, f_nocase) + suffix - return ret - else: - if RET_FOUND: ret = path, False - else: ret = path - return ret # cant find the right one, just return the path as is.
\ No newline at end of file diff --git a/release/scripts/bpymodules/BPyTextPlugin.py b/release/scripts/bpymodules/BPyTextPlugin.py deleted file mode 100644 index cd5a085de37..00000000000 --- a/release/scripts/bpymodules/BPyTextPlugin.py +++ /dev/null @@ -1,814 +0,0 @@ -"""The BPyTextPlugin Module - -Use get_cached_descriptor(txt) to retrieve information about the script held in -the txt Text object. - -Use print_cache_for(txt) to print the information to the console. - -Use line, cursor = current_line(txt) to get the logical line and cursor position - -Use get_targets(line, cursor) to find out what precedes the cursor: - aaa.bbb.cc|c.ddd -> ['aaa', 'bbb', 'cc'] - -Use resolve_targets(txt, targets) to turn a target list into a usable object if -one is found to match. -""" - -import bpy, sys, os -import __builtin__, tokenize -from Blender.sys import time -from tokenize import generate_tokens, TokenError, \ - COMMENT, DEDENT, INDENT, NAME, NEWLINE, NL, STRING, NUMBER - -class Definition: - """Describes a definition or defined object through its name, line number - and docstring. This is the base class for definition based descriptors. - """ - - def __init__(self, name, lineno, doc=''): - self.name = name - self.lineno = lineno - self.doc = doc - -class ScriptDesc: - """Describes a script through lists of further descriptor objects (classes, - defs, vars) and dictionaries to built-in types (imports). If a script has - not been fully parsed, its incomplete flag will be set. The time of the last - parse is held by the time field and the name of the text object from which - it was parsed, the name field. - """ - - def __init__(self, name, imports, classes, defs, vars, incomplete=False): - self.name = name - self.imports = imports - self.classes = classes - self.defs = defs - self.vars = vars - self.incomplete = incomplete - self.parse_due = 0 - - def set_delay(self, delay): - self.parse_due = time() + delay - -class ClassDesc(Definition): - """Describes a class through lists of further descriptor objects (defs and - vars). The name of the class is held by the name field and the line on - which it is defined is held in lineno. - """ - - def __init__(self, name, parents, defs, vars, lineno, doc=''): - Definition.__init__(self, name, lineno, doc) - self.parents = parents - self.defs = defs - self.vars = vars - -class FunctionDesc(Definition): - """Describes a function through its name and list of parameters (name, - params) and the line on which it is defined (lineno). - """ - - def __init__(self, name, params, lineno, doc=''): - Definition.__init__(self, name, lineno, doc) - self.params = params - -class VarDesc(Definition): - """Describes a variable through its name and type (if ascertainable) and the - line on which it is defined (lineno). If no type can be determined, type - will equal None. - """ - - def __init__(self, name, type, lineno): - Definition.__init__(self, name, lineno) - self.type = type # None for unknown (supports: dict/list/str) - -# Context types -CTX_UNSET = -1 -CTX_NORMAL = 0 -CTX_SINGLE_QUOTE = 1 -CTX_DOUBLE_QUOTE = 2 -CTX_COMMENT = 3 - -# Python keywords -KEYWORDS = ['and', 'del', 'from', 'not', 'while', 'as', 'elif', 'global', - 'or', 'with', 'assert', 'else', 'if', 'pass', 'yield', - 'break', 'except', 'import', 'print', 'class', 'exec', 'in', - 'raise', 'continue', 'finally', 'is', 'return', 'def', 'for', - 'lambda', 'try' ] - -# Module file extensions -MODULE_EXTS = ['.py', '.pyc', '.pyo', '.pyw', '.pyd'] - -ModuleType = type(__builtin__) -NoneScriptDesc = ScriptDesc('', dict(), dict(), dict(), dict(), True) - -_modules = {} -_modules_updated = 0 -_parse_cache = dict() - -def _load_module_names(): - """Searches the sys.path for module files and lists them, along with - sys.builtin_module_names, in the global dict _modules. - """ - - global _modules - - for n in sys.builtin_module_names: - _modules[n] = None - for p in sys.path: - if p == '': p = os.curdir - if not os.path.isdir(p): continue - for f in os.listdir(p): - for ext in MODULE_EXTS: - if f.endswith(ext): - _modules[f[:-len(ext)]] = None - break - -_load_module_names() - -def _trim_doc(doc): - """Trims the quotes from a quoted STRING token (eg. "'''text'''" -> "text") - """ - - l = len(doc) - i = 0 - while i < l/2 and (doc[i] == "'" or doc[i] == '"'): - i += 1 - return doc[i:-i] - -def resolve_targets(txt, targets): - """Attempts to return a useful object for the locally or externally defined - entity described by targets. If the object is local (defined in txt), a - Definition instance is returned. If the object is external (imported or - built in), the object itself is returned. If no object can be found, None is - returned. - """ - - count = len(targets) - if count==0: return None - - obj = None - local = None - i = 1 - - desc = get_cached_descriptor(txt) - b = targets[0].find('(') - if b==-1: b = None # Trick to let us use [:b] and get the whole string - - if desc.classes.has_key(targets[0][:b]): - local = desc.classes[targets[0][:b]] - elif desc.defs.has_key(targets[0]): - local = desc.defs[targets[0]] - elif desc.vars.has_key(targets[0]): - obj = desc.vars[targets[0]].type - - if local: - while i < count: - b = targets[i].find('(') - if b==-1: b = None - if hasattr(local, 'classes') and local.classes.has_key(targets[i][:b]): - local = local.classes[targets[i][:b]] - elif hasattr(local, 'defs') and local.defs.has_key(targets[i]): - local = local.defs[targets[i]] - elif hasattr(local, 'vars') and local.vars.has_key(targets[i]): - obj = local.vars[targets[i]].type - local = None - i += 1 - break - else: - local = None - break - i += 1 - - if local: return local - - if not obj: - if desc.imports.has_key(targets[0]): - obj = desc.imports[targets[0]] - else: - builtins = get_builtins() - if builtins.has_key(targets[0]): - obj = builtins[targets[0]] - - while obj and i < count: - if hasattr(obj, targets[i]): - obj = getattr(obj, targets[i]) - else: - obj = None - break - i += 1 - - return obj - -def get_cached_descriptor(txt, force_parse=0): - """Returns the cached ScriptDesc for the specified Text object 'txt'. If the - script has not been parsed in the last 'period' seconds it will be reparsed - to obtain this descriptor. - - Specifying TP_AUTO for the period (default) will choose a period based on the - size of the Text object. Larger texts are parsed less often. - """ - - global _parse_cache - - parse = True - key = hash(txt) - if not force_parse and _parse_cache.has_key(key): - desc = _parse_cache[key] - if desc.parse_due > time(): - parse = desc.incomplete - - if parse: - desc = parse_text(txt) - - return desc - -def parse_text(txt): - """Parses an entire script's text and returns a ScriptDesc instance - containing information about the script. - - If the text is not a valid Python script (for example if brackets are left - open), parsing may fail to complete. However, if this occurs, no exception - is thrown. Instead the returned ScriptDesc instance will have its incomplete - flag set and information processed up to this point will still be accessible. - """ - - start_time = time() - txt.reset() - tokens = generate_tokens(txt.readline) # Throws TokenError - - curl, cursor = txt.getCursorPos() - linen = curl + 1 # Token line numbers are one-based - - imports = dict() - imp_step = 0 - - classes = dict() - cls_step = 0 - - defs = dict() - def_step = 0 - - vars = dict() - var1_step = 0 - var2_step = 0 - var3_step = 0 - var_accum = dict() - var_forflag = False - - indent = 0 - prev_type = -1 - prev_text = '' - incomplete = False - - while True: - try: - type, text, start, end, line = tokens.next() - except StopIteration: - break - except (TokenError, IndentationError): - incomplete = True - break - - # Skip all comments and line joining characters - if type == COMMENT or type == NL: - continue - - ################# - ## Indentation ## - ################# - - if type == INDENT: - indent += 1 - elif type == DEDENT: - indent -= 1 - - ######################### - ## Module importing... ## - ######################### - - imp_store = False - - # Default, look for 'from' or 'import' to start - if imp_step == 0: - if text == 'from': - imp_tmp = [] - imp_step = 1 - elif text == 'import': - imp_from = None - imp_tmp = [] - imp_step = 2 - - # Found a 'from', create imp_from in form '???.???...' - elif imp_step == 1: - if text == 'import': - imp_from = '.'.join(imp_tmp) - imp_tmp = [] - imp_step = 2 - elif type == NAME: - imp_tmp.append(text) - elif text != '.': - imp_step = 0 # Invalid syntax - - # Found 'import', imp_from is populated or None, create imp_name - elif imp_step == 2: - if text == 'as': - imp_name = '.'.join(imp_tmp) - imp_step = 3 - elif type == NAME or text == '*': - imp_tmp.append(text) - elif text != '.': - imp_name = '.'.join(imp_tmp) - imp_symb = imp_name - imp_store = True - - # Found 'as', change imp_symb to this value and go back to step 2 - elif imp_step == 3: - if type == NAME: - imp_symb = text - else: - imp_store = True - - # Both imp_name and imp_symb have now been populated so we can import - if imp_store: - - # Handle special case of 'import *' - if imp_name == '*': - parent = get_module(imp_from) - imports.update(parent.__dict__) - - else: - # Try importing the name as a module - try: - if imp_from: - module = get_module(imp_from +'.'+ imp_name) - else: - module = get_module(imp_name) - except (ImportError, ValueError, AttributeError, TypeError): - # Try importing name as an attribute of the parent - try: - module = __import__(imp_from, globals(), locals(), [imp_name]) - imports[imp_symb] = getattr(module, imp_name) - except (ImportError, ValueError, AttributeError, TypeError): - pass - else: - imports[imp_symb] = module - - # More to import from the same module? - if text == ',': - imp_tmp = [] - imp_step = 2 - else: - imp_step = 0 - - ################### - ## Class parsing ## - ################### - - # If we are inside a class then def and variable parsing should be done - # for the class. Otherwise the definitions are considered global - - # Look for 'class' - if cls_step == 0: - if text == 'class': - cls_name = None - cls_lineno = start[0] - cls_indent = indent - cls_step = 1 - - # Found 'class', look for cls_name followed by '(' parents ')' - elif cls_step == 1: - if not cls_name: - if type == NAME: - cls_name = text - cls_sline = False - cls_parents = dict() - cls_defs = dict() - cls_vars = dict() - elif type == NAME: - if classes.has_key(text): - parent = classes[text] - cls_parents[text] = parent - cls_defs.update(parent.defs) - cls_vars.update(parent.vars) - elif text == ':': - cls_step = 2 - - # Found 'class' name ... ':', now check if it's a single line statement - elif cls_step == 2: - if type == NEWLINE: - cls_sline = False - else: - cls_sline = True - cls_doc = '' - cls_step = 3 - - elif cls_step == 3: - if not cls_doc and type == STRING: - cls_doc = _trim_doc(text) - if cls_sline: - if type == NEWLINE: - classes[cls_name] = ClassDesc(cls_name, cls_parents, cls_defs, cls_vars, cls_lineno, cls_doc) - cls_step = 0 - else: - if type == DEDENT and indent <= cls_indent: - classes[cls_name] = ClassDesc(cls_name, cls_parents, cls_defs, cls_vars, cls_lineno, cls_doc) - cls_step = 0 - - ################# - ## Def parsing ## - ################# - - # Look for 'def' - if def_step == 0: - if text == 'def': - def_name = None - def_lineno = start[0] - def_step = 1 - - # Found 'def', look for def_name followed by '(' - elif def_step == 1: - if type == NAME: - def_name = text - def_params = [] - elif def_name and text == '(': - def_step = 2 - - # Found 'def' name '(', now identify the parameters upto ')' - # TODO: Handle ellipsis '...' - elif def_step == 2: - if type == NAME: - def_params.append(text) - elif text == ':': - def_step = 3 - - # Found 'def' ... ':', now check if it's a single line statement - elif def_step == 3: - if type == NEWLINE: - def_sline = False - else: - def_sline = True - def_doc = '' - def_step = 4 - - elif def_step == 4: - if type == STRING: - def_doc = _trim_doc(text) - newdef = None - if def_sline: - if type == NEWLINE: - newdef = FunctionDesc(def_name, def_params, def_lineno, def_doc) - else: - if type == NAME: - newdef = FunctionDesc(def_name, def_params, def_lineno, def_doc) - if newdef: - if cls_step > 0: # Parsing a class - cls_defs[def_name] = newdef - else: - defs[def_name] = newdef - def_step = 0 - - ########################## - ## Variable assignation ## - ########################## - - if cls_step > 0: # Parsing a class - # Look for 'self.???' - if var1_step == 0: - if text == 'self': - var1_step = 1 - elif var1_step == 1: - if text == '.': - var_name = None - var1_step = 2 - else: - var1_step = 0 - elif var1_step == 2: - if type == NAME: - var_name = text - if cls_vars.has_key(var_name): - var_step = 0 - else: - var1_step = 3 - elif var1_step == 3: - if text == '=': - var1_step = 4 - elif text != ',': - var1_step = 0 - elif var1_step == 4: - var_type = None - if type == NUMBER: - close = end[1] - if text.find('.') != -1: var_type = float - else: var_type = int - elif type == STRING: - close = end[1] - var_type = str - elif text == '[': - close = line.find(']', end[1]) - var_type = list - elif text == '(': - close = line.find(')', end[1]) - var_type = tuple - elif text == '{': - close = line.find('}', end[1]) - var_type = dict - elif text == 'dict': - close = line.find(')', end[1]) - var_type = dict - if var_type and close+1 < len(line): - if line[close+1] != ' ' and line[close+1] != '\t': - var_type = None - cls_vars[var_name] = VarDesc(var_name, var_type, start[0]) - var1_step = 0 - - elif def_step > 0: # Parsing a def - # Look for 'global ???[,???]' - if var2_step == 0: - if text == 'global': - var2_step = 1 - elif var2_step == 1: - if type == NAME: - if not vars.has_key(text): - vars[text] = VarDesc(text, None, start[0]) - elif text != ',' and type != NL: - var2_step == 0 - - else: # In global scope - if var3_step == 0: - # Look for names - if text == 'for': - var_accum = dict() - var_forflag = True - elif text == '=' or (var_forflag and text == 'in'): - var_forflag = False - var3_step = 1 - elif type == NAME: - if prev_text != '.' and not vars.has_key(text): - var_accum[text] = VarDesc(text, None, start[0]) - elif not text in [',', '(', ')', '[', ']']: - var_accum = dict() - var_forflag = False - elif var3_step == 1: - if len(var_accum) != 1: - var_type = None - vars.update(var_accum) - else: - var_name = var_accum.keys()[0] - var_type = None - if type == NUMBER: - if text.find('.') != -1: var_type = float - else: var_type = int - elif type == STRING: var_type = str - elif text == '[': var_type = list - elif text == '(': var_type = tuple - elif text == '{': var_type = dict - vars[var_name] = VarDesc(var_name, var_type, start[0]) - var3_step = 0 - - ####################### - ## General utilities ## - ####################### - - prev_type = type - prev_text = text - - desc = ScriptDesc(txt.name, imports, classes, defs, vars, incomplete) - desc.set_delay(10 * (time()-start_time) + 0.05) - - global _parse_cache - _parse_cache[hash(txt)] = desc - return desc - -def get_modules(since=1): - """Returns the set of built-in modules and any modules that have been - imported into the system upto 'since' seconds ago. - """ - - global _modules, _modules_updated - - t = time() - if _modules_updated < t - since: - _modules.update(sys.modules) - _modules_updated = t - return _modules.keys() - -def suggest_cmp(x, y): - """Use this method when sorting a list of suggestions. - """ - - return cmp(x[0].upper(), y[0].upper()) - -def get_module(name): - """Returns the module specified by its name. The module itself is imported - by this method and, as such, any initialization code will be executed. - """ - - mod = __import__(name) - components = name.split('.') - for comp in components[1:]: - mod = getattr(mod, comp) - return mod - -def type_char(v): - """Returns the character used to signify the type of a variable. Use this - method to identify the type character for an item in a suggestion list. - - The following values are returned: - 'm' if the parameter is a module - 'f' if the parameter is callable - 'v' if the parameter is variable or otherwise indeterminable - - """ - - if isinstance(v, ModuleType): - return 'm' - elif callable(v): - return 'f' - else: - return 'v' - -def get_context(txt): - """Establishes the context of the cursor in the given Blender Text object - - Returns one of: - CTX_NORMAL - Cursor is in a normal context - CTX_SINGLE_QUOTE - Cursor is inside a single quoted string - CTX_DOUBLE_QUOTE - Cursor is inside a double quoted string - CTX_COMMENT - Cursor is inside a comment - - """ - - l, cursor = txt.getCursorPos() - lines = txt.asLines(0, l+1) - - # FIXME: This method is too slow in large files for it to be called as often - # as it is. So for lines below the 1000th line we do this... (quorn) - if l > 1000: return CTX_NORMAL - - # Detect context (in string or comment) - in_str = CTX_NORMAL - for line in lines: - if l == 0: - end = cursor - else: - end = len(line) - l -= 1 - - # Comments end at new lines - if in_str == CTX_COMMENT: - in_str = CTX_NORMAL - - for i in range(end): - if in_str == 0: - if line[i] == "'": in_str = CTX_SINGLE_QUOTE - elif line[i] == '"': in_str = CTX_DOUBLE_QUOTE - elif line[i] == '#': in_str = CTX_COMMENT - else: - if in_str == CTX_SINGLE_QUOTE: - if line[i] == "'": - in_str = CTX_NORMAL - # In again if ' escaped, out again if \ escaped, and so on - for a in range(i-1, -1, -1): - if line[a] == '\\': in_str = 1-in_str - else: break - elif in_str == CTX_DOUBLE_QUOTE: - if line[i] == '"': - in_str = CTX_NORMAL - # In again if " escaped, out again if \ escaped, and so on - for a in range(i-1, -1, -1): - if line[i-a] == '\\': in_str = 2-in_str - else: break - - return in_str - -def current_line(txt): - """Extracts the Python script line at the cursor in the Blender Text object - provided and cursor position within this line as the tuple pair (line, - cursor). - """ - - lineindex, cursor = txt.getCursorPos() - lines = txt.asLines() - line = lines[lineindex] - - # Join previous lines to this line if spanning - i = lineindex - 1 - while i > 0: - earlier = lines[i].rstrip() - if earlier.endswith('\\'): - line = earlier[:-1] + ' ' + line - cursor += len(earlier) - i -= 1 - - # Join later lines while there is an explicit joining character - i = lineindex - while i < len(lines)-1 and lines[i].rstrip().endswith('\\'): - later = lines[i+1].strip() - line = line + ' ' + later[:-1] - i += 1 - - return line, cursor - -def get_targets(line, cursor): - """Parses a period separated string of valid names preceding the cursor and - returns them as a list in the same order. - """ - - brk = 0 - targets = [] - j = cursor - i = j-1 - while i >= 0: - if line[i] == ')': brk += 1 - elif brk: - if line[i] == '(': brk -= 1 - else: - if line[i] == '.': - targets.insert(0, line[i+1:j]); j=i - elif not (line[i].isalnum() or line[i] == '_' or line[i] == '.'): - break - i -= 1 - targets.insert(0, line[i+1:j]) - return targets - -def get_defs(txt): - """Returns a dictionary which maps definition names in the source code to - a list of their parameter names. - - The line 'def doit(one, two, three): print one' for example, results in the - mapping 'doit' : [ 'one', 'two', 'three' ] - """ - - return get_cached_descriptor(txt).defs - -def get_vars(txt): - """Returns a dictionary of variable names found in the specified Text - object. This method locates all names followed directly by an equal sign: - 'a = ???' or indirectly as part of a tuple/list assignment or inside a - 'for ??? in ???:' block. - """ - - return get_cached_descriptor(txt).vars - -def get_imports(txt): - """Returns a dictionary which maps symbol names in the source code to their - respective modules. - - The line 'from Blender import Text as BText' for example, results in the - mapping 'BText' : <module 'Blender.Text' (built-in)> - - Note that this method imports the modules to provide this mapping as as such - will execute any initilization code found within. - """ - - return get_cached_descriptor(txt).imports - -def get_builtins(): - """Returns a dictionary of built-in modules, functions and variables.""" - - return __builtin__.__dict__ - - -################################# -## Debugging utility functions ## -################################# - -def print_cache_for(txt, period=sys.maxint): - """Prints out the data cached for a given Text object. If no period is - given the text will not be reparsed and the cached version will be returned. - Otherwise if the period has expired the text will be reparsed. - """ - - desc = get_cached_descriptor(txt, period) - print '================================================' - print 'Name:', desc.name, '('+str(hash(txt))+')' - print '------------------------------------------------' - print 'Defs:' - for name, ddesc in desc.defs.items(): - print ' ', name, ddesc.params, ddesc.lineno - print ' ', ddesc.doc - print '------------------------------------------------' - print 'Vars:' - for name, vdesc in desc.vars.items(): - print ' ', name, vdesc.type, vdesc.lineno - print '------------------------------------------------' - print 'Imports:' - for name, item in desc.imports.items(): - print ' ', name.ljust(15), item - print '------------------------------------------------' - print 'Classes:' - for clsnme, clsdsc in desc.classes.items(): - print ' *********************************' - print ' Name:', clsnme - print ' ', clsdsc.doc - print ' ---------------------------------' - print ' Defs:' - for name, ddesc in clsdsc.defs.items(): - print ' ', name, ddesc.params, ddesc.lineno - print ' ', ddesc.doc - print ' ---------------------------------' - print ' Vars:' - for name, vdesc in clsdsc.vars.items(): - print ' ', name, vdesc.type, vdesc.lineno - print ' *********************************' - print '================================================' diff --git a/release/scripts/bpymodules/BPyWindow.py b/release/scripts/bpymodules/BPyWindow.py deleted file mode 100644 index d3fd4fa88b5..00000000000 --- a/release/scripts/bpymodules/BPyWindow.py +++ /dev/null @@ -1,206 +0,0 @@ -import Blender -from Blender import Mathutils, Window, Scene, Draw, Mesh -from Blender.Mathutils import Matrix, Vector, Intersect - -# 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 mouseViewRay(screen_x, screen_y, localMatrix=None, useMid = False): - - # Constant function variables - p = mouseViewRay.p - d = mouseViewRay.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 = mouseViewRay.hms - ortho_d = mouseViewRay.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 - hms[:] = (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[:] = ortho_d[:3] - - - # 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 = mouseViewRay.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[:] = \ - 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[:] = 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[:] = 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() - localInvMatrix_notrans = localInvMatrix.rotationPart() - p = p * localInvMatrix - d = d * localInvMatrix # normalize_v3 - - # remove the translation from d - d.x -= localInvMatrix[3][0] - d.y -= localInvMatrix[3][1] - d.z -= localInvMatrix[3][2] - - - d.normalize() - ''' - # Debugging - me = Blender.Mesh.New() - me.verts.extend([p[0:3]]) - me.verts.extend([(p-d)[0:3]]) - me.edges.extend([0,1]) - ob = Blender.Scene.GetCurrent().objects.new(me) - ''' - return True, p, d # Origin, Direction - - # Mouse is not in any view, return None. - return False, None, None - -# Constant function variables -mouseViewRay.d = Vector(0,0,0) # Perspective, 3d -mouseViewRay.p = Vector(0,0,0) -mouseViewRay.fp = Vector(0,0,0) - -mouseViewRay.hms = Vector(0,0,0,0) # ortho only 4d -mouseViewRay.ortho_d = Vector(0,0,0,0) # ortho only 4d - - -LMB= Window.MButs['L'] -def mouseup(): - # Loop until click - mouse_buttons = Window.GetMouseButtons() - while not mouse_buttons & LMB: - Blender.sys.sleep(10) - mouse_buttons = Window.GetMouseButtons() - while mouse_buttons & LMB: - Blender.sys.sleep(10) - mouse_buttons = Window.GetMouseButtons() - - -if __name__=='__main__': - mouseup() - x,y= Window.GetMouseCoords() - isect, point, dir= mouseViewRay(x,y) - if isect: - scn= Blender.Scene.GetCurrent() - me = Blender.Mesh.New() - ob= Blender.Object.New('Mesh') - ob.link(me) - scn.link(ob) - ob.sel= 1 - me.verts.extend([point, dir]) - me.verts[0].sel= 1 - - print isect, point, dir - - - -def spaceRect(): - ''' - Returns the space rect - xmin,ymin,width,height - ''' - - __UI_RECT__ = Blender.BGL.Buffer(Blender.BGL.GL_FLOAT, 4) - Blender.BGL.glGetFloatv(Blender.BGL.GL_SCISSOR_BOX, __UI_RECT__) - __UI_RECT__ = __UI_RECT__.list - __UI_RECT__ = int(__UI_RECT__[0]), int(__UI_RECT__[1]), int(__UI_RECT__[2])-1, int(__UI_RECT__[3]) - - return __UI_RECT__ - -def mouseRelativeLoc2d(__UI_RECT__= None): - if not __UI_RECT__: - __UI_RECT__ = spaceRect() - - mco = Window.GetMouseCoords() - if mco[0] > __UI_RECT__[0] and\ - mco[1] > __UI_RECT__[1] and\ - mco[0] < __UI_RECT__[0] + __UI_RECT__[2] and\ - mco[1] < __UI_RECT__[1] + __UI_RECT__[3]: - - return (mco[0] - __UI_RECT__[0], mco[1] - __UI_RECT__[1]) - - else: - return None - - - - - - - - -
\ No newline at end of file diff --git a/release/scripts/bpymodules/blend2renderinfo.py b/release/scripts/bpymodules/blend2renderinfo.py deleted file mode 100644 index 1b9dec58d55..00000000000 --- a/release/scripts/bpymodules/blend2renderinfo.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/python - -# -------------------------------------------------------------------------- -# ***** 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 struct - -# In Blender, selecting scenes in the databrowser (shift+f4) will tag for rendering. - -# This struct wont change according to ton. -# Note that the size differs on 32/64bit -''' -typedef struct BHead { - int code, len; - void *old; - int SDNAnr, nr; -} BHead; -''' - - -def read_blend_rend_chunk(path): - file = open(path, 'rb') - - if file.read(len('BLENDER')) != 'BLENDER': - return [] - - # - if file.read(1) == '-': - is64bit = True - else: # '_' - is64bit = False - - if file.read(1) == 'V': - isBigEndian = True # ppc - else: # 'V' - isBigEndian = False # x86 - - - # Now read the bhead chunk!!! - file.read(3) # skip the version - - scenes = [] - - while file.read(4) == 'REND': - - if is64bit: sizeof_bhead = sizeof_bhead_left = 24 # 64bit - else: sizeof_bhead = sizeof_bhead_left = 20 # 32bit - - sizeof_bhead_left -= 4 - - if isBigEndian: rend_length = struct.unpack('>i', file.read(4))[0] - else: rend_length = struct.unpack('<i', file.read(4))[0] - - sizeof_bhead_left -= 4 - - # We dont care about the rest of the bhead struct - file.read(sizeof_bhead_left) - - # Now we want the scene name, start and end frame. this is 32bites long - - if isBigEndian: start_frame, end_frame = struct.unpack('>2i', file.read(8)) - else: start_frame, end_frame = struct.unpack('<2i', file.read(8)) - - scene_name = file.read(24) - scene_name = scene_name[ : scene_name.index('\0') ] - - scenes.append( (start_frame, end_frame, scene_name) ) - return scenes - -def main(): - import sys - for arg in sys.argv[1:]: - if arg.lower().endswith('.blend'): - print read_blend_rend_chunk(arg) - -if __name__ == '__main__': - main() - diff --git a/release/scripts/bpymodules/defaultdoodads.py b/release/scripts/bpymodules/defaultdoodads.py deleted file mode 100644 index 987b8b8ae71..00000000000 --- a/release/scripts/bpymodules/defaultdoodads.py +++ /dev/null @@ -1,941 +0,0 @@ -# Default Doodad Set for Discombobulator -# by Evan J. Rosky, 2005 -# GPL- http://www.gnu.org/copyleft/gpl.html -# -# $Id$ -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2005: Evan J. Rosky -# -# 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 ***** -# -------------------------------------------------------------------------- - - -#Run discombobulator.py, not this. - -import Blender -from Blender import NMesh,Object,Material -from Blender.NMesh import Vert,Face -from Blender.Mathutils import * - -import BPyMathutils -from BPyMathutils import genrand -a = BPyMathutils.sgenrand(4859) - -#Create random numbers -def randnum(low,high): - num = genrand() - num = num*(high-low) - num = num+low - return num - -face = Face() -xmin = Vector([0,0,0]) -xmax = Vector([0,0,0]) -ymin = Vector([0,0,0]) -ymax = Vector([0,0,0]) -mxmin = Vector([0,0,0]) -mxmax = Vector([0,0,0]) -mymin = Vector([0,0,0]) -mymax = Vector([0,0,0]) -doodadCenter = Vector([0,0,0]) -orientation = 0 -center = Vector([0,0,0]) -tosel = 0 -seltopsonly = 0 -tempx = [] -doodadMesh = NMesh.GetRaw() - -global materialArray -global reassignMats -global thereAreMats -global currmat -global doodSideMat -global doodTopMat - -#face is the face to add the doodad to. -#sizeX and sizeY are values from 0.0 to 1.0 that represents a percentage the face that is covered by the doodad. -#height is how tall the doodad is. - -def settings(seltops,matArr,reasMats,therMats,sidemat,topmat): - global seltopsonly - global materialArray - global reassignMats - global thereAreMats - global currmat - global doodSideMat - global doodTopMat - materialArray = matArr - reassignMats = reasMats - thereAreMats = therMats - seltopsonly = seltops - doodSideMat = sidemat - doodTopMat = topmat - -def setCurrMat(curma): - global currmat - currmat = curma - -#Find center and orientation of doodad -def findDoodadCenter(sizeX, sizeY): - #globalizing junk - global face - global xmin - global xmax - global ymin - global ymax - global orientation - global doodadCenter - global center - global tosel - global mxmin - global mxmax - global mymin - global mymax - global tempx - global seltopsonly - - #Find the center of the face - center = Vector([0,0,0]) - for pt in face.v: - center = center + pt.co - center = divideVectorByInt(center,len(face.v)) - - #Find Temp Location Range by looking at the sizes - txmin = ((divideVectorByInt((face.v[0].co + face.v[3].co),2)) - center)*(1-sizeX) + center - txmax = ((divideVectorByInt((face.v[1].co + face.v[2].co),2)) - center)*(1-sizeX) + center - tymin = ((divideVectorByInt((face.v[0].co + face.v[1].co),2)) - center)*(1-sizeY) + center - tymax = ((divideVectorByInt((face.v[2].co + face.v[3].co),2)) - center)*(1-sizeY) + center - - #Find Center of doodad - amtx = randnum(0.0,1.0) - amty = randnum(0.0,1.0) - thepoint = (((((txmin - txmax)*amtx + txmax) - ((tymin - tymax)*amty + tymax))*.5 + ((tymin - tymax)*amty + tymax)) - center)*2 + center - doodadCenter = Vector([thepoint[0],thepoint[1],thepoint[2]]) - - #Find Main Range by looking at the sizes - mxmin = divideVectorByInt((face.v[0].co + face.v[3].co),2) - mxmax = divideVectorByInt((face.v[1].co + face.v[2].co),2) - mymin = divideVectorByInt((face.v[0].co + face.v[1].co),2) - mymax = divideVectorByInt((face.v[2].co + face.v[3].co),2) - - #Find x/y equivs for whole face - ve1 = (txmin - txmax)*amtx + txmax - ve1 = ve1 - mxmax - nax = ve1.length - ve1 = (mxmin - mxmax) - nax = nax/ve1.length - - ve1 = (tymin - tymax)*amty + tymax - ve1 = ve1 - mymax - nay = ve1.length - ve1 = (mymin - mymax) - nay = nay/ve1.length - - #Find new box thing - tempx = [] - amtx = nax-sizeX/2 - amty = nay-sizeY/2 - tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center) - - amtx = nax-sizeX/2 - amty = nay+sizeY/2 - tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center) - - amtx = nax+sizeX/2 - amty = nay+sizeY/2 - tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center) - - amtx = nax+sizeX/2 - amty = nay-sizeY/2 - tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center) - - #Find New Location Range by looking at the sizes - xmin = divideVectorByInt((tempx[0] + tempx[3]),2) - xmax = divideVectorByInt((tempx[1] + tempx[2]),2) - ymin = divideVectorByInt((tempx[0] + tempx[1]),2) - ymax = divideVectorByInt((tempx[2] + tempx[3]),2) - -#Make a point -def makePoint(x,y,z=0): - global xmin - global xmax - global ymin - global ymax - global doodadCenter - global tosel - global seltopsonly - global face - - amtx = x - amty = y - thepoint = (((((xmin - xmax)*amtx + xmax) - ((ymin - ymax)*amty + ymax))*.5 + ((ymin - ymax)*amty + ymax)) - doodadCenter)*2 + doodadCenter - thepoint = thepoint + z*Vector(face.no) - tver = Vert(thepoint[0],thepoint[1],thepoint[2]) - if tosel == 1 and seltopsonly == 0 and z == 0: - tver.sel = 1 - return tver - -#extrude ground-plane(s) -def extrudedoodad(vArray,heig): - global face - global doodadMesh - global tosel - - topVArray = [] - - doodadMesh.verts.extend(vArray) - - #Create array for extruded verts - for ind in range(0,(len(vArray))): - point = vArray[ind].co + heig*Vector(face.no) - ver = Vert(point[0],point[1],point[2]) - if tosel == 1: - ver.sel = 1 - topVArray.append(ver) - doodadMesh.verts.append(topVArray[ind]) - - #make faces around sides - for ind in range(0,(len(vArray) - 1)): - face = Face() - face.v.extend([vArray[ind],vArray[ind+1],topVArray[ind+1],topVArray[ind]]) - if tosel == 1 and seltopsonly == 0: face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodSideMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vArray[len(vArray) - 1],vArray[0],topVArray[0],topVArray[len(topVArray) - 1]]) - if tosel == 1 and seltopsonly == 0: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodSideMat-1 - doodadMesh.faces.append(face) - - return topVArray - -#For switching face vertices -def fixvertindex(ind): - if ind > 3: - indx = ind - 4 - else: - indx = ind - return indx - -#runs doodads -def createDoodad(indexArray,facec,minsi,maxsi,minhei,maxhei,selec,amtmin,amtmax,facpercent): - global doodadMesh - global seltopsonly - global tosel - - doodadMesh = NMesh.GetRaw() - - theamt = round(randnum(amtmin,amtmax),0) - theamt = int(theamt) - tosel = selec - - for i in range(0,(theamt)): - if randnum(0,1) <= facpercent: - index = round(randnum(1,len(indexArray)),0) - index = indexArray[(int(index) - 1)] - - Xsi = randnum(minsi,maxsi) - Ysi = randnum(minsi,maxsi) - hei = randnum(minhei,maxhei) - - #Determine orientation - orient = int(round(randnum(0.0,3.0))) - - #face to use as range - facer = Face() - facer.v.extend([facec.v[orient],facec.v[fixvertindex(1+orient)],facec.v[fixvertindex(2+orient)],facec.v[fixvertindex(3+orient)]]) - - if index == 1: - singleBox(facer,Xsi,Ysi,hei) - if index == 2: - doubleBox(facer,Xsi,Ysi,hei) - if index == 3: - tripleBox(facer,Xsi,Ysi,hei) - if index == 4: - LShape(facer,Xsi,Ysi,hei) - if index == 5: - TShape(facer,Xsi,Ysi,hei) - if index == 6: - if randnum(0.0,1.0) > .5: - SShape(facer,Xsi,Ysi,hei) - else: - ZShape(facer,Xsi,Ysi,hei) - - return doodadMesh - -def divideVectorByInt(thevect,theint): - thevect.x = thevect.x/theint - thevect.y = thevect.y/theint - thevect.z = thevect.z/theint - return thevect - -#Single Box Doodad -def singleBox(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - vertArray = [] - - #place four points - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#Double Box Doodad -def doubleBox(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - vertArray = [] - - #place first box - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,1)) - vertArray.append(makePoint(0.45,1)) - vertArray.append(makePoint(0.45,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - vertArray = [] - - #place second box - vertArray.append(makePoint(0.55,0)) - vertArray.append(makePoint(0.55,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#Triple Box Doodad -def tripleBox(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - vertArray = [] - - #place first box - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,1)) - vertArray.append(makePoint(0.3,1)) - vertArray.append(makePoint(0.3,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - vertArray = [] - - #place second box - vertArray.append(makePoint(0.35,0)) - vertArray.append(makePoint(0.35,1)) - vertArray.append(makePoint(0.65,1)) - vertArray.append(makePoint(0.65,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - vertArray = [] - - #place third box - vertArray.append(makePoint(0.7,0)) - vertArray.append(makePoint(0.7,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#The "L" Shape -def LShape(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - rcon1 = randnum(0.2,0.8) - rcon2 = randnum(0.2,0.8) - - vertArray = [] - - #place L shape - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,rcon1)) - vertArray.append(makePoint(0,1)) - vertArray.append(makePoint(rcon2,1)) - vertArray.append(makePoint(rcon2,rcon1)) - vertArray.append(makePoint(1,rcon1)) - vertArray.append(makePoint(1,0)) - vertArray.append(makePoint(rcon2,0)) - topVertArray = extrudedoodad(vertArray,height) - - #This fills in the bottom of doodad with faceness - face = Face() - face.v.extend([vertArray[0],vertArray[1],vertArray[4],vertArray[7]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[1],vertArray[2],vertArray[3],vertArray[4]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[4],vertArray[5],vertArray[6],vertArray[7]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - #This fills in the top with faceness - face = Face() - face.v.extend([topVertArray[0],topVertArray[1],topVertArray[4],topVertArray[7]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[1],topVertArray[2],topVertArray[3],topVertArray[4]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[4],topVertArray[5],topVertArray[6],topVertArray[7]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#The "T" Shape -def TShape(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - rcony = randnum(0.25,0.75) - rconx1 = randnum(0.1,0.49) - rconx2 = randnum(0.51,0.9) - - vertArray = [] - - #place T shape - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,rcony)) - vertArray.append(makePoint(rconx1,rcony)) - vertArray.append(makePoint(rconx1,1)) - vertArray.append(makePoint(rconx2,1)) - vertArray.append(makePoint(rconx2,rcony)) - vertArray.append(makePoint(1,rcony)) - vertArray.append(makePoint(1,0)) - vertArray.append(makePoint(rconx2,0)) - vertArray.append(makePoint(rconx1,0)) - topVertArray = extrudedoodad(vertArray,height) - - #fills bottom with faceness - face = Face() - face.v.extend([vertArray[0],vertArray[1],vertArray[2],vertArray[9]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[2],vertArray[3],vertArray[4],vertArray[5]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[5],vertArray[6],vertArray[7],vertArray[8]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[8],vertArray[9],vertArray[2],vertArray[5]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - #fills top with faceness - face = Face() - face.v.extend([topVertArray[0],topVertArray[1],topVertArray[2],topVertArray[9]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[2],topVertArray[3],topVertArray[4],topVertArray[5]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[5],topVertArray[6],topVertArray[7],topVertArray[8]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[8],topVertArray[9],topVertArray[2],topVertArray[5]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#The "S" or "Z" Shapes -def SShape(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - rcony1 = randnum(0.1,0.49) - rcony2 = randnum(0.51,0.9) - rconx1 = randnum(0.1,0.49) - rconx2 = randnum(0.51,0.9) - - vertArray = [] - - #place S shape - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,rcony1)) - vertArray.append(makePoint(rconx1,rcony1)) - vertArray.append(makePoint(rconx1,rcony2)) - vertArray.append(makePoint(rconx1,1)) - vertArray.append(makePoint(rconx2,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,rcony2)) - vertArray.append(makePoint(rconx2,rcony2)) - vertArray.append(makePoint(rconx2,rcony1)) - vertArray.append(makePoint(rconx2,0)) - vertArray.append(makePoint(rconx1,0)) - topVertArray = extrudedoodad(vertArray,height) - - #fills bottom with faceness - face = Face() - face.v.extend([vertArray[0],vertArray[1],vertArray[2],vertArray[11]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[2],vertArray[9],vertArray[10],vertArray[11]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[2],vertArray[3],vertArray[8],vertArray[9]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[3],vertArray[4],vertArray[5],vertArray[8]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[5],vertArray[6],vertArray[7],vertArray[8]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - #fills top with faceness - face = Face() - face.v.extend([topVertArray[0],topVertArray[1],topVertArray[2],topVertArray[11]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[2],topVertArray[9],topVertArray[10],topVertArray[11]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[2],topVertArray[3],topVertArray[8],topVertArray[9]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[3],topVertArray[4],topVertArray[5],topVertArray[8]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[5],topVertArray[6],topVertArray[7],topVertArray[8]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -def ZShape(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - rcony1 = randnum(0.1,0.49) - rcony2 = randnum(0.51,0.9) - rconx1 = randnum(0.1,0.49) - rconx2 = randnum(0.51,0.9) - - vertArray = [] - - #place Z shape - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,rcony1)) - vertArray.append(makePoint(0,rcony2)) - vertArray.append(makePoint(rconx1,rcony2)) - vertArray.append(makePoint(rconx2,rcony2)) - vertArray.append(makePoint(rconx2,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,rcony2)) - vertArray.append(makePoint(1,rcony1)) - vertArray.append(makePoint(rconx2,rcony1)) - vertArray.append(makePoint(rconx1,rcony1)) - vertArray.append(makePoint(rconx1,0)) - topVertArray = extrudedoodad(vertArray,height) - - #fills bottom with faceness - face = Face() - face.v.extend([vertArray[0],vertArray[1],vertArray[10],vertArray[11]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[1],vertArray[2],vertArray[3],vertArray[10]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[3],vertArray[4],vertArray[9],vertArray[10]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[4],vertArray[7],vertArray[8],vertArray[9]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[4],vertArray[5],vertArray[6],vertArray[7]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - #fills top with faceness - face = Face() - face.v.extend([topVertArray[0],topVertArray[1],topVertArray[10],topVertArray[11]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[1],topVertArray[2],topVertArray[3],topVertArray[10]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[3],topVertArray[4],topVertArray[9],topVertArray[10]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[4],topVertArray[7],topVertArray[8],topVertArray[9]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[4],topVertArray[5],topVertArray[6],topVertArray[7]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - diff --git a/release/scripts/bpymodules/dxfColorMap.py b/release/scripts/bpymodules/dxfColorMap.py deleted file mode 100644 index 66c0bd4e9a2..00000000000 --- a/release/scripts/bpymodules/dxfColorMap.py +++ /dev/null @@ -1,282 +0,0 @@ -# dictionary mapping AutoCAD color indexes with Blender colors - -# -------------------------------------------------------------------------- -# color_map.py Final by Ed Blake (AKA Kitsu) -# -------------------------------------------------------------------------- -# ***** 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 ***** -# -------------------------------------------------------------------------- - -color_map = { - 0:[0.0, 0.0, 0.0], - 1:[0.99609375, 0.0, 0.0], - 2:[0.99609375, 0.99609375, 0.0], - 3:[0.0, 0.99609375, 0.0], - 4:[0.0, 0.99609375, 0.99609375], - 5:[0.0, 0.0, 0.99609375], - 6:[0.99609375, 0.0, 0.99609375], - 7:[0.99609375, 0.99609375, 0.99609375], - 8:[0.25390625, 0.25390625, 0.25390625], - 9:[0.5, 0.5, 0.5], - 10:[0.99609375, 0.0, 0.0], - 11:[0.99609375, 0.6640625, 0.6640625], - 12:[0.73828125, 0.0, 0.0], - 13:[0.73828125, 0.4921875, 0.4921875], - 14:[0.50390625, 0.0, 0.0], - 15:[0.50390625, 0.3359375, 0.3359375], - 16:[0.40625, 0.0, 0.0], - 17:[0.40625, 0.26953125, 0.26953125], - 18:[0.30859375, 0.0, 0.0], - 19:[0.30859375, 0.20703125, 0.20703125], - 20:[0.99609375, 0.24609375, 0.0], - 21:[0.99609375, 0.74609375, 0.6640625], - 22:[0.73828125, 0.1796875, 0.0], - 23:[0.73828125, 0.55078125, 0.4921875], - 24:[0.50390625, 0.12109375, 0.0], - 25:[0.50390625, 0.375, 0.3359375], - 26:[0.40625, 0.09765625, 0.0], - 27:[0.40625, 0.3046875, 0.26953125], - 28:[0.30859375, 0.07421875, 0.0], - 29:[0.30859375, 0.23046875, 0.20703125], - 30:[0.99609375, 0.49609375, 0.0], - 31:[0.99609375, 0.828125, 0.6640625], - 32:[0.73828125, 0.3671875, 0.0], - 33:[0.73828125, 0.61328125, 0.4921875], - 34:[0.50390625, 0.25, 0.0], - 35:[0.50390625, 0.41796875, 0.3359375], - 36:[0.40625, 0.203125, 0.0], - 37:[0.40625, 0.3359375, 0.26953125], - 38:[0.30859375, 0.15234375, 0.0], - 39:[0.30859375, 0.2578125, 0.20703125], - 40:[0.99609375, 0.74609375, 0.0], - 41:[0.99609375, 0.9140625, 0.6640625], - 42:[0.73828125, 0.55078125, 0.0], - 43:[0.73828125, 0.67578125, 0.4921875], - 44:[0.50390625, 0.375, 0.0], - 45:[0.50390625, 0.4609375, 0.3359375], - 46:[0.40625, 0.3046875, 0.0], - 47:[0.40625, 0.37109375, 0.26953125], - 48:[0.30859375, 0.23046875, 0.0], - 49:[0.30859375, 0.28515625, 0.20703125], - 50:[0.99609375, 0.99609375, 0.0], - 51:[0.99609375, 0.99609375, 0.6640625], - 52:[0.73828125, 0.73828125, 0.0], - 53:[0.73828125, 0.73828125, 0.4921875], - 54:[0.50390625, 0.50390625, 0.0], - 55:[0.50390625, 0.50390625, 0.3359375], - 56:[0.40625, 0.40625, 0.0], - 57:[0.40625, 0.40625, 0.26953125], - 58:[0.30859375, 0.30859375, 0.0], - 59:[0.30859375, 0.30859375, 0.20703125], - 60:[0.74609375, 0.99609375, 0.0], - 61:[0.9140625, 0.99609375, 0.6640625], - 62:[0.55078125, 0.73828125, 0.0], - 63:[0.67578125, 0.73828125, 0.4921875], - 64:[0.375, 0.50390625, 0.0], - 65:[0.4609375, 0.50390625, 0.3359375], - 66:[0.3046875, 0.40625, 0.0], - 67:[0.37109375, 0.40625, 0.26953125], - 68:[0.23046875, 0.30859375, 0.0], - 69:[0.28515625, 0.30859375, 0.20703125], - 70:[0.49609375, 0.99609375, 0.0], - 71:[0.828125, 0.99609375, 0.6640625], - 72:[0.3671875, 0.73828125, 0.0], - 73:[0.61328125, 0.73828125, 0.4921875], - 74:[0.25, 0.50390625, 0.0], - 75:[0.41796875, 0.50390625, 0.3359375], - 76:[0.203125, 0.40625, 0.0], - 77:[0.3359375, 0.40625, 0.26953125], - 78:[0.15234375, 0.30859375, 0.0], - 79:[0.2578125, 0.30859375, 0.20703125], - 80:[0.24609375, 0.99609375, 0.0], - 81:[0.74609375, 0.99609375, 0.6640625], - 82:[0.1796875, 0.73828125, 0.0], - 83:[0.55078125, 0.73828125, 0.4921875], - 84:[0.12109375, 0.50390625, 0.0], - 85:[0.375, 0.50390625, 0.3359375], - 86:[0.09765625, 0.40625, 0.0], - 87:[0.3046875, 0.40625, 0.26953125], - 88:[0.07421875, 0.30859375, 0.0], - 89:[0.23046875, 0.30859375, 0.20703125], - 90:[0.0, 0.99609375, 0.0], - 91:[0.6640625, 0.99609375, 0.6640625], - 92:[0.0, 0.73828125, 0.0], - 93:[0.4921875, 0.73828125, 0.4921875], - 94:[0.0, 0.50390625, 0.0], - 95:[0.3359375, 0.50390625, 0.3359375], - 96:[0.0, 0.40625, 0.0], - 97:[0.26953125, 0.40625, 0.26953125], - 98:[0.0, 0.30859375, 0.0], - 99:[0.20703125, 0.30859375, 0.20703125], - 100:[0.0, 0.99609375, 0.24609375], - 101:[0.6640625, 0.99609375, 0.74609375], - 102:[0.0, 0.73828125, 0.1796875], - 103:[0.4921875, 0.73828125, 0.55078125], - 104:[0.0, 0.50390625, 0.12109375], - 105:[0.3359375, 0.50390625, 0.375], - 106:[0.0, 0.40625, 0.09765625], - 107:[0.26953125, 0.40625, 0.3046875], - 108:[0.0, 0.30859375, 0.07421875], - 109:[0.20703125, 0.30859375, 0.23046875], - 110:[0.0, 0.99609375, 0.49609375], - 111:[0.6640625, 0.99609375, 0.828125], - 112:[0.0, 0.73828125, 0.3671875], - 113:[0.4921875, 0.73828125, 0.61328125], - 114:[0.0, 0.50390625, 0.25], - 115:[0.3359375, 0.50390625, 0.41796875], - 116:[0.0, 0.40625, 0.203125], - 117:[0.26953125, 0.40625, 0.3359375], - 118:[0.0, 0.30859375, 0.15234375], - 119:[0.20703125, 0.30859375, 0.2578125], - 120:[0.0, 0.99609375, 0.74609375], - 121:[0.6640625, 0.99609375, 0.9140625], - 122:[0.0, 0.73828125, 0.55078125], - 123:[0.4921875, 0.73828125, 0.67578125], - 124:[0.0, 0.50390625, 0.375], - 125:[0.3359375, 0.50390625, 0.4609375], - 126:[0.0, 0.40625, 0.3046875], - 127:[0.26953125, 0.40625, 0.37109375], - 128:[0.0, 0.30859375, 0.23046875], - 129:[0.20703125, 0.30859375, 0.28515625], - 130:[0.0, 0.99609375, 0.99609375], - 131:[0.6640625, 0.99609375, 0.99609375], - 132:[0.0, 0.73828125, 0.73828125], - 133:[0.4921875, 0.73828125, 0.73828125], - 134:[0.0, 0.50390625, 0.50390625], - 135:[0.3359375, 0.50390625, 0.50390625], - 136:[0.0, 0.40625, 0.40625], - 137:[0.26953125, 0.40625, 0.40625], - 138:[0.0, 0.30859375, 0.30859375], - 139:[0.20703125, 0.30859375, 0.30859375], - 140:[0.0, 0.74609375, 0.99609375], - 141:[0.6640625, 0.9140625, 0.99609375], - 142:[0.0, 0.55078125, 0.73828125], - 143:[0.4921875, 0.67578125, 0.73828125], - 144:[0.0, 0.375, 0.50390625], - 145:[0.3359375, 0.4609375, 0.50390625], - 146:[0.0, 0.3046875, 0.40625], - 147:[0.26953125, 0.37109375, 0.40625], - 148:[0.0, 0.23046875, 0.30859375], - 149:[0.20703125, 0.28515625, 0.30859375], - 150:[0.0, 0.49609375, 0.99609375], - 151:[0.6640625, 0.828125, 0.99609375], - 152:[0.0, 0.3671875, 0.73828125], - 153:[0.4921875, 0.61328125, 0.73828125], - 154:[0.0, 0.25, 0.50390625], - 155:[0.3359375, 0.41796875, 0.50390625], - 156:[0.0, 0.203125, 0.40625], - 157:[0.26953125, 0.3359375, 0.40625], - 158:[0.0, 0.15234375, 0.30859375], - 159:[0.20703125, 0.2578125, 0.30859375], - 160:[0.0, 0.24609375, 0.99609375], - 161:[0.6640625, 0.74609375, 0.99609375], - 162:[0.0, 0.1796875, 0.73828125], - 163:[0.4921875, 0.55078125, 0.73828125], - 164:[0.0, 0.12109375, 0.50390625], - 165:[0.3359375, 0.375, 0.50390625], - 166:[0.0, 0.09765625, 0.40625], - 167:[0.26953125, 0.3046875, 0.40625], - 168:[0.0, 0.07421875, 0.30859375], - 169:[0.20703125, 0.23046875, 0.30859375], - 170:[0.0, 0.0, 0.99609375], - 171:[0.6640625, 0.6640625, 0.99609375], - 172:[0.0, 0.0, 0.73828125], - 173:[0.4921875, 0.4921875, 0.73828125], - 174:[0.0, 0.0, 0.50390625], - 175:[0.3359375, 0.3359375, 0.50390625], - 176:[0.0, 0.0, 0.40625], - 177:[0.26953125, 0.26953125, 0.40625], - 178:[0.0, 0.0, 0.30859375], - 179:[0.20703125, 0.20703125, 0.30859375], - 180:[0.24609375, 0.0, 0.99609375], - 181:[0.74609375, 0.6640625, 0.99609375], - 182:[0.1796875, 0.0, 0.73828125], - 183:[0.55078125, 0.4921875, 0.73828125], - 184:[0.12109375, 0.0, 0.50390625], - 185:[0.375, 0.3359375, 0.50390625], - 186:[0.09765625, 0.0, 0.40625], - 187:[0.3046875, 0.26953125, 0.40625], - 188:[0.07421875, 0.0, 0.30859375], - 189:[0.23046875, 0.20703125, 0.30859375], - 190:[0.49609375, 0.0, 0.99609375], - 191:[0.828125, 0.6640625, 0.99609375], - 192:[0.3671875, 0.0, 0.73828125], - 193:[0.61328125, 0.4921875, 0.73828125], - 194:[0.25, 0.0, 0.50390625], - 195:[0.41796875, 0.3359375, 0.50390625], - 196:[0.203125, 0.0, 0.40625], - 197:[0.3359375, 0.26953125, 0.40625], - 198:[0.15234375, 0.0, 0.30859375], - 199:[0.2578125, 0.20703125, 0.30859375], - 200:[0.74609375, 0.0, 0.99609375], - 201:[0.9140625, 0.6640625, 0.99609375], - 202:[0.55078125, 0.0, 0.73828125], - 203:[0.67578125, 0.4921875, 0.73828125], - 204:[0.375, 0.0, 0.50390625], - 205:[0.4609375, 0.3359375, 0.50390625], - 206:[0.3046875, 0.0, 0.40625], - 207:[0.37109375, 0.26953125, 0.40625], - 208:[0.23046875, 0.0, 0.30859375], - 209:[0.28515625, 0.20703125, 0.30859375], - 210:[0.99609375, 0.0, 0.99609375], - 211:[0.99609375, 0.6640625, 0.99609375], - 212:[0.73828125, 0.0, 0.73828125], - 213:[0.73828125, 0.4921875, 0.73828125], - 214:[0.50390625, 0.0, 0.50390625], - 215:[0.50390625, 0.3359375, 0.50390625], - 216:[0.40625, 0.0, 0.40625], - 217:[0.40625, 0.26953125, 0.40625], - 218:[0.30859375, 0.0, 0.30859375], - 219:[0.30859375, 0.20703125, 0.30859375], - 220:[0.99609375, 0.0, 0.74609375], - 221:[0.99609375, 0.6640625, 0.9140625], - 222:[0.73828125, 0.0, 0.55078125], - 223:[0.73828125, 0.4921875, 0.67578125], - 224:[0.50390625, 0.0, 0.375], - 225:[0.50390625, 0.3359375, 0.4609375], - 226:[0.40625, 0.0, 0.3046875], - 227:[0.40625, 0.26953125, 0.37109375], - 228:[0.30859375, 0.0, 0.23046875], - 229:[0.30859375, 0.20703125, 0.28515625], - 230:[0.99609375, 0.0, 0.49609375], - 231:[0.99609375, 0.6640625, 0.828125], - 232:[0.73828125, 0.0, 0.3671875], - 233:[0.73828125, 0.4921875, 0.61328125], - 234:[0.50390625, 0.0, 0.25], - 235:[0.50390625, 0.3359375, 0.41796875], - 236:[0.40625, 0.0, 0.203125], - 237:[0.40625, 0.26953125, 0.3359375], - 238:[0.30859375, 0.0, 0.15234375], - 239:[0.30859375, 0.20703125, 0.2578125], - 240:[0.99609375, 0.0, 0.24609375], - 241:[0.99609375, 0.6640625, 0.74609375], - 242:[0.73828125, 0.0, 0.1796875], - 243:[0.73828125, 0.4921875, 0.55078125], - 244:[0.50390625, 0.0, 0.12109375], - 245:[0.50390625, 0.3359375, 0.375], - 246:[0.40625, 0.0, 0.09765625], - 247:[0.40625, 0.26953125, 0.3046875], - 248:[0.30859375, 0.0, 0.07421875], - 249:[0.30859375, 0.20703125, 0.23046875], - 250:[0.19921875, 0.19921875, 0.19921875], - 251:[0.3125, 0.3125, 0.3125], - 252:[0.41015625, 0.41015625, 0.41015625], - 253:[0.5078125, 0.5078125, 0.5078125], - 254:[0.7421875, 0.7421875, 0.7421875], - 255:[0.99609375, 0.99609375, 0.99609375], -} diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py deleted file mode 100644 index ccd8ef9b625..00000000000 --- a/release/scripts/bpymodules/dxfLibrary.py +++ /dev/null @@ -1,880 +0,0 @@ -#dxfLibrary.py : provides functions for generating DXF files -# -------------------------------------------------------------------------- -__version__ = "v1.33 - 2009.06.16" -__author__ = "Stani Michiels(Stani), Remigiusz Fiedler(migius)" -__license__ = "GPL" -__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" -__bpydoc__ ="""The library to export geometry data to DXF format r12 version. - -Copyright %s -Version %s -License %s -Homepage %s - -See the homepage for documentation. -Dedicated thread on BlenderArtists: http://blenderartists.org/forum/showthread.php?t=136439 - -IDEAs: -- - -TODO: -- add support for DXFr14 (needs extended file header) -- add support for SPLINEs (possible first in DXFr14 version) -- add user preset for floating point precision (3-16?) - -History -v1.33 - 2009.06.16 by migius - - modif _point(): converts all coords to floats - - modif LineType class: implement elements - - added VPORT class, incl. defaults - - fix Insert class -v1.32 - 2009.06.06 by migius - - modif Style class: changed defaults to widthFactor=1.0, obliqueAngle=0.0 - - modif Text class: alignment parameter reactivated -v1.31 - 2009.06.02 by migius - - modif _Entity class: added paperspace,elevation -v1.30 - 2009.05.28 by migius - - bugfix 3dPOLYLINE/POLYFACE: VERTEX needs x,y,z coordinates, index starts with 1 not 0 -v1.29 - 2008.12.28 by Yorik - - modif POLYLINE to support bulge segments -v1.28 - 2008.12.13 by Steeve/BlenderArtists - - bugfix for EXTMIN/EXTMAX to suit Cycas-CAD -v1.27 - 2008.10.07 by migius - - beautifying output code: keys whitespace prefix - - refactoring DXF-strings format: NewLine moved to the end of -v1.26 - 2008.10.05 by migius - - modif POLYLINE to support POLYFACE -v1.25 - 2008.09.28 by migius - - modif FACE class for r12 -v1.24 - 2008.09.27 by migius - - modif POLYLINE class for r12 - - changing output format from r9 to r12(AC1009) -v1.1 (20/6/2005) by www.stani.be/python/sdxf - - Python library to generate dxf drawings -______________________________________________________________ -""" % (__author__,__version__,__license__,__url__) - -# -------------------------------------------------------------------------- -# DXF Library: copyright (C) 2005 by Stani Michiels (AKA Stani) -# 2008/2009 modif by Remigiusz Fiedler (AKA migius) -# -------------------------------------------------------------------------- -# ***** 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 -#from Blender import Mathutils, Window, Scene, sys, Draw -#import BPyMessages - -try: - import copy - #from struct import pack -except: - copy = None - -####1) Private (only for developpers) -_HEADER_POINTS=['insbase','extmin','extmax'] - -#---helper functions----------------------------------- -def _point(x,index=0): - """Convert tuple to a dxf point""" - #print 'deb: _point=', x #------------- - return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))]) - -def _points(plist): - """Convert a list of tuples to dxf points""" - out = '\n'.join([_point(plist[i],i)for i in range(len(plist))]) - return out - -#---base classes---------------------------------------- -class _Call: - """Makes a callable class.""" - def copy(self): - """Returns a copy.""" - return copy.deepcopy(self) - - def __call__(self,**attrs): - """Returns a copy with modified attributes.""" - copied=self.copy() - for attr in attrs:setattr(copied,attr,attrs[attr]) - return copied - -#------------------------------------------------------- -class _Entity(_Call): - """Base class for _common group codes for entities.""" - def __init__(self,paperspace=None,color=None,layer='0', - lineType=None,lineTypeScale=None,lineWeight=None, - extrusion=None,elevation=None,thickness=None, - parent=None): - """None values will be omitted.""" - self.paperspace = paperspace - self.color = color - self.layer = layer - self.lineType = lineType - self.lineTypeScale = lineTypeScale - self.lineWeight = lineWeight - self.extrusion = extrusion - self.elevation = elevation - self.thickness = thickness - #self.visible = visible - self.parent = parent - - def _common(self): - """Return common group codes as a string.""" - if self.parent:parent=self.parent - else:parent=self - result ='' - if parent.paperspace==1: result+=' 67\n1\n' - if parent.layer!=None: result+=' 8\n%s\n'%parent.layer - if parent.color!=None: result+=' 62\n%s\n'%parent.color - if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType - # TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight - # TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible - if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale - if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation - if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness - if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200) - return result - -#-------------------------- -class _Entities: - """Base class to deal with composed objects.""" - def __dxf__(self): - return [] - - def __str__(self): - return ''.join([str(x) for x in self.__dxf__()]) - -#-------------------------- -class _Collection(_Call): - """Base class to expose entities methods to main object.""" - def __init__(self,entities=[]): - self.entities=copy.copy(entities) - #link entities methods to drawing - for attr in dir(self.entities): - if attr[0]!='_': - attrObject=getattr(self.entities,attr) - if callable(attrObject): - setattr(self,attr,attrObject) - -####2) Constants -#---color values -BYBLOCK=0 -BYLAYER=256 - -#---block-type flags (bit coded values, may be combined): -ANONYMOUS =1 # This is an anonymous block generated by hatching, associative dimensioning, other internal operations, or an application -NON_CONSTANT_ATTRIBUTES =2 # This block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all) -XREF =4 # This block is an external reference (xref) -XREF_OVERLAY =8 # This block is an xref overlay -EXTERNAL =16 # This block is externally dependent -RESOLVED =32 # This is a resolved external reference, or dependent of an external reference (ignored on input) -REFERENCED =64 # This definition is a referenced external reference (ignored on input) - -#---mtext flags -#attachment point -TOP_LEFT = 1 -TOP_CENTER = 2 -TOP_RIGHT = 3 -MIDDLE_LEFT = 4 -MIDDLE_CENTER = 5 -MIDDLE_RIGHT = 6 -BOTTOM_LEFT = 7 -BOTTOM_CENTER = 8 -BOTTOM_RIGHT = 9 -#drawing direction -LEFT_RIGHT = 1 -TOP_BOTTOM = 3 -BY_STYLE = 5 #the flow direction is inherited from the associated text style -#line spacing style (optional): -AT_LEAST = 1 #taller characters will override -EXACT = 2 #taller characters will not override - -#---polyline flags -CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction) -CURVE_FIT =2 # Curve-fit vertices have been added -SPLINE_FIT =4 # Spline-fit vertices have been added -POLYLINE_3D =8 # This is a 3D polyline -POLYGON_MESH =16 # This is a 3D polygon mesh -CLOSED_N =32 # The polygon mesh is closed in the N direction -POLYFACE_MESH =64 # The polyline is a polyface mesh -CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline - -#---text flags -#horizontal -LEFT = 0 -CENTER = 1 -RIGHT = 2 -ALIGNED = 3 #if vertical alignment = 0 -MIDDLE = 4 #if vertical alignment = 0 -FIT = 5 #if vertical alignment = 0 -#vertical -BASELINE = 0 -BOTTOM = 1 -MIDDLE = 2 -TOP = 3 - -####3) Classes -#---entitities ----------------------------------------------- -#-------------------------- -class Arc(_Entity): - """Arc, angles in degrees.""" - def __init__(self,center=(0,0,0),radius=1, - startAngle=0.0,endAngle=90,**common): - """Angles in degrees.""" - _Entity.__init__(self,**common) - self.center=center - self.radius=radius - self.startAngle=startAngle - self.endAngle=endAngle - def __str__(self): - return ' 0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\ - (self._common(),_point(self.center), - self.radius,self.startAngle,self.endAngle) - -#----------------------------------------------- -class Circle(_Entity): - """Circle""" - def __init__(self,center=(0,0,0),radius=1,**common): - _Entity.__init__(self,**common) - self.center=center - self.radius=radius - def __str__(self): - return ' 0\nCIRCLE\n%s%s\n 40\n%s\n'%\ - (self._common(),_point(self.center),self.radius) - -#----------------------------------------------- -class Face(_Entity): - """3dface""" - def __init__(self,points,**common): - _Entity.__init__(self,**common) - while len(points)<4: #fix for r12 format - points.append(points[-1]) - self.points=points - - def __str__(self): - out = ' 0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points)) - #print 'deb:out=', out #------------------- - return out - -#----------------------------------------------- -class Insert(_Entity): - """Block instance.""" - def __init__(self,name,point=(0,0,0), - xscale=None,yscale=None,zscale=None, - cols=None,colspacing=None,rows=None,rowspacing=None, - rotation=None, - **common): - _Entity.__init__(self,**common) - self.name=name - self.point=point - self.xscale=xscale - self.yscale=yscale - self.zscale=zscale - self.cols=cols - self.colspacing=colspacing - self.rows=rows - self.rowspacing=rowspacing - self.rotation=rotation - - def __str__(self): - result=' 0\nINSERT\n 2\n%s\n%s%s\n'%\ - (self.name,self._common(),_point(self.point)) - if self.xscale!=None:result+=' 41\n%s\n'%self.xscale - if self.yscale!=None:result+=' 42\n%s\n'%self.yscale - if self.zscale!=None:result+=' 43\n%s\n'%self.zscale - if self.rotation:result+=' 50\n%s\n'%self.rotation - if self.cols!=None:result+=' 70\n%s\n'%self.cols - if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing - if self.rows!=None:result+=' 71\n%s\n'%self.rows - if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing - return result - -#----------------------------------------------- -class Line(_Entity): - """Line""" - def __init__(self,points,**common): - _Entity.__init__(self,**common) - self.points=points - def __str__(self): - return ' 0\nLINE\n%s%s\n' %( - self._common(), _points(self.points)) - - -#----------------------------------------------- -class PolyLine(_Entity): - def __init__(self,points,org_point=[0,0,0],flag=0,width=None,**common): - #width = number, or width = list [width_start=None, width_end=None] - #for 2d-polyline: points = [ [x, y, z, width_start=None, width_end=None, bulge=0 or None], ...] - #for 3d-polyline: points = [ [x, y, z], ...] - #for polyface: points = [points_list, faces_list] - _Entity.__init__(self,**common) - self.points=points - self.org_point=org_point - self.flag=flag - self.polyface = False - self.polyline2d = False - self.faces = [] # dummy value - self.width= None # dummy value - if self.flag & POLYFACE_MESH: - self.polyface=True - self.points=points[0] - self.faces=points[1] - self.p_count=len(self.points) - self.f_count=len(self.faces) - elif not self.flag & POLYLINE_3D: - self.polyline2d = True - if width: - if type(width)!='list': - width=[width,width] - self.width=width - - def __str__(self): - result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.flag) - result+=' 66\n1\n' - result+='%s\n' %_point(self.org_point) - if self.polyface: - result+=' 71\n%s\n' %self.p_count - result+=' 72\n%s\n' %self.f_count - elif self.polyline2d: - if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1]) - for point in self.points: - result+=' 0\nVERTEX\n' - result+=' 8\n%s\n' %self.layer - if self.polyface: - result+='%s\n' %_point(point[0:3]) - result+=' 70\n192\n' - elif self.polyline2d: - result+='%s\n' %_point(point[0:2]) - if len(point)>4: - width1, width2 = point[3], point[4] - if width1!=None: result+=' 40\n%s\n' %width1 - if width2!=None: result+=' 41\n%s\n' %width2 - if len(point)==6: - bulge = point[5] - if bulge: result+=' 42\n%s\n' %bulge - else: - result+='%s\n' %_point(point[0:3]) - for face in self.faces: - result+=' 0\nVERTEX\n' - result+=' 8\n%s\n' %self.layer - result+='%s\n' %_point(self.org_point) - result+=' 70\n128\n' - result+=' 71\n%s\n' %face[0] - result+=' 72\n%s\n' %face[1] - result+=' 73\n%s\n' %face[2] - if len(face)==4: result+=' 74\n%s\n' %face[3] - result+=' 0\nSEQEND\n' - result+=' 8\n%s\n' %self.layer - return result - -#----------------------------------------------- -class Point(_Entity): - """Point.""" - def __init__(self,points=None,**common): - _Entity.__init__(self,**common) - self.points=points - def __str__(self): # TODO: - return ' 0\nPOINT\n%s%s\n' %(self._common(), - _points(self.points) - ) - -#----------------------------------------------- -class Solid(_Entity): - """Colored solid fill.""" - def __init__(self,points=None,**common): - _Entity.__init__(self,**common) - self.points=points - def __str__(self): - return ' 0\nSOLID\n%s%s\n' %(self._common(), - _points(self.points[:2]+[self.points[3],self.points[2]]) - ) - - -#----------------------------------------------- -class Text(_Entity): - """Single text line.""" - def __init__(self,text='',point=(0,0,0),alignment=None, - flag=None,height=1,justifyhor=None,justifyver=None, - rotation=None,obliqueAngle=None,style=None,xscale=None,**common): - _Entity.__init__(self,**common) - self.text=text - self.point=point - self.alignment=alignment - self.flag=flag - self.height=height - self.justifyhor=justifyhor - self.justifyver=justifyver - self.rotation=rotation - self.obliqueAngle=obliqueAngle - self.style=style - self.xscale=xscale - def __str__(self): - result= ' 0\nTEXT\n%s%s\n 40\n%s\n 1\n%s\n'%\ - (self._common(),_point(self.point),self.height,self.text) - if self.rotation: result+=' 50\n%s\n'%self.rotation - if self.xscale: result+=' 41\n%s\n'%self.xscale - if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle - if self.style: result+=' 7\n%s\n'%self.style - if self.flag: result+=' 71\n%s\n'%self.flag - if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor - if self.alignment: result+='%s\n'%_point(self.alignment,1) - if self.justifyver: result+=' 73\n%s\n'%self.justifyver - return result - -#----------------------------------------------- -class Mtext(Text): - """Surrogate for mtext, generates some Text instances.""" - def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options): - Text.__init__(self,text=text,point=point,**options) - if down:spacingFactor*=-1 - self.spacingFactor=spacingFactor - self.spacingWidth=spacingWidth - self.width=width - self.down=down - def __str__(self): - texts=self.text.replace('\r\n','\n').split('\n') - if not self.down:texts.reverse() - result='' - x=y=0 - if self.spacingWidth:spacingWidth=self.spacingWidth - else:spacingWidth=self.height*self.spacingFactor - for text in texts: - while text: - result+='%s\n'%Text(text[:self.width], - point=(self.point[0]+x*spacingWidth, - self.point[1]+y*spacingWidth, - self.point[2]), - alignment=self.alignment,flag=self.flag,height=self.height, - justifyhor=self.justifyhor,justifyver=self.justifyver, - rotation=self.rotation,obliqueAngle=self.obliqueAngle, - style=self.style,xscale=self.xscale,parent=self - ) - text=text[self.width:] - if self.rotation:x+=1 - else:y+=1 - return result[1:] - -#----------------------------------------------- -##class _Mtext(_Entity): -## """Mtext not functioning for minimal dxf.""" -## def __init__(self,text='',point=(0,0,0),attachment=1, -## charWidth=None,charHeight=1,direction=1,height=100,rotation=0, -## spacingStyle=None,spacingFactor=None,style=None,width=100, -## xdirection=None,**common): -## _Entity.__init__(self,**common) -## self.text=text -## self.point=point -## self.attachment=attachment -## self.charWidth=charWidth -## self.charHeight=charHeight -## self.direction=direction -## self.height=height -## self.rotation=rotation -## self.spacingStyle=spacingStyle -## self.spacingFactor=spacingFactor -## self.style=style -## self.width=width -## self.xdirection=xdirection -## def __str__(self): -## input=self.text -## text='' -## while len(input)>250: -## text+='3\n%s\n'%input[:250] -## input=input[250:] -## text+='1\n%s\n'%input -## result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\ -## (self._common(),_point(self.point),self.charHeight,self.width, -## self.attachment,self.direction,text, -## self.height, -## self.rotation) -## if self.style:result+='7\n%s\n'%self.style -## if self.xdirection:result+='%s\n'%_point(self.xdirection,1) -## if self.charWidth:result+='42\n%s\n'%self.charWidth -## if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle -## if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor -## return result - -#---tables --------------------------------------------------- -#----------------------------------------------- -class Block(_Collection): - """Use list methods to add entities, eg append.""" - def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]): - self.entities=copy.copy(entities) - _Collection.__init__(self,entities) - self.layer=layer - self.name=name - self.flag=0 - self.base=base - def __str__(self): # TODO: - e=''.join([str(x)for x in self.entities]) - return ' 0\nBLOCK\n 8\n%s\n 2\n%s\n 70\n%s\n%s\n 3\n%s\n%s 0\nENDBLK\n'%\ - (self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e) - -#----------------------------------------------- -class Layer(_Call): - """Layer""" - def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64): - self.name=name - self.color=color - self.lineType=lineType - self.flag=flag - def __str__(self): - return ' 0\nLAYER\n 2\n%s\n 70\n%s\n 62\n%s\n 6\n%s\n'%\ - (self.name.upper(),self.flag,self.color,self.lineType) - -#----------------------------------------------- -class LineType(_Call): - """Custom linetype""" - def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0): - self.name=name - self.description=description - self.elements=copy.copy(elements) - self.flag=flag - def __str__(self): - result = ' 0\nLTYPE\n 2\n%s\n 70\n%s\n 3\n%s\n 72\n65\n'%\ - (self.name.upper(),self.flag,self.description) - if self.elements: - elements = ' 73\n%s\n' %(len(self.elements)-1) - elements += ' 40\n%s\n' %(self.elements[0]) - for e in self.elements[1:]: - elements += ' 49\n%s\n' %e - result += elements - return result - - -#----------------------------------------------- -class Style(_Call): - """Text style""" - def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0, - mirror=0,lastHeight=1,font='arial.ttf',bigFont=''): - self.name=name - self.flag=flag - self.height=height - self.widthFactor=widthFactor - self.obliqueAngle=obliqueAngle - self.mirror=mirror - self.lastHeight=lastHeight - self.font=font - self.bigFont=bigFont - def __str__(self): - return ' 0\nSTYLE\n 2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\ - (self.name.upper(),self.flag,self.flag,self.widthFactor, - self.obliqueAngle,self.mirror,self.lastHeight, - self.font.upper(),self.bigFont.upper()) - -#----------------------------------------------- -class VPort(_Call): - def __init__(self,name,flag=0, - leftBottom=(0.0,0.0), - rightTop=(1.0,1.0), - center=(0.5,0.5), - snap_base=(0.0,0.0), - snap_spacing=(0.1,0.1), - grid_spacing=(0.1,0.1), - direction=(0.0,0.0,1.0), - target=(0.0,0.0,0.0), - height=1.0, - ratio=1.0, - lens=50, - frontClipping=0, - backClipping=0, - snap_rotation=0, - twist=0, - mode=0, - circle_zoom=100, - fast_zoom=1, - ucsicon=1, - snap_on=0, - grid_on=0, - snap_style=0, - snap_isopair=0 - ): - self.name=name - self.flag=flag - self.leftBottom=leftBottom - self.rightTop=rightTop - self.center=center - self.snap_base=snap_base - self.snap_spacing=snap_spacing - self.grid_spacing=grid_spacing - self.direction=direction - self.target=target - self.height=float(height) - self.ratio=float(ratio) - self.lens=float(lens) - self.frontClipping=float(frontClipping) - self.backClipping=float(backClipping) - self.snap_rotation=float(snap_rotation) - self.twist=float(twist) - self.mode=mode - self.circle_zoom=circle_zoom - self.fast_zoom=fast_zoom - self.ucsicon=ucsicon - self.snap_on=snap_on - self.grid_on=grid_on - self.snap_style=snap_style - self.snap_isopair=snap_isopair - def __str__(self): - output = [' 0', 'VPORT', - ' 2', self.name, - ' 70', self.flag, - _point(self.leftBottom), - _point(self.rightTop,1), - _point(self.center,2), # View center point (in DCS) - _point(self.snap_base,3), - _point(self.snap_spacing,4), - _point(self.grid_spacing,5), - _point(self.direction,6), #view direction from target (in WCS) - _point(self.target,7), - ' 40', self.height, - ' 41', self.ratio, - ' 42', self.lens, - ' 43', self.frontClipping, - ' 44', self.backClipping, - ' 50', self.snap_rotation, - ' 51', self.twist, - ' 71', self.mode, - ' 72', self.circle_zoom, - ' 73', self.fast_zoom, - ' 74', self.ucsicon, - ' 75', self.snap_on, - ' 76', self.grid_on, - ' 77', self.snap_style, - ' 78', self.snap_isopair - ] - - output_str = '' - for s in output: - output_str += '%s\n' %s - return output_str - - - -#----------------------------------------------- -class View(_Call): - def __init__(self,name,flag=0, - width=1, - height=1, - center=(0.5,0.5), - direction=(0,0,1), - target=(0,0,0), - lens=50, - frontClipping=0, - backClipping=0, - twist=0,mode=0 - ): - self.name=name - self.flag=flag - self.width=float(width) - self.height=float(height) - self.center=center - self.direction=direction - self.target=target - self.lens=float(lens) - self.frontClipping=float(frontClipping) - self.backClipping=float(backClipping) - self.twist=float(twist) - self.mode=mode - def __str__(self): - output = [' 0', 'VIEW', - ' 2', self.name, - ' 70', self.flag, - ' 40', self.height, - _point(self.center), - ' 41', self.width, - _point(self.direction,1), - _point(self.target,2), - ' 42', self.lens, - ' 43', self.frontClipping, - ' 44', self.backClipping, - ' 50', self.twist, - ' 71', self.mode - ] - output_str = '' - for s in output: - output_str += '%s\n' %s - return output_str - -#----------------------------------------------- -def ViewByWindow(name,leftBottom=(0,0),rightTop=(1,1),**options): - width=abs(rightTop[0]-leftBottom[0]) - height=abs(rightTop[1]-leftBottom[1]) - center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5) - return View(name=name,width=width,height=height,center=center,**options) - -#---drawing -#----------------------------------------------- -class Drawing(_Collection): - """Dxf drawing. Use append or any other list methods to add objects.""" - def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0), - layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[], - views=[],vports=[],entities=None,fileName='test.dxf'): - # TODO: replace list with None,arial - if not entities: - entities=[] - _Collection.__init__(self,entities) - self.insbase=insbase - self.extmin=extmin - self.extmax=extmax - self.layers=copy.copy(layers) - self.linetypes=copy.copy(linetypes) - self.styles=copy.copy(styles) - self.views=copy.copy(views) - self.vports=copy.copy(vports) - self.blocks=copy.copy(blocks) - self.fileName=fileName - #private - #self.acadver='9\n$ACADVER\n1\nAC1006\n' - self.acadver=' 9\n$ACADVER\n 1\nAC1009\n' - """DXF AutoCAD-Release format codes - AC1021 2008, 2007 - AC1018 2006, 2005, 2004 - AC1015 2002, 2000i, 2000 - AC1014 R14,14.01 - AC1012 R13 - AC1009 R12,11 - AC1006 R10 - AC1004 R9 - AC1002 R2.6 - AC1.50 R2.05 - """ - - def _name(self,x): - """Helper function for self._point""" - return ' 9\n$%s\n' %x.upper() - - def _point(self,name,x): - """Point setting from drawing like extmin,extmax,...""" - return '%s%s' %(self._name(name),_point(x)) - - def _section(self,name,x): - """Sections like tables,blocks,entities,...""" - if x: xstr=''.join(x) - else: xstr='' - return ' 0\nSECTION\n 2\n%s\n%s 0\nENDSEC\n'%(name.upper(),xstr) - - def _table(self,name,x): - """Tables like ltype,layer,style,...""" - if x: xstr=''.join(x) - else: xstr='' - return ' 0\nTABLE\n 2\n%s\n 70\n%s\n%s 0\nENDTAB\n'%(name.upper(),len(x),xstr) - - def __str__(self): - """Returns drawing as dxf string.""" - header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS] - header=self._section('header',header) - - tables=[self._table('vport',[str(x) for x in self.vports]), - self._table('ltype',[str(x) for x in self.linetypes]), - self._table('layer',[str(x) for x in self.layers]), - self._table('style',[str(x) for x in self.styles]), - self._table('view',[str(x) for x in self.views]), - ] - tables=self._section('tables',tables) - - blocks=self._section('blocks',[str(x) for x in self.blocks]) - - entities=self._section('entities',[str(x) for x in self.entities]) - - all=''.join([header,tables,blocks,entities,' 0\nEOF\n']) - return all - - def saveas(self,fileName): - self.fileName=fileName - self.save() - - def save(self): - test=open(self.fileName,'w') - test.write(str(self)) - test.close() - - -#---extras -#----------------------------------------------- -class Rectangle(_Entity): - """Rectangle, creates lines.""" - def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common): - _Entity.__init__(self,**common) - self.point=point - self.width=width - self.height=height - self.solid=solid - self.line=line - def __str__(self): - result='' - points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]), - (self.point[0]+self.width,self.point[1]+self.height,self.point[2]), - (self.point[0],self.point[1]+self.height,self.point[2]),self.point] - if self.solid: - result+= Solid(points=points[:-1],parent=self.solid) - if self.line: - for i in range(4): - result+= Line(points=[points[i],points[i+1]],parent=self) - return result[1:] - -#----------------------------------------------- -class LineList(_Entity): - """Like polyline, but built of individual lines.""" - def __init__(self,points=[],org_point=[0,0,0],closed=0,**common): - _Entity.__init__(self,**common) - self.closed=closed - self.points=copy.copy(points) - def __str__(self): - if self.closed:points=self.points+[self.points[0]] - else: points=self.points - result='' - for i in range(len(points)-1): - result+= Line(points=[points[i],points[i+1]],parent=self) - return result[1:] - -#----------------------------------------------------- -def test(): - #Blocks - b=Block('test') - b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1)) - b.append(Arc(center=(1,0,0),color=2)) - - #Drawing - d=Drawing() - #tables - d.blocks.append(b) #table blocks - d.styles.append(Style()) #table styles - d.views.append(View('Normal')) #table view - d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem - - #entities - d.append(Circle(center=(1,1,0),color=3)) - d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4)) - d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2)) - d.append(Line(points=[(0,0,0),(1,1,1)])) - d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90)) - d.append(Text('Please donate!',point=(3,0,1))) - #d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2))) - d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3)) - #d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1)) - - #d.saveas('c:\\test.dxf') - d.saveas('test.dxf') - -#----------------------------------------------------- -if __name__=='__main__': - if not copy: - Draw.PupMenu('Error%t|This script requires a full python install') - else: test() -
\ No newline at end of file diff --git a/release/scripts/bpymodules/dxfReader.py b/release/scripts/bpymodules/dxfReader.py deleted file mode 100644 index df4ebc309e4..00000000000 --- a/release/scripts/bpymodules/dxfReader.py +++ /dev/null @@ -1,381 +0,0 @@ -"""This module provides a function for reading dxf files and parsing them into a useful tree of objects and data. - - The convert function is called by the readDXF fuction to convert dxf strings into the correct data based - on their type code. readDXF expects a (full path) file name as input. -""" - -# -------------------------------------------------------------------------- -# DXF Reader v0.9 by Ed Blake (AKA Kitsu) -# 2008.05.08 modif.def convert() by Remigiusz Fiedler (AKA migius) -# -------------------------------------------------------------------------- -# ***** 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 ***** -# -------------------------------------------------------------------------- - - -#from dxfImportObjects import * - -class Object: - """Empty container class for dxf objects""" - - def __init__(self, _type='', block=False): - """_type expects a string value.""" - self.type = _type - self.name = '' - self.data = [] - - def __str__(self): - if self.name: - return self.name - else: - return self.type - - def __repr__(self): - return str(self.data) - - def get_type(self, kind=''): - """Despite the name, this method actually returns all objects of type 'kind' from self.data.""" - if type: - objects = [] - for item in self.data: - if type(item) != list and item.type == kind: - # we want this type of object - objects.append(item) - elif type(item) == list and item[0] == kind: - # we want this type of data - objects.append(item[1]) - return objects - - -class InitializationError(Exception): pass - -class StateMachine: - """(finite) State Machine from the great David Mertz's great Charming Python article.""" - - def __init__(self): - self.handlers = [] - self.startState = None - self.endStates = [] - - def add_state(self, handler, end_state=0): - """All states and handlers are functions which return - a state and a cargo.""" - self.handlers.append(handler) - if end_state: - self.endStates.append(handler) - def set_start(self, handler): - """Sets the starting handler function.""" - self.startState = handler - - - def run(self, cargo=None): - if not self.startState: - raise InitializationError,\ - "must call .set_start() before .run()" - if not self.endStates: - raise InitializationError, \ - "at least one state must be an end_state" - handler = self.startState - while 1: - (newState, cargo) = handler(cargo) - #print cargo - if newState in self.endStates: - return newState(cargo) - #break - elif newState not in self.handlers: - raise RuntimeError, "Invalid target %s" % newState - else: - handler = newState - -def get_name(data): - """Get the name of an object from its object data. - - Returns a pair of (data_item, name) where data_item is the list entry where the name was found - (the data_item can be used to remove the entry from the object data). Be sure to check - name not None before using the returned values! - """ - value = None - for item in data: - if item[0] == 2: - value = item[1] - break - return item, value - -def get_layer(data): - """Expects object data as input. - - Returns (entry, layer_name) where entry is the data item that provided the layer name. - """ - value = None - for item in data: - if item[0] == 8: - value = item[1] - break - return item, value - - -def convert(code, value): - """Convert a string to the correct Python type based on its dxf code. - code types: - ints = 60-79, 170-179, 270-289, 370-389, 400-409, 1060-1070 - longs = 90-99, 420-429, 440-459, 1071 - floats = 10-39, 40-59, 110-139, 140-149, 210-239, 460-469, 1010-1059 - hex = 105, 310-379, 390-399 - strings = 0-9, 100, 102, 300-309, 410-419, 430-439, 470-479, 999, 1000-1009 - """ - if 59 < code < 80 or 169 < code < 180 or 269 < code < 290 or 369 < code < 390 or 399 < code < 410 or 1059 < code < 1071: - value = int(float(value)) - elif 89 < code < 100 or 419 < code < 430 or 439 < code < 460 or code == 1071: - value = long(float(value)) - elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060: - value = float(value) - elif code == 105 or 309 < code < 380 or 389 < code < 400: - value = int(value, 16) # should be left as string? - else: # it's already a string so do nothing - pass - return value - - -def findObject(infile, kind=''): - """Finds the next occurance of an object.""" - obj = False - while 1: - line = infile.readline() - if not line: # readline returns '' at eof - return False - if not obj: # We're still looking for our object code - if line.lower().strip() == '0': - obj = True # found it - else: # we are in an object definition - if kind: # if we're looking for a particular kind - if line.lower().strip() == kind: - obj = Object(line.lower().strip()) - break - else: # otherwise take anything non-numeric - if line.lower().strip() not in string.digits: - obj = Object(line.lower().strip()) - break - obj = False # whether we found one or not it's time to start over - return obj - -def handleObject(infile): - """Add data to an object until end of object is found.""" - line = infile.readline() - if line.lower().strip() == 'section': - return 'section' # this would be a problem - elif line.lower().strip() == 'endsec': - return 'endsec' # this means we are done with a section - else: # add data to the object until we find a new object - obj = Object(line.lower().strip()) - obj.name = obj.type - done = False - data = [] - while not done: - line = infile.readline() - if not data: - if line.lower().strip() == '0': - #we've found an object, time to return - return obj - else: - # first part is always an int - data.append(int(line.lower().strip())) - else: - data.append(convert(data[0], line.strip())) - obj.data.append(data) - data = [] - -def handleTable(table, infile): - """Special handler for dealing with nested table objects.""" - item, name = get_name(table.data) - if name: # We should always find a name - table.data.remove(item) - table.name = name.lower() - # This next bit is from handleObject - # handleObject should be generalized to work with any section like object - while 1: - obj = handleObject(infile) - if obj.type == 'table': - print "Warning: previous table not closed!" - return table - elif obj.type == 'endtab': - return table # this means we are done with the table - else: # add objects to the table until one of the above is found - table.data.append(obj) - - - - -def handleBlock(block, infile): - """Special handler for dealing with nested table objects.""" - item, name = get_name(block.data) - if name: # We should always find a name - block.data.remove(item) - block.name = name - # This next bit is from handleObject - # handleObject should be generalized to work with any section like object - while 1: - obj = handleObject(infile) - if obj.type == 'block': - print "Warning: previous block not closed!" - return block - elif obj.type == 'endblk': - return block # this means we are done with the table - else: # add objects to the table until one of the above is found - block.data.append(obj) - - - - -"""These are the states/functions used in the State Machine. -states: - start - find first section - start_section - add data, find first object - object - add obj-data, watch for next obj (called directly by start_section) - end_section - look for next section or eof - end - return results -""" - -def start(cargo): - """Expects the infile as cargo, initializes the cargo.""" - #print "Entering start state!" - infile = cargo - drawing = Object('drawing') - section = findObject(infile, 'section') - if section: - return start_section, (infile, drawing, section) - else: - return error, (infile, "Failed to find any sections!") - -def start_section(cargo): - """Expects [infile, drawing, section] as cargo, builds a nested section object.""" - #print "Entering start_section state!" - infile = cargo[0] - drawing = cargo[1] - section = cargo[2] - # read each line, if it is an object declaration go to object mode - # otherwise create a [index, data] pair and add it to the sections data. - done = False - data = [] - while not done: - line = infile.readline() - - if not data: # if we haven't found a dxf code yet - if line.lower().strip() == '0': - # we've found an object - while 1: # no way out unless we find an end section or a new section - obj = handleObject(infile) - if obj == 'section': # shouldn't happen - print "Warning: failed to close previous section!" - return end_section, (infile, drawing) - elif obj == 'endsec': # This section is over, look for the next - drawing.data.append(section) - return end_section, (infile, drawing) - elif obj.type == 'table': # tables are collections of data - obj = handleTable(obj, infile) # we need to find all there contents - section.data.append(obj) # before moving on - elif obj.type == 'block': # the same is true of blocks - obj = handleBlock(obj, infile) # we need to find all there contents - section.data.append(obj) # before moving on - else: # found another sub-object - section.data.append(obj) - else: - data.append(int(line.lower().strip())) - else: # we have our code, now we just need to convert the data and add it to our list. - data.append(convert(data[0], line.strip())) - section.data.append(data) - data = [] -def end_section(cargo): - """Expects (infile, drawing) as cargo, searches for next section.""" - #print "Entering end_section state!" - infile = cargo[0] - drawing = cargo[1] - section = findObject(infile, 'section') - if section: - return start_section, (infile, drawing, section) - else: - return end, (infile, drawing) - -def end(cargo): - """Expects (infile, drawing) as cargo, called when eof has been reached.""" - #print "Entering end state!" - infile = cargo[0] - drawing = cargo[1] - #infile.close() - return drawing - -def error(cargo): - """Expects a (infile, string) as cargo, called when there is an error during processing.""" - #print "Entering error state!" - infile = cargo[0] - err = cargo[1] - infile.close() - print "There has been an error:" - print err - return False - -def readDXF(filename, objectify): - """Given a file name try to read it as a dxf file. - - Output is an object with the following structure - drawing - header - header data - classes - class data - tables - table data - blocks - block data - entities - entity data - objects - object data - where foo data is a list of sub-objects. True object data - is of the form [code, data]. -""" - infile = open(filename) - - sm = StateMachine() - sm.add_state(error, True) - sm.add_state(end, True) - sm.add_state(start_section) - sm.add_state(end_section) - sm.add_state(start) - sm.set_start(start) - try: - drawing = sm.run(infile) - if drawing: - drawing.name = filename - for obj in drawing.data: - item, name = get_name(obj.data) - if name: - obj.data.remove(item) - obj.name = name.lower() - setattr(drawing, name.lower(), obj) - # Call the objectify function to cast - # raw objects into the right types of object - obj.data = objectify(obj.data) - #print obj.name - finally: - infile.close() - return drawing -if __name__ == "__main__": - filename = r".\examples\block-test.dxf" - drawing = readDXF(filename) - for item in drawing.entities.data: - print item diff --git a/release/scripts/bpymodules/mesh_gradient.py b/release/scripts/bpymodules/mesh_gradient.py deleted file mode 100644 index e582a30152b..00000000000 --- a/release/scripts/bpymodules/mesh_gradient.py +++ /dev/null @@ -1,229 +0,0 @@ -# This is not to be used directly, vertexGradientPick can be used externaly - -import Blender -import BPyMesh -import BPyWindow - -mouseViewRay= BPyWindow.mouseViewRay -from Blender import Mathutils, Window, Scene, Draw, sys -from Blender.Mathutils import 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= DirectionA.cross(DirectionB) - ORTHO= False - - else: # Ortho - Same direction, different origin - cross_grad= DirectionA.cross(OriginA-OriginB) - ORTHO= True - - cross_grad.normalize() - cross_grad= cross_grad * 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 - - VSEL= [False] * (len(me.verts)) - - # Get the selected faces and apply the selection to the verts. - for f in me.faces: - if f.sel: - 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.sel: - 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, '') - - diff --git a/release/scripts/bpymodules/meshtools.py b/release/scripts/bpymodules/meshtools.py deleted file mode 100644 index 274a12ea6da..00000000000 --- a/release/scripts/bpymodules/meshtools.py +++ /dev/null @@ -1,355 +0,0 @@ -# $Id$ -# -# +---------------------------------------------------------+ -# | Copyright (c) 2001 Anthony D'Agostino | -# | http://www.redrival.com/scorpius | -# | scorpius@netzero.com | -# | September 28, 2002 | -# +---------------------------------------------------------+ -# | Common Functions & Global Variables For All IO Modules | -# +---------------------------------------------------------+ - -# ***** 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 sys - -show_progress = 1 # Set to 0 for faster performance -average_vcols = 1 # Off for per-face, On for per-vertex -overwrite_mesh_name = 0 # Set to 0 to increment object-name version - -blender_version = Blender.Get('version') -blender_version_str = `blender_version`[0] + '.' + `blender_version`[1:] - -try: - import operator -except: - msg = "Error: you need a full Python install to run this script." - meshtools.print_boxed(msg) - Blender.Draw.PupMenu("ERROR%t|"+msg) - -# ================================= -# === Append Faces To Face List === -# ================================= -def append_faces(mesh, faces, facesuv, uvcoords): - for i in xrange(len(faces)): - if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Generating Faces") - numfaceverts=len(faces[i]) - if numfaceverts == 2: #This is not a face is an edge - if mesh.edges == None: #first run - mesh.addEdgeData() - #rev_face = revert(cur_face) - i1 = faces[i][0] - i2 = faces[i][1] - ee = mesh.addEdge(mesh.verts[i1],mesh.verts[i2]) - ee.flag |= Blender.NMesh.EdgeFlags.EDGEDRAW - ee.flag |= Blender.NMesh.EdgeFlags.EDGERENDER - elif numfaceverts in [3,4]: # This face is a triangle or quad - face = Blender.NMesh.Face() - for j in xrange(numfaceverts): - index = faces[i][j] - face.v.append(mesh.verts[index]) - if len(uvcoords) > 1: - uvidx = facesuv[i][j] - face.uv.append(uvcoords[uvidx]) - face.mode = 0 - face.col = [Blender.NMesh.Col()]*4 - mesh.faces.append(face) - else: # Triangulate n-sided convex polygon. - a, b, c = 0, 1, 2 # Indices of first triangle. - for j in xrange(numfaceverts-2): # Number of triangles in polygon. - face = Blender.NMesh.Face() - face.v.append(mesh.verts[faces[i][a]]) - face.v.append(mesh.verts[faces[i][b]]) - face.v.append(mesh.verts[faces[i][c]]) - b = c; c += 1 - mesh.faces.append(face) - #face.smooth = 1 - -# =================================== -# === Append Verts to Vertex List === -# =================================== -def append_verts(mesh, verts, normals): - #print "Number of normals:", len(normals) - #print "Number of verts :", len(verts) - for i in xrange(len(verts)): - if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(verts), "Generating Verts") - x, y, z = verts[i] - mesh.verts.append(Blender.NMesh.Vert(x, y, z)) - if normals: - mesh.verts[i].no[0] = normals[i][0] - mesh.verts[i].no[1] = normals[i][1] - mesh.verts[i].no[2] = normals[i][2] - -# =========================== -# === Create Blender Mesh === -# =========================== -def create_mesh(verts, faces, objname, facesuv=[], uvcoords=[], normals=[]): - if normals: normal_flag = 0 - else: normal_flag = 1 - mesh = Blender.NMesh.GetRaw() - append_verts(mesh, verts, normals) - append_faces(mesh, faces, facesuv, uvcoords) - if not overwrite_mesh_name: - objname = versioned_name(objname) - ob= Blender.NMesh.PutRaw(mesh, objname, normal_flag) # Name the Mesh - ob.name= objname # Name the Object - Blender.Redraw() - -# ============================== -# === Increment Name Version === -# ============================== -def versioned_name(objname): - existing_names = [] - for object in Blender.Object.Get(): - existing_names.append(object.name) - existing_names.append(object.getData(name_only=1)) - if objname in existing_names: # don't over-write other names - try: - name, ext = objname.split('.') - except ValueError: - name, ext = objname, '' - try: - num = int(ext) - root = name - except ValueError: - root = objname - for i in xrange(1, 1000): - objname = "%s.%03d" % (root, i) - if objname not in existing_names: - break - return objname - -# =========================== -# === Print Text In A Box === -# =========================== -def print_boxed(text): - lines = text.splitlines() - maxlinelen = max(map(len, lines)) - if sys.platform[:3] == "win": - print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191) - for line in lines: - print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179) - print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217) - else: - print '+-' + '-'*maxlinelen + '-+' - for line in lines: print '| ' + line.ljust(maxlinelen) + ' |' - print '+-' + '-'*maxlinelen + '-+' - print '\a\r', # beep when done - -# =============================================== -# === Get euler angles from a rotation matrix === -# =============================================== -def mat2euler(mat): - angle_y = -math.asin(mat[0][2]) - c = math.cos(angle_y) - if math.fabs(c) > 0.005: - angle_x = math.atan2(mat[1][2]/c, mat[2][2]/c) - angle_z = math.atan2(mat[0][1]/c, mat[0][0]/c) - else: - angle_x = 0.0 - angle_z = -math.atan2(mat[1][0], mat[1][1]) - return (angle_x, angle_y, angle_z) - -# ========================== -# === Transpose A Matrix === -# ========================== -def transpose(A): - S = len(A) - T = len(A[0]) - B = [[None]*S for i in xrange(T)] - for i in xrange(T): - for j in xrange(S): - B[i][j] = A[j][i] - return B - -# ======================= -# === Apply Transform === -# ======================= -def apply_transform(vertex, matrix): - x, y, z = vertex - xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2] - xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc - ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc - zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc - vertex = [xcomponent, ycomponent, zcomponent] - return vertex - -# ========================= -# === Has Vertex Colors === -# ========================= -def has_vertex_colors(mesh): - # My replacement/workaround for hasVertexColours() - # The docs say: - # "Warning: If a mesh has both vertex colours and textured faces, - # this function will return False. This is due to the way Blender - # deals internally with the vertex colours array (if there are - # textured faces, it is copied to the textured face structure and - # the original array is freed/deleted)." - try: - return mesh.faces[0].col[0] - except: - return 0 - -# =========================== -# === Generate Edge Table === -# =========================== -def generate_edgetable(mesh): - edge_table = {} - numfaces = len(mesh.faces) - - for i in xrange(numfaces): - if not i%100 and show_progress: - Blender.Window.DrawProgressBar(float(i)/numfaces, "Generating Edge Table") - if len(mesh.faces[i].v) == 4: # Process Quadrilaterals - generate_entry_from_quad(mesh, i, edge_table) - elif len(mesh.faces[i].v) == 3: # Process Triangles - generate_entry_from_tri(mesh, i, edge_table) - else: # Skip This Face - print "Face #", i, "was skipped." - - # === Sort Edge_Table Keys & Add Edge Indices === - i = 0 - keys = edge_table.keys() - keys.sort() - for key in keys: - edge_table[key][6] = i - i += 1 - - # === Replace Tuples With Indices === - for key in keys: - for i in [2,3,4,5]: - if edge_table.has_key(edge_table[key][i]): - edge_table[key][i] = edge_table[edge_table[key][i]][6] - else: - keyrev = (edge_table[key][i][1], edge_table[key][i][0]) - edge_table[key][i] = edge_table[keyrev][6] - - return edge_table - -# ================================ -# === Generate Entry From Quad === -# ================================ -def generate_entry_from_quad(mesh, i, edge_table): - vertex4, vertex3, vertex2, vertex1 = mesh.faces[i].v - - if has_vertex_colors(mesh): - vcolor4, vcolor3, vcolor2, vcolor1 = mesh.faces[i].col - Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0) - Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0) - Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0) - Dcol = (vcolor4.r/255.0, vcolor4.g/255.0, vcolor4.b/255.0) - - # === verts are upper case, edges are lower case === - A, B, C, D = vertex1.index, vertex2.index, vertex3.index, vertex4.index - a, b, c, d = (A, B), (B, C), (C, D), (D, A) - - if edge_table.has_key((B, A)): - edge_table[(B, A)][1] = i - edge_table[(B, A)][4] = d - edge_table[(B, A)][5] = b - if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol - else: - if has_vertex_colors(mesh): - edge_table[(A, B)] = [i, None, d, b, None, None, None, Bcol, None] - else: - edge_table[(A, B)] = [i, None, d, b, None, None, None] - - if edge_table.has_key((C, B)): - edge_table[(C, B)][1] = i - edge_table[(C, B)][4] = a - edge_table[(C, B)][5] = c - if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol - else: - if has_vertex_colors(mesh): - edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None] - else: - edge_table[(B, C)] = [i, None, a, c, None, None, None] - - if edge_table.has_key((D, C)): - edge_table[(D, C)][1] = i - edge_table[(D, C)][4] = b - edge_table[(D, C)][5] = d - if has_vertex_colors(mesh): edge_table[(D, C)][8] = Dcol - else: - if has_vertex_colors(mesh): - edge_table[(C, D)] = [i, None, b, d, None, None, None, Dcol, None] - else: - edge_table[(C, D)] = [i, None, b, d, None, None, None] - - if edge_table.has_key((A, D)): - edge_table[(A, D)][1] = i - edge_table[(A, D)][4] = c - edge_table[(A, D)][5] = a - if has_vertex_colors(mesh): edge_table[(A, D)][8] = Acol - else: - if has_vertex_colors(mesh): - edge_table[(D, A)] = [i, None, c, a, None, None, None, Acol, None] - else: - edge_table[(D, A)] = [i, None, c, a, None, None, None] - -# ==================================== -# === Generate Entry From Triangle === -# ==================================== -def generate_entry_from_tri(mesh, i, edge_table): - vertex3, vertex2, vertex1 = mesh.faces[i].v - - if has_vertex_colors(mesh): - vcolor3, vcolor2, vcolor1, _vcolor4_ = mesh.faces[i].col - Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0) - Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0) - Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0) - - # === verts are upper case, edges are lower case === - A, B, C = vertex1.index, vertex2.index, vertex3.index - a, b, c = (A, B), (B, C), (C, A) - - if edge_table.has_key((B, A)): - edge_table[(B, A)][1] = i - edge_table[(B, A)][4] = c - edge_table[(B, A)][5] = b - if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol - else: - if has_vertex_colors(mesh): - edge_table[(A, B)] = [i, None, c, b, None, None, None, Bcol, None] - else: - edge_table[(A, B)] = [i, None, c, b, None, None, None] - - if edge_table.has_key((C, B)): - edge_table[(C, B)][1] = i - edge_table[(C, B)][4] = a - edge_table[(C, B)][5] = c - if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol - else: - if has_vertex_colors(mesh): - edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None] - else: - edge_table[(B, C)] = [i, None, a, c, None, None, None] - - if edge_table.has_key((A, C)): - edge_table[(A, C)][1] = i - edge_table[(A, C)][4] = b - edge_table[(A, C)][5] = a - if has_vertex_colors(mesh): edge_table[(A, C)][8] = Acol - else: - if has_vertex_colors(mesh): - edge_table[(C, A)] = [i, None, b, a, None, None, None, Acol, None] - else: - edge_table[(C, A)] = [i, None, b, a, None, None, None] - diff --git a/release/scripts/bpymodules/paths_ai2obj.py b/release/scripts/bpymodules/paths_ai2obj.py deleted file mode 100644 index 6eb5023a8d4..00000000000 --- a/release/scripts/bpymodules/paths_ai2obj.py +++ /dev/null @@ -1,506 +0,0 @@ -# -*- coding: latin-1 -*- -""" -paths_ai2obj.py -# --------------------------------------------------------------- -Copyright (c) jm soler juillet/novembre 2004-april 2007, -# --------------------------------------------------------------- - released under GNU Licence - for the Blender 2.45 Python Scripts Bundle. -Ce programme est libre, vous pouvez le redistribuer et/ou -le modifier selon les termes de la Licence Publique Générale GNU -publiée par la Free Software Foundation (version 2 ou bien toute -autre version ultérieure choisie par vous). - -Ce programme est distribué car potentiellement utile, mais SANS -AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties -de commercialisation ou d'adaptation dans un but spécifique. -Reportez-vous à la Licence Publique Générale GNU pour plus de détails. - -Vous devez avoir reçu une copie de la Licence Publique Générale GNU -en même temps que ce programme ; si ce n'est pas le cas, écrivez à la -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307, États-Unis. - - -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 St, Fifth Floor, Boston, MA 02110-1301 USA -# --------------------------------------------------------------- -#---------------------------------------------- -# -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_ai_en.htm -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -#---------------------------------------------- - -#Changelog -#---------------------------------------------- -# 0.1.1 : 2004/08/03, bug in boundingbox reading when Value are negative -# 0.1.2 : 2005/06/12, gmove tranformation properties -# 0.1.3 : 2005/06/25, added a __name__ test to use the script alone -# 0.1.4 : 2005/06/25, closepath improvements -# 0.1.5 : 2005/06/25, ... -# 0.1.6 : 2005/06/26, warning for compacted file - compatibility increased up to AI 10.0 plain text -# 0.1.7 : 2005/06/25, two more closepath improvements -# -# 0.1.8 : 2006/07/03, two more closepath improvements -# 0.1.9 : 2007/05/06, modif on the method that gets the last object on - the list data -# 2008/03/12, Added character encoding line so french text -# does not break python interpreters. - -""" -SHARP_IMPORT=0 -SCALE=1 -NOTHING_TODO=1 -AI_VERSION='' - -GSTACK = [] -GSCALE = [] -GTRANSLATE = [] - -import sys -#oldpath=sys.path -import Blender -BLversion=Blender.Get('version') - -try: - import nt - os=nt - os.sep='\\' - -except: - import posix - os=posix - os.sep='/' - -def isdir(path): - try: - st = os.stat(path) - return 1 - except: - return 0 - -def split(pathname): - if pathname.find(os.sep)!=-1: - k0=pathname.split(os.sep) - else: - if os.sep=='/': - k0=pathname.split('\\') - else: - k0=pathname.split('/') - - directory=pathname.replace(k0[len(k0)-1],'') - Name=k0[len(k0)-1] - return directory, Name - -def join(l0,l1): - return l0+os.sep+l1 - -os.isdir=isdir -os.split=split -os.join=join - -def filtreFICHIER(nom): - f=open(nom,'rU') - t=f.readlines() - f.close() - - if len(t)>1 and t[0].find('EPSF')==-1: - return t - else: - name = "OK?%t| Not a valid file or an empty file ... " # if no %xN int is set, indices start from 1 - result = Blender.Draw.PupMenu(name) - - return 'false' - -#=============================== -# Data -#=============================== -#=============================== -# Blender Curve Data -#=============================== -objBEZIER=0 -objSURFACE=5 -typBEZIER3D=1 #3D -typBEZIER2D=9 #2D - -class Bez: - def __init__(self): - self.co=[] - self.ha=[0,0] - self.tag='' - -class ITEM: - def __init__(self): - self.type = typBEZIER3D, - self.pntsUV = [0,0] - self.resolUV = [32,0] - self.orderUV = [0,0] - self.flagUV = [0,0] - self.Origine = [0.0,0.0] - self.beziers_knot = [] - -class COURBE: - def __init__(self): - self.magic_number='3DG3' - self.type = objBEZIER - self.number_of_items = 0 - self.ext1_ext2 = [0,0] - self.matrix = """0.0 0.0 1.0 0.0 -0.0 1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 """ - self.ITEM = {} - -courbes=COURBE() - -PATTERN={} - -BOUNDINGBOX={'rec':[],'coef':1.0} -npat=0 -#===================================================================== -#======== name of the curve in teh courbes dictionnary =============== -#===================================================================== -n0=0 - -#===================================================================== -#====================== current Point ================================ -#===================================================================== -CP=[0.0,0.0] #currentPoint - - -# modifs 12/06/2005 -#===================================================================== -#====================== current transform ============================ -#===================================================================== -class transform: - def __init__(self,matrix=[1,0,01],x=0.0,y=0.0): - self.matrix=matrix[:] - self.xy=[x,y] - -def G_move(l,a): - global GSCALE, GTRANSLATE, GSTACK - #print GSCALE, GTRANSLATE, GSTACK - return str((float(l)+GTRANSLATE[a]+GSTACK[-1].xy[a])*GSCALE[a]) -# modifs 12/06/2005 - - -#===================================================================== -#===== to compare last position to the original move to displacement = -#===== needed for cyclic efinition ================================= -#===================================================================== -def test_egalitedespositions(f1,f2): - if f1[0]==f2[0] and f1[1]==f2[1]: - return Blender.TRUE - else: - return Blender.FALSE - - -def Open_GEOfile(dir,nom): - if BLversion>=233: - in_editmode = Blender.Window.EditMode() - if in_editmode: Blender.Window.EditMode(0) - Blender.Load(dir+nom+'OOO.obj', 1) - BO=Blender.Scene.GetCurrent().objects.active - BO.RotY=0.0 - BO.RotX=1.57 - BO.makeDisplayList() - Blender.Window.RedrawAll() - else: - print "Not yet implemented" - -def create_GEOtext(courbes): - global SCALE, B, BOUNDINGBOX - r=BOUNDINGBOX['rec'] - - if SCALE==1: - SCALE=1.0 - elif SCALE==2: - SCALE=r[2]-r[0] - elif SCALE==3: - SCALE=r[3]-r[1] - - t=[] - t.append(courbes.magic_number+'\n') - t.append(str(courbes.type)+'\n') - t.append(str(courbes.number_of_items)+'\n') - t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n') - t.append(courbes.matrix+'\n') - - for k in courbes.ITEM.keys(): - if len(courbes.ITEM[k].beziers_knot)>1 : - t.append("%s\n"%courbes.ITEM[k].type) - t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1])) - - flag =courbes.ITEM[k].flagUV[0] - - for k2 in range(len(courbes.ITEM[k].beziers_knot)): - #print k2 - k1 =courbes.ITEM[k].beziers_knot[k2] - t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE)) - - t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n') - return t - -def save_GEOfile(dir,nom,t): - f=open(dir+nom+'OOO.obj','w') - f.writelines(t) - f.close() - #warning = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1" - #result = Blender.Draw.PupMenu(warning) - - -#===================================================================== -#===== AI format : DEBUT ========================= -#===================================================================== -def mouvement_vers(l,n0,CP): - if n0 in courbes.ITEM.keys(): - n0+=1 - - CP=[l[-3].replace('d',''),l[-2]] - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]] - - B=Bez() - B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]] - B.ha=[0,0] - B.tag=l[-1] - - courbes.ITEM[n0].beziers_knot.append(B) - - return courbes,n0,CP - -def courbe_vers_c(l,l2, n0,CP): #c,C - - B=Bez() - B.co=[l[4],l[5],l[2],l[3],l[4],l[5]] - B.tag=l[-1] - B.ha=[0,0] - - BP=courbes.ITEM[n0].beziers_knot[-1] - - BP.co[0]=l[0] - BP.co[1]=l[1] - - courbes.ITEM[n0].beziers_knot.append(B) - - CP=[B.co[4],B.co[5]] - return courbes,n0,CP - - -def courbe_vers_v(l,n0,CP): #v-V - - B=Bez() - B.tag=l[-1] - B.co=[l[2],l[3],l[0],l[1],l[2],l[3]] - B.ha=[0,0] - - courbes.ITEM[n0].beziers_knot.append(B) - - CP=[B.co[4],B.co[5]] - return courbes,n0,CP - -def courbe_vers_y(l,n0,CP): #y - B=Bez() - B.tag=l[-1] - B.co=[l[2],l[3],l[2],l[3],l[2],l[3]] - B.ha=[0,0] - - BP=courbes.ITEM[n0].beziers_knot[-1] - BP.co[0]=l[0] - BP.co[1]=l[1] - - courbes.ITEM[n0].beziers_knot.append(B) - CP=[B.co[4],B.co[5]] - return courbes,n0,CP - - -def ligne_tracee_l(l,n0,CP): - B=Bez() - B.tag=l[-1] - B.co=[l[0],l[1],l[0],l[1],l[0],l[1]] - B.ha=[0,0] - - BP=courbes.ITEM[n0].beziers_knot[-1] - - courbes.ITEM[n0].beziers_knot.append(B) - CP=[B.co[4],B.co[5]] - return courbes,n0,CP - -def ligne_fermee(l,n0,CP): - courbes.ITEM[n0].flagUV[0]=1 - - if len(courbes.ITEM[n0].beziers_knot)>1: - BP=courbes.ITEM[n0].beziers_knot[-1] - BP0=courbes.ITEM[n0].beziers_knot[0] - - if BP.tag not in ['l','L']: - BP.co[0]=BP0.co[0] #4-5 point prec - BP.co[1]=BP0.co[1] - - del courbes.ITEM[n0].beziers_knot[0] - return courbes,n0,CP - -def passe(l,n0,CP): - return courbes,n0,CP - -Actions= { "C" : courbe_vers_c, - "c" : courbe_vers_c, - "V" : courbe_vers_v, - "v" : courbe_vers_v, - "Y" : courbe_vers_y, - "y" : courbe_vers_y, - "m" : mouvement_vers, - "l" : ligne_tracee_l, - "L" : ligne_tracee_l, - "F" : passe, - "f" : ligne_fermee, - "B" : passe, - "b" : ligne_fermee, - "S" : passe, - "s" : ligne_fermee, - "N" : ligne_fermee, - "n" : passe, - } - -TAGcourbe=Actions.keys() - -def pik_pattern(t,l): - global npat, PATTERN, BOUNDINGBOX, AI_VERSION - while t[l].find('%%EndSetup')!=0: - if t[l].find('%%Creator: Adobe Illustrator(R)')!=-1: - print t[l] - AI_VERSION=t[l].split()[-1] - print AI_VERSION - - if t[l].find('%%BoundingBox:')!=-1: - t[l]=t[l][t[l].find(':')+1:] - l0=t[l].split() - BOUNDINGBOX['rec']=[float(l0[-4]),float(l0[-3]),float(l0[-2]),float(l0[-1])] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=(r[3]-r[1])/(r[2]-r[0]) - #print l, - if t[l].find('BeginPattern')!=-1: - nomPattern=t[l][t[l].find('(')+1:t[l].find(')')] - PATTERN[nomPattern]={} - - if t[l].find('BeginPatternLayer')!=-1: - npat+=1 - PATTERN[nomPattern][npat]=[] - while t[l].find('EndPatternLayer')==-1: - #print t[l] - PATTERN[nomPattern][npat].append(l) - l+=1 - if l+1<len(t): - l=l+1 - else: - return 1,l - return 1,l - -def scan_FILE(nom): - global CP, courbes, SCALE, NOTHING_TODO - dir,name=split(nom) - name=name.split('.') - n0=0 - result=0 - t=filtreFICHIER(nom) - - if nom.upper().find('.AI')!=-1 and t!='false': - if not SHARP_IMPORT: - warning = "Select Size : %t| As is %x1 | Scale on Height %x2| Scale on Width %x3" - SCALE = Blender.Draw.PupMenu(warning) - - npat=0 - l=0 - do=0 - while l <len(t)-1 : - if not do: - do,l=pik_pattern(t,l) - #print 'len(t)',len(t) - t[l].replace('\n','') - if t[l].find('%%EOF')==0: - break - if t[l][0]!='%': - l0=t[l].split() - #print l0 - if l0[0][0] in ['F','f','N','n','B','b']: - l3=l0[0][0] - courbes,n0,CP=Actions[l3](l3,n0,CP) - l0[0]=l0[1:] - - if l0[-1] in TAGcourbe: - NOTHING_TODO=0 - if l0[-1] in ['C','c']: - l2=t[l+1].split() - courbes,n0,CP=Actions[l0[-1]](l0,l2,n0,CP) - else: - courbes,n0,CP=Actions[l0[-1]](l0,n0,CP) - l=l+1; #print l - t=[] - - - courbes.number_of_items=len(courbes.ITEM.keys()) - for k in courbes.ITEM.keys(): - courbes.ITEM[k].pntsUV[0] =len(courbes.ITEM[k].beziers_knot) - - - if courbes.number_of_items>0: - if len(PATTERN.keys() )>0: - #print len(PATTERN.keys() ) - warning = "Pattern list (for info not used): %t| " - p0=1 - for P in PATTERN.keys(): - warning+="%s %%x%s|"%(P,p0) - p0+=1 - Padd = Blender.Draw.PupMenu(warning) - - t=create_GEOtext(courbes) - save_GEOfile(dir,name[0],t) - - # 0.1.8 --------------------------------- - # [O.select(0) for O in Blender.Scene.getCurrent().getChildren()] - # 0.1.8 --------------------------------- - - Open_GEOfile(dir,name[0]) - - # 0.1.8 --------------------------------- - Blender.Object.Get()[-1].setName(name[0]) - # 0.1.8 --------------------------------- - - else: - pass -#===================================================================== -#====================== AI format mouvements ========================= -#===================================================================== -#========================================================= -# une sorte de contournement qui permet d'utiliser la fonction -# et de documenter les variables Window.FileSelector -#========================================================= -def fonctionSELECT(nom): - global NOTHING_TODO,AI_VERSION - scan_FILE(nom) - if NOTHING_TODO==1: - warning = "AI %s compatible file "%AI_VERSION+" but nothing to do ? %t| Perhaps a compacted file ... " - NOTHING = Blender.Draw.PupMenu(warning) - -if __name__=="__main__": - Blender.Window.FileSelector (fonctionSELECT, 'SELECT AI FILE') -#sys.path=oldpath diff --git a/release/scripts/bpymodules/paths_eps2obj.py b/release/scripts/bpymodules/paths_eps2obj.py deleted file mode 100644 index e1643c3bf40..00000000000 --- a/release/scripts/bpymodules/paths_eps2obj.py +++ /dev/null @@ -1,452 +0,0 @@ -#---------------------------------------------- -# (c) jm soler juillet 2004-juin 2005 , released under Blender Artistic Licence -# for the Blender 2.34-2.37 Python Scripts Bundle. -# -# last update: 06/05/2007 -#---------------------------------------------- -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_eps.htm -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -#---------------------------------------------- -SHARP_IMPORT = 0 -SCALE = 1.0 -scale = 1 - -import sys -#oldpath=sys.path - -import Blender -from Blender import Draw -BLversion=Blender.Get('version') - -try: - import nt - os=nt - os.sep='\\' - -except: - import posix - os=posix - os.sep='/' - -def isdir(path): - try: - st = os.stat(path) - return 1 - except: - return 0 - -def split(pathname): - if pathname.find(os.sep)!=-1: - k0=pathname.split(os.sep) - else: - if os.sep=='/': - k0=pathname.split('\\') - else: - k0=pathname.split('/') - - directory=pathname.replace(k0[len(k0)-1],'') - Name=k0[len(k0)-1] - return directory, Name - -def join(l0,l1): - return l0+os.sep+l1 - -os.isdir=isdir -os.split=split -os.join=join - -def filtreFICHIER(nom): - f=open(nom,'rU') - t=f.readlines() - f.close() - if len(t)==1 and t[0].find('\r'): - t=t[0].split('\r') - if len(t)>1 and t[0].find('PS-Adobe-3.0')==-1 and t[0].find('EPSF')==-1: - return t - else: - name = "OK?%t| Not a valid file or an empty file or... %x1| not a pure PS-Adobe-2.0 file %x2 " - result = Blender.Draw.PupMenu(name) - return 'false' - -#=============================== -# Data -#=============================== -#=============================== -# Blender Curve Data -#=============================== -objBEZIER=0 -objSURFACE=5 -typBEZIER3D=1 #3D -typBEZIER2D=9 #2D - -class Bez: - def __init__(self): - self.co=[] - self.ha=[0,0] - -class ITEM: - def __init__(self): - self.type = typBEZIER3D, - self.pntsUV = [0,0] - self.resolUV = [32,0] - self.orderUV = [0,0] - self.flagUV = [0,0] - self.Origine = [0.0,0.0] - self.beziers_knot = [] - -class COURBE: - def __init__(self): - self.magic_number='3DG3' - self.type = objBEZIER - self.number_of_items = 0 - self.ext1_ext2 = [0,0] - self.matrix = """0.0 0.0 1.0 0.0 -0.0 1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 """ #- right-handed object matrix. Used to determine position, rotation and size - self.ITEM = {} - -courbes=COURBE() -PATTERN={} -BOUNDINGBOX={'rec':[],'coef':1.0} -npat=0 -#===================================================================== -#======== name of the curve in teh courbes dictionnary =============== -#===================================================================== -n0=0 - -#===================================================================== -#====================== current Point ================================ -#===================================================================== -CP=[0.0,0.0] #currentPoint - -# modifs 12/06/2005 -#===================================================================== -#====================== current transform ============================ -#===================================================================== -class transform: - def __init__(self,matrix=[1,0,01],x=0.0,y=0.0): - self.matrix=matrix[:] - self.xy=[x,y] - -GSTACK = [] -stack=transform() -GSTACK.append(stack) - -GSCALE = [1.0,1.0] -GTRANSLATE = [0.0,0.0] - -def G_move(l,a): - global GSCALE, GTRANSLATE, GSTACK - #print GSCALE, GTRANSLATE, GSTACK - return str((float(l)+GTRANSLATE[a]+GSTACK[-1].xy[a])*GSCALE[a]) -# modifs 12/06/2005 - -#===================================================================== -#===== to compare last position to the original move to displacement = -#===== needed for cyclic efinition ================================= -#===================================================================== -def test_egalitedespositions(f1,f2): - if f1[0]==f2[0] and f1[1]==f2[1]: - return Blender.TRUE - else: - return Blender.FALSE - - -def Open_GEOfile(dir,nom): - global SCALE,BOUNDINGBOX, scale - if BLversion>=233: - Blender.Load(dir+nom+'OOO.obj', 1) - BO=Blender.Scene.GetCurrent().objects.active - BO.RotY=3.1416 - BO.RotZ=3.1416 - BO.RotX=3.1416/2.0 - if scale==1: - BO.LocY+=BOUNDINGBOX['rec'][3] - else: - BO.LocY+=BOUNDINGBOX['rec'][3]/SCALE - - BO.makeDisplayList() - Blender.Window.RedrawAll() - else: - print "Not yet implemented" - -def create_GEOtext(courbes): - global SCALE, B, BOUNDINGBOX,scale - r=BOUNDINGBOX['rec'] - - if scale==1: - SCALE=1.0 - elif scale==2: - SCALE=r[2]-r[0] - elif scale==3: - SCALE=r[3]-r[1] - - t=[] - t.append(courbes.magic_number+'\n') - t.append(str(courbes.type)+'\n') - t.append(str(courbes.number_of_items)+'\n') - t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n') - t.append(courbes.matrix+'\n') - - for k in courbes.ITEM.keys(): - t.append("%s\n"%courbes.ITEM[k].type) - t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1])) - - flag =courbes.ITEM[k].flagUV[0] - - for k2 in range(flag,len(courbes.ITEM[k].beziers_knot)): - k1 =courbes.ITEM[k].beziers_knot[k2] - t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE)) - t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n') - return t - -def save_GEOfile(dir,nom,t): - f=open(dir+nom+'OOO.obj','w') - f.writelines(t) - f.close() - - #name = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1" - #result = Blender.Draw.PupMenu(name) - - -#===================================================================== -#===== EPS format : DEBUT ========================= -#===================================================================== -def mouvement_vers(l,n0,CP): - if n0 in courbes.ITEM.keys(): - #if test_egalitedespositions(courbes.ITEM[n0].Origine,CP): - # courbes.ITEM[n0].flagUV[0]=1 - n0+=1 - CP=[l[-3].replace('d',''),l[-2]] - else: - CP=[l[-3].replace('d',''),l[-2]] - #i= - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]] - - B=Bez() - B.co=[G_move(CP[0],0), - G_move(CP[1],1), - G_move(CP[0],0), - G_move(CP[1],1), - G_move(CP[0],0), - G_move(CP[1],1)] - - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - - return courbes,n0,CP - -def rmouvement_vers(l,n0,CP): - if n0 in courbes.ITEM.keys(): - #if test_egalitedespositions(courbes.ITEM[n0].Origine,CP): - # courbes.ITEM[n0].flagUV[0]=1 - n0+=1 - CP=["%4f"%(float(l[-3])+float(CP[0])),"%4f"%(float(l[-2])+float(CP[1]))] - else: - CP=["%4f"%(float(l[-3])+float(CP[0])),"%4f"%(float(l[-2])+float(CP[1]))] - #i= - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]] - - B=Bez() - B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]] - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - return courbes,n0,CP - -def courbe_vers_c(l, l2, n0,CP): #c,C - """ - B=Bez() - B.co=[l[0],l[1],l[2],l[3],l[4],l[5]] - B.ha=[0,0] - - courbes.ITEM[n0].beziers_knot.append(B) - """ - B=Bez() - B.co=[G_move(l[2],0), - G_move(l[3],1), - G_move(l[4],0), - G_move(l[5],1), - G_move(l[0],0), - G_move(l[1],1)] - if len(courbes.ITEM[n0].beziers_knot)==1: - CP=[l[0],l[1]] - courbes.ITEM[n0].Origine=[l[0],l[1]] - if l[-1]=='C': - B.ha=[2,2] - else: - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - if len(l2)>1 and l2[-1] in Actions.keys(): - B.co[-2]=G_move(l2[0],0) - B.co[-1]=G_move(l2[1],1) - else: - B.co[-2]=G_move(CP[0],0) - B.co[-1]=G_move(CP[1],1) - return courbes,n0,CP - -def ligne_tracee_l(l,n0,CP): - B=Bez() - B.co=[G_move(l[0],0), - G_move(l[1],1), - G_move(l[0],0), - G_move(l[1],1), - G_move(l[0],0), - G_move(l[1],1)] - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - return courbes,n0,CP - -def rligne_tracee_l(l,n0,CP): - B=Bez() - B.co=["%4f"%(float(l[0])+float(CP[0])), - "%4f"%(float(l[1])+float(CP[1])), - "%4f"%(float(l[0])+float(CP[0])), - "%4f"%(float(l[1])+float(CP[1])), - "%4f"%(float(l[0])+float(CP[0])), - "%4f"%(float(l[1])+float(CP[1]))] - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - return courbes,n0,CP - -Actions= { "curveto" : courbe_vers_c, - "curveto" : courbe_vers_c, - "moveto" : mouvement_vers, - "rmoveto" : mouvement_vers, - "lineto" : ligne_tracee_l, - "rlineto" : rligne_tracee_l -} - -TAGcourbe=Actions.keys() - -""" -def pik_pattern(t,l): - global npat, PATTERN, BOUNDINGBOX - while t[l].find('%%EndSetup')!=0: - if t[l].find('%%BoundingBox:')!=-1: - l0=t[l].split() - BOUNDINGBOX['rec']=[float(l0[-4]),float(l0[-3]),float(l0[-2]),float(l0[-1])] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=(r[3]-r[1])/(r[2]-r[0]) - print l, - if t[l].find('BeginPatternLayer')!=-1: - npat+=1 - PATTERN[npat]=[] - while t[l].find('EndPatternLayer')==-1: - print t[l] - PATTERN[npat].append(l) - l+=1 - if l+1<len(t): - l=l+1 - else: - return 1,l - return 1,l -""" - -def scan_FILE(nom): - global CP, courbes, SCALE, scale, GSTACK, GSCALE, GTRANSLATE - dir,name=split(nom) - name=name.split('.') - n0=0 - result=0 - t=filtreFICHIER(nom) - #print t - if t!='false' and (nom.upper().find('.EPS')!=-1 or nom.upper().find('.PS')!=-1 ): - if not SHARP_IMPORT: - warning = "Select Size : %t| As is %x1 | Scale on Height %x2| Scale on Width %x3" - scale = Blender.Draw.PupMenu(warning) - npat=0 - l=0 - do=0 - while l <len(t)-1 : - if t[l].find('%%BoundingBox:')!=-1: - l0=t[l].split() - BOUNDINGBOX['rec']=[float(l0[-4]),float(l0[-3]),float(l0[-2]),float(l0[-1])] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=(r[3]-r[1])/(r[2]-r[0]) - """ - if not do: - do,l=pik_pattern(t,l) - """ - #print 'len(t)',len(t) - t[l].replace('\n','') - if t[l][0]!='%': - l0=t[l].split() - if l0!=[] and l0[-1] in TAGcourbe: - if l0[-1] in ['curveto']: - l2=t[l+1].split() - courbes,n0,CP=Actions[l0[-1]](l0,l2,n0,CP) - else: - courbes,n0,CP=Actions[l0[-1]](l0,n0,CP) - # modifs 10/06/2005 - elif l0!=[] and l0[-1] in ['scale']: - GSCALE=[float(l0[-3]),float(l0[-2])] - elif l0!=[] and l0[-1] in ['translate']: - GTRANSLATE=[float(l0[-3]),float(l0[-2])] - elif l0!=[] and l0[-1] in ['concat'] and l0[0] in ['gsave']: - l0[1]=l0[1].replace('[','') - l0[-2]=l0[-2].replace(']','') - stack=transform([float(l0[1]),float(l0[2]),float(l0[3]),float(l0[4])],float(l0[5]),float(l0[6])) - GSTACK.append(stack) - #print GSTACK - elif l0!=[] and l0[-1] in ['concat'] and l0[0] in ['grestore']: - del GSTACK[-1] - # modifs 12/06/2005 : end - - - l=l+1#; print l - t=[] - - if t!='false': - courbes.number_of_items=len(courbes.ITEM.keys()) - - for k in courbes.ITEM.keys(): - courbes.ITEM[k].pntsUV[0] =len(courbes.ITEM[k].beziers_knot) - - if test_egalitedespositions(courbes.ITEM[k].Origine, - [courbes.ITEM[k].beziers_knot[-1].co[-2], - courbes.ITEM[k].beziers_knot[-1].co[-1]]): - courbes.ITEM[k].flagUV[0]=1 - courbes.ITEM[k].pntsUV[0] -=1 - - if courbes.number_of_items>0: - if len(PATTERN.keys() )>0: - #print len(PATTERN.keys() ) - pass - t=create_GEOtext(courbes) - save_GEOfile(dir,name[0],t) - Open_GEOfile(dir,name[0]) - - # 03 juillet 2006 ---------------------- - Blender.Object.Get()[-1].setName(name[0]) - # 03 juillet 2006 ---------------------- - - else: - pass - - -#===================================================================== -#====================== EPS format mouvements ========================= -#===================================================================== -#========================================================= -# une sorte de contournement qui permet d'utiliser la fonction -# et de documenter les variables Window.FileSelector -#========================================================= -def fonctionSELECT(nom): - scan_FILE(nom) - -if __name__=="__main__": - Blender.Window.FileSelector (fonctionSELECT, 'SELECT EPS FILE') - - diff --git a/release/scripts/bpymodules/paths_gimp2obj.py b/release/scripts/bpymodules/paths_gimp2obj.py deleted file mode 100644 index c2ce9718c71..00000000000 --- a/release/scripts/bpymodules/paths_gimp2obj.py +++ /dev/null @@ -1,363 +0,0 @@ -# -*- coding: latin-1 -*- -""" -#---------------------------------------------- -# (c) jm soler juillet 2004, -#---------------------------------------------- - released under GNU Licence - for the Blender 2.45 Python Scripts Bundle. -Ce programme est libre, vous pouvez le redistribuer et/ou -le modifier selon les termes de la Licence Publique Générale GNU -publiée par la Free Software Foundation (version 2 ou bien toute -autre version ultérieure choisie par vous). - -Ce programme est distribué car potentiellement utile, mais SANS -AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties -de commercialisation ou d'adaptation dans un but spécifique. -Reportez-vous à la Licence Publique Générale GNU pour plus de détails. - -Vous devez avoir reçu une copie de la Licence Publique Générale GNU -en même temps que ce programme ; si ce n'est pas le cas, écrivez à la -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307, États-Unis. - - -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 St, Fifth Floor, Boston, MA 02110-1301 USA - -""" - -# --------------------------------------------------------------- -# last update : 07/05/2007 -#---------------------------------------------- -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_gimp.htm -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -# Modification History: -# 2008-03-12 Added character encoding line so french text does not break -# python interpreters. -#--------------------------------------------- - -SHARP_IMPORT=0 -SCALE=1 - -import sys -#oldpath=sys.path - -import Blender -BLversion=Blender.Get('version') - -try: - import nt - os=nt - os.sep='\\' - -except: - import posix - os=posix - os.sep='/' - -def isdir(path): - try: - st = os.stat(path) - return 1 - except: - return 0 - -def split(pathname): - if pathname.find(os.sep)!=-1: - k0=pathname.split(os.sep) - else: - if os.sep=='/': - k0=pathname.split('\\') - else: - k0=pathname.split('/') - - directory=pathname.replace(k0[len(k0)-1],'') - Name=k0[len(k0)-1] - return directory, Name - -def join(l0,l1): - return l0+os.sep+l1 - -os.isdir=isdir -os.split=split -os.join=join - -def filtreFICHIER(nom): - f=open(nom,'r') - t=f.readlines() - f.close() - if len(t)==1 and t[0].find('\r'): - t=t[0].split('\r') - if len(t)>1 and t[1].find('#POINTS:')==0: - return t - else: - warning = "OK?%t| Not a valid file or an empty file ... " # if no %xN int is set, indices start from 1 - result = Blender.Draw.PupMenu(warning) - return "false" - -#=============================== -# Data -#=============================== -#=============================== -# Blender Curve Data -#=============================== -objBEZIER=0 -objSURFACE=5 -typBEZIER3D=1 #3D -typBEZIER2D=9 #2D - -class Bez: - def __init__(self): - self.co=[] - self.ha=[0,0] - - def echo(self): - #print 'co = ', self.co - #print 'ha = ', self.ha - pass - -class ITEM: - def __init__(self): - self.type = typBEZIER3D, - self.pntsUV = [0,0] - self.resolUV = [32,0] - self.orderUV = [0,0] - self.flagUV = [0,0] - self.Origine = [0.0,0.0] - self.beziers_knot = [] - -class COURBE: - def __init__(self): - self.magic_number='3DG3' - self.type = objBEZIER - self.number_of_items = 0 - self.ext1_ext2 = [0,0] - self.matrix = """0.0 0.0 1.0 0.0 -0.0 1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 """ #- right-handed object matrix. Used to determine position, rotation and size - self.ITEM = {} - -courbes=COURBE() -PATTERN={} -BOUNDINGBOX={'rec':[],'coef':1.0} -npat=0 -#===================================================================== -#======== name of the curve in the courbes dictionnary =============== -#===================================================================== -n0=0 - -#===================================================================== -#====================== current Point ================================ -#===================================================================== -CP=[0.0,0.0] #currentPoint - -def MINMAX(b): - global BOUNDINGBOX - r=BOUNDINGBOX['rec'] - for m in range(0,len(b)-2,2): - #print m, m+1 , len(b)-1 - #print b[m], r, r[0] - if float(b[m])<r[0]: - r[0]=float(b[m]) - - if float(b[m])>r[2]: r[2]=float(b[m]) - - if float(b[m+1])<r[1]: r[1]=float(b[m+1]) - if float(b[m+1])>r[3]: r[3]=float(b[m+1]) - -#===================================================================== -#===== to compare last position to the original move to displacement = -#===== needed for cyclic efinition ================================= -#===================================================================== -def test_egalitedespositions(f1,f2): - if f1[0]==f2[0] and f1[1]==f2[1]: - return Blender.TRUE - else: - return Blender.FALSE - - -def Open_GEOfile(dir,nom): - if BLversion>=233: - Blender.Load(dir+nom+'OOO.obj', 1) - BO=Blender.Scene.GetCurrent().objects.active - BO.LocZ=1.0 - BO.makeDisplayList() - Blender.Window.RedrawAll() - else: - print "Not yet implemented" - -def create_GEOtext(courbes): - global SCALE, B, BOUNDINGBOX - r=BOUNDINGBOX['rec'] - if SCALE==1: - SCALE=1.0 - elif SCALE==2: - SCALE=r[2]-r[0] - elif SCALE==3: - SCALE=r[3]-r[1] - - t=[] - t.append(courbes.magic_number+'\n') - t.append(str(courbes.type)+'\n') - t.append(str(courbes.number_of_items)+'\n') - t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n') - t.append(courbes.matrix+'\n') - - for k in courbes.ITEM.keys(): - - t.append("%s\n"%courbes.ITEM[k].type) - - t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1])) - - flag =0#courbes.ITEM[k].flagUV[0] - - for k2 in range(flag,len(courbes.ITEM[k].beziers_knot)): - k1 =courbes.ITEM[k].beziers_knot[k2] - t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE)) - t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n') - return t - -def save_GEOfile(dir,nom,t): - f=open(dir+nom+'OOO.obj','w') - f.writelines(t) - f.close() - #warning = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1" - #result = Blender.Draw.PupMenu(warning) - - -#===================================================================== -#===== GIMP format : DEBUT ========================= -#===================================================================== -CLOSED=0 - -def mouvement_vers(l,l1,l2,n0): - global BOUNDINGBOX, CP - if l[1] == '3' : - n0+=1 - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3],l[-1],] - courbes.ITEM[n0-1].beziers_knot[0].co[0]=CP[0] - courbes.ITEM[n0-1].beziers_knot[0].co[1]=CP[1] - CP=[l2[-3], l2[-1]] - - elif l[1]=='1' and (n0 not in courbes.ITEM.keys()): - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3],l[-1],] - CP=[l2[-3], l2[-1]] - - B=Bez() - B.co=[ CP[0],CP[1], - l1[-3], l1[-1], - l[-3], l[-1]] - - CP=[l2[-3], l2[-1]] - - if BOUNDINGBOX['rec']==[]: - BOUNDINGBOX['rec']=[float(l2[-3]), float(l2[-1]), float(l[-3]), float(l[-1])] - B.ha=[0,0] - - """ - if len( courbes.ITEM[n0].beziers_knot)>=1: - courbes.ITEM[n0].beziers_knot[-1].co[2]=l1[-3] - courbes.ITEM[n0].beziers_knot[-1].co[3]=l1[-1] - """ - - MINMAX(B.co) - courbes.ITEM[n0].beziers_knot.append(B) - return courbes,n0 - -Actions= { "1" : mouvement_vers, - "3" : mouvement_vers } - -TAGcourbe=Actions.keys() - -def scan_FILE(nom): - global CP, courbes, SCALE, MAX, MIN, CLOSED - dir,name=split(nom) - name=name.split('.') - #print name - n0=0 - result=0 - t=filtreFICHIER(nom) - if t!="false": - if not SHARP_IMPORT: - warning = "Select Size : %t| As is %x1 | Scale on Height %x2| Scale on Width %x3" - SCALE = Blender.Draw.PupMenu(warning) - npat=0 - l=0 - while l <len(t)-1 : - #print 'len(t)',len(t) - t[l].replace('\n','') - if t[l][0]!='%': - l0=t[l].split() - #print l0[0], l0[1] - if l0[0]=='TYPE:' and l0[1] in TAGcourbe: - #print l0[0], l0[1], - l1=t[l+1].split() - l2=t[l+2].split() - courbes,n0=Actions[l0[1]](l0,l1,l2,n0) - elif l0[0]=='#Point': - POINTS= int(l0[0]) - elif l0[0]=='CLOSED:' and l0[1]=='1': - CLOSED=1 - l=l+1; - - courbes.number_of_items=len(courbes.ITEM.keys()) - - courbes.ITEM[n0].beziers_knot[0].co[0]=CP[0] - courbes.ITEM[n0].beziers_knot[0].co[1]=CP[1] - - for k in courbes.ITEM.keys(): - #print k - if CLOSED == 1: - B=Bez() - B.co=courbes.ITEM[k].beziers_knot[0].co[:] - B.ha=courbes.ITEM[k].beziers_knot[0].ha[:] - B.echo() - courbes.ITEM[k].beziers_knot.append(B) - courbes.ITEM[k].flagUV[0]=1 - courbes.ITEM[k].pntsUV[0] =len(courbes.ITEM[k].beziers_knot) - - if courbes.number_of_items>0: - t=create_GEOtext(courbes) - save_GEOfile(dir,name[0],t) - Open_GEOfile(dir,name[0]) - # 0.1.8 --------------------------------- - Blender.Object.Get()[-1].setName(name[0]) - # 0.1.8 --------------------------------- - - else: - pass - -#===================================================================== -#====================== GIMP Path format mouvements ========================= -#===================================================================== -#========================================================= -# une sorte de contournement qui permet d'utiliser la fonction -# et de documenter les variables Window.FileSelector -#========================================================= -def fonctionSELECT(nom): - scan_FILE(nom) - -if __name__=="__main__": - Blender.Window.FileSelector (fonctionSELECT, 'SELECT GIMP FILE') - diff --git a/release/scripts/bpymodules/paths_svg2obj.py b/release/scripts/bpymodules/paths_svg2obj.py deleted file mode 100644 index 6bab6dcbfd8..00000000000 --- a/release/scripts/bpymodules/paths_svg2obj.py +++ /dev/null @@ -1,1651 +0,0 @@ -# -*- coding: latin-1 -*- -""" -SVG 2 OBJ translater, 0.5.9o -Copyright (c) jm soler juillet/novembre 2004-april 2009, -# --------------------------------------------------------------- - released under GNU Licence - for the Blender 2.42 Python Scripts Bundle. -Ce programme est libre, vous pouvez le redistribuer et/ou -le modifier selon les termes de la Licence Publique Générale GNU -publiée par la Free Software Foundation (version 2 ou bien toute -autre version ultérieure choisie par vous). - -Ce programme est distribué car potentiellement utile, mais SANS -AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties -de commercialisation ou d'adaptation dans un but spécifique. -Reportez-vous à la Licence Publique Générale GNU pour plus de détails. - -Vous devez avoir reçu une copie de la Licence Publique Générale GNU -en même temps que ce programme ; si ce n'est pas le cas, écrivez à la -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307, États-Unis. - -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 St, Fifth Floor, Boston, MA 02110-1301 USA -# --------------------------------------------------------------- -# -#--------------------------------------------------------------------------- -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg.htm -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg_en.htm -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -#--------------------------------------------------------------------------- - ---Old Concept : translate SVG file in GEO .obj file and try to load it. - was removed for the Blender 2.4x release. - .-- Curiousity : the original matrix must be : - | - | 0.0 0.0 1.0 0.0 - | 0.0 1.0 0.0 0.0 - | 0.0 0.0 1.0 0.0 - | 0.0 0.0 0.0 1.0 - | - | and not: - | 1.0 0.0 0.0 0.0 - | 0.0 1.0 0.0 0.0 - | 0.0 0.0 1.0 0.0 - | 0.0 0.0 0.0 1.0 - | - '-- Possible bug : sometime, the new curves object's RotY value - jumps to -90.0 degrees without any reason. - ---Options : - SHARP_IMPORT = 0 - choise between "As is", "Devide by height" and "Devide by width" - SHARP_IMPORT = 1 - no choise - - - -All commands are managed: - M : absolute move to - Z : close path - L : absolute line to - C : absolute curve to - S : absolute curve to with only one handle - H : absolute horizontal line to - V : absolute vertical line to - - l : relative line to 2004/08/03 - c : relative curve to 2004/08/03 - s : relative curve to with only one handle - h : relative horizontal line to - v : relative vertical line to - - A : curve_to_a, - V : draw_line_v, - H : draw_line_h, - Z : close_z, - Q : curve_to_q, - T : curve_to_t, - a : curve_to_a, - v : draw_line_v, - h : draw_line_h, - z : close_z, - q : curve_to_q, - - transfrom for <g> tag - transform for <path> tag - -The circle, rectangle closed or open polygons lines are managed too. - -Changelog: - 0.1.1 : - control file without extension - 0.2.0 : - improved reading of several data of the same type - following the same command (for gimp import) - 0.2.1 : - better choice for viewboxing ( takes the viewbox if found, - instead of x,y,width and height - 0.2.2 : - read compact path data from Illustrator 10 - 0.2.3 : - read a few new relative displacements - 0.2.4 : - better hash for command followed by a lone data - (h,v) or uncommun number (a) - 0.2.5 : - correction for gimp import - 0.2.6 : - correction for illustrator 10 SVG - 0.2.7 : - correction for inskape 0.40 cvs SVG - 0.2.8 : - correction for inskape plain SVG - 0.3 : - reading of the transform properties added : - translate - 0.3.1 : - compatibility restored with gimp - 0.3.2 : - transform properties added (june, 15-16): - scale, - rotate, - matrix, - skew - - added a test on __name__ to load the script - outside from the blender menu - 0.3.3 : - matrix transform content control - 0.3.4 : - paths data reading rewritten (19/06/05) - 0.3.5 : - test on empty curve (22/06/05) - - removed overlayed points - 0.3.6 : - rewriting of the bezier point contruction to correct - a problem in the connection between L type point and - C or S type point - 0.3.7 : - code correction for bezier knot in Curveto command when - the command close a path - 0.3.8 : - code was aded to manage quadratic bezier, - Q,q command and T,t commands, as a normal blender's bezier point - - The last modications does not work with gimp 2.0 svg export . - corrected too . - 0.3.9 : - Path's A,a command for ellipse's arc . - 0.4.0 : - To speed up the function filter_DATA was removed and text - variables are changed into numeric variables - 0.4.1 : - svg, groups and shapes hierarchy added - - now transform properties are computed using a stack with all - parented groups - - removed or replaced useless functions : - - skewY, skewX transforms - - radians in rotate transform - 0.4.2 : - Added functon to translate others shapes in path - rect, line, polyline, polygon - 0.4.3 : - various corrections - text font (id property exported by Adobe Illustrator are between coma) - function to code s tag has been rewritten - 0.4.4 : - various corrections - to oblige the script to understand a line feed just after - a tag . Rarely encountered problem, but it exits in a svg file - format exported by a outliner script for mesh . - 0.4.5 : - update for CVS only, at least blender 2.38 and upper - no BezTriple module in older version - added a createCURVES function to avoid to use - the OBJ format export/import . - Perhaps problems with cyclic curves . If a closed curve - does not appear closed in blender, enter edit mode select - all knot with Akey, do a Hkey to set handle type (without - this the knot are recalculated) , and finally use the Ckey - to close the curve . - Should work ... not guaranted . - 0.4.6 : - cyclic flag ... - 0.4.7 : - Management of the svgz files . the complete python or the - gzip.py file is needed . - Little improvement of the curve drawing using the createCURVES - function - 0.4.8 : - short modif for a fantasy font case in the OOo svg format - ('viewbox' is written 'viewBox', for instance) . - Note that (at this time, 2006/05/01, 1OOo exports in svg - but does not read its own export - 0.4.9 : - skipped version : private test - 0.5.0 : - the script worked perfectly with Blender 2.41 but in Blender - 2.42, use the original svg name file + 'OOO.obj' to - write a videoscape file made blender crash under window XP when - the script loaded it . Curiously, use a more simple - name with a sole 'O' solved this problem . - - script returned errors on open path : corrected - - in b2.42, several successive imports seem to be added to - the same original curve . So now the script automaticaly - renames the last group of imported curve with the original - name file . - 0.5.1 : - without join option in the internal curve creation function - 0.5.2 : - the createCURVES() function has been cleanded . Now it works - fine but all bezier curves are joined in the same curve object . - 0.5.3 : - removed two things : - 1/ the ajustement function to increase speed . 35 % faster : - 5690 curves and 30254 points in 11 seconds . User should do - a ctrl-a on the object . - 2/ the import method menu . No reason to choose between the - old extern curve creat and the new intern curve creation - this last one is largely faster . - 0.5.4 : - translation of the functions' name + improvment in the dict lookup . - Quite 15% faster . 9.75 seconds instead of 11 to load the file test . - A test was also added to find the fill style so now the script closes - these curves even if they are not defined as closed in the strict path - commands . - The old non used functions have been completely removed . - 0.5.5 : - Modifs for architect users . - 0.5.6 : - Exec was removed from the collect_ATTRIBUTS function . - Other uses was evaluated. - 0.5.7 : - Wash down of some handle problems. - - 0.5.8 : - 2007/3/9 - Wash down of the last exec and correction of a - problem with the curve's first beztriple handle - which was not recorded at first time . - - Added some units managements - - Correction of the rotate matrix - - Correction of the skew matrix - - change in the wash_DATA function suggested by cambo - - added __slot__ in class Bez, ITEM and CURVE suggested by cambo - - remove unused properties in class ITEM and CURVE - - 0.5.9 : - 2007/3/28 - - many improvements for faster and clearer code suggested by cambo and martin. - replacement of "%s" statement by str function. - - correction of an error in the scale transform management - - correction in the management of the stack transformation that rise an error - under python 2.5 but curiously not with python 2.4 - - 0.5.9a : - 2007/3/29 - - Again a lot of minors corrections - - Backward to 0.5.8 of the function that manages float numbers exported - by the Adobe Illustrator's SVG. After a lot of tests it seems that this oldest - version is also faster too . - - correction (bad) on handle management with V and H commands. - - 0.5.9b : - 2007/3/31 - - one or two minor corrections - - now the new object curve is added in the current layer. - - short modif in the scale menu... - - 0.5.9d : - 2007/4/5 - - when a svg file containts several curves they can be imported in - separate object. - - managment of paths' name when paths are imported as separate curves. - - a menu was added to select between separate or joined curves - - management of colors - - 0.5.9e : - 2007/4/7 - - corrected a scale problem that only appears when one uses beveldepth - - in separate curve option, name is also given to the curve data - - added the list of svg's color names (147) and modified the color's method - to work with. - - 0.5.9h : - 2007/5/2 - - script was updated with the modifs by cambo - - removed all debug statements - - correction of a zero division error in the calc_arc function. - - 0.5.9f: - 2007/15/7 - - Correction de plusieurs bugs sur l'attributions des couleurs et le nommage - des courbes - - 0.5.9i : - ??/??/?? - - Patch externe réalisé sur blender.org project. - - 0.5.9j : - 08/11/2008 - 0.5.9k : - 14/01/2009 - 0.5.9l : - 31/01/2009 - 0.5.9n : - 01/02/2009 - 0.5.9o : - 04/04/2009, remove pattern if it made with path. - - -================================================================================== -==================================================================================""" -SHARP_IMPORT=0 -SCALE=1 -scale_=1 -DEBUG = 0 -DEVELOPPEMENT=0 -TESTCOLOR=0 - -LAST_ID='' -LAST_COLOR=[0.0,0.0,0.0,0.0] -SEPARATE_CURVES=0 -USE_COLORS=0 -PATTERN=0 - -SVGCOLORNAMELIST={ 'aliceblue':[240, 248, 255] ,'antiquewhite':[250, 235, 215] -,'aqua':[ 0, 255, 255], 'aquamarine':[127, 255, 212] -,'azure':[240, 255, 255], 'beige':[245, 245, 220] -,'bisque':[255, 228, 196], 'black':[ 0, 0, 0] -,'blanchedalmond':[255, 235, 205] ,'blue':[ 0, 0, 255] -,'blueviolet':[138, 43, 226],'brown':[165, 42, 42] -,'burlywood':[222, 184, 135],'cadetblue':[ 95, 158, 160] -,'chartreuse':[127, 255, 0] ,'chocolate':[210, 105, 30] -,'coral':[255, 127, 80],'cornflowerblue':[100, 149, 237] -,'cornsilk':[255, 248, 220],'crimson':[220, 20, 60] -,'cyan':[ 0, 255, 255],'darkblue':[ 0, 0, 139] -,'darkcyan':[ 0, 139, 139],'darkgoldenrod':[184, 134, 11] -,'darkgray':[169, 169, 169],'darkgreen':[ 0, 100, 0] -,'darkgrey':[169, 169, 169],'darkkhaki':[189, 183, 107] -,'darkmagenta':[139, 0, 139],'darkolivegreen':[ 85, 107, 47] -,'darkorange':[255, 140, 0],'darkorchid':[153, 50, 204] -,'darkred':[139, 0, 0],'darksalmon':[233, 150, 122] -,'darkseagreen':[143, 188, 143],'darkslateblue':[ 72, 61, 139] -,'darkslategray':[ 47, 79, 79],'darkslategrey':[ 47, 79, 79] -,'darkturquoise':[ 0, 206, 209],'darkviolet':[148, 0, 211] -,'deeppink':[255, 20, 147],'deepskyblue':[ 0, 191, 255] -,'dimgray':[105, 105, 105],'dimgrey':[105, 105, 105] -,'dodgerblue':[ 30, 144, 255],'firebrick':[178, 34, 34] -,'floralwhite':[255, 250, 240],'forestgreen':[ 34, 139, 34] -,'fuchsia':[255, 0, 255],'gainsboro':[220, 220, 220] -,'ghostwhite':[248, 248, 255],'gold':[255, 215, 0] -,'goldenrod':[218, 165, 32],'gray':[128, 128, 128] -,'grey':[128, 128, 128],'green':[ 0, 128, 0] -,'greenyellow':[173, 255, 47],'honeydew':[240, 255, 240] -,'hotpink':[255, 105, 180],'indianred':[205, 92, 92] -,'indigo':[ 75, 0, 130],'ivory':[255, 255, 240] -,'khaki':[240, 230, 140],'lavender':[230, 230, 250] -,'lavenderblush':[255, 240, 245],'lawngreen':[124, 252, 0] -,'lemonchiffon':[255, 250, 205],'lightblue':[173, 216, 230] -,'lightcoral':[240, 128, 128],'lightcyan':[224, 255, 255] -,'lightgoldenrodyellow':[250, 250, 210],'lightgray':[211, 211, 211] -,'lightgreen':[144, 238, 144],'lightgrey':[211, 211, 211] -,'lightpink':[255, 182, 193],'lightsalmon':[255, 160, 122] -,'lightseagreen':[ 32, 178, 170],'lightskyblue':[135, 206, 250] -,'lightslategray':[119, 136, 153],'lightslategrey':[119, 136, 153] -,'lightsteelblue':[176, 196, 222],'lightyellow':[255, 255, 224] -,'lime':[ 0, 255, 0],'limegreen':[ 50, 205, 50] -,'linen':[250, 240, 230],'magenta':[255, 0, 255] -,'maroon':[128, 0, 0],'mediumaquamarine':[102, 205, 170] -,'mediumblue':[ 0, 0, 205],'mediumorchid':[186, 85, 211] -,'mediumpurple':[147, 112, 219],'mediumseagreen':[ 60, 179, 113] -,'mediumslateblue':[123, 104, 238],'mediumspringgreen':[ 0, 250, 154] -,'mediumturquoise':[ 72, 209, 204],'mediumvioletred':[199, 21, 133] -,'midnightblue':[ 25, 25, 112],'mintcream':[245, 255, 250] -,'mistyrose':[255, 228, 225],'moccasin':[255, 228, 181] -,'navajowhite':[255, 222, 173],'navy':[ 0, 0, 128] -,'oldlace':[253, 245, 230],'olive':[128, 128, 0] -,'olivedrab':[107, 142, 35],'orange':[255, 165, 0] -,'orangered':[255, 69, 0],'orchid':[218, 112, 214] -,'palegoldenrod':[238, 232, 170],'palegreen':[152, 251, 152] -,'paleturquoise':[175, 238, 238],'palevioletred':[219, 112, 147] -,'papayawhip':[255, 239, 213],'peachpuff':[255, 218, 185] -,'peru':[205, 133, 63],'pink':[255, 192, 203] -,'plum':[221, 160, 221],'powderblue':[176, 224, 230] -,'purple':[128, 0, 128],'red':[255, 0, 0] -,'rosybrown':[188, 143, 143],'royalblue':[ 65, 105, 225] -,'saddlebrown':[139, 69, 19],'salmon':[250, 128, 114] -,'sandybrown':[244, 164, 96],'seagreen':[ 46, 139, 87] -,'seashell':[255, 245, 238],'sienna':[160, 82, 45] -,'silver':[192, 192, 192],'skyblue':[135, 206, 235] -,'slateblue':[106, 90, 205],'slategray':[112, 128, 144] -,'slategrey':[112, 128, 144],'snow':[255, 250, 250] -,'springgreen':[ 0, 255, 127],'steelblue':[ 70, 130, 180] -,'tan':[210, 180, 140],'teal':[ 0, 128, 128] -,'thistle':[216, 191, 216],'tomato':[255, 99, 71] -,'turquoise':[ 64, 224, 208],'violet':[238, 130, 238] -,'wheat':[245, 222, 179],'white':[255, 255, 255] -,'whitesmoke':[245, 245, 245],'yellow':[255, 255, 0] -,'yellowgreen':[154, 205, 50]} - - -import sys -from math import cos,sin,tan, atan2, pi, ceil -PI=pi -import Blender -from Blender import Mathutils - -try: - import nt - os=nt - os.sep='\\' - -except: - import posix - os=posix - os.sep='/' - -def isdir(path): - try: - st = os.stat(path) - return 1 - except: - return 0 - -def split(pathname): - if os.sep in pathname: - k0=pathname.split(os.sep) - else: - if os.sep=='/': - k0=pathname.split('\\') - else: - k0=pathname.split('/') - directory=pathname.replace(k0[len(k0)-1],'') - Name=k0[len(k0)-1] - return directory, Name - -def join(l0,l1): - return l0+os.sep+l1 - -os.isdir=isdir -os.split=split -os.join=join - -def filterFILE(nom): - """ - Function filterFILE - - in : string nom , filename - out : string t , if correct filecontaint - - read the file's content and try to see if the format - is correct . - - Lit le contenu du fichier et en fait une pre-analyse - pour savoir s'il merite d'etre traite . - """ - # ---------- - # 0.4.7 - # ---------- - if nom.upper().endswith('.SVGZ'): - try : - import gzip - tz=gzip.GzipFile(nom) - t=tz.read() - except: - name = "ERROR: fail to import gzip module or gzip error ... " - result = Blender.Draw.PupMenu(name) - return "false" - else: - f=open(nom,'rU') - t=f.read() - f.close() - # ---------- - # 0.4.7 : end - # ---------- - # ----------------- - # pre-format ... - # ----------------- - # -------------------- - # 0.4.4 '\r','' --> '\r',' ' - # '\n','' --> '\n',' ' - #-------------------- - t=t.replace('\r',' ') - t=t.replace('\n',' ') - t=t.replace('svg:','') - #-------------------- - # may be needed in some import case when the - # file is saved from a mozilla display - #-------------------- - t=t.replace(chr(0),'') - if not '<SVG' in t.upper(): - name = "ERROR: invalid or empty file ... " # if no %xN int is set, indices start from 1 - result = Blender.Draw.PupMenu(name) - return "false" - else: - return t - -#=============================== -# Data -#=============================== -#=============================== -# Blender Curve Data -#=============================== -objBEZIER=0 -objSURFACE=5 -typBEZIER3D=1 #3D -typBEZIER2D=9 #2D - -class Bez(object): - __slots__ = 'co', 'ha', 'tag' # suggested by cambo, should save memory - def __init__(self): - self.co=[] - self.ha=['C','C'] - self.tag='' - -class ITEM(object): - __slots__ = 'type', 'pntsUV', 'flagUV', 'beziers_knot','fill','color','id','mat','matname' - def __init__(self): - self.type = typBEZIER3D - self.pntsUV = [0,0] - self.flagUV = [0,0] - self.beziers_knot = [] - self.fill=0 - self.color=[0.0,0.0,0.0,0.0] - self.id='' - self.mat=0 - self.matname='' - -class CURVE(object): - __slots__ = 'type','number_of_items','ITEM' - def __init__(self): - self.type = objBEZIER - self.number_of_items = 0 - self.ITEM = {} - -curves=CURVE() -PATTERN={} -BOUNDINGBOX={'rec':[],'coef':1.0} - -npat=0 -#===================================================================== -#======== name of the curve in the curves dictionnary =============== -#===================================================================== -n0=0 - -#===================================================================== -#====================== current Point ================================ -#===================================================================== -CP=[0.0,0.0] #currentPoint - - -#===================================================================== -#===== to compare last position to the original move to displacement = -#===== needed for cyclic definition in AI, EPS forma ================ -#===================================================================== -def test_samelocations(f1,f2): - EPSILON=0.0001 - if abs(f1[4])- abs(f2[4])< EPSILON and abs(f1[4])- abs(f2[4])>= 0.0\ - and abs(f1[5])-abs(f2[5])< EPSILON and abs(f1[5])-abs(f2[5])>= 0.0 : - return 1 - else: - return 0 - - -#-------------------- -# 0.4.5 : for blender cvs 2.38 .... -#-------------------- -def createCURVES(curves, name): - """ - internal curves creation - """ - global SCALE, B, BOUNDINGBOX,scale_, SEPARATE_CURVES - global USE_COLORS - from Blender import Curve, Object, Scene, BezTriple - HANDLE={'C':BezTriple.HandleTypes.FREE,'L':BezTriple.HandleTypes.VECT} - r=BOUNDINGBOX['rec'] - - if scale_==3: - SCALE=1.0 - elif scale_==1: - SCALE=r[2]-r[0] - elif scale_==2: - SCALE=r[3]-r[1] - - scene = Scene.GetCurrent() - scene.objects.selected = [] - - if not SEPARATE_CURVES: - c = Curve.New() - c.setResolu(24) - - MATNAME=[] - nloc=0.0 - - def new_MATERIAL(val): - # ----------------------- - # have to create a material - #------------------------ - if val.matname and val.matname in MATNAME: - mat = Blender.Material.Get(val.matname) - elif val.matname: - mat = Blender.Material.New(val.matname) - mat.rgbCol = [val.color[0]/255.0, val.color[1]/255.0, val.color[2]/255.0] - else: - mat = Blender.Material.New(val.id) - mat.rgbCol = [val.color[0]/255.0, val.color[1]/255.0, val.color[2]/255.0] - return [mat] - - for I,val in curves.ITEM.iteritems(): - if SEPARATE_CURVES: - c = Curve.New() - c.setResolu(24) - if USE_COLORS and val.mat: - c.materials=new_MATERIAL(val) - - bzn=0 - if val.beziers_knot[-1].tag in ['L','l','V','v','H','h'] and\ - test_samelocations(val.beziers_knot[-1].co,val.beziers_knot[0].co): - del val.beziers_knot[-1] - - for k2 in xrange(0,len(val.beziers_knot)): - bz= [co for co in val.beziers_knot[k2].co] - if bzn==0: - cp1 = bz[4]/SCALE, bz[5]/-SCALE,0.0, bz[0]/SCALE, bz[1]/-SCALE,0.0, bz[2]/SCALE,bz[3]/-SCALE,0.0, - beztriple1 = BezTriple.New(cp1) - bez = c.appendNurb(beztriple1) - bez[0].handleTypes=(HANDLE[val.beziers_knot[k2].ha[0]],HANDLE[val.beziers_knot[k2].ha[1]]) - bzn = 1 - else: - cp2 = bz[4]/SCALE,bz[5]/-SCALE,0.0 , bz[0]/SCALE, bz[1]/-SCALE,0.0, bz[2]/SCALE,bz[3]/-SCALE,0.0 - beztriple2 = BezTriple.New(cp2) - beztriple2.handleTypes= (HANDLE[val.beziers_knot[k2].ha[0]],HANDLE[val.beziers_knot[k2].ha[1]]) - bez.append(beztriple2) - - if val.flagUV[0]==1 or val.fill==1: - #-------------------- - # 0.4.6 : cyclic flag ... - #-------------------- - bez.flagU += 1 - - if SEPARATE_CURVES: - ob = scene.objects.new(c,val.id) - scene.objects.active = ob - ob.setLocation(0.0,0.0,nloc) - nloc+=0.0001 - c.update() - - if not SEPARATE_CURVES: - ob = scene.objects.new(c,name) - scene.objects.active = ob - c.update() - -#===================================================================== -#===== SVG format : DEBUT ========================= -#===================================================================== -#-------------------- -# 0.5.8, needed with the new -# tranform evaluation -#-------------------- -pxUNIT={'pt':1.25, - 'pc':15.0, - 'mm':3.543307, - 'cm':35.43307, - 'in':90.0, - 'em':1.0, # should be taken from font size - # but not currently managed - 'ex':1.0, # should be taken from font size - # but not currently managed - '%':1.0, - } - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def rect(prp): - """ - build rectangle paths - """ - D=[] - if 'x' not in prp: x=0.0 - else : x=float(prp['x']) - if 'y' not in prp: y=0.0 - else : y=float(prp['y']) - #-------------------- - # 0.5.8 - #-------------------- - try: - height=float(prp['height']) - except: - pxUNIT['%']=(BOUNDINGBOX['rec'][3]-BOUNDINGBOX['rec'][1])/100.0 - for key in pxUNIT:#.keys(): - if key in prp['height']: - height=float(prp['height'].replace(key,''))*pxUNIT[key] - try: - width=float(prp['width']) - except: - pxUNIT['%']=(BOUNDINGBOX['rec'][2]-BOUNDINGBOX['rec'][0])/100.0 - for key in pxUNIT:#.keys(): - if key in prp['width']: - width=float(prp['width'].replace(key,''))*pxUNIT[key] - #-------------------- - # 0.5.8, end - #-------------------- - """ - normal rect - x,y - h1 - *----------* - | | - | | - | | - *----------* v1 - h2 - """ - if 'rx' not in prp or 'rx' not in prp: - D=['M',str(x),str(y),'h',str(width),'v',str(height),'h',str(-width),'z'] - else : - rx=float(prp['rx']) - if 'ry' not in prp : - ry=float(prp['rx']) - else : ry=float(prp['ry']) - if 'rx' in prp and prp['rx']<0.0: rx*=-1 - if 'ry' in prp and prp['ry']<0.0: ry*=-1 - """ - rounded corner - - x,y M h1 - ---*----------* - / \ - / \ - v2 * * c1 - | | - | | - | | - c3 * * v2 - \ / - \ / - *----------* - h2 c2 - """ - - D=['M',str(x+rx),str(y), - 'h',str(width-2*rx), - 'c',str(rx),'0.0',str(rx),str(ry),str(rx),str(ry), - 'v',str(height-ry), - 'c','0.0',str(ry),str(-rx),str(ry),str(-rx),str(ry), - 'h',str(-width+2*rx), - 'c',str(-rx),'0.0',str(-rx),str(-ry),str(-rx),str(-ry), - 'v',str(-height+ry), - 'c','0.0','0.0','0.0',str(-ry),str(rx),str(-ry), - 'z'] - - return D - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def circle(prp): - if 'cx' not in prp: cx=0.0 - else : cx =float(prp['cx']) - if 'cy' not in prp: cy=0.0 - else : cy =float(prp['cy']) - r = float(prp['r']) - D=['M',str(cx),str(cy+r), - 'C',str(cx-r), str(cy+r*0.552),str(cx-0.552*r),str(cy+r), str(cx),str(cy+r), - 'C',str(cx+r*0.552), str(cy+r), str(cx+r), str(cy+r*0.552), str(cx+r),str(cy), - 'C',str(cx+r), str(cy-r*0.552),str(cx+r*0.552),str(cy-r),str(cx), str(cy-r), - 'C',str(cx-r*0.552), str(cy-r), str(cx-r), str(cy-r*0.552),str(cx-r),str(cy), - 'Z'] - return D - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def ellipse(prp): - if 'cx' not in prp: cx=0.0 - else : cx =float(prp['cx']) - if 'cy' not in prp: cy=0.0 - else : cy =float(prp['cy']) - ry = float(prp['rx']) - rx = float(prp['ry']) - D=['M',str(cx),str(cy+rx), - 'C',str(cx-ry),str(cy+rx*0.552),str(cx-0.552*ry),str(cy+rx),str(cx),str(cy+rx), - 'C',str(cx+ry*0.552),str(cy+rx),str(cx+ry),str(cy+rx*0.552),str(cx+ry),str(cy), - 'C',str(cx+ry),str(cy-rx*0.552),str(cx+ry*0.552),str(cy-rx),str(cx),str(cy-rx), - 'C',str(cx-ry*0.552),str(cy-rx),str(cx-ry),str(cy-rx*0.552),str(cx-ry),str(cy), - 'z'] - return D - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def line(prp): - D=['M',str(prp['x1']),str(prp['y1']), - 'L',str(prp['x2']),str(prp['y2'])] - return D - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def polyline(prp): - if 'points' in prp: - points=prp['points'].split(' ') - np=0 - for p in points: - if p!='': - p=p.split(',') - if np==0: - D=['M',str(p[0]),str(p[1])] - np+=1 - else: - D.append('L'); D.append(str(p[0])); D.append(str(p[1])) - return D - else: - return [] - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def polygon(prp): - D=polyline(prp) - if D!=[]: - D.append('Z') - return D - - -#-------------------- -# 0.5.8, to remove exec -#-------------------- -OTHERSSHAPES={ 'rect' : rect, - 'line' : line, - 'polyline': polyline, - 'polygon' : polygon, - 'circle' : circle, - 'ellipse' : ellipse} - -#-------------------- -# 0.3.9 -#-------------------- -def calc_arc (cpx,cpy, rx, ry, ang, fa , fs , x, y) : - """ - Calc arc paths - """ - rx=abs(rx) - ry=abs(ry) - px=abs((cos(ang)*(cpx-x)+sin(ang)*(cpy-y))*0.5)**2.0 - py=abs((cos(ang)*(cpy-y)-sin(ang)*(cpx-x))*0.5)**2.0 - rpx=rpy=0.0 - if abs(rx)>0.0: rpx=px/(rx**2.0) - if abs(ry)>0.0: rpy=py/(ry**2.0) - pl=rpx+rpy - if pl>1.0: - pl=pl**0.5;rx*=pl;ry*=pl - carx=sarx=cary=sary=0.0 - if abs(rx)>0.0: - carx=cos(ang)/rx;sarx=sin(ang)/rx - if abs(ry)>0.0: - cary=cos(ang)/ry;sary=sin(ang)/ry - x0=(carx)*cpx+(sarx)*cpy - y0=(-sary)*cpx+(cary)*cpy - x1=(carx)*x+(sarx)*y - y1=(-sary)*x+(cary)*y - d=(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0) - if abs(d)>0.0 :sq=1.0/d-0.25 - else: sq=-0.25 - if sq<0.0 :sq=0.0 - sf=sq**0.5 - if fs==fa :sf=-sf - xc=0.5*(x0+x1)-sf*(y1-y0) - yc=0.5*(y0+y1)+sf*(x1-x0) - ang_0=atan2(y0-yc,x0-xc) - ang_1=atan2(y1-yc,x1-xc) - ang_arc=ang_1-ang_0; - if (ang_arc < 0.0 and fs==1) : - ang_arc += 2.0 * PI - elif (ang_arc>0.0 and fs==0) : - ang_arc-=2.0*PI - n_segs=int(ceil(abs(ang_arc*2.0/(PI*0.5+0.001)))) - P=[] - for i in xrange(n_segs): - ang0=ang_0+i*ang_arc/n_segs - ang1=ang_0+(i+1)*ang_arc/n_segs - ang_demi=0.25*(ang1-ang0) - t=2.66666*sin(ang_demi)*sin(ang_demi)/sin(ang_demi*2.0) - x1=xc+cos(ang0)-t*sin(ang0) - y1=yc+sin(ang0)+t*cos(ang0) - x2=xc+cos(ang1) - y2=yc+sin(ang1) - x3=x2+t*sin(ang1) - y3=y2-t*cos(ang1) - P.append([[(cos(ang)*rx)*x1+(-sin(ang)*ry)*y1, - (sin(ang)*rx)*x1+(cos(ang)*ry)*y1], - [(cos(ang)*rx)*x3+(-sin(ang)*ry)*y3, - (sin(ang)*rx)*x3+(cos(ang)*ry)*y3], - [(cos(ang)*rx)*x2+(-sin(ang)*ry)*y2, - (sin(ang)*rx)*x2+(cos(ang)*ry)*y2]]) - return P - -#-------------------- -# 0.3.9 -#-------------------- -def curve_to_a(curves, c,D,n0,CP): #A,a - global SCALE - l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]), - int(D[c[1]+4]),int(D[c[1]+5]),float(D[c[1]+6]),float(D[c[1]+7])] - if c[0]=='a': - l[5]=l[5] + CP[0] - l[6]=l[6] + CP[1] - B=Bez() - B.co=[ CP[0], CP[1], CP[0], CP[1], CP[0], CP[1] ] - B.ha=['C','C'] - B.tag=c[0] - POINTS= calc_arc (CP[0],CP[1], - l[0], l[1], l[2]*(PI / 180.0), - l[3], l[4], - l[5], l[6] ) - for p in POINTS : - B=Bez() - B.co=[ p[2][0],p[2][1], p[0][0],p[0][1], p[1][0],p[1][1]] - B.ha=['C','C'] - B.tag='C' - BP=curves.ITEM[n0].beziers_knot[-1] - BP.co[2]=B.co[2] - BP.co[3]=B.co[3] - curves.ITEM[n0].beziers_knot.append(B) - BP=curves.ITEM[n0].beziers_knot[-1] - BP.co[2]=BP.co[0] - BP.co[3]=BP.co[1] - CP=[l[5], l[6]] - #---------- 059m------------ - if len(D)>c[1]+7 and D[c[1]+8] not in TAGcourbe : - c[1]+=7 - curves,n0,CP=curve_to_a(curves, c, D, n0,CP) - #---------- 059m------------ - return curves,n0,CP - -def move_to(curves, c, D, n0,CP, proprietes): - global DEBUG,TAGcourbe, LAST_ID - global USE_COLORS - - l=[float(D[c[1]+1]),float(D[c[1]+2])] - - if c[0]=='m': - l=[l[0]+CP[0], - l[1] + CP[1]] - - if n0 in curves.ITEM: - n0+=1 - CP=[l[0],l[1]] - curves.ITEM[n0]=ITEM() - - if 'id' in proprietes: - curves.ITEM[n0].id=proprietes['id'] - else: - curves.ITEM[n0].id=LAST_ID - - proprietes['n'].append(n0) - if USE_COLORS: - pr= proprietes.get('fill') # None or the property - if pr != None: - if '#' in pr: - i=1 - curves.ITEM[n0].color=[int(pr[i:i+2],16),int(pr[i+2:i+4],16),int(pr[i+4:i+6],16)] - curves.ITEM[n0].mat=1 - elif pr in SVGCOLORNAMELIST: - Courbe[n].color=SVGCOLORNAMELIST[pr] - Courbe[n].mat=1 - - B=Bez() - B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]] - B.ha=['L','C'] - B.tag=c[0] - curves.ITEM[n0].beziers_knot.append(B) - return curves,n0,CP - -def close_z(curves, c,D,n0,CP): #Z,z - curves.ITEM[n0].flagUV[0]=1 - if len(curves.ITEM[n0].beziers_knot)>1: - BP=curves.ITEM[n0].beziers_knot[-1] - BP0=curves.ITEM[n0].beziers_knot[0] - if BP.tag in ['c','C','s','S',]: - BP.co[2]=BP0.co[2] #4-5 point prec - BP.co[3]=BP0.co[3] - del curves.ITEM[n0].beziers_knot[0] - else: - del curves.ITEM[n0] - n0-=1 - return curves,n0,CP - -def curve_to_q(curves, c,D,n0,CP): #Q,q - l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]),float(D[c[1]+4])] - if c[0]=='q': - l=[l[0]+CP[0], l[1]+CP[1], l[2]+CP[0], l[3]+CP[1]] - B=Bez() - B.co=[l[2], l[3], l[2], l[3], l[0], l[1]] #plus toucher au 2-3 - B.ha=['C','C'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - BP.co[2]=BP.co[0] - BP.co[3]=BP.co[1] - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[2],l[3]] - #if DEBUG==1: pass - if len(D)>c[1]+5 and D[c[1]+5] not in TAGcourbe : - c[1]+=4 - curves,n0,CP=curve_to_q(curves, c, D, n0,CP) - return curves,n0,CP - -def curve_to_t(curves, c,D,n0,CP): #T,t - l=[float(D[c[1]+1]),float(D[c[1]+2])] - if c[0]=='t': - l=[l[0]+CP[0], l[1]+CP[1]] - B=Bez() - B.co=[l[0], l[1], l[0], l[1], l[0], l[1]] #plus toucher au 2-3 - B.ha=['C','C'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - l0=build_SYMETRIC([BP.co[0],BP.co[1],BP.co[4],BP.co[5]]) - if BP.tag in ['q','Q','t','T','m','M']: - BP.co[2]=l0[2] - BP.co[3]=l0[3] - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe : - c[1]+=4 - curves,n0,CP=curve_to_t(curves, c, D, n0,CP) - return curves,n0,CP - -#-------------------- -# 0.4.3 : rewritten -#-------------------- -def build_SYMETRIC(l): - X=l[2]-(l[0]-l[2]) - Y=l[3]-(l[1]-l[3]) - return X,Y - -def curve_to_s(curves, c,D,n0,CP): #S,s - l=[float(D[c[1]+1]), - float(D[c[1]+2]), - float(D[c[1]+3]), - float(D[c[1]+4])] - if c[0]=='s': - l=[l[0]+CP[0], l[1]+CP[1], - l[2]+CP[0], l[3]+CP[1]] - B=Bez() - B.co=[l[2],l[3],l[2],l[3],l[0],l[1]] #plus toucher au 2-3 - B.ha=['C','C'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - #-------------------- - # 0.4.3 - #-------------------- - BP.co[2],BP.co[3]=build_SYMETRIC([BP.co[4],BP.co[5],BP.co[0],BP.co[1]]) - curves.ITEM[n0].beziers_knot.append(B) - #-------------------- - # 0.4.3 - #-------------------- - CP=[l[2],l[3]] - if len(D)>c[1]+5 and D[c[1]+5] not in TAGcourbe : - c[1]+=4 - curves,n0,CP=curve_to_c(curves, c, D, n0,CP) - return curves,n0,CP - -def curve_to_c(curves, c, D, n0,CP): #c,C - l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]), - float(D[c[1]+4]),float(D[c[1]+5]),float(D[c[1]+6])] - if c[0]=='c': - l=[l[0]+CP[0], - l[1]+CP[1], - l[2]+CP[0], - l[3]+CP[1], - l[4]+CP[0], - l[5]+CP[1]] - B=Bez() - B.co=[l[4], - l[5], - l[4], - l[5], - l[2], - l[3]] #plus toucher au 2-3 - - - B.ha=['C','C'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - BP.co[2]=l[0] - BP.co[3]=l[1] - BP.ha[1]='C' - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[4],l[5]] - if len(D)>c[1]+7 and D[c[1]+7] not in TAGcourbe : - c[1]+=6 - curves,n0,CP=curve_to_c(curves, c, D, n0,CP) - return curves,n0,CP - -def draw_line_l(curves, c, D, n0,CP): #L,l - - l=[float(D[c[1]+1]),float(D[c[1]+2])] - if c[0]=='l': - l=[l[0]+CP[0], - l[1]+CP[1]] - B=Bez() - B.co=[l[0],l[1], - l[0],l[1], - l[0],l[1]] - - B.ha=['L','L'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - BP.ha[1]='L' - - curves.ITEM[n0].beziers_knot.append(B) - CP=[B.co[4],B.co[5]] - - if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe : - c[1]+=2 - curves,n0,CP=draw_line_l(curves, c, D, n0,CP) #L - - return curves,n0,CP - -def draw_line_h(curves, c,D,n0,CP): #H,h - if c[0]=='h': - l=[float(D[c[1]+1])+float(CP[0]),CP[1]] - else: - l=[float(D[c[1]+1]),CP[1]] - B=Bez() - B.co=[l[0],l[1],l[0],l[1],l[0],l[1]] - B.ha=['L','L'] - B.tag=c[0] - #BP=curves.ITEM[n0].beziers_knot[-1] - #BP.ha[0]='L' - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - return curves,n0,CP - -def draw_line_v(curves, c,D,n0,CP): #V, v - if c[0]=='v': - l=[CP[0], float(D[c[1]+1])+CP[1]] - else: - l=[CP[0], float(D[c[1]+1])] - - B=Bez() - B.co=[l[0],l[1],l[0],l[1],l[0],l[1]] - B.ha=['L','L'] - B.tag=c[0] - #BP=curves.ITEM[n0].beziers_knot[-1] - #BP.ha[0]='L' - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - return curves,n0,CP - -Actions= { "C" : curve_to_c, - "A" : curve_to_a, - "S" : curve_to_s, - "M" : move_to, - "V" : draw_line_v, - "L" : draw_line_l, - "H" : draw_line_h, - "Z" : close_z, - "Q" : curve_to_q, - "T" : curve_to_t, - - "c" : curve_to_c, - "a" : curve_to_a, - "s" : curve_to_s, - "m" : move_to, - "v" : draw_line_v, - "l" : draw_line_l, - "h" : draw_line_h, - "z" : close_z, - "q" : curve_to_q, - "T" : curve_to_t -} - -TAGcourbe=Actions.keys() -TAGtransform=['M','L','C','S','H','V','T','Q'] -tagTRANSFORM=0 - -def wash_DATA(ndata): - if ndata: - ndata = ndata.strip() - - if ndata[0]==',':ndata=ndata[1:] - if ndata[-1]==',':ndata=ndata[:-1] - - #-------------------- - # 0.4.0 : 'e' - #-------------------- - ni=0 - i = ndata.find('-',ni) - if i != -1: - while i>-1 : - i = ndata.find('-',ni) - # 059l ------ - if i>0 : - if ndata[i-1] not in [' ',',','e']: - ndata=ndata[:i]+','+ndata[i:] - ni=i+2 - else: - ni=i+1 - elif i>-1: - ni=1 - # 059l ------ - - ndata=ndata.replace(',,',',') - ndata=ndata.replace(' ',',') - ndata=ndata.split(',') - ndata=[i for i in ndata if i] #059a - - return ndata - -#-------------------- -# 0.3.4 : - read data rewrittten -#-------------------- -def list_DATA(DATA): - """ - This function translate a text in a list of - correct commandswith the right number of waited - values for each of them . For example : - d="'M0,14.0 z" becomes ['M','0.0','14.0','z'] - """ - # ---------------------------------------- - # borner les differents segments qui devront etre - # traites - # pour cela construire une liste avec chaque - # position de chaque emplacement tag de type - # commande path... - # ---------------------------------------- - tagplace=[] - for d in Actions: - b1=0 - while True: - i = DATA.find(d,b1) - if i==-1: break - tagplace.append(i) - b1=i+1 - #------------------------------------------ - # cette liste doit etre traites dans l'ordre - # d'apparition des tags - #------------------------------------------ - tagplace.sort() - - tpn=range(len(tagplace)) - - - #-------------------- - # 0.3.5 :: short data, only one tag - #-------------------- - if len(tagplace)-1>0: - DATA2=[] - for t in tpn[:-1]: - DATA2.append(DATA[tagplace[t]:tagplace[t]+1]) - ndata=DATA[tagplace[t]+1:tagplace[t+1]] - - if DATA2[-1] not in ['z','Z'] : - ndata=wash_DATA(ndata) - DATA2.extend(ndata) - - DATA2.append(DATA[tagplace[t+1]:tagplace[t+1]+1]) - - if DATA2[-1] not in ['z','Z'] and len(DATA)-1>=tagplace[t+1]+1: - ndata=DATA[tagplace[t+1]+1:] - ndata=wash_DATA(ndata) - DATA2.extend(ndata) #059a - - else: - #-------------------- - # 0.3.5 : short data,only one tag - #-------------------- - DATA2=[] - DATA2.append(DATA[tagplace[0]:tagplace[0]+1]) - ndata=DATA[tagplace[0]+1:] - ndata=wash_DATA(ndata) - DATA2.extend(ndata) - return DATA2 - -#---------------------------------------------- -# 0.3 -# 0.5.8, to remove exec -#---------------------------------------------- -def translate(t): - tx=t[0] - ty=t[1] - return [1, 0, tx], [0, 1, ty],[0,0,1] - -#---------------------------------------------- -# 0.3.2 -# 0.5.8, to remove exec -#---------------------------------------------- -def scale(s): - sx=s[0] - if len(s)>1: sy=s[1] - else: sy=sx - return [sx, 0, 0], [0, sy, 0],[0,0,1] - -#---------------------------------------------- -# 0.4.1 : transslate a in radians -# 0.5.8, to remove exec -#---------------------------------------------- -def rotate(t): - a=t[0] - return [cos(a*3.1416/180.0), -sin(a*3.1416/180.0), 0], [sin(a*3.1416/180.0), cos(a*3.1416/180.0),0],[0,0,1] - -#---------------------------------------------- -# 0.3.2 -# 0.5.8, to remove exec -#---------------------------------------------- -def skewx(t): - a=t[0] - return [1, tan(a*3.1416/180.0), 0], [0, 1, 0],[0,0,1] - -#---------------------------------------------- -# 0.4.1 -# 0.5.8, to remove exec -#---------------------------------------------- -def skewy(t): - a=t[0] - return [1, 0, 0], [tan(a*3.1416/180.0), 1 , 0],[0,0,1] - -#---------------------------------------------- -# 0.3.2 -# 0.5.8, to remove exec -#---------------------------------------------- -def matrix(t): - a,b,c,d,e,f=t - return [a,c,e],[b,d,f],[0,0,1] - -#-------------------- -# 0.5.8, to remove exec -#-------------------- -matrixTRANSFORM={ 'translate':translate, - 'scale':scale, - 'rotate':rotate, - 'skewx':skewx, - 'skewy':skewy, - 'matrix':matrix - } - -#---------------------------------------------- -# 0.4.2 : rewritten -# 0.5.8 : to remove exec uses. -#---------------------------------------------- -def control_CONTAINT(txt): - """ - the transforms' descriptions can be sole or several - and separators might be forgotten - """ - t0=0 - tlist=[] - while txt.count(')',t0)>0: - t1=txt.find(')',t0) - nt0=txt[t0:t1+1] - t2=nt0[nt0.find('(')+1:-1] - val=nt0[:nt0.find('(')] - - while t2.find(' ')!=-1: - t2=t2.replace(' ',' ') - while t2.find(', ')!=-1: #059l - t2=t2.replace(', ',',') #059l - - t2=t2.replace(' ',',') - t2=[float(t) for t in t2.split(',')] - - if val=='rotate' : - t3=t2 - if len(t3)==3: - tlist.append(['translate',[t3[1],t3[2]]]) - tlist.append(['rotate',[t3[0]/180.0*3.1416]]) - tlist.append(['translate',[-t3[1],-t3[2]]]) - else: - tlist.append(['rotate',[t3[0]]]) - else: - tlist.append([val,t2]) - t0=t1+1 - return tlist - - -def curve_FILL(Courbe,proprietes): - global USE_COLORS - for n in proprietes['n']: - pr = proprietes['style'] - if n in Courbe and 'fill:' in pr: - if not 'fill:none' in pr: - Courbe[n].fill=1 - if USE_COLORS: - i= pr.find('fill:#') - if i != -1: - i= i+6 - Courbe[n].color=[int(pr[i:i+2],16),int(pr[i+2:i+4],16),int(pr[i+4:i+6],16)] - Courbe[n].mat=1 - elif ';fill-opacity' in pr: - if pr.find('fill:url')==-1: - i= pr.find('fill:')+5 - i2= pr.find(';',i) - COLORNAME= pr[i:i2] - Courbe[n].color=SVGCOLORNAMELIST[COLORNAME] - Courbe[n].mat=1 - elif 'color:' in pr: - i= pr.find('color:')+6 - i2= pr.find(';',i) - COLORNAME= pr[i:i2] - Courbe[n].color=SVGCOLORNAMELIST[COLORNAME] - Courbe[n].mat=1 - else : - COLORNAME= 'white' - Courbe[n].color=SVGCOLORNAMELIST[COLORNAME] - Courbe[n].mat=1 - -#---------------------------------------------- -# 0.4.1 : apply transform stack -#---------------------------------------------- -def curve_TRANSFORM(Courbe,proprietes): - # 1/ unpack the STACK - # create a matrix for each transform - ST=[] - for st in proprietes['stack'] : - if st and type(st)==list: - for t in st: - code = control_CONTAINT(t) - a,b,c=matrixTRANSFORM[code[0][0]](code[0][1][:]) - T=Mathutils.Matrix(a,b,c) - ST.append(T) - elif st : - code = control_CONTAINT(st) - a,b,c=matrixTRANSFORM[code[0][0]](code[0][1][:]) - T=Mathutils.Matrix(a,b,c) - ST.append(T) - if 'transform' in proprietes: - for trans in control_CONTAINT(proprietes['transform']): - #-------------------- - # 0.5.8, to remove exec - #-------------------- - a,b,c=matrixTRANSFORM[trans[0].strip()](trans[1][:]) #059 - T=Mathutils.Matrix(a,b,c) - ST.append(T) - ST.reverse() - for n in proprietes['n']: - if n in Courbe: - for bez0 in Courbe[n].beziers_knot: - bez=bez0.co - for b in [0,2,4]: - for t in ST: - v=t * Mathutils.Vector([bez[b],bez[b+1],1.0]) #059a - bez[b]=v[0] - bez[b+1]=v[1] - -def filter(d): - for nn in d: - if nn not in '0123456789.': #059a - d=d.replace(nn,"") - return d - -def get_BOUNDBOX(BOUNDINGBOX,SVG): - if 'viewbox' not in SVG: - h=float(filter(SVG['height'])) - - w=float(filter(SVG['width'])) - BOUNDINGBOX['rec']=[0.0,0.0,w,h] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=w/h - else: - viewbox=SVG['viewbox'].split() - BOUNDINGBOX['rec']=[float(viewbox[0]),float(viewbox[1]),float(viewbox[2]),float(viewbox[3])] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=(r[2]-r[0])/(r[3]-r[1]) - return BOUNDINGBOX - -#---------------------------------------------- -# 0.4.1 : attributs ex : 'id=', 'transform=', 'd=' ... -#---------------------------------------------- -def collect_ATTRIBUTS(data): - #---------------------------------------------- - # 0.4.8 : short modif for a fantasy font case - # in the OOo svg format ('viewbox' is - # written 'viewBox', for instance) - #---------------------------------------------- - data=data.replace(' ',' ').lower() - ELEM={'TYPE':data[1:data.find(' ')]} - t1=len(data) - t2=0 - ct=data.count('="') - while ct>0: - t0=data.find('="',t2) - t2=data.find(' ',t2)+1 - id=data[t2:t0] - t2=data.find('"',t0+2) - if id!='d': - ELEM[id]=data[t0+2:t2].replace('\\','/') - else: - ELEM[id]=[] - ELEM[id].append(t0+2) - ELEM[id].append(t2) - ct=data.count('="',t2) - return ELEM - -# -------------------------------------------- -# 0.4.1 : to avoid to use sax and ths xml -# tools of the complete python -# -------------------------------------------- -def build_HIERARCHY(t): - global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - global LAST_ID, PATTERN - TRANSFORM=0 - t=t.replace('\t',' ') - while t.find(' ')!=-1: t=t.replace(' ',' ') - n0=0 - t0=t1=0 - #baliste=[] - balisetype=['?','?','/','/','!','!'] - BALISES=['D', #DECL_TEXTE', - 'D', #DECL_TEXTE', - 'F', #FERMANTE', - 'E', #ELEM_VIDE', - 'd', #DOC', - 'R', #REMARQUES', - 'C', #CONTENU', - 'O' #OUVRANTE' - ] - STACK=[] - while t1<len(t) and t0>-1: - t0=t.find('<',t0) - t1=t.find('>',t0) - ouvrante=0 - #-------------------- - # 0.4.4 , add 'else:' and 'break' to the 'if' statement - #-------------------- - if t0>-1 and t1>-1: - if t[t0+1] in balisetype: - b=balisetype.index(t[t0+1]) - - if t[t0+2]=='-': - b=balisetype.index(t[t0+1])+1 - - balise=BALISES[b] - - if b==2: - parent=STACK.pop(-1) - if parent!=None and TRANSFORM>0: - TRANSFORM-=1 - - elif t[t1-1] in balisetype: - balise=BALISES[balisetype.index(t[t1-1])+1] - - else: - t2=t.find(' ',t0) - if t2>t1: t2=t1 - ouvrante=1 - NOM=t[t0+1:t2] - - - if '</'+NOM in t: #.find('</'+NOM)>-1: - balise=BALISES[-1] - if NOM=='pattern' and not PATTERN: - t1=t.find('</'+NOM+'>',t0)+len('</'+NOM+'>') - balise=BALISES[-3] - else: - balise=BALISES[-2] - - if balise=='E' or balise=='O': - - proprietes=collect_ATTRIBUTS(t[t0:t1+ouvrante]) - - if 'id' in proprietes: - LAST_ID=proprietes['id'] - - if balise=='O' and 'transform' in proprietes: - STACK.append(proprietes['transform']) - TRANSFORM+=1 - elif balise=='O' : - STACK.append(None) - - proprietes['stack']=STACK[:] - D=[] - - if proprietes['TYPE'] in ['path'] and (proprietes['d'][1]-proprietes['d'][0]>1): - D=list_DATA(t[proprietes['d'][0]+t0:proprietes['d'][1]+t0]) - - elif proprietes['TYPE'] in OTHERSSHAPES: - #-------------------- - # 0.5.8, to remove exec - #-------------------- - D=OTHERSSHAPES[proprietes['TYPE']](proprietes) - - #elif proprietes['TYPE'] in ['pattern']: - # print 'pattern' - # D='' - - CP=[0.0,0.0] - if len(D)>0: - cursor=0 - proprietes['n']=[] - for cell in D: - - if len(cell)>=1 and cell[0] in TAGcourbe: - #-------------------- - # 0.5.8, to remove exec - #-------------------- - if cell[0] in ['m','M']: - curves,n0,CP=Actions[cell](curves, [cell,cursor], D, n0,CP,proprietes) - else: - curves,n0,CP=Actions[cell](curves, [cell,cursor], D, n0,CP) - - cursor+=1 - if TRANSFORM>0 or 'transform' in proprietes : - curve_TRANSFORM(curves.ITEM,proprietes) - - if 'style' in proprietes : - curve_FILL(curves.ITEM,proprietes) - - - elif proprietes['TYPE'] == 'svg': - BOUNDINGBOX = get_BOUNDBOX(BOUNDINGBOX,proprietes) - else: - #-------------------- - # 0.4.4 - #-------------------- - break - t1+=1 - t0=t1 - -def scan_FILE(nom): - global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - global SEPARATE_CURVES, USE_COLORS, PATTERN - - dir,name=split(nom) - name=name.split('.') - result=0 - #Choise=1 - t1=Blender.sys.time() - t=filterFILE(nom) - if t!='false': - Blender.Window.EditMode(0) - if not SHARP_IMPORT: - togH = Blender.Draw.Create(1) - togW = Blender.Draw.Create(0) - togAS = Blender.Draw.Create(0) - togSP = Blender.Draw.Create(0) - togCOL = Blender.Draw.Create(0) - Pattern= Blender.Draw.Create(0) - block=[\ - ("Clamp Width 1", togW, "Rescale the import with a Width of one unit"),\ - ("Clamp Height 1", togH, "Rescale the import with a Heightof one unit"),\ - ("No Rescaling", togAS, "No rescaling, the result can be very large"),\ - ("Separate Curves", togSP, "Create an object for each curve, Slower. May manage colors"),\ - ("Import Colors", togCOL, "try to import color if the path is set as 'fill'. Only With separate option"),\ - ("Import Patterns", Pattern, "import pattern content if it is made with paths.")] - retval = Blender.Draw.PupBlock("Import Options", block) - if togW.val: scale_=1 - elif togH.val: scale_=2 - elif togAS.val: scale_=3 - - if togSP.val: SEPARATE_CURVES=1 - - if togCOL.val and SEPARATE_CURVES : USE_COLORS=1 - - if Pattern.val : PATTERN =1 - - t1=Blender.sys.time() - # 0.4.1 : to avoid to use sax and the xml - # tools of the complete python - build_HIERARCHY(t) - r=BOUNDINGBOX['rec'] - curves.number_of_items=len(curves.ITEM) - for k, val in curves.ITEM.iteritems(): - val.pntsUV[0] =len(val.beziers_knot) - if curves.number_of_items>0 : #and Choise==1 : - #-------------------- - # 0.4.5 and 0.4.9 - #-------------------- - createCURVES(curves, name[0]) - else: - pass - print ' elapsed time : ',Blender.sys.time()-t1 - Blender.Redraw() - -#===================================================================== -#====================== SVG format mouvements ======================== -#===================================================================== -def functionSELECT(nom): - scan_FILE(nom) - - -if __name__=='__main__': - Blender.Window.FileSelector (functionSELECT, 'SELECT an .SVG FILE', '*.svg')
\ No newline at end of file |