def addprops(scene, lods): try: propobj=Object.Get('FSXProperties') propobj.removeAllProperties() except: propobj=Object.New('Empty', 'FSXProperties') scene.objects.link(propobj) propobj.layers=[] # invisible for layer in range(min(10,len(lods))): propobj.addProperty('LOD_%02d' % (layer+1), lods[layer])
def NewObject(flag): global ob, me, sc if flag == 1: DumpData() DeselectAllObjects() sc = Scene.GetCurrent() cursorpos = Window.GetCursorPos() ob = Object.New('Mesh', 'Cyl_') me = NMesh.New('MyCylMesh') ob.setLocation(cursorpos) ob.link(me) sc.link(ob)
def create_topomesh(filename): Window.WaitCursor(True) #link to object obj = Object.New('Mesh', 'myObj') #link to scene sc = Scene.GetCurrent() sc.link(obj) me = load_topomesh(filename, obj) Window.RedrawAll()
def addattach(scene, name, matrix): if name.startswith('attachpt_'): name=name[9:] if not name: name='AttachPoint' obj=Object.New('Empty', name) scene.objects.link(obj) obj.layers=[1] obj.addProperty('name', obj.name) # Need to convert between right and left handed coordinate systems. obj.setMatrix(RotationMatrix(-90,4,'x')*matrix*Matrix([1,0,0,0],[0,0,1,0],[0,-1,0,0],[0,0,0,1])) obj.LocY=-obj.LocY return obj
def shp_to_blender (shp, discretizer = None, mats = {}) : """Create a blender object for this shape :Parameters: - `shp` (Shape) - the shape to transform - `discretizer` (Discretizer) - algorithm to triangulate the geometry - `mats` (dict of (mat_id,Material) ) - precomputed pgl Material to avoid to recreate many instances of the same material :Returns Type: Object """ #name if shp.isNamed() : name = shp.getName() else : name = "pglshp%d" % shp.getId() #create material app = shp.appearance try : mat = mats[app.getId()] except KeyError : mat = material_to_blender(app) mats[app.getId()] = mat #create mesh mesh,mmat = geometry_to_blender(shp.geometry) #create object ob = Object.New('Mesh',name) ob.link(mesh) ob.setMaterials([mat]) if mmat is None : ob.colbits = 1 << 0 #return return ob
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 imageFromObjectsOrtho(objects, path, width, height, smooth, alpha=True, camera_matrix=None, format=Render.PNG): ''' Takes any number of objects and renders them on the z axis, between x:y-0 and x:y-1 Usefull for making images from a mesh without per pixel operations - objects must be alredy placed - smooth, anti alias True/False - path renders to a PNG image - alpha weather to render background as alpha returns the blender image ''' ext = '.' + extFromFormat(format) print ext # remove an extension if its alredy there if path.lower().endswith(ext): path = path[:-4] path_expand = sys.expandpath(path) + ext print path_expand, 'path' # Touch the path try: f = open(path_expand, 'w') f.close() except: raise 'Error, could not write to path:' + path_expand # RENDER THE FACES. scn = Scene.GetCurrent() render_scn = Scene.New() render_scn.makeCurrent() render_scn.Layers |= (1 << 20) - 1 # all layers enabled # Add objects into the current scene for ob in objects: render_scn.link(ob) render_context = render_scn.getRenderingContext() render_context.setRenderPath( '') # so we can ignore any existing path and save to the abs path. render_context.imageSizeX(width) render_context.imageSizeY(height) if smooth: render_context.enableOversampling(True) render_context.setOversamplingLevel(16) else: render_context.enableOversampling(False) render_context.setRenderWinSize(100) render_context.setImageType(format) render_context.enableExtensions(True) #render_context.enableSky() # No alpha needed. if alpha: render_context.alphaMode = 1 render_context.enableRGBAColor() else: render_context.alphaMode = 0 render_context.enableRGBColor() render_context.displayMode = 0 # fullscreen # New camera and object render_cam_data = Camera.New('ortho') render_cam_ob = Object.New('Camera') render_cam_ob.link(render_cam_data) render_scn.link(render_cam_ob) render_scn.objects.camera = render_cam_ob render_cam_data.type = 'ortho' # Position the camera if camera_matrix: render_cam_ob.setMatrix(camera_matrix) # We need to take into account the matrix scaling when setting the size # so we get the image bounds defined by the matrix # first get the x and y factors from the matrix. # To render the correct dimensions we must use the aspy and aspy to force the matrix scale to # override the aspect enforced by the width and weight. cent = Vector() * camera_matrix xvec = Vector(1, 0, 0) * camera_matrix yvec = Vector(0, 1, 0) * camera_matrix # zvec= Vector(0,0,1) * camera_matrix xlen = (cent - xvec).length # half height of the image ylen = (cent - yvec).length # half width of the image # zlen = (cent-zvec).length # dist to place the camera? - just use the loc for now. # less then 1.0 portrate, 1.0 or more is portrate asp_cam_mat = xlen / ylen # divide by zero? - possible but scripters fault. asp_image_res = float(width) / height #print 'asp quad', asp_cam_mat, 'asp_image', asp_image_res #print 'xylen', xlen, ylen, 'w/h', width, height # Setup the aspect if asp_cam_mat > asp_image_res: # camera is wider then image res. # to make the image wider, reduce the aspy asp_diff = asp_image_res / asp_cam_mat min_asp = asp_diff * 200 #print 'X', min_asp elif asp_cam_mat < asp_image_res: # asp_cam_mat < asp_image_res # camera is narrower then image res # to make the image narrower, reduce the aspx asp_diff = asp_cam_mat / asp_image_res min_asp = asp_diff * 200 #print 'Y', min_asp else: min_asp = 200 # set the camera size if xlen > ylen: if asp_cam_mat > asp_image_res: render_context.aspectX = 200 # get the greatest range possible render_context.aspectY = min_asp # get the greatest range possible else: render_context.aspectY = 200 # get the greatest range possible render_context.aspectX = min_asp # get the greatest range possible #print "xlen bigger" render_cam_data.scale = xlen * 2 elif xlen < ylen: # ylen is bigger if asp_cam_mat > asp_image_res: render_context.aspectX = 200 # get the greatest range possible render_context.aspectY = min_asp # get the greatest range possible else: render_context.aspectY = 200 # get the greatest range possible render_context.aspectX = min_asp # get the greatest range possible #print "ylen bigger" render_cam_data.scale = ylen * 2 else: # asppect 1:1 #print 'NOLEN Bigger' render_cam_data.scale = xlen * 2 #print xlen, ylen, 'xlen, ylen' else: if width > height: min_asp = int((float(height) / width) * 200) render_context.aspectX = min_asp render_context.aspectY = 200 else: min_asp = int((float(width) / height) * 200) render_context.aspectX = 200 render_context.aspectY = min_asp render_cam_data.scale = 1.0 render_cam_ob.LocZ = 1.0 render_cam_ob.LocX = 0.5 render_cam_ob.LocY = 0.5 Blender.Window.RedrawAll() render_context.render() render_context.saveRenderedImage(path) Render.CloseRenderWindow() #if not B.sys.exists(PREF_IMAGE_PATH_EXPAND): # raise 'Error!!!' scn.makeCurrent() Scene.Unlink(render_scn) # NOW APPLY THE SAVED IMAGE TO THE FACES! #print PREF_IMAGE_PATH_EXPAND try: target_image = Image.Load(path_expand) return target_image except: raise 'Error: Could not render or load the image at path "%s"' % path_expand return
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 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 loadgeomnode(file, words, pdata): def objprop(file, words, data): data['nwnprops'].write('%s.%s=%s\n'%(data['object'].name, words[0], words[1])) def parent(file, words, data): if words[1]=='NULL': data['nwnprops'].write('SCENE.baseobjectname=%s\n'%data['object'].name) else: p=Object.Get(words[1]) p.makeParent([data['object']]) def position(file, words, data): data['object'].setLocation(map(float, words[1:4])) def orientation(file, words, data): data['object'].setEuler(nwn2euler(map(float, words[1:5]))) def bitmap(file, words, data): global filename imagefname=os.path.dirname(filename) + '\\' + words[1]+'.tga' try: image=Image.Get(imagefname) except NameError: try: image=Image.Load(imagefname) except IOError: print '**************ERROR********************' print 'file : ' + filename print 'texture : ' + words[1]+'.tga unknown in directory : ' print os.path.dirname(filename) print 'check if the bitmap exists with an other extension => translate in tga format' print 'or move it in the directory of the .mdl model' print 'null.tga could be used instead of the current one' print '**************ERROR********************' imagefname=os.path.dirname(filename) + '\\null.tga' image=Image.Load(imagefname) pass data['nwnprops'].write('%s.texture=%s\n'%(data['object'].name, words[1])) data['texture']=image def verts(file, words, data): vertexcount=int(words[1]) while vertexcount>0: data['mesh'].verts.append(apply(NMesh.Vert, map(float, file.readline().split()))) vertexcount-=1 # Well, Torlack's NWN model decompiler puts faces after tverts. # NWN's sample file had it the other way around, so we support both. def fixuvs(data): mesh=data['mesh'] uvi=data['uvi'] uvc=data['uvc'] for fi in range(len(uvi)): face=mesh.faces[fi] face.uv=map(lambda x: uvc[x], uvi[fi]) face.mode=NMesh.FaceModes.TEX # TODO: recalculate the normals. They're all random, and PutRaw cancels transforms. #NMesh.PutRaw(mesh, data['object'].name) mesh.update() def faces(file, words, data): uvi=[] mesh=data['mesh'] facecount=int(words[1]) while facecount>0: f=NMesh.Face() line=map(int, file.readline().split()) f.image=data['texture'] for v in line[0:3]: f.v.append(mesh.verts[v]) f.smooth=line[3] mesh.faces.append(f) uvi.append(line[4:7]) facecount-=1 data['uvi']=uvi if data.has_key('uvc'): fixuvs(data) def tverts(file, words, data): mesh=data['mesh'] uvc=[] uvcount=int(words[1]) while uvcount>0: uvc.append(tuple(map(float, file.readline().split()[0:2]))) uvcount-=1 data['uvc']=uvc if data.has_key('uvi'): fixuvs(data) nodedict={'parent': parent, 'position': position, 'bitmap': bitmap, 'verts': verts, 'faces': faces, 'endnode': linereaderbreak, 'tverts': tverts, 'orientation': orientation, 'tilefade': objprop} data=None if words[1]=='dummy': data={'object': Object.New('Empty')} elif words[1]=='trimesh': data={'object': Object.New('Mesh'), 'mesh': NMesh.New(words[2])} data['object'].link(data['mesh']) else: return # unsupported node type # Note: Blender 2.27, New(type, name) didn't work. object.name worked. data['object'].name=words[2] data['nwnprops']=pdata['nwnprops'] linereader(file, nodedict, data) pdata['scene'].link(data['object'])
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)
orientationZValues.append(float(lineSplit[3])) for line in lines[i + 1:]: lineSplit = line.split() accelerationTimeStamp.append(float(lineSplit[0]) / 1000000000.0) accelerationXValues.append(float(lineSplit[1])) accelerationYValues.append(float(lineSplit[2])) accelerationZValues.append(float(lineSplit[3])) #Create the camera cur = Scene.getCurrent() cam = Camera.New('persp') cam.lens = 35.0 cam.setDrawSize(1.0) obj = Object.New('Camera') obj.name = "imported_camera" obj.link(cam) cur.link(obj) cur.setCurrentCamera(obj) ipo = Blender.Ipo.New('Object', 'camera_ipo') obj.setIpo(ipo) locx = ipo.addCurve('LocX') locx.setInterpolation('Linear') locy = ipo.addCurve('LocY') locy.setInterpolation('Linear') locz = ipo.addCurve('LocZ') locz.setInterpolation('Linear')
def adddata(scene, layer, material, vert, inde, matrix, plat=None): # Need to convert between right and left handed coordinate systems. matrix=matrix*Matrix([1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]) # This results in a negatively scaled matrix, which causes problems # for face normals. So separate out and apply scale&rotation parts. tran=TranslationMatrix(matrix.translationPart()) matrix[3]=[0,0,0,1] # detect back-to-back duplicate faces facelookup={} newvert=[[]] for i in range(0, len(inde), 3): face=[(vert[inde[j]][0], vert[inde[j]][1], vert[inde[j]][2]) for j in range(i+2,i-1,-1)] # duplicate faces may be rotated - eg Oil_Rig_Sample if tuple(face) in facelookup or (face[1],face[2],face[0]) in facelookup or (face[2],face[0],face[1]) in facelookup: # back-to-back duplicate - start new mesh newvert.append([]) facelookup={} face.reverse() facelookup[tuple(face)]=True newvert[-1].extend([vert[inde[j]] for j in range(i,i+3)]) for vert in newvert: mesh=Mesh.New('Mesh') mesh.mode &= ~(Mesh.Modes.TWOSIDED|Mesh.Modes.AUTOSMOOTH) mesh.mode |= Mesh.Modes.NOVNORMALSFLIP mesh.materials+=[material] mesh.verts.extend([v[0:3] for v in vert]) mesh.faces.extend([[i,i+1,i+2] for i in range(0, len(vert), 3)], ignoreDups=True) mesh.faceUV=True mtex=material.getTextures()[0] if mtex: image=mtex.tex.image else: image=None surface=None i=0 for face in mesh.faces: face.mode &= ~(Mesh.FaceModes.TWOSIDE|Mesh.FaceModes.TILES) if image: face.mode|=Mesh.FaceModes.TEX face.image=image face.uv=[Vector(v[6],1-v[7]) for v in [vert[j] for j in range(i,i+3)]] # smooth if vertex normals are different face.smooth=not (vert[i][3:6]==vert[i+1][3:6]==vert[i+2][3:6]) # is this a platform? if plat: v=(vert[i][:3], vert[i+1][:3], vert[i+2][:3]) #for vt in v: print "%.4f %.4f %.4f" % vt #print if v in plat: face.mode&=~Mesh.FaceModes.DYNAMIC surface=plat.pop(v) else: face.mode |= Mesh.FaceModes.DYNAMIC else: face.mode |= Mesh.FaceModes.DYNAMIC i+=3 ob = Object.New('Mesh') ob.link(mesh) scene.objects.link(ob) ob.layers=[layer] ob.setMatrix(tran) if surface!=None: ob.addProperty('surfaceType', SURFACES[surface]) # following must be after object linked to scene mesh.transform(matrix) mesh.sel=True mesh.remDoubles(0.001) # 1/10mm mesh.sel=True mesh.calcNormals() # calculate vertex normals mesh.sel=False