def subdivMesh(me, subdivs): oldmode = Mesh.Mode() Mesh.Mode(Mesh.SelectModes['FACE']) me.sel = 1 for i in xrange(subdivs): me.subdivide(0) Mesh.Mode(oldmode)
def bevent(evt): global EVENT_NOEVENT, EVENT_DRAW, EVENT_EXIT if (evt == EVENT_EXIT): Draw.Exit() elif (evt == EVENT_DRAW): Draw.Redraw() elif (evt == EVENT_EXPORT): sce = bpy.data.scenes.active if (export_all == 1): print "oh ja" # get a list of mesh objects obs = [ob for ob in sce.objects if ob.type == 'Mesh'] # export all object names for ob in obs: me = Mesh.New() me.getFromObject(ob, 0) print(me.name) export_to_as(ob) Draw.PupMenu("Export Successful") else: export_to_as(sce.objects.active) Draw.PupMenu("Export Successful") elif (evt == EVENT_BROWSEFILE): Window.FileSelector(FileSelected, "Export .as", expFileName) Draw.Redraw(1)
def export_to_as(ob): me = Mesh.New() me.getFromObject(ob, 0) class_name = ob.name.replace(".", "") #get transformations global ob_locX, ob_locY, ob_locZ, ob_mtrx, ob_rotX, ob_rotY, ob_rotZ, ob_scaleX, ob_scaleY, ob_scaleZ ob_locX = ob.LocX ob_locY = ob.LocY ob_locZ = ob.LocZ ob_mtrx = ob.matrix.rotationPart() ob_rotX = ob.RotX * (180 / pi) ob_rotY = ob.RotY * (180 / pi) ob_rotZ = ob.RotZ * (180 / pi) ob_scaleX = ob.SizeX ob_scaleY = ob.SizeY ob_scaleZ = ob.SizeZ if (engine_menu.val == 2): export_papervision(me, class_name) elif (engine_menu.val == 3): export_papervision2(me, class_name) elif (engine_menu.val == 4): export_sandy(me, class_name) elif (engine_menu.val == 1): export_away3d(me, class_name) elif (engine_menu.val == 5): export_away3d_210(me, class_name) elif (engine_menu.val == 6): export_away3d_220(me, class_name)
def drawmesh(meshdata, sce): "draws meshes in blender" mes = Mesh.New() mes.verts.extend(meshdata['verts']) if meshdata['edges']: mes.edges.extend(meshdata['edges']) if meshdata['faces']: mes.faces.extend(meshdata['faces']) sce.objects.new(mes, meshdata['name'])
def CreateSegment(self, camera, nameSuffix, length): editmode = Window.EditMode() # are we in edit mode? If so ... if editmode: Window.EditMode(0) # leave edit mode before getting the mesh name = camera.getName() + nameSuffix # define vertices and faces for a pyramid coords = [[-length / 2, 0, 0], [length / 2, 0, 0]] edges = [[0, 1]] try: print "LOOKING FOR MESHDATA" me = Mesh.Get(name + 'mesh') print dir(me) except: print "COULD NOT FIND MESH" me = Mesh.New(name + 'mesh') #print "____ EDGES: ", len(me.edges), "____ VERTS: ", len(me.verts) me.verts = None me.edges.delete() #print "____ EDGES: ", len(me.edges), "____ VERTS: ", len(me.verts) me.verts.extend(coords) # add vertices to mesh me.edges.extend(edges) # add faces to the mesh (also adds edges) #print "____ EDGES: ", len(me.edges), "____ VERTS: ", len(me.verts) try: print "TRYING TO RECOVER OBJECT: " ob = Object.Get(name) print "++++++ OBJECT RECOVERED: " except: print "++++++ CREATING NEW OBJECT" ob = self.scene.objects.new(me, name) if editmode: Window.EditMode(1) # optional, just being nice return ob
def export_wall2(wall, all, fi, obj_idx): kids = getChildren(wall, all) if has_prefix(wall.name, 'SEG'): fi.write("SEGMENT %s\n" % strip_prefix(wall.name, 'SEG')) else: fi.write("SEGMENT_CURVED %s\n" % strip_prefix(wall.name, 'CRV')) grp_list = Group.Get() grp_list.sort(lambda x, y: cmp(x.name.lower(), y.name.lower())) grp_list.insert(0, None) for layer, lod in [[1, 5000], [2, 20000]]: for gi, g in enumerate(grp_list): my_kids = [] for k in kids: if layer in k.layers: if findgroup(grp_list, k) == g: if k.getType() == 'Mesh': my_kids.append(k) if len(my_kids) > 0: out_mesh = FacMesh() for k in my_kids: mesh = k.getData(mesh=True) if k.getType() != 'Mesh' or k.modifiers: mesh = Mesh.New() mesh.getFromObject(k) for f in mesh.faces: out_mesh.add_face(f, k) divs = 4 if has_prefix(wall.name, 'SEG'): divs = 1 divs = int(float(get_prop(wall, 'divs', divs))) fi.write( "MESH %d %f %d %d %d\n" % (gi, lod, divs, len(out_mesh.vlist), out_mesh.idx_count)) out_mesh.output(fi) fi.write("\n") for k in kids: if k.getType() == 'Empty' and has_prefix(k.name, 'OBJ'): ki = obj_idx[get_prop(k, 'external', k.name)] loc = k.getMatrix('localspace').translationPart() if has_close_prop(k, ['GRADED', 'DRAPED']) == 'GRADED': fi.write("ATTACH_GRADED %d %f %f %f %f" % (ki, loc[0], loc[2], -loc[1], make_degs(-k.RotZ))) else: fi.write("ATTACH_DRAPED %d %f %f %f %f" % (ki, loc[0], loc[2], -loc[1], make_degs(-k.RotZ))) if has_prop(k, 'show_level'): fi.write(" %s" % get_prop(k, 'show_level', '')) fi.write("\n")
def New(self, panelimage): if self.obj: mesh = self.obj.getData(mesh=True) for n in range(1, len(mesh.faces)): if mesh.faces[n].image != mesh.faces[0].image: self.delRegion(mesh.faces[n].image) self.obj.removeAllProperties() else: mesh = Mesh.New(PanelRegionHandler.NAME) self.obj = Mesh.New(PanelRegionHandler.NAME) self.obj = Object.New('Mesh', PanelRegionHandler.NAME) self.obj.link(mesh) Scene.GetCurrent().link(self.obj) self.obj.layers = [] # invisible # (re)build faces and assign panel texture for n in range(len(mesh.faces), PanelRegionHandler.REGIONCOUNT + 1): v = len(mesh.verts) mesh.verts.extend([[0, 0, -n], [1, 0, -n], [0, 1, -n]]) mesh.faces.extend([[v, v + 1, v + 2]]) for n in range(PanelRegionHandler.REGIONCOUNT + 1): mesh.faces[n].image = panelimage return self
def Import(self): lines = self.lines print "importing into Blender ..." scene = bpy.data.scenes.active mesh_indicies = {} # the index of each 'Mesh' is used as the key for those meshes indicies context_indicies = None # will raise an error if used! #Get the line of Texture Coords nr_uv_ind = 0 #Get Materials nr_fac_mat = 0 i = -1 mat_list = [] tex_list = [] mesh_line_indicies = [] for j, line in enumerate(lines): l = line.strip() words = line.split() if words[0] == "Material" : #context_indicies["Material"] = j self.loadMaterials(j, mat_list, tex_list) elif words[0] == "MeshTextureCoords" : context_indicies["MeshTextureCoords"] = j #nr_uv_ind = j elif words[0] == "MeshMaterialList" : context_indicies["MeshMaterialList"] = j+2 #nr_fac_mat = j + 2 elif words[0] == "Mesh": # Avoid a second loop context_indicies = mesh_indicies[j] = {'MeshTextureCoords':0, 'MeshMaterialList':0} for mesh_index, value in mesh_indicies.iteritems(): mesh = Mesh.New() self.loadVertices(mesh_index, mesh, value['MeshTextureCoords'], value['MeshMaterialList'], tex_list) mesh.materials = mat_list[:16] if value['MeshMaterialList']: self.loadMeshMaterials(value['MeshMaterialList'], mesh) scene.objects.new(mesh) self.file.close() print "... finished"
def __init__(self, scene_objects, file): self.file = file objs = [o for o in scene_objects if o.type == 'Mesh'] # not sure if needed # create a temporary mesh to hold actual (modified) mesh data TMP_mesh = Mesh.New('tmp_for_stl_export') # write the objects for obj in objs: self.obj = obj objtype = obj.type objname = obj.name mesh = TMP_mesh # temporary mesh to hold actual (modified) mesh data mesh.getFromObject(objname) self.mesh = mesh self.export_mesh(mesh, obj)
def writeMesh(o, obj): o.write("# Mesh " + obj.name + "\n") mesh = Mesh.New( obj.name ) # Note the "mesh.verts = None" at the end of this if. Used to clear the new mesh from memory mesh.getFromObject(obj, 0, 1) mesh.transform(obj.mat, 1) # mesh = mesh.getData() verts = mesh.verts faces = mesh.faces # writeMatrix(o, obj.getMatrix()) if len(mesh.materials) > 0: mat = mesh.materials[0] writeMaterial(o, mat) else: writeDefaultMaterial(o) o.write("shape {\n") o.write(" mesh\n") o.write(" vertexCount %u\n" % len(verts)) o.write(" faceCount %u\n" % len(faces)) for v in verts: o.write(" v %.6f %.6f %.6f\n" % (v.co[0], v.co[1], v.co[2])) for face in faces: fv = face.v o.write(" f ") if len(fv) == 4: o.write("%d %d %d %d\n" % (fv[0].index, fv[1].index, fv[2].index, fv[3].index)) elif len(fv) == 3: o.write("%d %d %d\n" % (fv[2].index, fv[1].index, fv[0].index)) o.write("}\n")
def writeMesh(self, ob, normals=0): imageMap = {} # set of used images sided = {} # 'one':cnt , 'two':cnt vColors = {} # 'multi':1 if (len(ob.modifiers) > 0): me = Mesh.New() me.getFromObject(ob.name) # Careful with the name, the temporary mesh may # reuse the default name for other meshes. So we # pick our own name. me.name = "MOD_%s" % (ob.name) else: me = ob.getData(mesh=1) self.classifyMesh(me, ob) if (self.collnode): self.writeCollisionMesh(me, ob, normals) return else: self.writeRegularMesh(me, ob, normals) return
def ImportPSK(infile): print "Importing file: ", infile pskFile = file(infile, 'rb') # mesh = Mesh.New('mesh01') # read general header header = axChunkHeader() header.Load(pskFile) header.Dump() # read the PNTS0000 header header.Load(pskFile) header.Dump() axPoints = [] for i in range(0, header.dataCount): point = axPoint() point.Load(pskFile) axPoints.append(point) #mesh.verts.extend([[point.x, point.y, point.z]]) # read the VTXW0000 header header.Load(pskFile) header.Dump() xyzList = [] uvList = [] axVerts = [] for i in range(0, header.dataCount): vert = axVertex() vert.Load(pskFile) #vert.Dump() axVerts.append(vert) xyzList.append( Vector([ axPoints[vert.pointIndex].x, axPoints[vert.pointIndex].y, axPoints[vert.pointIndex].z ])) uvList.append(Vector([vert.u, vert.v])) mesh.verts.extend(xyzList) # read the FACE0000 header header.Load(pskFile) header.Dump() axTriangles = [] for i in range(0, header.dataCount): tri = axTriangle() tri.Load(pskFile) #tri.Dump() axTriangles.append(tri) SGlist = [] for i in range(0, header.dataCount): tri = axTriangles[i] mesh.faces.extend(tri.indexes) uvData = [] uvData.append(uvList[tri.indexes[0]]) uvData.append(uvList[tri.indexes[1]]) uvData.append(uvList[tri.indexes[2]]) mesh.faces[i].uv = uvData # collect a list of the smoothing groups if SGlist.count(tri.smoothingGroups) == 0: SGlist.append(tri.smoothingGroups) # assign a material index to the face #mesh.faces[-1].materialIndex = SGlist.index(indata[5]) mesh.faces[i].mat = tri.materialIndex mesh.update() meshObject = Object.New('Mesh', 'PSKMesh') meshObject.link(mesh) scene = Scene.GetCurrent() scene.link(meshObject) # read the MATT0000 header header.Load(pskFile) header.Dump() for i in range(0, header.dataCount): data = unpack('64s6i', pskFile.read(88)) matName = asciiz(data[0]) print("creating material", matName) if matName == "": matName = "no_texture" try: mat = Material.Get(matName) except: #print("creating new material:", matName) mat = Material.New(matName) # create new texture texture = Texture.New(matName) texture.setType('Image') # texture to material mat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) # read the REFSKELT header header.Load(pskFile) header.Dump() axReferenceBones = [] for i in range(0, header.dataCount): axReferenceBones.append(axReferenceBone()) axReferenceBones[i].Load(pskFile) #axReferenceBones[i].Dump() quat = axReferenceBones[i].quat if i == 0: axReferenceBones[i].parentIndex = -1 quat.y = -quat.y #quat.inverse() else: quat.inverse() # create an armature skeleton armData = Armature.Armature("PSK") armData.drawAxes = True armObject = Object.New('Armature', "ReferenceBones") armObject.link(armData) scene = Scene.GetCurrent() scene.objects.link(armObject) armData.makeEditable() editBones = [] for i in range(0, header.dataCount): refBone = axReferenceBones[i] refBone.name = refBone.name.replace(' ', '_') print("processing bone ", refBone.name) #if refBone.position.length == 0: #refBone.Dump() editBone = Armature.Editbone() editBone.name = refBone.name #editBone.length = refBone.position.length if refBone.parentIndex >= 0: refParent = axReferenceBones[refBone.parentIndex] parentName = refParent.name #print type(parentName) print("looking for parent bone", parentName) #parent = armData.bones[parentName] #parent. # editBone.head = refParent.position.copy() editParent = editBones[refBone.parentIndex] #editParent = armData.bones[editBones[refBone.parentIndex].name] #editParent = armData.bones[parentName] editBone.parent = editParent #editBone.tail = refBone.position #editBone.matrix = refBone.quat.toMatrix() #m = Matrix(QuatToMatrix(refParent.quat)) #rotatedPos = m * refBone.position.copy() rotatedPos = refParent.quat * refBone.position.copy() editBone.tail = refParent.position + rotatedPos refBone.position = refParent.position + rotatedPos #editBone.tail = refBone.position = refParent.position + refBone.position q1 = refParent.quat.copy() q2 = refBone.quat.copy() refBone.quat = QuatMultiply1(q1, q2) #editBone.matrix = refBone.quat.toMatrix() #matrix = Matrix(refParent.quat.toMatrix() * refBone.quat.toMatrix()) #m1 = refParent.quat.copy().toMatrix() #m2 = refBone.quat.toMatrix() #refBone.quat = matrix.toQuat() #editBone.options = [Armature.HINGE] #editBone.options = [Armature.HINGE, Armature.CONNECTED] editBone.options = [Armature.CONNECTED] else: editBone.head = Vector(0, 0, 0) editBone.tail = refBone.position.copy() #editBone.tail = refBone.quat.toMatrix() * refBone.position #editBone.options = [Armature.HINGE] #editBone.matrix = refBone.quat.toMatrix() editBones.append(editBone) armData.bones[editBone.name] = editBone # only update after adding all edit bones or it will crash Blender !!! armData.update() print("done processing reference bones") #for editBone in editBones: #armData.makeEditable() #armData.bones[editBone.name] = editBone #armData.update() armObject.makeDisplayList() scene.update() Window.RedrawAll() # read the RAWWEIGHTS header header.Load(pskFile) header.Dump() axBoneWeights = [] for i in range(0, header.dataCount): axBoneWeights.append(axBoneWeight()) axBoneWeights[i].Load(pskFile) #if i < 10: # axBoneWeights[i].Dump() # calculate the vertex groups vertGroupCreated = [] for i in range(0, len(axReferenceBones)): vertGroupCreated.append(0) for i in range(0, len(axReferenceBones)): refBone = axReferenceBones[i] for boneWeight in axBoneWeights: if boneWeight.boneIndex == i: # create a vertex group for this bone if not done yet if vertGroupCreated[i] == 0: print('creating vertex group:', refBone.name) mesh.addVertGroup(refBone.name) vertGroupCreated[i] = 1 for j in range(0, len(axVerts)): axVert = axVerts[j] #vertList.append(boneWeight.pointIndex) if boneWeight.pointIndex == axVert.pointIndex: mesh.assignVertsToGroup(refBone.name, [j], boneWeight.weight, Mesh.AssignModes.ADD) #mesh.assignVertsToGroup(refBone.name, vertList, ) armObject.makeParentDeform([meshObject], 0, 0) pskFile.close() Window.RedrawAll() print "PSK2Blender completed"
def MakeMesh(image): """This takes an image as input and creates a mesh that is an extrusion of the mesh treated as a height field, with the zero value areas cut from the mesh. """ epsilon = 1.0 / 10000000.0 set_aspect_ratio = True scale_factor = 2.0 # scale the z value zscale = -1.2 xscale = 14.2 yscale = 14.2 xmax, ymax = image.getMaxXY() xmin, ymin = image.getMinXY() name = image.getName() depth = image.depth has_data = image.has_data xres, yres = image.getSize() inv_xres = 1.0 / float(xres) inv_yres = 1.0 / float(yres) # scale output mesh to have correct aspect ratio # to fit within a unit cube if set_aspect_ratio: aspect_ratio = float(xres) * inv_yres if aspect_ratio > 1.0: inv_xres *= 1.0 inv_yres *= 1.0 / aspect_ratio else: inv_xres *= aspect_ratio inv_yres *= 1.0 # scale the x and y together inv_xres *= scale_factor inv_yres *= scale_factor print("xres: %d, yres: %d, xinv %f, yinv %f" % (xres, yres, inv_xres, inv_yres)) print("depth: %d, has_data: %s, name: %s" % (depth, has_data, name)) coords = [] faces = [] zero_verts = {} # Create coordinate array, mark zero z vertices. count = 0 for y in range(yres): for x in range(xres): r, g, b, a = image.getPixelF(x, y) v = g + r * 256 + b * 256 * 256 if v > 125: v = 125 coords.append([(float(x) * inv_xres - 0.5) * xscale, (float(y) * inv_yres - 0.5) * yscale, v * zscale]) #if v < epsilon: if v < epsilon and False: print "Z: %d" % count, zero_verts[count] = 4 count += 1 # Create face list. Decrement zero verts. for y in range(yres - 1): for x in range(xres - 1): p1 = x + (y * xres) p2 = p1 + 1 # clockwise? p3 = x + (y + 1) * xres + 1 p4 = p3 - 1 if (coords[p1][2] < epsilon and coords[p2][2] < epsilon and coords[p3][2] < epsilon and coords[p4][2] < epsilon and False): zero_verts[p1] -= 1 zero_verts[p2] -= 1 zero_verts[p3] -= 1 zero_verts[p4] -= 1 else: faces.append([p1, p2, p3, p4]) # Adjust edges for unused zeros for y in range(yres): p1 = y * xres if zero_verts.has_key(p1): zero_verts[p1] -= 2 p1 = p1 + xres - 1 if zero_verts.has_key(p1): zero_verts[p1] -= 2 for x in range(xres): p1 = x if zero_verts.has_key(p1): zero_verts[p1] -= 2 p1 = x + xres * (yres - 1) if zero_verts.has_key(p1): zero_verts[p1] -= 2 p1 = 0 if zero_verts.has_key(p1): zero_verts[p1] += 1 p1 = xres - 1 if zero_verts.has_key(p1): zero_verts[p1] += 1 p1 = (yres - 1) * xres if zero_verts.has_key(p1): zero_verts[p1] += 1 p1 = p1 + xres - 1 if zero_verts.has_key(p1): zero_verts[p1] += 1 # Filter vert list and remove unused zeros new_verts = [] remap = {} new_count = 0 for v in range(len(coords)): is_zero = zero_verts.has_key(v) if not is_zero or zero_verts[v] > 0: remap[v] = new_count new_verts.append(coords[v]) new_count += 1 # Re Map old coords to new coords in face list new_faces = [] for f in faces: #print "Making face: %s" % f n1 = remap[f[0]] n2 = remap[f[1]] n3 = remap[f[2]] n4 = remap[f[3]] new_faces.append([n1, n2, n3, n4]) # Verbatim sample code from Blender.Mesh.__doc__ editmode = Window.EditMode() # are we in edit mode? If so ... if editmode: Window.EditMode(0) # leave edit mode before getting the mesh me = Mesh.New('myMesh') me.verts.extend(new_verts) # add vertices to mesh me.faces.extend(new_faces) # add faces to the mesh (also adds edges) #me.mesh.MFace.smooth(1) scn = Scene.GetCurrent() # link object to current scene ob = scn.objects.new(me, 'myObj') if editmode: Window.EditMode(1) # optional, just being nice # End Verbatim code return ob
def write(filename, objects,\ EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\ EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False, EXPORT_ARMATURE=False): ''' Basic write function. The context and options must be alredy set This can be accessed externaly eg. write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options. ''' def veckey3d(v): return round(v.x, 6), round(v.y, 6), round(v.z, 6) def veckey2d(v): return round(v.x, 6), round(v.y, 6) print 'OBJ Export path: "%s"' % filename temp_mesh_name = '~tmp-mesh' time1 = sys.time() scn = Scene.GetCurrent() file = open(filename, "w") # Write Header file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] )) file.write('# www.blender3d.org\n') # Tell the obj file what material file to use. if EXPORT_MTL: mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) # Get the container mesh. - used for applying modifiers and non mesh objects. containerMesh = meshName = tempMesh = None for meshName in Blender.NMesh.GetNames(): if meshName.startswith(temp_mesh_name): tempMesh = Mesh.Get(meshName) if not tempMesh.users: containerMesh = tempMesh if not containerMesh: containerMesh = Mesh.New(temp_mesh_name) if EXPORT_ROTX90: mat_xrot90= Blender.Mathutils.RotationMatrix(-90, 4, 'x') del meshName del tempMesh # Initialize totals, these are updated each object totverts = totuvco = totno = 1 face_vert_index = 1 globalNormals = {} # Get all meshs for ob_main in objects: for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): # Will work for non meshes now! :) # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None) if EXPORT_ARMATURE: write_armature(file,ob) write_poses(file,ob) me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scn) if not me: continue if EXPORT_UV: faceuv= me.faceUV else: faceuv = False # We have a valid mesh if EXPORT_TRI and me.faces: # Add a dummy object to it. has_quads = False for f in me.faces: if len(f) == 4: has_quads = True break if has_quads: oldmode = Mesh.Mode() Mesh.Mode(Mesh.SelectModes['FACE']) me.sel = True tempob = scn.objects.new(me) me.quadToTriangle(0) # more=0 shortest length oldmode = Mesh.Mode(oldmode) scn.objects.unlink(tempob) Mesh.Mode(oldmode) faces = [ f for f in me.faces ] if EXPORT_EDGES: edges = me.edges else: edges = [] if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write continue # dont bother with this mesh. if EXPORT_ROTX90: me.transform(ob_mat*mat_xrot90) else: me.transform(ob_mat) # High Quality Normals if EXPORT_NORMALS and faces: if EXPORT_NORMALS_HQ: BPyMesh.meshCalcNormals(me) else: # transforming normals is incorrect # when the matrix is scaled, # better to recalculate them me.calcNormals() # # Crash Blender #materials = me.getMaterials(1) # 1 == will return None in the list. materials = me.materials materialNames = [] materialItems = materials[:] if materials: for mat in materials: if mat: # !=None materialNames.append(mat.name) else: materialNames.append(None) # Cant use LC because some materials are None. # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. # Possible there null materials, will mess up indicies # but at least it will export, wait until Blender gets fixed. materialNames.extend((16-len(materialNames)) * [None]) materialItems.extend((16-len(materialItems)) * [None]) # Sort by Material, then images # so we dont over context switch in the obj file. if EXPORT_MORPH_TARGET: pass elif faceuv: try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) elif len(materials) > 1: try: faces.sort(key = lambda a: (a.mat, a.smooth)) except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) else: # no materials try: faces.sort(key = lambda a: a.smooth) except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) # Set the default mat to no material and no image. contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. contextSmooth = None # Will either be true or false, set bad to force initialization switch. if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: name1 = ob.name name2 = ob.getData(1) if name1 == name2: obnamestring = fixName(name1) else: obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) if EXPORT_BLEN_OBS: file.write('o %s\n' % obnamestring) # Write Object name else: # if EXPORT_GROUP_BY_OB: file.write('g %s\n' % obnamestring) # Vert mesh = ob.getData() objmat = ob.getMatrix() for i in objmat: file.write('obm: %.6f %.6f %.6f %.6f\n' % tuple(i)) vgrouplist = mesh.getVertGroupNames() file.write('vgroupcount: %i\n' % len(vgrouplist)) for vgname in vgrouplist: file.write('vgroup: %s\n' % vgname) for v in mesh.verts: file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) influences = mesh.getVertexInfluences(v.index) file.write('influence: %i\n' % len(influences)) for name,weight in influences: file.write('GroupName: %s\n' % name) file.write('Weight: %f\n' % weight) # UV if faceuv: uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ uv_dict = {} # could use a set() here for f_index, f in enumerate(faces): for uv_index, uv in enumerate(f.uv): uvkey = veckey2d(uv) try: uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] except: uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) file.write('vt %.6f %.6f\n' % tuple(uv)) uv_unique_count = len(uv_dict) del uv, uvkey, uv_dict, f_index, uv_index # Only need uv_unique_count and uv_face_mapping # NORMAL, Smooth/Non smoothed. if EXPORT_NORMALS: for f in faces: if f.smooth: for v in f: noKey = veckey3d(v.no) if not globalNormals.has_key( noKey ): globalNormals[noKey] = totno totno +=1 file.write('vn %.6f %.6f %.6f\n' % noKey) else: # Hard, 1 normal from the face. noKey = veckey3d(f.no) if not globalNormals.has_key( noKey ): globalNormals[noKey] = totno totno +=1 file.write('vn %.6f %.6f %.6f\n' % noKey) if not faceuv: f_image = None for f_index, f in enumerate(faces): f_v= f.v f_smooth= f.smooth f_mat = min(f.mat, len(materialNames)-1) if faceuv: f_image = f.image f_uv= f.uv # MAKE KEY if faceuv and f_image: # Object is always true. key = materialNames[f_mat], f_image.name else: key = materialNames[f_mat], None # No image, use None instead. # CHECK FOR CONTEXT SWITCH if key == contextMat: pass # Context alredy switched, dont do anythoing else: if key[0] == None and key[1] == None: # Write a null material, since we know the context has changed. if EXPORT_GROUP_BY_MAT: file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null) file.write('usemtl (null)\n') # mat, image else: mat_data= MTL_DICT.get(key) if not mat_data: # First add to global dict so we can export to mtl # Then write mtl # Make a new names from the mat and image name, # converting any spaces to underscores with fixName. # If none image dont bother adding it to the name if key[1] == None: mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image else: mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image if EXPORT_GROUP_BY_MAT: file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) contextMat = key if f_smooth != contextSmooth: if f_smooth: # on now off file.write('s 1\n') contextSmooth = f_smooth else: # was off now on file.write('s off\n') contextSmooth = f_smooth file.write('f') if faceuv: if EXPORT_NORMALS: if f_smooth: # Smoothed, use vertex normals for vi, v in enumerate(f_v): file.write( ' %d/%d/%d' % (\ v.index+totverts,\ totuvco + uv_face_mapping[f_index][vi],\ globalNormals[ veckey3d(v.no) ])) # vert, uv, normal else: # No smoothing, face normals no = globalNormals[ veckey3d(f.no) ] for vi, v in enumerate(f_v): file.write( ' %d/%d/%d' % (\ v.index+totverts,\ totuvco + uv_face_mapping[f_index][vi],\ no)) # vert, uv, normal else: # No Normals for vi, v in enumerate(f_v): file.write( ' %d/%d' % (\ v.index+totverts,\ totuvco + uv_face_mapping[f_index][vi])) # vert, uv face_vert_index += len(f_v) else: # No UV's if EXPORT_NORMALS: if f_smooth: # Smoothed, use vertex normals for v in f_v: file.write( ' %d//%d' % (\ v.index+totverts,\ globalNormals[ veckey3d(v.no) ])) else: # No smoothing, face normals no = globalNormals[ veckey3d(f.no) ] for v in f_v: file.write( ' %d//%d' % (\ v.index+totverts,\ no)) else: # No Normals for v in f_v: file.write( ' %d' % (\ v.index+totverts)) file.write('\n') # Write edges. if EXPORT_EDGES: LOOSE= Mesh.EdgeFlags.LOOSE for ed in edges: if ed.flag & LOOSE: file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) # Make the indicies global rather then per mesh totverts += len(me.verts) if faceuv: totuvco += uv_unique_count me.verts= None file.close() # Now we have all our materials, save them if EXPORT_MTL: write_mtl(mtlfilename) if EXPORT_COPY_IMAGES: dest_dir = filename # Remove chars until we are just the path. while dest_dir and dest_dir[-1] not in '\\/': dest_dir = dest_dir[:-1] if dest_dir: copy_images(dest_dir) else: print '\tError: "%s" could not be used as a base for an image path.' % filename print "OBJ Export time: %.2f" % (sys.time() - time1)
def write(directory, filename, objects): def v_n_uv_key(v, n, uv): return round(v.x, 6), round(v.y, 6), round(v.z, 6), round(n.x, 6), round( n.y, 6), round(n.z, 6), round(uv[0], 6), round(uv[1], 6) def v_n_key(v, n): return round(v.x, 6), round(v.y, 6), round(v.z, 6), round(n.x, 6), round(n.y, 6), round(n.z, 6) def adjust_key(key, obCenter): keyList = list(key) keyList[0] -= obCenter[0] keyList[1] -= obCenter[1] keyList[2] -= obCenter[2] return tuple(keyList) temp_mesh_name = '~tmp-mesh' scn = Scene.GetCurrent() # Get the container mesh. - used for applying modifiers and non mesh objects. containerMesh = meshName = tempMesh = None for meshName in Blender.NMesh.GetNames(): if meshName.startswith(temp_mesh_name): tempMesh = Mesh.Get(meshName) if not tempMesh.users: containerMesh = tempMesh if not containerMesh: containerMesh = Mesh.New(temp_mesh_name) del meshName del tempMesh try: armature = Blender.Object.Get("Armature") write_armature(directory + filename, armature) except: armature = None # Get all meshs for ob_main in objects: for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): me = BPyMesh.getMeshFromObject(ob, containerMesh, True, False, scn) if not me: continue # Initialize globalVertices and globalMaterials dictionaries vertIndex = 0 matIndex = 0 globalVertices = {} globalMaterials = {} # Dictionary of materials: (material.name, image.name):matname_imagename # matname_imagename has fixed names. materialDict = {} # We have a valid mesh if me.faces: # Add a dummy object to it. has_quads = False for f in me.faces: if len(f) == 4: has_quads = True break if has_quads: oldmode = Mesh.Mode() Mesh.Mode(Mesh.SelectModes['FACE']) me.sel = True tempob = scn.objects.new(me) me.quadToTriangle(0) # more=0 shortest length oldmode = Mesh.Mode(oldmode) scn.objects.unlink(tempob) Mesh.Mode(oldmode) else: continue # High Quality Normals BPyMesh.meshCalcNormals(me) # Make our own list so it can be sorted to reduce context switching faces = [f for f in me.faces] faceuv = me.faceUV edges = me.edges materials = me.materials materialNames = [] materialItems = materials[:] if materials: for mat in materials: if mat: materialNames.append(mat.name) else: materialNames.append(None) # Possible there null materials, will mess up indicies # but at least it will export, wait until Blender gets fixed. materialNames.extend((16 - len(materialNames)) * [None]) materialItems.extend((16 - len(materialItems)) * [None]) # Sort by Material, then images # so we dont over context switch in the obj file. if faceuv: try: faces.sort(key=lambda a: (a.mat, a.image, a.smooth)) except: faces.sort(lambda a, b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) elif len(materials) > 1: try: faces.sort(key=lambda a: (a.mat, a.smooth)) except: faces.sort(lambda a, b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) else: # no materials try: faces.sort(key=lambda a: a.smooth) except: faces.sort(lambda a, b: cmp(a.smooth, b.smooth)) # Set the default mat to no material and no image. contextMat = ( 0, 0 ) # Can never be this, so we will label a new material the first chance we get. contextSmooth = None # Will either be true or false, set bad to force initialization switch. name1 = ob.name name2 = ob.getData(1) obnamestring = fixName(name1) file = open(directory + obnamestring + ".drkMesh", "w") # Fill globalVertices dictionary by creating (vert, normal, uv) tuple for all vertices of all faces vertString = "" obCenter = ob.getLocation() if faceuv: vOutputFormat = 'v %.6f %.6f %.6f %.6f %.6f %.6f %.6f %.6f\n' else: vOutputFormat = 'v %.6f %.6f %.6f %.6f %.6f %.6f\n' f_image = None #Loop through all faces submeshCount = 0 faceCount = 0 faceCounts = [] for face in faces: if faceuv: faceUVs = list(face.uv) faceUVindex = 0 faceIndices = [] for v in face: if face.smooth: vno = v.no else: vno = face.no if faceuv: key = v_n_uv_key(v.co, v.no, faceUVs[faceUVindex]) faceUVindex += 1 else: key = v_n_key(v.co, v.no) if not globalVertices.has_key(key): globalVertices[key] = vertIndex vertString += vOutputFormat % key faceIndices.append(vertIndex) vertIndex += 1 else: faceIndices.append(globalVertices[key]) # Make material,texture key f_mat = min(face.mat, len(materialNames) - 1) if faceuv: f_image = face.image if faceuv and f_image: matKey = materialNames[f_mat], f_image.name else: matKey = materialNames[f_mat], None # Check for context switch if matKey != contextMat: submeshCount += 1 if matKey[0] == None and matKey[1] == None: # Write a null material, since we know the context has changed. faceString += 'use (null)\n' # mat, image else: mat_data = materialDict.get(matKey) if not mat_data: mat_data = materialDict[matKey] = fixName( matKey[0]), materialItems[f_mat], f_image vertString += 'use %d\n' % matIndex globalMaterials[mat_data[0]] = matIndex matIndex += 1 if faceCount != 0: faceCounts.append(faceCount) faceCount = 0 contextMat = matKey vertString += 'face %d %d %d\n' % tuple(faceIndices) faceCount += 1 faceCounts.append(faceCount) file.write('count %d\n' % vertIndex) if faceuv: file.write('uvs\n') file.write('submeshes %d\n' % submeshCount) for faceCount in faceCounts: file.write('faces %d\n' % faceCount) file.write(vertString) me.verts = None write_mtl(file, materialDict, globalMaterials) file.close()
def readDSF(path): baddsf=(0, "Invalid DSF file", path) h=file(path, 'rb') h.seek(0, 2) hlen=h.tell() h.seek(0, 0) if h.read(8)!='XPLNEDSF' or unpack('<I',h.read(4))!=(1,) or h.read(4)!='DAEH': raise IOError, baddsf (l,)=unpack('<I', h.read(4)) headend=h.tell()+l-8 if h.read(4)!='PORP': raise IOError, baddsf (l,)=unpack('<I', h.read(4)) properties=[] c=h.read(l-9).split('\0') h.read(1) overlay=0 for i in range(0, len(c)-1, 2): if c[i]=='sim/overlay': overlay=int(c[i+1]) elif c[i]=='sim/south': lat=int(c[i+1]) elif c[i]=='sim/west': lon=int(c[i+1]) properties.append((c[i],c[i+1])) h.seek(headend) if overlay: # Overlay DSF - bail early h.close() raise IOError, (0, "This is an overlay DSF", path) # Definitions Atom if h.read(4)!='NFED': raise IOError, baddsf (l,)=unpack('<I', h.read(4)) defnend=h.tell()+l-8 terrain=objects=polygons=network=[] while h.tell()<defnend: c=h.read(4) (l,)=unpack('<I', h.read(4)) if l==8: pass # empty elif c=='TRET': terrain=h.read(l-9).replace('\\','/').replace(':','/').split('\0') h.read(1) elif c=='TJBO': objects=h.read(l-9).replace('\\','/').replace(':','/').split('\0') h.read(1) elif c=='YLOP': polygons=h.read(l-9).replace('\\','/').replace(':','/').split('\0') h.read(1) elif c=='WTEN': networks=h.read(l-9).replace('\\','/').replace(':','/').split('\0') h.read(1) else: h.seek(l-8, 1) # Geodata Atom if h.read(4)!='DOEG': raise IOError, baddsf (l,)=unpack('<I', h.read(4)) geodend=h.tell()+l-8 pool=[] scal=[] while h.tell()<geodend: c=h.read(4) (l,)=unpack('<I', h.read(4)) if c=='LOOP': thispool=[] (n,)=unpack('<I', h.read(4)) (p,)=unpack('<B', h.read(1)) for i in range(p): thisplane=[] (e,)=unpack('<B', h.read(1)) if e==0 or e==1: last=0 for j in range(n): (d,)=unpack('<H', h.read(2)) if e==1: d=(last+d)&65535 thisplane.append(d) last=d elif e==2 or e==3: last=0 while(len(thisplane))<n: (r,)=unpack('<B', h.read(1)) if (r&128): (d,)=unpack('<H', h.read(2)) for j in range(r&127): if e==3: thisplane.append((last+d)&65535) last=(last+d)&65535 else: thisplane.append(d) else: for j in range(r): (d,)=unpack('<H', h.read(2)) if e==3: d=(last+d)&65535 thisplane.append(d) last=d else: raise IOError, baddsf thispool.append(thisplane) pool.append(thispool) elif c=='LACS': thisscal=[] for i in range(0, l-8, 8): d=unpack('<2f', h.read(8)) thisscal.append(d) scal.append(thisscal) else: h.seek(l-8, 1) # Rescale pool and transform to one list per entry if len(scal)!=len(pool): raise(IOError) newpool=[] for i in range(len(pool)): curpool=pool[i] n=len(curpool[0]) newpool=[[] for j in range(n)] for plane in range(len(curpool)): (scale,offset)=scal[i][plane] scale=scale/65535 for j in range(n): newpool[j].append(curpool[plane][j]*scale+offset) pool[i]=newpool # Commands Atom if h.read(4)!='SDMC': raise IOError, baddsf (l,)=unpack('<I', h.read(4)) cmdsend=h.tell()+l-8 curpool=0 idx=0 near=0 far=-1 flags=0 # 0=physical, 1=overlay f=[[[],[]] for i in range(len(terrain))] v=[[[],[]] for i in range(len(terrain))] t=[[[],[]] for i in range(len(terrain))] pscale=99.0/(hlen-geodend) progress=0 while h.tell()<cmdsend: now=int((h.tell()-geodend)*pscale) if progress!=now: progress=now Window.DrawProgressBar(progress/100.0, "Importing %2d%%"%progress) (c,)=unpack('<B', h.read(1)) if c==1: # Coordinate Pool Select (curpool,)=unpack('<H', h.read(2)) elif c==2: # Junction Offset Select h.read(4) # not implemented elif c==3: # Set Definition (idx,)=unpack('<B', h.read(1)) elif c==4: # Set Definition (idx,)=unpack('<H', h.read(2)) elif c==5: # Set Definition (idx,)=unpack('<I', h.read(4)) elif c==6: # Set Road Subtype h.read(1) # not implemented elif c==7: # Object h.read(2) # not implemented elif c==8: # Object Range h.read(4) # not implemented elif c==9: # Network Chain (l,)=unpack('<B', h.read(1)) h.read(l*2) # not implemented elif c==10: # Network Chain Range h.read(4) # not implemented elif c==11: # Network Chain (l,)=unpack('<B', h.read(1)) h.read(l*4) # not implemented elif c==12: # Polygon (param,l)=unpack('<HB', h.read(3)) h.read(l*2) # not implemented elif c==13: # Polygon Range (DSF2Text uses this one) (param,first,last)=unpack('<HHH', h.read(6)) # not implemented elif c==14: # Nested Polygon (param,n)=unpack('<HB', h.read(3)) for i in range(n): (l,)=unpack('<B', h.read(1)) h.read(l*2) # not implemented elif c==15: # Nested Polygon Range (DSF2Text uses this one too) (param,n)=unpack('<HB', h.read(3)) h.read((n+1)*2) # not implemented elif c==16: # Terrain Patch pass elif c==17: # Terrain Patch w/ flags (flags,)=unpack('<B', h.read(1)) flags-=1 elif c==18: # Terrain Patch w/ flags & LOD (flags,near,far)=unpack('<Bff', h.read(9)) flags-=1 elif c==23: # Patch Triangle (l,)=unpack('<B', h.read(1)) n=len(v[idx][flags]) for i in range(n,n+l,3): f[idx][flags].append([i+2,i+1,i]) for i in range(l): (d,)=unpack('<H', h.read(2)) p=pool[curpool][d] v[idx][flags].append([(p[0]-lon)*hscale, (p[1]-lat)*hscale, p[2]*vscale]) if len(p)>=7: t[idx][flags].append([p[5],p[6]]) elif c==24: # Patch Triangle - cross-pool (l,)=unpack('<B', h.read(1)) n=len(v[idx][flags]) for i in range(n,n+l,3): f[idx][flags].append([i+2,i+1,i]) for i in range(l): (c,d)=unpack('<HH', h.read(4)) p=pool[c][d] v[idx][flags].append([(p[0]-lon)*hscale, (p[1]-lat)*hscale, p[2]*vscale]) if len(p)>=7: t[idx][flags].append([p[5],p[6]]) elif c==25: # Patch Triangle Range (first,last)=unpack('<HH', h.read(4)) n=len(v[idx][flags]) for i in range(n,n+last-first,3): f[idx][flags].append([i+2,i+1,i]) for d in range(first,last): p=pool[curpool][d] v[idx][flags].append([(p[0]-lon)*hscale, (p[1]-lat)*hscale, p[2]*vscale]) if len(p)>=7: t[idx][flags].append([p[5],p[6]]) #elif c==26: # Patch Triangle Strip (not used by DSF2Text) #elif c==27: #elif c==28: elif c==29: # Patch Triangle Fan (l,)=unpack('<B', h.read(1)) n=len(v[idx][flags]) for i in range(1,l-1): f[idx][flags].append([n+i+1,n+i,n]) for i in range(l): (d,)=unpack('<H', h.read(2)) p=pool[curpool][d] v[idx][flags].append([(p[0]-lon)*hscale, (p[1]-lat)*hscale, p[2]*vscale]) if len(p)>=7: t[idx][flags].append([p[5],p[6]]) elif c==30: # Patch Triangle Fan - cross-pool (l,)=unpack('<B', h.read(1)) n=len(v[idx][flags]) for i in range(1,l-1): f[idx][flags].append([n+i+1,n+i,n]) for i in range(l): (c,d)=unpack('<HH', h.read(4)) p=pool[c][d] v[idx][flags].append([(p[0]-lon)*hscale, (p[1]-lat)*hscale, p[2]*vscale]) if len(p)>=7: t[idx][flags].append([p[5],p[6]]) elif c==31: # Patch Triangle Fan Range (first,last)=unpack('<HH', h.read(4)) n=len(v[idx][flags]) for i in range(1,last-first-1): f[idx][flags].append([n+i+1,n+i,n]) for d in range(first, last): p=pool[curpool][d] v[idx][flags].append([(p[0]-lon)*hscale, (p[1]-lat)*hscale, p[2]*vscale]) if len(p)>=7: t[idx][flags].append([p[5],p[6]]) elif c==32: # Comment (l,)=unpack('<B', h.read(1)) h.read(l) elif c==33: # Comment (l,)=unpack('<H', h.read(2)) h.read(l) elif c==34: # Comment (l,)=unpack('<I', h.read(4)) h.read(l) else: raise IOError, (c, "Unrecognised command (%d)" % c, c) h.close() Window.DrawProgressBar(0.99, "Realising") scene=Scene.GetCurrent() scene.layers=[1,2] for flags in [0]:# was [1,0]: # overlay first so overlays for idx in range(len(terrain)): if not f[idx][flags]: continue if idx: name=basename(terrain[idx])[:-4] if flags: name=name+'.2' if terrain[idx] in libterrain: (texture, angle, xscale, zscale)=readTER(libterrain[terrain[idx]]) elif exists(join(dirname(path), pardir, pardir, terrain[idx])): (texture, angle, xscale, zscale)=readTER(abspath(join(dirname(path), pardir, pardir, terrain[idx]))) else: raise IOError(0, 'Terrain %s not found' % terrain[idx], terrain[idx]) try: mat=Material.Get(name) except: mat=Material.New(name) mat.rgbCol=[1.0, 1.0, 1.0] mat.spec=0 try: img=Image.Get(basename(texture)) except: img=Image.Load(texture) tex=Texture.New(name) tex.setType('Image') tex.image=img mat.setTexture(0, tex) if flags: mat.zOffset=1 mat.mode |= Material.Modes.ZTRANSP mtex=mat.getTextures()[0] mtex.size=(xscale*250, zscale*250, 0) mtex.zproj=Texture.Proj.NONE if t[idx][flags]: mtex.texco=Texture.TexCo.UV else: mtex.texco=Texture.TexCo.GLOB else: name=terrain[idx] mat=Material.New(terrain[idx]) mat.rgbCol=[0.1, 0.1, 0.2] mat.spec=0 mesh=Mesh.New(name) mesh.mode &= ~(Mesh.Modes.TWOSIDED|Mesh.Modes.AUTOSMOOTH) mesh.mode |= Mesh.Modes.NOVNORMALSFLIP mesh.materials += [mat] mesh.verts.extend(v[idx][flags]) mesh.faces.extend(f[idx][flags]) if t[idx][flags]: faceno=0 for face in mesh.faces: face.uv=[Vector(t[idx][flags][i][0], t[idx][flags][i][1]) for i in f[idx][flags][faceno]] face.image=img faceno+=1 mesh.update() ob = Object.New("Mesh", name) ob.link(mesh) scene.objects.link(ob) ob.Layer=flags+1 ob.addProperty('terrain', terrain[idx]) mesh.sel=True mesh.remDoubles(0.001) # must be after linked to object mesh.sel=False if 0: # Unreliable for face in mesh.faces: for v in face.verts: if v.co[2]!=0.0: break else: face.mat=1 # water lamp=Lamp.New("Lamp", "Sun") ob = Object.New("Lamp", "Sun") ob.link(lamp) scene.objects.link(ob) lamp.type=1 ob.Layer=3 ob.setLocation(500, 500, 1000)
def write_object(obj): """Write drawables and empties""" s = "" name = obj.name defname = sketchify(obj.name) prop = obj.properties mtrx = obj.matrix.rotationPart() xvec, yvec, zvec = mtrx[0], mtrx[1], mtrx[2] x, y, z = obj.getLocation('worldspace') if obj.type == 'Empty': if obj.parent: # need to transform Empty to world coordinates #vec = Mathutils.Vector(obj.getLocation()) #nvec = vec*obj.matrixWorld #x,y,z = nvec.x, nvec.y, nvec.z x, y, z = obj.getLocation('worldspace') else: x, y, z = obj.loc s += "def %s (%s,%s,%s)\n" % (sketchify(name), x, y, z) elif obj.type in ['Mesh', 'Curve', 'Surf', 'MBall']: is_curve = (obj.type == 'Curve') is_mesh = (obj.type == 'Mesh') drawables.append(sketchify(name)) # write mesh to file if TRANSFORM_VERTICES: # The transformation code is from the Blender Python API # documentation. mesh = Mesh.New() mesh.getFromObject(obj.name) verts = mesh.verts[:] mesh.transform(obj.matrix) else: if not is_mesh: mesh = Mesh.New() mesh.getFromObject(obj.name) else: # Ensure that we get a mesh of the Mesh type mesh = obj.getData(mesh=True) twosided = (mesh.mode & Mesh.Modes['TWOSIDED']) and USE_TWOSIDED_FLAG s += 'def %s_o (%f,%f,%f)\n' % (defname, x, y, z) s += 'def %s_x [%f,%f,%f]\n' % tuple([defname] + list(xvec)) s += 'def %s_y [%f,%f,%f]\n' % tuple([defname] + list(yvec)) s += 'def %s_z [%f,%f,%f]\n' % tuple([defname] + list(zvec)) polyoptsname = "%s_polyopts" % defname polyoptions = [] try: polyopts = prop['polyoptions'] polyoptions.append(polyopts) except: pass if twosided: polyoptions.append('cull=false') if polyoptions: s += 'def %s [%s]\n' % (polyoptsname, ",".join(polyoptions)) else: polyoptsname = "" lineoptsname = "" try: lineopts = prop['lineoptions'] lineoptsname = "%s_lineopts" % defname s += 'def %s [%s]\n' % (lineoptsname, lineopts) except: lineoptsname = "" s += 'def %s {\n' % (defname) if EXPORT_MATERIALS: if is_mesh: materials = mesh.materials else: try: materials = obj.data.getMaterials() # does not work with MBall except: materials = [] if len(mesh.faces) > 0: # iterate over all faces in the mesh for face in mesh.faces: polyoptions = [] # each face is represented as a polygon if EXPORT_MATERIALS and len(materials): polymatopts = get_material(materials[face.mat], is_face=True) polyoptions.append(polymatopts) if polyoptsname: polyoptions.append(polyoptsname) if polyoptions: polyoptions = "[%s]" % ",".join(polyoptions) else: polyoptions = "" s += ' polygon%s' % polyoptions # iterate over the vertices in the mesh for vert in face.v: v = mesh.verts[vert.index] s += '(%f,%f,%f)' % tuple(v.co) s += '\n' else: prev = None connectededges = False lineoptions = [] if EXPORT_MATERIALS and materials: # pick first material for mat in materials: if mat: linematopts = get_material(mat, is_face=False) lineoptions.append(linematopts) break if lineoptsname: lineoptions.append(lineoptsname) if lineoptions: lineoptions = "[%s]" % ",".join(lineoptions) else: lineoptions = "" for edge in mesh.edges: if prev and (prev.v2.co == edge.v1.co): connectededges = True s += '(%f,%f,%f)' % tuple(edge.v2.co) else: if connectededges: s += '\n' connectededges = False s += ' line%s (%f,%f,%f)(%f,%f,%f)' % \ (lineoptions, edge.v1.co.x, edge.v1.co.y, edge.v1.co.z, edge.v2.co.x, edge.v2.co.y, edge.v2.co.z) prev = edge s += '\n' if TRANSFORM_VERTICES: # Restore vertices. mesh.verts = verts s += '}\n\n' return s
def ImportFromC(file_name): file = open(file_name, "r") scene = bpy.data.scenes.active meshes = [] for ob in scene.objects: obtype = ob.type if obtype == "Mesh": meshes.append(ob) lines = [ l_split for l in file.readlines() for l_split in (' '.join(l.split()), ) if l_split ] # erase all of the comments (/* */) i = 0 insideComment = 0 while i < len(lines): stopErase = 0 commentStart = lines[i].find("/*") if insideComment == 1: commentStart = 0 if lines[i].find("//") != -1: if lines[i].find("//") < commentStart: stopErase = 1 if stopErase != 1: if commentStart != -1: insideComment = 1 lineEnd = len(lines[i]) commentEnd = lines[i].find("*/") if commentEnd != -1: if insideComment == 1: commentEnd = lines[i].find("*/") + 2 insideComment = 0 else: if insideComment == 1: commentEnd = lineEnd if commentStart != -1: if lines[i].find("//") != -1: if lines[i].find("//") < commentStart: stopErase = 1 if lines[i].find("//") + 2 < commentEnd: stopErase = 1 if stopErase != 1: lines[i] = lines[i].replace(lines[i][commentStart:commentEnd], "") commentStart = lines[i].find("/*") if commentStart == -1: i = i + 1 if stopErase == 1: i = i + 1 # erase all of the comments (//) i = 0 while i < len(lines): commentStart = lines[i].find("//") commentEnd = len(lines[i]) if commentStart != -1: lines[i] = lines[i].replace(lines[i][commentStart:commentEnd], "") i = i + 1 # erase all spaces i = 0 while i < len(lines): lines[i] = lines[i].replace(" ", "") i = i + 1 # move the data from "lines" to "code" ignoring returns i = 0 code = [] while i < len(lines): lineEnd = len(lines[i]) j = 0 while j < lineEnd: code[len(code):] = lines[i][j] j = j + 1 i = i + 1 # find the first listed vertex array size i = 0 while i < len(code): if code[0 + i:12 + i] == [ "_", "P", "O", "I", "N", "T", "D", "A", "T", "S", "Z", "[" ]: codePos = i + 12 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0 + i:3 + i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 # read the vertex array sizes from the code endOfNum = 0 numCnt = 0 pointDatSz = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos + i] == "," or code[codePos + i] == "}": endOfNum = 1 else: num = num + code[codePos + i] i = i + 1 if code[codePos + i] == "}": endOfNum = 2 if endOfNum != 2: codePos = codePos + i pointDatSz[len(pointDatSz):] = [int(num)] #number of meshes meshCnt = len(pointDatSz) # find the first listed face array size i = 0 while i < len(code): if code[0 + i:11 + i] == ["_", "L", "I", "N", "E", "D", "A", "T", "S", "Z", "["]: codePos = i + 11 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0 + i:3 + i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 # read the face array sizes from the code endOfNum = 0 numCnt = 0 lineDatSz = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos + i] == "," or code[codePos + i] == "}": endOfNum = 1 else: num = num + code[codePos + i] i = i + 1 if code[codePos + i] == "}": endOfNum = 2 if endOfNum != 2: codePos = codePos + i lineDatSz[len(lineDatSz):] = [int(num)] # find the first listed color array size i = 0 while i < len(code): if code[0 + i:12 + i] == [ "_", "C", "O", "L", "O", "R", "D", "A", "T", "S", "Z", "[" ]: codePos = i + 11 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0 + i:3 + i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 # read the color array sizes from the code endOfNum = 0 numCnt = 0 colorDatSz = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos + i] == "," or code[codePos + i] == "}": endOfNum = 1 else: num = num + code[codePos + i] i = i + 1 if code[codePos + i] == "}": endOfNum = 2 if endOfNum != 2: codePos = codePos + i colorDatSz[len(colorDatSz):] = [int(num)] # find the first listed vertex i = 0 while i < len(code): if code[0 + i:7 + i] == ["_", "P", "O", "I", "N", "T", "["]: codePos = i + 7 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0 + i:3 + i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 # read the verticies from the code endOfNum = 0 vert = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos + i] == "," or code[codePos + i] == "}": endOfNum = 1 else: num = num + code[codePos + i] i = i + 1 if code[codePos + i] == "}": endOfNum = 2 if endOfNum != 2: codePos = codePos + i vert[len(vert):] = [float(num)] # find the first listed line data number i = 0 while i < len(code): if code[0 + i:6 + i] == ["_", "L", "I", "N", "E", "["]: codePos = i + 6 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0 + i:3 + i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 # read the line data from the code endOfNum = 0 line = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos + i] == "," or code[codePos + i] == "}": endOfNum = 1 else: num = num + code[codePos + i] i = i + 1 if code[codePos + i] == "}": endOfNum = 2 if endOfNum != 2: codePos = codePos + i line[len(line):] = [int(num)] # find the first listed color i = 0 while i < len(code): if code[0 + i:7 + i] == ["_", "C", "O", "L", "O", "R", "["]: codePos = i + 7 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0 + i:3 + i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 # read the colors from the code endOfNum = 0 color = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos + i] == "," or code[codePos + i] == "}": endOfNum = 1 else: num = num + code[codePos + i] i = i + 1 if code[codePos + i] == "}": endOfNum = 2 if endOfNum != 2: codePos = codePos + i color[len(color):] = [int(float.fromhex(num))] meshInc = 0 while meshInc < meshCnt: mesh = Mesh.New() # import verticies to blender if meshInc == 0: i = 0 else: i = pointDatSz[meshInc - 1] while i < pointDatSz[meshInc]: mesh.verts.extend(vert[i], vert[i + 1], vert[i + 2]) i = i + 3 # import faces to blender if meshInc == 0: i = 0 polyBgn = 0 else: i = lineDatSz[meshInc - 1] polyBgn = pointDatSz[meshInc - 1] / 3 while i < lineDatSz[meshInc]: if line[i] == 4: mesh.faces.extend(line[i + 1] - polyBgn, line[i + 2] - polyBgn, line[i + 3] - polyBgn, line[i + 4] - polyBgn) i = i + 5 else: if line[i] == 3: mesh.faces.extend(line[i + 1] - polyBgn, line[i + 2] - polyBgn, line[i + 3] - polyBgn) i = i + 4 # import a list of colors into blender mat_list = [] if meshInc == 0: i = 0 else: i = colorDatSz[meshInc - 1] colorPal = [color[i]] while i < colorDatSz[meshInc]: j = 0 addColor = 1 while j < len(colorPal): if colorPal[j] == color[i]: addColor = 0 j = j + 1 if addColor == 1: colorPal[len(colorPal):] = [color[i]] i = i + 1 colorPalSz = len(colorPal) i = 0 while i < colorPalSz: mat = bpy.data.materials.new() mat.rgbCol = [float(colorPal[i] & 0x0000FF) / 255,\ float((colorPal[i] & 0x00FF00) >> 8) / 255,\ float((colorPal[i] & 0xFF0000) >> 16) / 255] mat_list.append(mat) mesh.materials = mat_list[:16] i = i + 1 if i == 16: colorPalSz = 16 print "Only 16 colors is allowed." # link the faces with the colors if meshInc == 0: colorArrayPos = 0 else: colorArrayPos = colorDatSz[meshInc - 1] i = 0 while i < len(mesh.faces): j = 0 while j < len(colorPal): if color[colorArrayPos + i] == colorPal[j]: colorNum = j j = j + 1 mesh.faces[i].mat = colorNum i = i + 1 scene.objects.new(mesh) meshInc = meshInc + 1 scene = Blender.Scene.GetCurrent() meshes = [] for ob in scene.objects: obtype = ob.type if obtype == "Mesh": meshes.append(ob) # find the first listed transformation data value i = 0 while i < len(code): if code[0 + i:7 + i] == ["_", "T", "R", "A", "N", "S", "["]: codePos = i + 7 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0 + i:3 + i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 # read the transformation data from the code endOfNum = 0 numCnt = 0 trans = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos + i] == "," or code[codePos + i] == "}": endOfNum = 1 else: num = num + code[codePos + i] i = i + 1 if code[codePos + i] == "}": endOfNum = 2 if endOfNum != 2: codePos = codePos + i trans[len(trans):] = [float(num)] #Read the transformation data from file i = 0 matrix = ob.getMatrix() while i < meshCnt: meshes[meshCnt - 1 - i].rot = [trans[i * 9 + 0], trans[i * 9 + 1], trans[i * 9 + 2]] meshes[meshCnt - 1 - i].loc = [trans[i * 9 + 3], trans[i * 9 + 4], trans[i * 9 + 5]] meshes[meshCnt - 1 - i].size = [ trans[i * 9 + 6], trans[i * 9 + 7], trans[i * 9 + 8] ] i = i + 1
#!BPY import Blender from Blender import Mesh filePath = '/users/u1/vrabaud/SSFM/data/cylinder/coord.txt' out = open(filePath, 'w') for iFrame in range(1, 201): Blender.Set('curframe', iFrame) curve = Blender.Object.Get('Curve') out.write('%i Inf Inf\n' % (iFrame)) mesh = Mesh.New() mesh.getFromObject(curve.name) for vert in mesh.verts: out.write('%f %f %f\n' % (vert.co.x, vert.co.y, vert.co.z)) out.close()
def ImportFromC(file_name): print ("\n" * 2) print ("_" * 20) print ("\n" * 2) print "Beginning import from c script..." print ("\n" * 2) #get header filename from filename print file_name stringParts = file_name.split(".") headerFile_name = "" for i in range(0, len(stringParts)-1): headerFile_name += stringParts[i] headerFile_name += "." headerFile_name += "h" #open and read header file file = open(headerFile_name, "r") code = [l_split for l in file.readlines() for l_split in (' '.join(l.split()),) if l_split] fileLinePos = 0 fileColPos = 0 cDefineNames = [] cDefineValues = [] cDefineCount = 0 print "Finding c defines" while True: # find the listed c defines fileLineCount = len(code) doesExist = False for i in range(0, fileLineCount-fileLinePos): #for (i=0; i < sizeof(code); i++) if code[fileLinePos+i][0:len("#define")] == "#define": fileLinePos += i cDefineCount += 1 doesExist = True break # break the while loop if c defines are not found if doesExist == False: break # find the first underscore fileColCount = len(code[fileLinePos]) for i in range(0, fileColCount): #for (i=0; i < sizeof(code[fileLinePos]); i++) if code[fileLinePos][i] == "_": fileColPos = i+1 break # read c define name after the first underscore cDefName = '' for i in range(0, fileColCount-fileColPos): if code[fileLinePos][fileColPos+i] == " ": fileColPos += i+1 break cDefName += code[fileLinePos][fileColPos+i] cDefineNames.append(cDefName) # read c define value cDefVal = '' for i in range(0, fileColCount-fileColPos): cDefVal += code[fileLinePos][fileColPos+i] cDefineValues.append(int(cDefVal)) fileLinePos += 1 objectNames = [] imageNamesUnderscore = [] imageNames = [] # seperate the c defines into object and image names # find where the image Names are located within c defines imagesLoc = cDefineCount for i in range(1, cDefineCount): if cDefineValues[i] == 0: imagesLoc = i break # get the object names for i in range(0, imagesLoc): objectNames.append(cDefineNames[i]) # get the image names for i in range(imagesLoc, cDefineCount): imgNameUnder = [] for j in range(0, len(cDefineNames[i])): imgNameUnder.append(cDefineNames[i][j]) imageNamesUnderscore.extend([imgNameUnder]) # find the last underscore in each of the image names # and change it to a period for i in range(0, len(imageNamesUnderscore)): for j in range(0, len(imageNamesUnderscore[i])): if imageNamesUnderscore[i][len(imageNamesUnderscore[i])-j-1] == "_": imageNamesUnderscore[i][len(imageNamesUnderscore[i])-j-1] = "." break for i in range(0, len(imageNamesUnderscore)): imgName = '' for j in range(0, len(imageNamesUnderscore[i])): imgName += imageNamesUnderscore[i][j] imageNames.append(imgName) #close header file file.close() #open and read c file file = open(file_name, "r") scene = bpy.data.scenes.active meshes = [] for ob in scene.objects: obtype = ob.type if obtype == "Mesh": meshes.append(ob) fileLines = [l_split for l in file.readlines() for l_split in (' '.join(l.split()),) if l_split] print "Erasing all comments" # erase all of the comments (/* */) i = 0 insideComment = 0 while i < len(fileLines): stopErase = 0 commentStart = fileLines[i].find("/*") if insideComment == 1: commentStart = 0 if fileLines[i].find("//") != -1: if fileLines[i].find("//") < commentStart: stopErase = 1 if stopErase != 1: if commentStart != -1: insideComment = 1 lineEnd = len(fileLines[i]) commentEnd = fileLines[i].find("*/") if commentEnd != -1: if insideComment == 1: commentEnd = fileLines[i].find("*/")+2 insideComment = 0 else: if insideComment == 1: commentEnd = lineEnd if commentStart != -1: if fileLines[i].find("//") != -1: if fileLines[i].find("//") < commentStart: stopErase = 1 if fileLines[i].find("//")+2 < commentEnd: stopErase = 1 if stopErase != 1: fileLines[i] = fileLines[i].replace(fileLines[i][commentStart:commentEnd], "") commentStart = fileLines[i].find("/*") if commentStart == -1: i = i + 1 if stopErase == 1: i = i + 1 # erase all of the comments (//) i = 0 while i < len(fileLines): commentStart = fileLines[i].find("//") commentEnd = len(fileLines[i]) if commentStart != -1: fileLines[i] = fileLines[i].replace(fileLines[i][commentStart:commentEnd], "") i = i + 1 print "Erasing all spaces" # erase all spaces i = 0 while i < len(fileLines): fileLines[i] = fileLines[i].replace(" ", "") i = i + 1 print "Moving code to buffer" # move the data from "fileLines" buffer to "code" buffer ignoring returns i = 0 code = [] while i < len(fileLines): lineEnd = len(fileLines[i]) j = 0 while j < lineEnd: code[len(code):] = fileLines[i][j] j = j + 1 i = i + 1 ################################################################################################## codePos = 0 print "Finding vertex array size" # find the first listed vertex array size i = 0 while i < len(code): if code[0+i:12+i] == ["_", "P", "O", "I", "N", "T", "D", "A", "T", "S", "Z", "["]: codePos = i + 12 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading vertex array sizes" # read the vertex array sizes from the code endOfNum = 0 numCnt = 0 pointDatSz = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": pointDatSz[len(pointDatSz):] = [int(num)] print pointDatSz #number of meshes meshCnt = len(pointDatSz)-1 print "Finding quad array size" # find the first listed quad array size i = 0 while i < len(code): if code[0+i:11+i] == ["_", "Q", "U", "A", "D", "D", "A", "T", "S", "Z", "["]: codePos = i + 11 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading quad array sizes" # read the quad array sizes from the code endOfNum = 0 numCnt = 0 quadDatSz = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": quadDatSz[len(quadDatSz):] = [int(num)] print "Finding tri array size" # find the first listed tri array size i = 0 while i < len(code): if code[0+i:10+i] == ["_", "T", "R", "I", "D", "A", "T", "S", "Z", "["]: codePos = i + 10 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading tri array sizes" # read the tri array sizes from the code endOfNum = 0 numCnt = 0 triDatSz = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": triDatSz[len(triDatSz):] = [int(num)] ################################################################################################## print "Finding fist listed vertex" # find the first listed vertex i = 0 while i < len(code): if code[0+i:7+i] == ["_", "P", "O", "I", "N", "T", "["]: codePos = i + 7 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading verticies" # read the verticies from the code endOfNum = 0 vert = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": vert[len(vert):] = [float(num)] print "Finding first listed quad" # find the first listed quad data number i = 0 while i < len(code): if code[0+i:6+i] == ["_", "Q", "U", "A", "D", "["]: codePos = i + 6 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading quads" # read the quad data from the code endOfNum = 0 quad = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": quad[len(quad):] = [int(num)] print "Finding first listed tri" # find the first listed tri data number i = 0 while i < len(code): if code[0+i:5+i] == ["_", "T", "R", "I", "["]: codePos = i + 5 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading tris" # read the tri data from the code endOfNum = 0 tri = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": tri[len(tri):] = [int(num)] print "Finding first listed vertex color" # find the first listed vertex color data number i = 0 while i < len(code): if code[0+i:8+i] == ["_", "V", "C", "O", "L", "O", "R", "["]: codePos = i + 8 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading vertex color" # read the vertex color data from the code endOfNum = 0 vColor = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": vColor[len(vColor):] = [int(num)] print "Finding first listed texture coordinate" # find the first listed texture coordinate data number i = 0 while i < len(code): if code[0+i:8+i] == ["_", "T", "E", "X", "C", "O", "O", "R", "D", "["]: codePos = i + 8 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading texture coordinates" # read the texture coordinate data from the code endOfNum = 0 texCoord = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": texCoord[len(texCoord):] = [float(num)] print "Finding first listed texture link data" # find the first listed texture link data number i = 0 while i < len(code): if code[0+i:8+i] == ["_", "T", "E", "X", "L", "I", "N", "K", "D", "A", "T", "["]: codePos = i + 8 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 print "Reading texture link data" # read the texture link data from the code endOfNum = 0 texLinkDat = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": texLinkDat[len(texLinkDat):] = [int(num)] ################################################################################################## vColorInc = 0 texCoordInc = 0 for meshInc in range(0, meshCnt): print ("meshInc %i" % (meshInc)) mesh = Mesh.New() print "Importing verticies" # import verticies to blender i = pointDatSz[meshInc] while i < pointDatSz[meshInc+1]: mesh.verts.extend(vert[i],vert[i+1],vert[i+2]) i = i + 3 print "Importing quads" # import quads to blender i = quadDatSz[meshInc] polyBgn = pointDatSz[meshInc] / 3 while i < quadDatSz[meshInc+1]: mesh.faces.extend(quad[i]-polyBgn, quad[i+1]-polyBgn, quad[i+2]-polyBgn, quad[i+3]-polyBgn) i = i + 4 print "Importing tris" # import tris to blender i = triDatSz[meshInc] polyBgn = pointDatSz[meshInc] / 3 while i < triDatSz[meshInc+1]: mesh.faces.extend(tri[i]-polyBgn, tri[i+1]-polyBgn, tri[i+2]-polyBgn) i = i + 3 # enable vertex colors mesh.vertexColors = 1 print "Importing vertex colors" # import vertex colors for quads to blender faceCnt = 0 i = quadDatSz[meshInc] while i < quadDatSz[meshInc+1]: mesh.faces[faceCnt].col[0].r = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[0].g = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[0].b = vColor[vColorInc] vColorInc += 2 mesh.faces[faceCnt].col[1].r = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[1].g = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[1].b = vColor[vColorInc] vColorInc += 2 mesh.faces[faceCnt].col[2].r = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[2].g = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[2].b = vColor[vColorInc] vColorInc += 2 mesh.faces[faceCnt].col[3].r = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[3].g = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[3].b = vColor[vColorInc] vColorInc += 2 faceCnt += 1 i += 4 # import vertex colors for tris to blender i = triDatSz[meshInc] while i < triDatSz[meshInc+1]: mesh.faces[faceCnt].col[0].r = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[0].g = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[0].b = vColor[vColorInc] vColorInc += 2 mesh.faces[faceCnt].col[1].r = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[1].g = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[1].b = vColor[vColorInc] vColorInc += 2 mesh.faces[faceCnt].col[2].r = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[2].g = vColor[vColorInc] vColorInc += 1 mesh.faces[faceCnt].col[2].b = vColor[vColorInc] vColorInc += 2 faceCnt += 1 i += 3 # if object has texture than make "faceUV" true if texLinkDat[meshInc] != -1: mesh.faceUV = True else: mesh.faceUV = False print "Importing texture coordinates" # import texture coordinate for quads to blender uvFaceCnt = 0 i = quadDatSz[meshInc] if texLinkDat[meshInc] != -1: while i < quadDatSz[meshInc+1]: mesh.faces[uvFaceCnt].uv[0].x = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[0].y = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[1].x = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[1].y = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[2].x = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[2].y = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[3].x = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[3].y = texCoord[texCoordInc] texCoordInc += 1 uvFaceCnt += 1 i += 4 else: texCoordInc += (quadDatSz[meshInc+1]-i)/4*8 uvFaceCnt += (quadDatSz[meshInc+1]-i)/4 # import texture coordinate for tris to blender i = triDatSz[meshInc] if texLinkDat[meshInc] != -1: while i < triDatSz[meshInc+1]: mesh.faces[uvFaceCnt].uv[0].x = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[0].y = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[1].x = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[1].y = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[2].x = texCoord[texCoordInc] texCoordInc += 1 mesh.faces[uvFaceCnt].uv[2].y = texCoord[texCoordInc] texCoordInc += 1 uvFaceCnt += 1 i += 3 else: texCoordInc += (triDatSz[meshInc+1]-i)/3*6 uvFaceCnt += (triDatSz[meshInc+1]-i)/3 # import image files to blender print "Importing texture data" tex_dir = Blender.sys.dirname(file_name) + "/texture/" for i in range(0, len(imageNames)): try: imgData = Image.Load(Blender.sys.join(tex_dir, imageNames[i])) except IOError: continue else: if texLinkDat[meshInc] == i: for f in mesh.faces: f.image = imgData scene.objects.new(mesh) ################################################################################################## scene = Blender.Scene.GetCurrent() meshes = [] i = len(objectNames)-1 for ob in scene.objects: obtype = ob.type if obtype == "Mesh": meshes.append(ob) # rename objects if i >= 0: ob.name = objectNames[i] i -= 1 print "Importing trasformation data for each mesh object" # find the first listed transformation data value i = 0 while i < len(code): if code[0+i:7+i] == ["_", "T", "R", "A", "N", "S", "["]: codePos = i + 7 i = len(code) i = i + 1 i = codePos while i < len(code): if code[0+i:3+i] == ["]", "=", "{"]: codePos = i + 3 i = len(code) i = i + 1 # read the transformation data from the code endOfNum = 0 numCnt = 0 trans = [] while endOfNum != 2: i = 0 num = "" endOfNum = 0 while endOfNum == 0: if code[codePos+i] == "," or code[codePos+i] == "}": endOfNum = 1 else: num = num + code[codePos+i] if code[codePos+i] == "}": endOfNum = 2 i = i + 1 if endOfNum != 2: codePos = codePos+i if num != "": trans[len(trans):] = [float(num)] #Read the transformation data from file i = 0 matrix = ob.getMatrix() while i < meshCnt: meshes[meshCnt-1-i].rot = [trans[i*16+0]*math.pi/180.0, trans[i*16+1]*math.pi/180.0, trans[i*16+2]*math.pi/180.0] meshes[meshCnt-1-i].loc = [trans[i*16+3], trans[i*16+4], trans[i*16+5]] meshes[meshCnt-1-i].size = [trans[i*16+6], trans[i*16+7], trans[i*16+8]] i = i + 1 #close c file file.close()
def save_opengl(filename): # Open file f = open(filename + ".c", "w") header_file = open(filename + ".h", "w") bone_file = open(filename + ".bone", "w") print "File %s created and opened. Now exporting..." % filename # Write all the preprocessors in the header file required to # make it work w/ vbo_Utilities.h : header_file.write("#ifndef MODEL_H") header_file.write("\n#define MODEL_H") header_file.write("\n\n#include <GL/gl.h>") header_file.write("\n#include <GL/glu.h>") header_file.write("\n\n#include \"Transformation.h\"") header_file.write("\n\n#include \"vbo_Utilities.h\"") header_file.write("\n\n#include \"bone.h\"") header_file.write( "\n\n// The following is the list of objects that will be exported :") # The actual object names and their estern declarations will be written out in the loop below f.write("#include \"%s.h\"\n\n" % filename) # Which object to export # currently all objects (meshes only - see below) objects = [ob for ob in Object.GetSelected() if ob.getType() == 'Mesh'] obj_index = 0 for obj in objects: nmesh = NMesh.GetRawFromObject(obj.name) header_file.write("\n\nextern CVBO_Model %s;" % (nmesh.name)) f.write("\n// Object: %s" % (nmesh.name)) f.write("\nCVBO_Model %s;" % (nmesh.name)) f.write("\n\nvoid make_%s_vbo_arrays () {" % (nmesh.name)) # Get the list of vertices for the object vertices = nmesh.verts[:] # Get the list of faces for the object faces = nmesh.faces[:] # initialize a refCount array for the vertices refCount_for_vertices = [] for idx in range(len(vertices)): refCount_for_vertices.append(0) # Make one pass through all the faces in the object # to identify all the vertices that will have to be split # into 2 or more vertices if they have different texture coordinates # as part of different faces. Example : vertices along uv-unwrapping_seams. # Naturally, this has to be done only if the mesh uses face-UV textures if nmesh.hasFaceUV(): for face in faces: for idx in range(len(face.v)): vertex_idx = face.v[idx].index if refCount_for_vertices[vertex_idx] == 0: refCount_for_vertices[vertex_idx] = 1 vertices[vertex_idx].uvco.x = face.uv[idx][0] vertices[vertex_idx].uvco.y = face.uv[idx][1] elif face.uv[idx][0] != vertices[ vertex_idx].uvco.x or face.uv[idx][1] != vertices[ vertex_idx].uvco.y: # get a new temp vert of type MyVert newVert = MyVert(0.0, 0.0, 0.0) refCount_for_vertices.append(1) # Copy over relevant stuff to newVert newVert.co = Co(vertices[vertex_idx].co.x, vertices[vertex_idx].co.y, vertices[vertex_idx].co.z) newVert.index = vertices[vertex_idx].index newVert.dup_vertex_index = vertices[vertex_idx].index newVert.no = No(vertices[vertex_idx].no.x, vertices[vertex_idx].no.y, vertices[vertex_idx].no.z) newVert.uvco = Uvco(vertices[vertex_idx].uvco.x, vertices[vertex_idx].uvco.y) # Append it to the list vertices.append(newVert) vertex_idx = len( vertices ) - 1 # new vertex_idx, of the newly appended vertex # Now set the diverged uvco and index at the newly appended vertex vertices[vertex_idx].uvco.x = face.uv[idx][0] vertices[vertex_idx].uvco.y = face.uv[idx][1] vertices[vertex_idx].index = vertex_idx # And, set the face's v to point to this newly appended vertex face.v[idx] = vertices[vertex_idx] numVerts = len(vertices) f.write("\n\tint numVertices = %d;\n" % numVerts) # Write out the list of vertices for the object f.write("\n\t// List of vertices for object %s" % (nmesh.name)) f.write("\n\tGLfloat vertices[] = {") for vertex in vertices: f.write("\n\t\t%f,\t%f,\t%f,\t1.0000," % (vertex.co.x, vertex.co.y, vertex.co.z)) f.write("\t\t// index : %d" % (vertex.index)) f.write("\n\t};") f.write( "\n\t%s.bulk_init_vertices (numVertices, (vec4 *)vertices);\n\n" % (nmesh.name)) # Write out the texture coordinates for the object if nmesh.hasFaceUV(): f.write("\n\t// List of texture_coords for object %s" % (nmesh.name)) f.write("\n\tGLfloat textures[] = {") for vertex in vertices: f.write("\n\t\t%f,\t%f," % (vertex.uvco.x, vertex.uvco.y)) f.write("\t\t// index : %d" % (vertex.index)) f.write("\n\t};") f.write( "\n\t%s.bulk_init_textures (numVertices, (vec2 *)textures);\n\n" % (nmesh.name)) # Write out the normals for the object f.write("\n\t// List of normals for object %s" % (nmesh.name)) f.write("\n\tGLfloat normals[] = {") for vertex in vertices: f.write("\n\t\t%f,\t%f,\t%f," % (vertex.no.x, vertex.no.y, vertex.no.z)) f.write("\t\t// index : %d" % (vertex.index)) f.write("\n\t};") f.write( "\n\t%s.bulk_init_normals (numVertices, (vec3 *)normals);\n\n" % (nmesh.name)) numFaces = 0 for face in nmesh.faces: numFaces = numFaces + 1 if len( face.v ) == 4: # , because quads will be exported as 2 triangles (see below) numFaces = numFaces + 1 f.write("\n\tint numFaces = %d;\n" % numFaces) # Write out the indices to form each face of the object f.write("\n\tGLuint indices[] = {") for face in nmesh.faces: f.write("\n\t\t") f.write("%d, " % face.v[0].index) f.write("%d, " % face.v[1].index) f.write("%d, " % face.v[2].index) if len(face.v) == 4: f.write("\n\t\t") f.write("%d, " % face.v[3].index) f.write("%d, " % face.v[0].index) f.write("%d, " % face.v[2].index) f.write("\n\t};") f.write("\n\t%s.bulk_init_indices (numFaces, (GLuint *)indices);\n\n" % (nmesh.name)) #translation locx = 0 locy = 0 locz = 0 if obj.LocX > 0.0001 or obj.LocX < -0.0001: locx = obj.LocX if obj.LocY > 0.0001 or obj.LocY < -0.0001: locy = obj.LocY if obj.LocZ > 0.0001 or obj.LocZ < -0.0001: locz = obj.LocZ f.write("\n\t%s.locX = %f;" % (nmesh.name, locx)) f.write("\n\t%s.locY = %f;" % (nmesh.name, locy)) f.write("\n\t%s.locZ = %f;" % (nmesh.name, locz)) f.write("\n\treturn;") f.write("\n}") # Bone stuff mesh = Mesh.Get(obj.name) obj.link(mesh) f.write("\n\n// Object : %s " % (mesh.name)) numRealVerts = len(mesh.verts) armatures = Armature.Get() # type: dict armature_names = armatures.keys() for armature_name in armature_names: f.write("\n// Armature %s, being used by %d users" % (armature_name, armatures[armature_name].users)) if armatures[ armature_name].users > 0: # being used by at least 1 user (helps discard deleted armatures which are (for some reason) still lying around in Blender) armature = armatures[armature_name] bones = armature.bones # type: dict bone_names = bones.keys() for bone_name in bone_names: # loop over all bones bone = bones[bone_name] f.write("\n\nBone %s;" % bone.name) header_file.write("\nextern Bone %s;" % bone.name) f.write("\n\nvoid init_%s_bone_influences () {" % bone.name) f.write("\n\tInfluence influences[] = {") num_influences = 0 for vertex_idx in range( numVerts ): # loop over all vertices, looking for The bone's influences # bone_file.write("\nindex : %d " % (vertex_idx)) if vertex_idx < numRealVerts: for influence in mesh.getVertexInfluences( vertex_idx): if influence[0] == bone.name: # bone_file.write("\n %s, %f" % (influence[0], influence[1])) f.write("\n\t\tInfluence(%d, %f)," % (vertex_idx, influence[1])) num_influences = num_influences + 1 elif vertex_idx >= numRealVerts: for influence in mesh.getVertexInfluences( vertices[vertex_idx].dup_vertex_index): if influence[0] == bone.name: # bone_file.write("\n %s, %f" % (influence[0], influence[1])) f.write("\n\t\tInfluence(%d, %f)," % (vertex_idx, influence[1])) num_influences = num_influences + 1 f.write("\n\t};") f.write("\n\n\t%s.bulkInitInfluences (%d, influences);" % (bone.name, num_influences)) f.write("\n\t%s.name = \"%s\";" % (bone.name, bone.name)) f.write("\n\n\treturn;") f.write("\n};\n") obj_index += 1 header_file.write("\n\nvoid initialize_all_models ();") header_file.write("\nvoid ready_all_models_for_render ();") f.write("\n\nvoid initialize_all_models () {") for obj in objects: nmesh = NMesh.GetRawFromObject(obj.name) f.write("\n\n\tmake_%s_vbo_arrays ();" % (nmesh.name)) f.write("\n\t%s.setTexture (\"./cube_texture_test.png\", PNG);" % nmesh.name) f.write("\n\t%s.setMatColor (0.2, 0.3, 0.4, 1.0);" % nmesh.name) # Bone stuff : armatures = Armature.Get() # type: dict armature_names = armatures.keys() for armature_name in armature_names: if armatures[ armature_name].users > 0: # being used by at least 1 user (helps discard deleted armatures which are (for some reason) still lying around in Blender) armature = armatures[armature_name] bones = armature.bones # type: dict bone_names = bones.keys() for bone_name in bone_names: # loop over all bones bone = bones[bone_name] f.write("\n\tinit_%s_bone_influences ();" % bone.name) f.write("\n\t%s.setVBO (&%s);" % (bone.name, obj.name)) f.write("\n\t%s.addBone (&%s);" % (obj.name, bone.name)) f.write("\n\n\treturn;\n}\n") f.write("\n\nvoid ready_all_models_for_render () {") for obj in objects: nmesh = NMesh.GetRawFromObject(obj.name) f.write("\n\t%s.make_ready_for_render ();" % nmesh.name) f.write("\n\n\treturn;\n}\n\n") header_file.write("\n\n#endif\n\n") print "Export complete" f.close()
def doimport(self): h1 = self.m.TXT_str_scan_space() self.m.TXT_str_scan_eoln() v = self.m.TXT_int_scan() self.m.TXT_str_scan_eoln() h2 = self.m.TXT_str_scan_space() self.m.TXT_str_scan_eoln() if h1.upper() != 'A' and h1.upper() != 'I': raise ParseError(ParseError.MISC, "Bad header, must be A or I") if v != 800: raise ParseError(ParseError.MISC, "Bad version, must be 800") if h2.upper() != 'ROADS': raise ParseError(ParseError.MISC, "Bad header, file class must be ROADS") header = [] footer = [] dir = os.path.dirname(self.filename) last_name = '' while not self.m.TXT_is_done(): t = self.m.TXT_str_scan_space() if t in [ '#SHADER', 'TEXTURE', 'TEXTURE_LIT', 'TEXTURE_NORMAL', 'NO_BLEND', 'ONE_SIDED', 'SPECULAR', 'DECAL', 'DECAL_RGBA', 'DECAL_KEYED', 'DECAL_PARAMS', 'DECAL_LIB', 'NO_APHA', 'DITHER_ALPHA', 'TEXTURE_TILE', 'TEXTURE_DETAIL', 'TEXTURE_CONTROL', 'TEXTURE_TERRAIN', 'VARIANTS', 'CAR_MODEL', 'TRAIN', 'TRAIN_VARIANT', 'TRAIN_CAR' ]: t += ' ' t += self.m.TXT_str_scan_eoln() if self.shaders.is_shader_line(t): self.shaders.handle_shader_line(t) header.append(t) elif t in ['ROAD_DRAPED', 'ROAD_DRAPE_CHOICE', '#VROAD']: t += ' ' t += self.m.TXT_str_scan_eoln() footer.append(t) elif t == 'SCALE': self.scale = self.m.TXT_flt_scan() self.m.TXT_str_scan_eoln() elif t == '#ROAD': last_name = self.m.TXT_str_scan_eoln() elif t == 'ROAD_TYPE': self.shaders.load_all_images(dir) id = self.m.TXT_str_scan_space() self.chain = Blender.Object.New('Empty', 'ROA%s.%s' % (id, last_name)) self.chain_width = self.m.TXT_flt_scan() self.chain_length = self.m.TXT_flt_scan() self.shader_idx = self.m.TXT_int_scan() self.chain_center = self.chain_width * 0.5 prop_import(self.chain, 'RGB', self.m.TXT_str_scan_eoln()) prop_import(self.chain, 'NAME', last_name) Blender.Scene.GetCurrent().objects.link(self.chain) num_id = int(id) core = num_id / 1000 grad = num_id % 10 side = (num_id / 100) % 10 self.chain.setLocation(core * 100, (side * 5 + grad) * 200, 0) elif t == 'ROAD_CENTER': self.chain_center = self.m.TXT_flt_scan() self.m.TXT_str_scan_eoln() elif t in ['SHOW_LEVEL', 'REQUIRE_EVEN']: prop_import(self.chain, t, self.m.TXT_str_scan_eoln()) elif t == 'SEGMENT_GRADED' or t == 'SEGMENT_DRAPED': shader_idx = self.m.TXT_int_scan() near_lod = self.m.TXT_flt_scan() far_lod = self.m.TXT_flt_scan() t_scale = self.m.TXT_flt_scan() x1 = self.m.TXT_flt_scan() - self.chain_center if t == 'SEGMENT_GRADED': y1 = self.m.TXT_flt_scan() else: y1 = draped_y s1 = self.m.TXT_flt_scan() / self.scale x2 = self.m.TXT_flt_scan() - self.chain_center if t == 'SEGMENT_GRADED': y2 = self.m.TXT_flt_scan() else: y2 = draped_y s2 = self.m.TXT_flt_scan() / self.scale surf = self.m.TXT_str_scan_space_optional() self.m.TXT_str_scan_eoln() nm = Mesh.New() verts = [[x1, 0, y1], [x2, 0, y2], [x2, self.chain_length, y2], [x1, self.chain_length, y1]] loc = self.chain.getLocation('localspace') #for v in verts: # v[0] += loc[0] # v[1] += loc[1] # v[2] += loc[2] faces = [[0, 1, 2, 3]] nm.verts.extend(verts) nm.faces.extend(faces) nm.faceUV = 1 my_img = self.shaders.material_for_idx(shader_idx) # append won't work, materials is returned by value or somethign silly. nm.materials += [my_img] for f in nm.faces: f.image = my_img.textures[0].tex.image f.mode |= Mesh.FaceModes.TEX f.transp = Mesh.FaceTranspModes.ALPHA if t == 'SEGMENT_DRAPED': f.mode |= Mesh.FaceModes.TILES if self.shaders.poly_os_for_idx(shader_idx) == 0: print "WARNING: draped segment has non-draped shader." else: if self.shaders.poly_os_for_idx(shader_idx) > 0: print "WARNING: draped segment has non-draped shader." f.uv[0][0] = s1 f.uv[1][0] = s2 f.uv[2][0] = s2 f.uv[3][0] = s1 f.uv[0][1] = 0 f.uv[1][1] = 0 f.uv[2][1] = t_scale f.uv[3][1] = t_scale f.mat = nm.materials.index(my_img) ob = Object.New('Mesh', "%d" % shader_idx) ob.setLocation(loc[0], loc[1], loc[2]) Blender.Scene.GetCurrent().objects.link(ob) ob.link(nm) kids = [] kids.append(ob) self.chain.makeParent(kids, 1, 1) elif t == 'WIRE': lod_near = self.m.TXT_flt_scan() lod_far = self.m.TXT_flt_scan() dx = self.m.TXT_flt_scan( ) * self.chain_width - self.chain_center y = self.m.TXT_flt_scan() droop = self.m.TXT_flt_scan() nm = Mesh.New() verts = [[dx, 0, y * droop], [dx, 0, y], [dx, self.chain_length, y], [dx, self.chain_length, y * droop]] faces = [[0, 1, 2, 3]] loc = self.chain.getLocation('localspace') #for v in verts: # v[0] += loc[0] # v[1] += loc[1] # v[2] += loc[2] nm.verts.extend(verts) nm.faces.extend(faces) nm.faceUV = 1 for f in nm.faces: f.mode |= Mesh.FaceModes.TWOSIDE ob = Object.New('Mesh', "wire") ob.setLocation(loc[0], loc[1], loc[2]) Blender.Scene.GetCurrent().objects.link(ob) ob.link(nm) kids = [] kids.append(ob) self.chain.makeParent(kids, 1, 1) self.m.TXT_str_scan_eoln() else: self.m.TXT_str_scan_eoln() h = TEXT_create_or_clear('header') f = TEXT_create_or_clear('footer') for l in header: h.write("%s\n" % l) for l in footer: f.write("%s\n" % l)
def __init__(self, scene_objects, file): global ARG, SKIP_DATA, ADD_DEFAULT_MAT, DEFAULT_MAT header = 'AC3Db' self.file = file self.buf = '' self.mbuf = [] self.mlist = [] world_kids = 0 parents_list = self.parents_list = [] kids_dict = self.kids_dict = {} objs = [] exp_objs = self.exp_objs = [] tree = {} file.write(header+'\n') objs = \ [o for o in scene_objects if o.type in ['Mesh', 'Empty']] # create a tree from parents to children objects for obj in objs[:]: parent = obj.parent lineage = [obj] while parent: parents_list.append(parent.name) obj = parent parent = parent.getParent() lineage.insert(0, obj) d = tree for i in xrange(len(lineage)): lname = lineage[i].getType()[:2] + lineage[i].name if lname not in d.keys(): d[lname] = {} d = d[lname] # traverse the tree to get an ordered list of names of objects to export self.traverse_dict(tree) world_kids = len(tree.keys()) # get list of objects to export, start writing the .ac file objlist = [Object.Get(name) for name in exp_objs] meshlist = [o for o in objlist if o.type == 'Mesh'] # create a temporary mesh to hold actual (modified) mesh data TMP_mesh = Mesh.New('tmp_for_ac_export') # write materials self.MATERIALS(meshlist, TMP_mesh) mbuf = self.mbuf if not mbuf or ADD_DEFAULT_MAT: mbuf.insert(0, "%s\n" % DEFAULT_MAT) mbuf = "".join(mbuf) file.write(mbuf) file.write('OBJECT world\nkids %s\n' % world_kids) # write the objects for obj in objlist: self.obj = obj objtype = obj.type objname = obj.name kidsnum = kids_dict[objname] # A parent plus its children are exported as a group. # If the parent is a mesh, its rot and loc are exported as the # group rot and loc and the mesh (w/o rot and loc) is added to the group. if kidsnum: self.OBJECT('group') self.name(objname) if objtype == 'Mesh': kidsnum += 1 if not GLOBAL_COORDS: localmatrix = obj.getMatrix('localspace') if not obj.getParent(): localmatrix *= BLEND_TO_AC3D_MATRIX self.rot(localmatrix.rotationPart()) self.loc(localmatrix.translationPart()) self.kids(kidsnum) if objtype == 'Mesh': mesh = TMP_mesh # temporary mesh to hold actual (modified) mesh data mesh.getFromObject(objname) self.mesh = mesh if mesh.faceUV: meshes = self.split_mesh(mesh) else: meshes = [mesh] if len(meshes) > 1: if NO_SPLIT or self.dont_split(objname): self.export_mesh(mesh, ob) REPORT_DATA['nosplit'].append(objname) else: self.OBJECT('group') self.name(objname) self.kids(len(meshes)) counter = 0 for me in meshes: self.export_mesh(me, obj, name = '%s_%s' % (obj.name, counter), foomesh = True) self.kids() counter += 1 else: self.export_mesh(mesh, obj) self.kids()
def export(self, scene, world, alltextures,\ EXPORT_APPLY_MODIFIERS = False,\ EXPORT_TRI= False,\ ): print "Info: starting X3D export to " + self.filename + "..." self.writeHeader() # self.writeScript() self.writeNavigationInfo(scene) self.writeBackground(world, alltextures) self.writeFog(world) self.proto = 0 # COPIED FROM OBJ EXPORTER if EXPORT_APPLY_MODIFIERS: temp_mesh_name = '~tmp-mesh' # Get the container mesh. - used for applying modifiers and non mesh objects. containerMesh = meshName = tempMesh = None for meshName in Blender.NMesh.GetNames(): if meshName.startswith(temp_mesh_name): tempMesh = Mesh.Get(meshName) if not tempMesh.users: containerMesh = tempMesh if not containerMesh: containerMesh = Mesh.New(temp_mesh_name) # -------------------------- for ob_main in scene.objects.context: for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): objType = ob.type objName = ob.name self.matonly = 0 if objType == "Camera": self.writeViewpoint(ob, ob_mat, scene) elif objType in ("Mesh", "Curve", "Surf", "Text"): if EXPORT_APPLY_MODIFIERS or objType != 'Mesh': me = BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene) else: me = ob.getData(mesh=1) self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI=EXPORT_TRI) elif objType == "Lamp": data = ob.data datatype = data.type if datatype == Lamp.Types.Lamp: self.writePointLight(ob, ob_mat, data, world) elif datatype == Lamp.Types.Spot: self.writeSpotLight(ob, ob_mat, data, world) elif datatype == Lamp.Types.Sun: self.writeDirectionalLight(ob, ob_mat, data, world) else: self.writeDirectionalLight(ob, ob_mat, data, world) # do you think x3d could document what to do with dummy objects? #elif objType == "Empty" and objName != "Empty": # self.writeNode(ob, ob_mat) else: #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType) pass self.file.write("\n</Scene>\n</X3D>") if EXPORT_APPLY_MODIFIERS: if containerMesh: containerMesh.verts = None self.cleanup()
def geometry_to_blender(geom, bld_mesh=None, discretizer=None): """Create a blender mesh Paint the faces too if needed :Parameters: - `geom` (pgl.Geometry) - the geometry to transform - `bld_mesh` (Mesh) - a mesh in which to append the shape. If None, a blank new one will be created - `discretizer` (Discretizer) - algorithm to triangulate the geometry :Returns Type: Mesh """ #create bld_mesh if bld_mesh is None: if geom.isNamed(): name = geom.name else: name = "pglgeom%d" % geom.getId() bld_mesh = Mesh.New(name) #geometry (mesh) if discretizer is None: d = Discretizer() else: d = discretizer geom.apply(d) geom = d.result #fill mesh pts = array(geom.pointList) nbv = len(bld_mesh.verts) faces = nbv + array(geom.indexList) bld_mesh.verts.extend(pts) nbf = len(bld_mesh.faces) bld_mesh.faces.extend(faces.tolist()) #set vertex colors if needed mat = None if not geom.isColorListToDefault(): bld_mesh.vertexColors = True #create material to render mesh colors try: mat = Material.Get("default_vtx_mat") except NameError: mat = Material.New("default_vtx_mat") mat.mode += Material.Modes['VCOL_PAINT'] bld_mesh.materials = [mat] #modify color list to duplicate colors per face per vertex if geom.colorPerVertex and geom.isColorIndexListToDefault(): #each vertex has a color for i, inds in enumerate(faces): face = bld_mesh.faces[nbf + i] for j, v in enumerate(face): col = face.col[j] pglcol = geom.colorList[geom.indexList[i][j]] col.r = pglcol.red col.g = pglcol.green col.b = pglcol.blue col.a = pglcol.alpha elif geom.colorPerVertex and not geom.isColorIndexListToDefault(): #each local vertex of each face has a color for i, inds in enumerate(geom.colorIndexList): face = bld_mesh.faces[nbf + i] for j, v in enumerate(face): col = face.col[j] pglcol = geom.colorList[inds[j]] col.r = pglcol.red col.g = pglcol.green col.b = pglcol.blue col.a = pglcol.alpha else: #each face has a color for i, col in enumerate(geom.colorList): face = bld_mesh.faces[nbf + i] R, G, B, A = col.red, col.green, col.blue, col.alpha for j, v in enumerate(face): col = face.col[j] col.r = R col.g = G col.b = B col.a = A # #assign # for fid in xrange(nb,len(bld_mesh.faces) ) : # face = bld_mesh.faces[fid] # for i,v in enumerate(face) : # col = face.col[i] # col.r = ambient.red # col.g = ambient.green # col.b = ambient.blue # for vtx in bld_mesh.verts : # vtx.sel = 0 #return return bld_mesh, mat
def PolyDataMapperToBlender(pmapper, me=None): global flags faces = [] edges = [] oldmats = None newmesh = 0 if (me == None): me = Mesh.New() newmesh = 1 else: if me.materials: oldmats = me.materials me.verts = None # this kills the faces/edges tooo pmapper.Update() pdata = pmapper.GetInput() plut = pmapper.GetLookupTable() #print pdata.GetNumberOfCells() scalars = pdata.GetPointData().GetScalars() verts = [] for i in range(pdata.GetNumberOfPoints()): point = pdata.GetPoint(i) verts.append([point[0], point[1], point[2]]) me.verts.extend(verts) # I think we can free some memory by killing the reference # from vert to the list it points at (not sure though) verts = [] colors = None if ((scalars != None) and (plut != None)): colors = [] # Have to be a bit careful since VTK 5.0 changed the # prototype of vtkLookupTable.GetColor() try: # VTK 5.x scolor = [0, 0, 0] for i in range(scalars.GetNumberOfTuples()): plut.GetColor(scalars.GetTuple1(i), scolor) color = map(VTKToBlenderColor, scolor) alpha = int(plut.GetOpacity(scalars.GetTuple1(i)) * 255) colors.append([color[0], color[1], color[2], alpha]) except: # VTK 4.x for i in range(scalars.GetNumberOfTuples()): color = map(VTKToBlenderColor, \ plut.GetColor(scalars.GetTuple1(i))) alpha = int(plut.GetOpacity(scalars.GetTuple1(i)) * 255) colors.append([color[0], color[1], color[2], alpha]) skiptriangle = False for i in range(pdata.GetNumberOfCells()): cell = pdata.GetCell(i) #print i, pdata.GetCellType(i) # Do lines if pdata.GetCellType(i) == 3: n1 = cell.GetPointId(0) n2 = cell.GetPointId(1) BlenderAddEdge(me, edges, n1, n2) # Do poly lines if pdata.GetCellType(i) == 4: for j in range(cell.GetNumberOfPoints() - 1): n1 = cell.GetPointId(j) n2 = cell.GetPointId(j + 1) BlenderAddEdge(me, edges, n1, n2) # Do triangles if pdata.GetCellType(i) == 5: if skiptriangle == True: skiptriangle = False elif ((flags & TRIS_TO_QUADS) and (i < pdata.GetNumberOfCells() - 1) and (pdata.GetCellType(i + 1) == 5)): n1 = cell.GetPointId(0) n2 = cell.GetPointId(1) n3 = cell.GetPointId(2) nextcell = pdata.GetCell(i + 1) m1 = nextcell.GetPointId(0) m2 = nextcell.GetPointId(1) m3 = nextcell.GetPointId(2) if ((n2 == m3) and (n3 == m2)): BlenderAddFace(me, faces, n1, n2, m1, n3) skiptriangle = True else: BlenderAddFace(me, faces, n1, n2, n3) else: n1 = cell.GetPointId(0) n2 = cell.GetPointId(1) n3 = cell.GetPointId(2) BlenderAddFace(me, faces, n1, n2, n3) # Do triangle strips if pdata.GetCellType(i) == 6: numpoints = cell.GetNumberOfPoints() if ((flags & TRIS_TO_QUADS) and (numpoints % 2 == 0)): for j in range(cell.GetNumberOfPoints() - 3): if (j % 2 == 0): n1 = cell.GetPointId(j) n2 = cell.GetPointId(j + 1) n3 = cell.GetPointId(j + 2) n4 = cell.GetPointId(j + 3) BlenderAddFace(me, faces, n1, n2, n4, n3) else: for j in range(cell.GetNumberOfPoints() - 2): if (j % 2 == 0): n1 = cell.GetPointId(j) n2 = cell.GetPointId(j + 1) n3 = cell.GetPointId(j + 2) else: n1 = cell.GetPointId(j) n2 = cell.GetPointId(j + 2) n3 = cell.GetPointId(j + 1) BlenderAddFace(me, faces, n1, n2, n3) # Do polygon if pdata.GetCellType(i) == 7: # Add a vert at the center of the polygon, # and break into triangles x = 0.0 y = 0.0 z = 0.0 scal = 0.0 N = cell.GetNumberOfPoints() for j in range(N): point = pdata.GetPoint(cell.GetPointId(j)) x = x + point[0] y = y + point[1] z = z + point[2] if (scalars != None): scal = scal + scalars.GetTuple1(j) x = x / N y = y / N z = z / N scal = scal / N newidx = len(me.verts) me.verts.extend(x, y, z) if (scalars != None): try: # VTK 5.x scolor = [0, 0, 0] plut.GetColor(scal, scolor) color = map(VTKToBlenderColor, scolor) except: color = map(VTKToBlenderColor, plut.GetColor(scal)) alpha = int(plut.GetOpacity(scalars.GetTuple1(i)) * 255) colors.append([color[0], color[1], color[2], alpha]) # Add triangles connecting polynomial sides to new vert for j in range(N): n1 = cell.GetPointId(j) n2 = cell.GetPointId((j + 1) % N) n3 = newidx BlenderAddFace(me, faces, n1, n2, n3) # Do pixel if pdata.GetCellType(i) == 8: n1 = cell.GetPointId(0) n2 = cell.GetPointId(1) n3 = cell.GetPointId(2) n4 = cell.GetPointId(3) BlenderAddFace(me, faces, n1, n2, n3, n4) # Do quad if pdata.GetCellType(i) == 9: n1 = cell.GetPointId(0) n2 = cell.GetPointId(1) n3 = cell.GetPointId(2) n4 = cell.GetPointId(3) BlenderAddFace(me, faces, n1, n2, n3, n4) if len(edges) > 0: me.edges.extend(edges) if len(faces) > 0: me.faces.extend(faces) if (flags & SMOOTH_FACES): for f in me.faces: f.smooth = 1 # Some faces in me.faces may have been discarded from our # list, so best to compute the vertex colors after the faces # have been added to the mesh if (colors != None): me.vertexColors = 1 for f in me.faces: f_col = [] for v in f.v: f_col.append(colors[v.index]) SetVColors(f.col, f_col) if not me.materials: if oldmats: me.materials = oldmats else: newmat = Material.New() if (colors != None): newmat.mode |= Material.Modes.VCOL_PAINT me.materials = [newmat] if (newmesh == 0): me.update() return me
def loadTri(filename): if BPyMessages.Error_NoFile(filename): return importMenu() print('\nImporting tri: "%s"' % (Blender.sys.expandpath(filename))) istrm = open(filename, 'rb') data = TriFormat.Data() data.inspect(istrm) data.read(istrm) istrm.close() print("\nTRI version 0x%x | Ve:%d | Fa:%d | UV:%d |" % (data.version, data.num_vertices, data.num_tri_faces, data.num_uvs)) print("Num Morphs:%d | Num Modifiers:%d\n" % (data.num_morphs, data.num_modifiers)) name = filename.split('\\')[-1].split('/')[-1] scn = bpy.data.scenes.active mesh = Mesh.New() # vertex verts_list = [(v.x, v.y, v.z) for v in data.vertices] if ROTATE_X90: verts_list[:] = [(v[0], -v[2], v[1]) for v in verts_list] mesh.verts.extend(verts_list) # face face_list = [(f.v_1, f.v_2, f.v_3) for f in data.tri_faces] mesh.faces.extend(face_list) del face_list # UV if data.num_uvs > 0: mesh.faceUV = True for i, face in enumerate(mesh.faces): utf = data.uv_tri_faces[i] idx = [utf.v_1, utf.v_2, utf.v_3] for ii, j in enumerate(face): uv = data.uvs[idx[ii]] face.uv[ii].x = uv.u face.uv[ii].y = uv.v ob = scn.objects.new(mesh, name) # Shape Keys if (data.num_morphs > 0 and INPORT_MORPH_SHAPE) or (data.num_modifiers > 0 and INPORT_MODIFIERS_SHAPE): mesh.insertKey(1, 'relative') if INPORT_MORPH_SHAPE: for morph in data.morphs: morphName = str(morph.name.decode("ascii")) scale = morph.scale print("... Morhph:" + morphName) for i, nv in enumerate(mesh.verts): verts_morph = morph.vertices[i] v3 = [verts_morph.x, verts_morph.y, verts_morph.z] if ROTATE_X90: v3 = [v3[0], -v3[2], v3[1]] nv.co[0] = verts_list[i][0] + v3[0] * scale nv.co[1] = verts_list[i][1] + v3[1] * scale nv.co[2] = verts_list[i][2] + v3[2] * scale mesh.insertKey(1, 'relative') mesh.key.blocks[-1].name = morphName if INPORT_MODIFIER_SHAPE: for modifier in data.modifiers: modifierName = str(modifier.name.decode("ascii")) print("... Modifier:" + modifierName) for i, nv in enumerate(mesh.verts): nv.co[0] = verts_list[i][0] nv.co[1] = verts_list[i][1] nv.co[2] = verts_list[i][2] for i, n in enumerate(modifier.vertices_to_modify): nv = mesh.verts[n] mv = modifier.modifier_vertices[i] v3 = [mv.x, mv.y, mv.z] if ROTATE_X90: v3 = [v3[0], -v3[2], v3[1]] nv.co[0] = v3[0] nv.co[1] = v3[1] nv.co[2] = v3[2] mesh.insertKey(1, 'relative') mesh.key.blocks[-1].name = modifierName for i, nv in enumerate(mesh.verts): nv.co[0] = verts_list[i][0] nv.co[1] = verts_list[i][1] nv.co[2] = verts_list[i][2] del verts_list print("done.")
def main(): scn = Scene.GetCurrent() act_ob = scn.getActiveObject() if act_ob.getType() != 'Mesh': act_ob = None sel = [ ob for ob in Object.GetSelected() if ob.getType() == 'Mesh' if ob != act_ob ] if not sel and not act_ob: Draw.PupMenu('Error, select a mesh as your active object') return # Defaults PREF_EDITMESH_ONLY = Draw.Create(1) PREF_MIRROR_LOCATION = Draw.Create(1) PREF_XMID_SNAP = Draw.Create(1) PREF_MAX_DIST = Draw.Create(0.02) PREF_XZERO_THRESH = Draw.Create(0.002) #PREF_MODE= Draw.Create(0) # THIS IS TOOO CONFUSING, HAVE 2 BUTTONS AND MAKE THE MODE FROM THEM. PREF_MODE_L2R = Draw.Create(1) PREF_MODE_R2L = Draw.Create(0) PREF_SEL_ONLY = Draw.Create(1) PREF_EDGE_USERS = Draw.Create(0) # Weights PREF_MIRROR_WEIGHTS = Draw.Create(0) PREF_FLIP_NAMES = Draw.Create(1) PREF_CREATE_FLIP_NAMES = Draw.Create(1) pup_block = [\ ('EditMesh Only', PREF_EDITMESH_ONLY, 'If disabled, will mirror all selected meshes.'),\ 'Left (-), Right (+)',\ ('Left > Right', PREF_MODE_L2R, 'Copy from the Left to Right of the mesh. Enable Both for a mid loc/weight.'),\ ('Right > Left', PREF_MODE_R2L, 'Copy from the Right to Left of the mesh. Enable Both for a mid loc/weight.'),\ '',\ ('MaxDist:', PREF_MAX_DIST, 0.0, 1.0, 'Generate interpolated verts so closer vert weights can be copied.'),\ ('XZero limit:', PREF_XZERO_THRESH, 0.0, 1.0, 'Mirror verts above this distance from the middle, else lock to X/zero.'),\ ('Sel Verts Only', PREF_SEL_ONLY, 'Only mirror selected verts. Else try and mirror all'),\ ('Edge Users', PREF_EDGE_USERS, 'Only match up verts that have the same number of edge users.'),\ 'Location Prefs',\ ('Mirror Location', PREF_MIRROR_LOCATION, 'Mirror vertex locations.'),\ ('XMidSnap Verts', PREF_XMID_SNAP, 'Snap middle verts to X Zero (uses XZero limit)'),\ 'Weight Prefs',\ ('Mirror Weights', PREF_MIRROR_WEIGHTS, 'Mirror vertex locations.'),\ ('Flip Groups', PREF_FLIP_NAMES, 'Mirror flip names.'),\ ('New Flip Groups', PREF_CREATE_FLIP_NAMES, 'Make new groups for flipped names.'),\ ] if not Draw.PupBlock("X Mirror mesh tool", pup_block): return # WORK OUT THE MODE 0 # PREF_MODE, 0:middle, 1: Left. 2:Right. PREF_MODE_R2L = PREF_MODE_R2L.val PREF_MODE_L2R = PREF_MODE_L2R.val if PREF_MODE_R2L and PREF_MODE_L2R: PREF_MODE = 0 # Middle elif not PREF_MODE_R2L and PREF_MODE_L2R: PREF_MODE = 1 # Left to Right elif PREF_MODE_R2L and not PREF_MODE_L2R: PREF_MODE = 2 # Right to Left else: # Neither Selected. Do middle anyway PREF_MODE = 0 PREF_EDITMESH_ONLY = PREF_EDITMESH_ONLY.val PREF_MIRROR_LOCATION = PREF_MIRROR_LOCATION.val PREF_XMID_SNAP = PREF_XMID_SNAP.val PREF_MAX_DIST = PREF_MAX_DIST.val PREF_XZERO_THRESH = PREF_XZERO_THRESH.val PREF_SEL_ONLY = PREF_SEL_ONLY.val PREF_EDGE_USERS = PREF_EDGE_USERS.val # weights PREF_MIRROR_WEIGHTS = PREF_MIRROR_WEIGHTS.val PREF_FLIP_NAMES = PREF_FLIP_NAMES.val PREF_CREATE_FLIP_NAMES = PREF_CREATE_FLIP_NAMES.val t = sys.time() is_editmode = Window.EditMode() # Exit Editmode. if is_editmode: Window.EditMode(0) Mesh.Mode(Mesh.SelectModes['VERTEX']) Window.WaitCursor(1) if act_ob: mesh_mirror(act_ob.getData(mesh=1), PREF_MIRROR_LOCATION, PREF_XMID_SNAP, PREF_MAX_DIST, PREF_XZERO_THRESH, PREF_MODE, PREF_SEL_ONLY, PREF_EDGE_USERS, PREF_MIRROR_WEIGHTS, PREF_FLIP_NAMES, PREF_CREATE_FLIP_NAMES) if (not PREF_EDITMESH_ONLY) and sel: for ob in sel: mesh_mirror(ob.getData(mesh=1), PREF_MIRROR_LOCATION, PREF_XMID_SNAP, PREF_MAX_DIST, PREF_XZERO_THRESH, PREF_MODE, PREF_SEL_ONLY, PREF_EDGE_USERS, PREF_MIRROR_WEIGHTS, PREF_FLIP_NAMES, PREF_CREATE_FLIP_NAMES) if is_editmode: Window.EditMode(1) Window.WaitCursor(0) Window.DrawProgressBar(1.0, '') Window.RedrawAll() print 'Mirror done in %.6f sec.' % (sys.time() - t)
def write(filename, objects,\ EXPORT_NORMALS_HQ=False,\ EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ EXPORT_APPLY_MODIFIERS=True, EXPORT_BLEN_OBS=True,\ EXPORT_GROUP_BY_OB=False): ''' Basic write function. The context and options must be alredy set This can be accessed externaly eg. write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options. ''' def veckey3d(v): return round(v.x, 6), round(v.y, 6), round(v.z, 6) def veckey2d(v): return round(v.x, 6), round(v.y, 6) print 'WTF Export path: "%s"' % filename temp_mesh_name = '~tmp-mesh' time1 = sys.time() scn = Scene.GetCurrent() file = open(filename, "w") file.write('<?xml version="1.0"?>\n') file.write('<OPEN_TRACK>\n') # Write Header # file.write('\n<!--\n' # + ' Blender3D v%s WTF File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] ) # + ' www.blender3d.org\n' # + '-->\n\n') # Get the container mesh. - used for applying modifiers and non mesh objects. containerMesh = meshName = tempMesh = None for meshName in Blender.NMesh.GetNames(): if meshName.startswith(temp_mesh_name): tempMesh = Mesh.Get(meshName) if not tempMesh.users: containerMesh = tempMesh if not containerMesh: containerMesh = Mesh.New(temp_mesh_name) del meshName del tempMesh # Initialize totals, these are updated each object totverts = totuvco = totno = 0 face_vert_index = 0 globalNormals = {} file.write('\n<library_objects>\n') # Get all meshs for ob_main in objects: obnamestring = fixName(ob_main.name) file.write('\t<object id="%s">\n' % obnamestring) # Write Object name for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): # Will work for non meshes now! :) # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None) me = BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scn) if not me: file.write('\t\t<loc>%.6f %.6f %.6f</loc>\n' % tuple(ob_main.loc)) # Write Object name file.write('\t\t<rot>%.6f %.6f %.6f</rot>\n' % tuple(ob_main.rot)) # Write Object name continue faceuv = me.faceUV # We have a valid mesh if me.faces: # Add a dummy object to it. has_quads = False for f in me.faces: if len(f) == 4: has_quads = True break if has_quads: oldmode = Mesh.Mode() Mesh.Mode(Mesh.SelectModes['FACE']) me.sel = True tempob = scn.objects.new(me) me.quadToTriangle(0) # more=0 shortest length oldmode = Mesh.Mode(oldmode) scn.objects.unlink(tempob) Mesh.Mode(oldmode) # Make our own list so it can be sorted to reduce context switching faces = [f for f in me.faces] edges = me.edges if not (len(faces) + len(edges) + len(me.verts)): # Make sure there is somthing to write continue # dont bother with this mesh. me.transform(ob_mat) # High Quality Normals if faces: if EXPORT_NORMALS_HQ: BPyMesh.meshCalcNormals(me) else: # transforming normals is incorrect # when the matrix is scaled, # better to recalculate them me.calcNormals() # # Crash Blender #materials = me.getMaterials(1) # 1 == will return None in the list. materials = me.materials materialNames = [] materialItems = materials[:] if materials: for mat in materials: if mat: # !=None materialNames.append(mat.name) else: materialNames.append(None) # Cant use LC because some materials are None. # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. # Possible there null materials, will mess up indicies # but at least it will export, wait until Blender gets fixed. materialNames.extend((16 - len(materialNames)) * [None]) materialItems.extend((16 - len(materialItems)) * [None]) # Sort by Material, then images # so we dont over context switch in the obj file. if faceuv: try: faces.sort(key=lambda a: (a.mat, a.image, a.smooth)) except: faces.sort(lambda a, b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) elif len(materials) > 1: try: faces.sort(key=lambda a: (a.mat, a.smooth)) except: faces.sort(lambda a, b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) else: # no materials try: faces.sort(key=lambda a: a.smooth) except: faces.sort(lambda a, b: cmp(a.smooth, b.smooth)) # Set the default mat to no material and no image. contextMat = ( 0, 0 ) # Can never be this, so we will label a new material teh first chance we get. contextSmooth = None # Will either be true or false, set bad to force initialization switch. if len(faces) > 0: file.write('\t\t<mesh>\n') else: file.write('\t\t<curve>\n') vertname = "%s-Vertices" % obnamestring vertarrayname = "%s-Array" % vertname normname = "%s-Normals" % obnamestring normarrayname = "%s-Array" % normname texname = "%s-TexCoord" % obnamestring texarrayname = "%s-Array" % texname # Vert file.write('\t\t\t<float_array count="%d" id="%s">' % (len(me.verts), vertarrayname)) for v in me.verts: file.write(' %.6f %.6f %.6f' % tuple(v.co)) file.write('</float_array>\n') file.write('\t\t\t<vertices id="%s" source="#%s" />\n' % (vertname, vertarrayname)) # UV if faceuv: file.write('\t\t\t<float_array id="%s">' % texarrayname) uv_face_mapping = [[0, 0, 0, 0] for f in faces ] # a bit of a waste for tri's :/ uv_dict = {} # could use a set() here for f_index, f in enumerate(faces): for uv_index, uv in enumerate(f.uv): uvkey = veckey2d(uv) try: uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] except: uv_face_mapping[f_index][uv_index] = uv_dict[ uvkey] = len(uv_dict) file.write(' %.6f %.6f' % tuple(uv)) uv_unique_count = len(uv_dict) del uv, uvkey, uv_dict, f_index, uv_index # Only need uv_unique_count and uv_face_mapping file.write('</float_array>\n') file.write('\t\t\t<texcoords id="%s" source="#%s" />\n' % (texname, texarrayname)) # NORMAL, Smooth/Non smoothed. if len(faces) > 0: file.write('\t\t\t<float_array id="%s">' % normarrayname) for f in faces: if f.smooth: for v in f: noKey = veckey3d(v.no) if not globalNormals.has_key(noKey): globalNormals[noKey] = totno totno += 1 file.write(' %.6f %.6f %.6f' % noKey) else: # Hard, 1 normal from the face. noKey = veckey3d(f.no) if not globalNormals.has_key(noKey): globalNormals[noKey] = totno totno += 1 file.write(' %.6f %.6f %.6f' % noKey) file.write('</float_array>\n') file.write('\t\t\t<normals id="%s" source="#%s" />\n' % (normname, normarrayname)) if not faceuv: f_image = None in_triangles = False for f_index, f in enumerate(faces): f_v = f.v f_smooth = f.smooth f_mat = min(f.mat, len(materialNames) - 1) if faceuv: f_image = f.image f_uv = f.uv # MAKE KEY if faceuv and f_image: # Object is always true. key = materialNames[f_mat], f_image.name else: key = materialNames[ f_mat], None # No image, use None instead. # CHECK FOR CONTEXT SWITCH if key == contextMat: pass # Context alredy switched, dont do anythoing else: if key[0] == None and key[1] == None: # Write a null material, since we know the context has changed. if in_triangles: file.write('</p>\n') file.write('\t\t\t</triangles>\n') file.write('\t\t\t<triangles id="%s_%s">\n' % (fixName(ob.name), fixName(ob.getData(1)))) in_triangles = True else: mat_data = MTL_DICT.get(key) if not mat_data: # First add to global dict so we can export to mtl # Then write mtl # Make a new names from the mat and image name, # converting any spaces to underscores with fixName. # If none image dont bother adding it to the name if key[1] == None: mat_data = MTL_DICT[key] = ('%s' % fixName( key[0])), materialItems[f_mat], f_image else: mat_data = MTL_DICT[key] = ( '%s_%s' % (fixName(key[0]), fixName(key[1])) ), materialItems[f_mat], f_image if in_triangles: file.write('</p>\n') file.write('\t\t\t</triangles>\n') file.write( '\t\t\t<triangles id="%s_%s_%s" material="#%s">\n' % (fixName(ob.name), fixName( ob.getData(1)), mat_data[0], mat_data[0])) in_triangles = True file.write( '\t\t\t\t<input offset="0" semantic="VERTEX" source="#%s" />\n' % vertname) file.write( '\t\t\t\t<input offset="1" semantic="NORMAL" source="#%s" />\n' % normname) if faceuv: file.write( '\t\t\t\t<input offset="2" semantic="TEXCOORD" source="#%s" />\n' % texname) file.write('\t\t\t\t<p>') contextMat = key if f_smooth != contextSmooth: if f_smooth: # on now off # file.write('s 1\n') contextSmooth = f_smooth else: # was off now on # file.write('s off\n') contextSmooth = f_smooth if faceuv: if f_smooth: # Smoothed, use vertex normals for vi, v in enumerate(f_v): file.write( ' %d %d %d' % (\ v.index+totverts,\ totuvco + uv_face_mapping[f_index][vi],\ globalNormals[ veckey3d(v.no) ])) # vert, uv, normal else: # No smoothing, face normals no = globalNormals[veckey3d(f.no)] for vi, v in enumerate(f_v): file.write( ' %d %d %d' % (\ v.index+totverts,\ totuvco + uv_face_mapping[f_index][vi],\ no)) # vert, uv, normal face_vert_index += len(f_v) else: # No UV's if f_smooth: # Smoothed, use vertex normals for v in f_v: file.write( ' %d %d' % (\ v.index+totverts,\ globalNormals[ veckey3d(v.no) ])) else: # No smoothing, face normals no = globalNormals[veckey3d(f.no)] for v in f_v: file.write( ' %d %d' % (\ v.index+totverts,\ no)) if in_triangles: file.write('</p>\n') file.write('\t\t\t</triangles>\n') # Write edges. LOOSE = Mesh.EdgeFlags.LOOSE has_edge = False for ed in edges: if ed.flag & LOOSE: has_edge = True if has_edge: file.write('\t\t\t<edges>\n') file.write( '\t\t\t\t<input offset="0" semantic="VERTEX" source="#%s" />\n' % vertname) file.write('\t\t\t\t<p>') for ed in edges: if ed.flag & LOOSE: file.write( ' %d %d' % (ed.v1.index + totverts, ed.v2.index + totverts)) file.write('</p>\n') file.write('\t\t\t</edges>\n') # Make the indicies global rather then per mesh # totverts += len(me.verts) # if faceuv: # totuvco += uv_unique_count me.verts = None if len(faces) > 0: file.write('\t\t</mesh>\n') else: file.write('\t\t</curve>\n') file.write('\t</object>\n') file.write('</library_objects>\n\n') # Now we have all our materials, save them if EXPORT_MTL: write_library_materials(file) # Save the groups write_library_groups(file) file.write('</OPEN_TRACK>\n') file.close() if EXPORT_COPY_IMAGES: dest_dir = filename # Remove chars until we are just the path. while dest_dir and dest_dir[-1] not in '\\/': dest_dir = dest_dir[:-1] if dest_dir: copy_images(dest_dir) else: print '\tError: "%s" could not be used as a base for an image path.' % filename print "WTF Export time: %.2f" % (sys.time() - time1)
def imgImport(imgPath): global CUROFFS, PARAMS ###################################### # Load the image ###################################### try: img = Image.Load(imgPath) imgDimensions = img.getSize() # do this to ensure the data is available except: Blender.Draw.PupMenu('Error%t|Unsupported image format for "'+ imgPath.split('\\')[-1].split('/')[-1] +'"') return if PARAMS['PackImage']: img.pack() name = Blender.sys.makename(imgPath, strip = 1) ###################################### # Construct the mesh ###################################### me = Mesh.New(name) # Calculate Dimensions from Image Size dim = [float(i)/PARAMS['PPU'] for i in imgDimensions] v = [[dim[0], dim[1], 0], [-dim[0], dim[1], 0], [-dim[0], -dim[1], 0], [dim[0], -dim[1], 0]] me.verts.extend(v) me.faces.extend([0, 1, 2, 3]) me.faces[0].image = img me.faces[0].uv = [Vector(1.0, 1.0), Vector(0.0, 1.0), Vector(0.0, 0.0), Vector(1.0, 0.0)] if PARAMS['MakeTransp']: me.faces[0].transp = Mesh.FaceTranspModes.ALPHA ###################################### # Modify the Material ###################################### mat = None if not PARAMS['NewMat']: mat = PARAMS['Materials'][PARAMS['MaterialId']].__copy__() mat.setName(name) else: mat = Material.New(name) properties = PARAMS['MatProps'] mat.setRGBCol(properties['Col']) mat.setRef(properties['Ref']) mat.setSpec(properties['Spec']) mat.setHardness(properties['Hard']) mat.setAlpha(properties['Alpha']) if properties['Shadeless']: mat.mode |= Material.Modes.SHADELESS if properties['ZTransp']: mat.mode |= Material.Modes.ZTRANSP properties = PARAMS['TexProps'] tex = Texture.New(name) tex.setType('Image') tex.setImage(img) if properties['UseAlpha']: tex.useAlpha = Texture.ImageFlags.USEALPHA if properties['CalcAlpha']: tex.calcAlpha = Texture.ImageFlags.CALCALPHA if properties['ExtendMode']: tex.setExtend('Extend') if PARAMS['ImageProp'] == Image.Sources.SEQUENCE: properties = PARAMS['SeqProps'] img.source = PARAMS['ImageProp'] # Needs to be done here, otherwise an error with earlier getSize() tex.animStart = properties['StartFr'] tex.animOffset = properties['Offs'] tex.animFrames = properties['Frames'] tex.autoRefresh = properties['AutoRefresh'] tex.cyclic = properties['Cyclic'] texMapSetters = Texture.TexCo.UV # PARAMS['TexMapTo']['Col'] (and alpha) will either be 0 or 1 because its from a toggle, otherwise this line doesn't work texChanSetters = Texture.MapTo.COL * PARAMS['TexMapTo']['Col'] | Texture.MapTo.ALPHA * PARAMS['TexMapTo']['Alpha'] mat.setTexture(PARAMS['TexChannel'], tex, texMapSetters, texChanSetters) me.materials += [mat] ###################################### # Object Construction ###################################### ob = scn.objects.new(me, name) p = Vector(ob.getLocation()) # Should be the origin, but just to be safe, get it ob.setLocation((CUROFFS * PARAMS['ObOffset']) + p) return