for i in items: path=i[3].split('/')[:-1] extend_pop_for(pop_list,path) if len(path): append_to_inner(pop_list,(i[3].split('/')[-1],items.index(i))) else: pop_list.append((i[3].split('/')[-1],items.index(i))) r = Draw.PupTreeMenu(pop_list) if r >= 0: print items[r] set_pref_key('xplane.tools','annotate.last_item',items[r]) cur = Window.GetCursorPos() mm = TranslationMatrix(Vector([0,0,0])).resize4x4() #mm = TranslationMatrix(Vector(Window.GetCursorPos())).resize4x4() importer=OBJimport(items[r][1],mm) importer.verbose=1 try: sel = Blender.Scene.GetCurrent().objects.selected old_objs = set(Blender.Scene.GetCurrent().objects) obj_list = importer.doimport() new_objs = set(Blender.Scene.GetCurrent().objects) wrapper=Blender.Object.New('Empty','OBJ%s' % items[r][0].split('/')[-1]) Blender.Scene.GetCurrent().objects.link(wrapper) added = new_objs-old_objs wrapper.makeParent(list(added),1,0) if len(sel) == 1: sel[0].makeParent([wrapper],1,0) base = sel[0].getLocation('worldspace')
def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_KEEP_ASPECT, PREF_IMAGE_MARGIN): #, PREF_SIZE_FROM_UV=True): ''' Main packing function All meshes from mesh_list must have faceUV else this function will fail. ''' face_groups= {} for me in mesh_list: for f in me.faces: if f.mode & TEXMODE: image= f.image if image: try: face_groups[image.name] # will fail if teh groups not added. except: try: size= image.size except: B.Draw.PupMenu('Aborting: Image cold not be loaded|' + image.name) return face_groups[image.name]= faceGroup(mesh_list, image, size, PREF_IMAGE_MARGIN) if not face_groups: B.Draw.PupMenu('No Images found in mesh(es). Aborting!') return if len(face_groups)<2: B.Draw.PupMenu('Only 1 image found|Select a mesh(es) using 2 or more images.') return ''' if PREF_SIZE_FROM_UV: for fg in face_groups.itervalues(): fg.set_worldspace_scale() ''' # RENDER THE FACES. render_scn= B.Scene.New() render_scn.makeCurrent() render_context= render_scn.getRenderingContext() render_context.setRenderPath('') # so we can ignore any existing path and save to the abs path. PREF_IMAGE_PATH_EXPAND= B.sys.expandpath(PREF_IMAGE_PATH) + '.png' # TEST THE FILE WRITING. try: # Can we write to this file??? f= open(PREF_IMAGE_PATH_EXPAND, 'w') f.close() except: B.Draw.PupMenu('Error%t|Could not write to path|' + PREF_IMAGE_PATH_EXPAND) return render_context.imageSizeX(PREF_IMAGE_SIZE) render_context.imageSizeY(PREF_IMAGE_SIZE) render_context.enableOversampling(True) render_context.setOversamplingLevel(16) render_context.setRenderWinSize(100) render_context.setImageType(Render.PNG) render_context.enableExtensions(True) render_context.enableSky() # No alpha needed. render_context.enableRGBColor() render_context.threads = 2 #Render.EnableDispView() # Broken?? # New Mesh and Object render_mat= B.Material.New() render_mat.mode |= B.Material.Modes.SHADELESS render_mat.mode |= B.Material.Modes.TEXFACE render_me= B.Mesh.New() render_me.verts.extend([Vector(0,0,0)]) # Stupid, dummy vert, preverts errors. when assigning UV's/ render_ob= B.Object.New('Mesh') render_ob.link(render_me) render_scn.link(render_ob) render_me.materials= [render_mat] # New camera and object render_cam_data= B.Camera.New('ortho') render_cam_ob= B.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' render_cam_data.scale= 1.0 # Position the camera render_cam_ob.LocZ= 1.0 render_cam_ob.LocX= 0.5 render_cam_ob.LocY= 0.5 # List to send to to boxpack function. boxes2Pack= [ fg.box_pack for fg in face_groups.itervalues()] packWidth, packHeight = B.Geometry.BoxPack2D(boxes2Pack) if PREF_KEEP_ASPECT: packWidth= packHeight= max(packWidth, packHeight) # packedLs is a list of [(anyUniqueID, left, bottom, width, height)...] # Re assign the face groups boxes to the face_group. for box in boxes2Pack: face_groups[ box[4] ].box_pack= box # box[4] is the ID (image name) # Add geometry to the mesh for fg in face_groups.itervalues(): # Add verts clockwise from the bottom left. _x= fg.box_pack[0] / packWidth _y= fg.box_pack[1] / packHeight _w= fg.box_pack[2] / packWidth _h= fg.box_pack[3] / packHeight render_me.verts.extend([\ Vector(_x, _y, 0),\ Vector(_x, _y +_h, 0),\ Vector(_x + _w, _y +_h, 0),\ Vector(_x + _w, _y, 0),\ ]) render_me.faces.extend([\ render_me.verts[-1],\ render_me.verts[-2],\ render_me.verts[-3],\ render_me.verts[-4],\ ]) target_face= render_me.faces[-1] target_face.image= fg.image target_face.mode |= TEXMODE # Set the UV's, we need to flip them HOZ? target_face.uv[0].x= target_face.uv[1].x= fg.xmax target_face.uv[2].x= target_face.uv[3].x= fg.xmin target_face.uv[0].y= target_face.uv[3].y= fg.ymin target_face.uv[1].y= target_face.uv[2].y= fg.ymax for uv in target_face.uv: uv_rot= ((uv-fg.cent) * fg.rot_mat[1]) + fg.cent uv.x= uv_rot.x uv.y= uv_rot.y render_context.render() Render.CloseRenderWindow() render_context.saveRenderedImage(PREF_IMAGE_PATH_EXPAND) #if not B.sys.exists(PREF_IMAGE_PATH_EXPAND): # raise 'Error!!!' # NOW APPLY THE SAVED IMAGE TO THE FACES! #print PREF_IMAGE_PATH_EXPAND try: target_image= B.Image.Load(PREF_IMAGE_PATH_EXPAND) except: B.Draw.PupMenu('Error: Could not render or load the image at path|' + PREF_IMAGE_PATH_EXPAND) return # Set to the 1 image. for me in mesh_list: for f in me.faces: if f.mode & TEXMODE and f.image: f.image= target_image for fg in face_groups.itervalues(): fg.move2packed(packWidth, packHeight) scn.makeCurrent() render_me.verts= None # free a tiny amount of memory. B.Scene.Unlink(render_scn) target_image.makeCurrent()
def load_md2(md2_filename, texture_filename): #read the file in file = open(md2_filename, "rb") WaitCursor(1) DrawProgressBar(0.0, 'Loading MD2') md2 = md2_obj() md2.load(file) #md2.dump() file.close() ######### Creates a new mesh mesh = Mesh.New() uv_coord = [] #uv_list=[] verts_extend = [] #load the textures to use later #-1 if there is no texture to load mesh_image = load_textures(md2, texture_filename) if mesh_image == -1 and texture_filename: print 'MD2 Import, Warning, texture "%s" could not load' ######### Make the verts DrawProgressBar(0.25, "Loading Vertex Data") frame = md2.frames[0] scale = g_scale.val def tmp_get_vertex(i): #use the first frame for the mesh vertices x = (frame.scale[0] * frame.vertices[i].vertices[0] + frame.translate[0]) * scale y = (frame.scale[1] * frame.vertices[i].vertices[1] + frame.translate[1]) * scale z = (frame.scale[2] * frame.vertices[i].vertices[2] + frame.translate[2]) * scale return y, -x, z mesh.verts.extend([tmp_get_vertex(i) for i in xrange(0, md2.num_vertices)]) del tmp_get_vertex ######## Make the UV list DrawProgressBar(0.50, "Loading UV Data") w = float(md2.skin_width) h = float(md2.skin_height) if w <= 0.0: w = 1.0 if h <= 0.0: h = 1.0 #for some reason quake2 texture maps are upside down, flip that uv_list = [Vector(co.u / w, 1 - (co.v / h)) for co in md2.tex_coords] del w, h ######### Make the faces DrawProgressBar(0.75, "Loading Face Data") faces = [] face_uvs = [] for md2_face in md2.faces: f = md2_face.vertex_index[0], md2_face.vertex_index[ 2], md2_face.vertex_index[1] uv = uv_list[md2_face.texture_index[0]], uv_list[ md2_face.texture_index[2]], uv_list[md2_face.texture_index[1]] if f[2] == 0: # EEKADOODLE :/ f = f[1], f[2], f[0] uv = uv[1], uv[2], uv[0] #ditto in reverse order with the texture verts faces.append(f) face_uvs.append(uv) face_mapping = mesh.faces.extend(faces, indexList=True) print len(faces) print len(mesh.faces) mesh.faceUV = True #turn on face UV coordinates for this mesh mesh_faces = mesh.faces for i, uv in enumerate(face_uvs): if face_mapping[i] != None: f = mesh_faces[face_mapping[i]] f.uv = uv if (mesh_image != -1): f.image = mesh_image scn = Blender.Scene.GetCurrent() mesh_obj = scn.objects.new(mesh) animate_md2(md2, mesh) DrawProgressBar(0.98, "Loading Animation Data") #locate the Object containing the mesh at the cursor location cursor_pos = Blender.Window.GetCursorPos() mesh_obj.setLocation(float(cursor_pos[0]), float(cursor_pos[1]), float(cursor_pos[2])) DrawProgressBar(1.0, "") WaitCursor(0)
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 parse_surf(self, value): i = self.i is_smooth = 0 double_sided = 0 lines = self.lines obj = self.objlist[-1] vlist = obj.vlist matlist = obj.matlist numsurf = int(value) NUMSURF = numsurf badface_notpoly = badface_multirefs = 0 while numsurf: flags = lines[i].split()[1][2:] if len(flags) > 1: flaghigh = int(flags[0]) flaglow = int(flags[1]) else: flaghigh = 0 flaglow = int(flags[0]) is_smooth = flaghigh & 1 twoside = flaghigh & 2 nextline = lines[i+1].split() if nextline[0] != 'mat': # the "mat" line may be missing (found in one buggy .ac file) matid = 0 if not matid in matlist: matlist.append(matid) i += 2 else: matid = int(nextline[1]) if not matid in matlist: matlist.append(matid) nextline = lines[i+2].split() i += 3 refs = int(nextline[1]) face = [] faces = [] edges = [] fuv = [] fuvs = [] rfs = refs while rfs: line = lines[i].split() v = int(line[0]) + 1 # + 1 to avoid vindex == 0 uv = [float(line[1]), float(line[2])] face.append(v) fuv.append(Vector(uv)) rfs -= 1 i += 1 if flaglow: # it's a line or closed line, not a polygon while len(face) >= 2: cut = face[:2] edges.append(cut) face = face[1:] if flaglow == 1 and edges: # closed line face = [edges[-1][-1], edges[0][0]] edges.append(face) else: # polygon # check for bad face, that references same vertex more than once lenface = len(face) if lenface < 3: # less than 3 vertices, not a face badface_notpoly += 1 elif sum(map(face.count, face)) != lenface: # multiple references to the same vertex badface_multirefs += 1 else: # ok, seems fine if len(face) > 4: # ngon, triangulate it polyline = [] for vi in face: polyline.append(Vector(vlist[vi])) tris = PolyFill([polyline]) for t in tris: tri = [face[t[0]], face[t[1]], face[t[2]]] triuvs = [fuv[t[0]], fuv[t[1]], fuv[t[2]]] faces.append(tri) fuvs.append(triuvs) else: # tri or quad faces.append(face) fuvs.append(fuv) obj.flist_cfg.extend([[matid, is_smooth, twoside]] * len(faces)) obj.flist_v.extend(faces) obj.flist_uv.extend(fuvs) obj.elist.extend(edges) # loose edges numsurf -= 1 if badface_notpoly or badface_multirefs: inform('Object "%s" - ignoring bad faces:' % obj.name) if badface_notpoly: inform('\t%d face(s) with less than 3 vertices.' % badface_notpoly) if badface_multirefs: inform('\t%d face(s) with multiple references to a same vertex.' % badface_multirefs) self.i = i
def build_hierarchy(self): blmatrix = AC_TO_BLEND_MATRIX olist = self.objlist[1:] olist.reverse() scene = self.scene newlist = [] for o in olist: kids = o.kids if kids: children = newlist[-kids:] newlist = newlist[:-kids] if o.type == AC_GROUP: parent = self.found_parent(o.name, children) if parent: children.remove(parent) o.bl_obj = parent.bl_obj else: # not found, use an empty empty = scene.objects.new('Empty', o.name) o.bl_obj = empty bl_children = [c.bl_obj for c in children if c.bl_obj != None] o.bl_obj.makeParent(bl_children, 0, 1) for child in children: blob = child.bl_obj if not blob: continue if child.rot: eul = euler_in_radians(child.rot.toEuler()) blob.setEuler(eul) if child.size: blob.size = child.size if not child.loc: child.loc = Vector(0.0, 0.0, 0.0) blob.setLocation(child.loc) newlist.append(o) for o in newlist: # newlist now only has objs w/o parents blob = o.bl_obj if not blob: continue if o.size: o.bl_obj.size = o.size if not o.rot: blob.setEuler([1.5707963267948966, 0, 0]) else: matrix = o.rot * blmatrix eul = euler_in_radians(matrix.toEuler()) blob.setEuler(eul) if o.loc: o.loc *= blmatrix else: o.loc = Vector(0.0, 0.0, 0.0) blob.setLocation(o.loc) # forces DAG update, so we do it even for 0, 0, 0 # XXX important: until we fix the BPy API so it doesn't increase user count # when wrapping a Blender object, this piece of code is needed for proper # object (+ obdata) deletion in Blender: for o in self.objlist: if o.bl_obj: o.bl_obj = None
def CreateBlenderMeshObjectFromNode(scene, meshNode, blenderScene): # Get a alchemedia mesh for the node and buidl a blender mesh mesh = pyScene.pyMesh(scene, meshNode) # create a blender mesh newMesh = bpy.data.meshes.new(scene.GetNodeName(meshNode)) # Create all verte and face data vertexList = [] vertexCount = mesh.GetVertexCount() for i in range(0, vertexCount): vertex = mesh.GetVertex(i) vertexList.append([vertex.x, vertex.y, vertex.z]) faceList = [] faceNode = mesh.GetFirstTriangle() while faceNode != None: face = mesh.GetTriangle(faceNode) faceList.append([face.p0.vertex, face.p1.vertex, face.p2.vertex]) faceNode = mesh.GetNextTriangle(faceNode) newMesh.verts.extend(vertexList) # add vertices to mesh newMesh.faces.extend(faceList) # add faces to the mesh (also adds edges) # create all materials from this mesh materialIndex = 0 materialMap = {} meshMaterials = newMesh.materials childLink = scene.GetFirstChildLink(meshNode) while childLink != None: childNode = scene.GetNodeFromLink(childLink) if scene.IsMaterialNode(childNode) == True: # make a blender material and a alchemdia material material = CreateBlenderMaterialFromNode(scene, childNode, blenderScene) meshMaterials.append(material) # add a map key for asigning faces sourceMaterial = pyScene.pyMaterial(scene, childNode) materialMap[sourceMaterial.GetId()] = materialIndex materialIndex = materialIndex + 1 childLink = scene.GetNextChildLink(meshNode, childLink) newMesh.materials = meshMaterials # In a secund pass asign material and uv mapping to faces faceIndex = 0 newMesh.faceUV = True faceNode = mesh.GetFirstTriangle() while faceNode != None: face = mesh.GetTriangle(faceNode) newMesh.faces[faceIndex].mat = materialMap[face.materialIndex] uv0 = mesh.GetUV0(face.p0.uv0) uv1 = mesh.GetUV0(face.p1.uv0) uv2 = mesh.GetUV0(face.p2.uv0) newMesh.faces[faceIndex].uv = [ Vector(uv0.x, uv0.y), Vector(uv1.x, uv1.y), Vector(uv2.x, uv2.y) ] faceIndex = faceIndex + 1 faceNode = mesh.GetNextTriangle(faceNode) # link mesh to blend objects object = blenderScene.objects.new(newMesh, scene.GetNodeName(meshNode)) # calculate normal after mesh is parented #newMesh.mode |= Blender.Mesh.Modes.AUTOSMOOTH #newMesh.degr = 30 #for face in newMesh.faces: # face.smooth = 1 #newMesh.calcNormals() return object
def parse_loc(self, trash): i = self.i - 1 loc = self.lines[i].split(' ', 1)[1] loc = map(float, loc.split()) self.objlist[-1].loc = Vector(loc)
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
def file_callback (filename): try: bgl=file(filename,'rb') except: Draw.PupMenu("ERROR%%t|Can't open %s" % filename) return bgldir=dirname(filename) guid=None friendly=None texnames=[] # list of texture file names matlist=[] # fs9 materials mats=[] # list of Blender Materials inde=[] vert=[] tran=[] amap=[] # fsx map scen=[] # (child, peer, matrix, parent) data={} # (material, vert, inde, scene) by LOD plat={} # (surface, vertices) by scene atta=[] # (name, scene) attobjs=[] atteffects=[] partcount=0 Window.WaitCursor(1) Window.DrawProgressBar(0, "Opening ...") try: (c,size,endmdl)=container(bgl,0) assert (c=='RIFF') assert (bgl.read(4) in ['MDL9','MDLX']) while bgl.tell()<endmdl: (c,size,end1)=container(bgl,1) if c=='MDLG': # FSX guid guid='{%x-%x-%x-%x%x-%x%x%x%x%x%x}' % unpack('<IHH8B',bgl.read(size)) if debug: print guid elif c=='MDLH': if size==36: # FS9 header (size,reserved,reserved,radius,reserved,reserved,reserved,reserved,reserved)=unpack('<9I', bgl.read(size)) if debug: print radius else: bgl.seek(size,1) elif c=='MDLN': # FSX friendly name friendly=bgl.read(size).strip('\0').strip() if debug: print friendly elif c=='MDLD': # FSX data while bgl.tell()<end1: Window.DrawProgressBar(float(bgl.tell())/(endmdl+endmdl), "Reading ...") (c,size,end2)=container(bgl,2) if c=='TEXT': texnames=[bgl.read(64).strip('\0').strip() for i in range(0,size,64)] elif c=='MATE': mats.extend([getmaterialx(bgl.read(120), bgldir, texnames) for i in range(0,size,120)]) elif c=='INDE': # reverse order of vertices in each triangle for i in range(size/6): t=list(unpack('<3H', bgl.read(6))) t.reverse() inde.extend(t) elif c=='VERB': while bgl.tell()<end2: (c,size,end3)=container(bgl,3) if c=='VERT': vert.append([tuple([round(i,VROUND) for i in unpack('<8f',bgl.read(32))]) for j in range(0,size,32)]) else: bgl.seek(size,1) elif c=='TRAN': for i in range(0,size,64): tran.append(Matrix(*[unpack('<4f',bgl.read(16)) for j in range(4)])) elif c=='AMAP': for i in range(0,size,8): (a,b)=unpack('<2I',bgl.read(8)) amap.append(b) elif c=='SCEN': # Assumed to be after TRAN and AMAP sections count=size/8 for i in range(count): (child,peer,offset,unk)=unpack('<4h',bgl.read(8)) thismatrix=tran[amap[offset/8]] scen.append((child,peer,thismatrix,-1)) elif c=='LODT': while bgl.tell()<end2: (c,size,end3)=container(bgl,3) if c=='LODE': (lod,)=unpack('<I', bgl.read(4)) while bgl.tell()<end3: (c,size,end4)=container(bgl,4) if c=='PART': (typ,sceneg,material,verb,voff,vcount,ioff,icount,mouserect)=unpack('<9I', bgl.read(36)) if debug: print lod, typ,sceneg,material,verb,voff,vcount,ioff,icount,mouserect assert (typ==1) # TRIANGLE_LIST if not lod in data: data[lod]=[] data[lod].append((mats[material], vert[verb][voff:voff+vcount], inde[ioff:ioff+icount], sceneg)) partcount+=1 else: bgl.seek(size,1) else: bgl.seek(size,1) elif c=='PLAL': while bgl.tell()<end2: (c,size,end3)=container(bgl,3) if c=='PLAT': (surface,sceneg,numvert,v0x,v0y,v0z,v1x,v1y,v1z,v2x,v2y,v2z)=unpack('<3I9f', bgl.read(48)) assert (numvert==3) #print (surface,scene,numvert,v0x,v0y,v0z,v1x,v1y,v1z,v2x,v2y,v2z) if not sceneg in plat: plat[sceneg]={} plat[sceneg][((round(v2x,VROUND),round(v2y,VROUND),round(v2z,VROUND)),(round(v1x,VROUND),round(v1y,VROUND),round(v1z,VROUND)),(round(v0x,VROUND),round(v0y,VROUND),round(v0z,VROUND)))]=surface else: bgl.seek(size,1) elif c=='REFL': while bgl.tell()<end2: (c,size,end3)=container(bgl,3) if c=='REFP': (sceneg,size)=unpack('<II', bgl.read(8)) atta.append((bgl.read(size).strip('\0').strip(),sceneg)) else: bgl.seek(size,1) elif c=='ATTO': while bgl.tell()<end2: (unk,flags,size)=unpack('<IHH', bgl.read(8)) d=bgl.read(size) if flags==2: # Attached object attobjs.append((d[40:-5], '{%x-%x-%x-%x%x-%x%x%x%x%x%x}' % unpack('<IHH8B', d[20:36]))) elif flags==4: # Attached effect p=d[100:-5].split('\0') # params, attachpt atteffects.append((p[1], d[20:100].strip(' \0'), p[0])) elif debug: print "Unknown attach %d:\n%s" % (flags, d) else: bgl.seek(size,1) elif c=='EXTE': # FS9 data while bgl.tell()<end1: Window.DrawProgressBar(float(bgl.tell())/(endmdl+endmdl), "Reading ...") (c,size,end2)=container(bgl,2) if c=='TEXT': (bglop,count,reserved)=unpack('<HHI', bgl.read(8)) assert(bglop==0xb7) texnames=[unpack('<4I', bgl.read(16)) + (bgl.read(64).strip('\0').strip(),) for i in range(count)] assert (bgl.read(2)=='\x22\0') # return elif c=='MATE': (bglop,count,reserved)=unpack('<HHI', bgl.read(8)) assert(bglop==0xb6) matlist.extend([unpack('<17f', bgl.read(17*4)) for i in range(count)]) assert (bgl.read(2)=='\x22\0') # return elif c=='VERT': (bglop,count,reserved)=unpack('<HHI', bgl.read(8)) assert(bglop==0xb5) vert.extend([tuple([round(i,VROUND) for i in unpack('<8f',bgl.read(32))]) for j in range(count)]) assert (bgl.read(2)=='\x22\0') # return elif c=='BGL ': code=bgl.read(size) lods=[0] lodno=0 while lodno<len(lods): ip=0 lod=lods[lodno] sceneg=0 curmat=None stack=[] if debug: print "LOD >", lod while True: (bglop,)=unpack('<H', code[ip:ip+2]) if debug: print "%s%04x: %02x" % (' '*len(stack), ip, bglop) ip+=2 # mostly just opcodes from BGLFP.doc if bglop==0x0d: # BGL_JUMP (offset,)=unpack('<h', code[ip:ip+2]) ip=ip-2+offset elif bglop==0x22: # BGLOP_RETURN ip=stack.pop() elif bglop==0x23: # BGLOP_CALL (offset,)=unpack('<h', code[ip:ip+2]) stack.append(ip+2) ip=ip-2+offset elif bglop==0x24: # BGLOP_IFIN1 ip+=8 # assume true elif bglop==0x39: # BGLOP_IFMASK ip+=6 # assume true elif bglop==0x5f: # BGLOP_IFSIZEV (offset,r,pixels)=unpack('<hHH', code[ip:ip+6]) newlod=int(0.5+radius*2475.0/r) if newlod not in lods: lods.append(newlod) if lod<newlod: ip=ip-2+offset else: ip+=6 elif bglop==0x88: # BGLOP_JUMP_32 (offset,)=unpack('<i', code[ip:ip+4]) ip=ip-2+offset elif bglop==0x89: # BGLOP_JUMP_32 (offset,)=unpack('<i', code[ip:ip+4]) assert (offset==-1) ip=ip+4 elif bglop==0x8a: # BGLOP_CALL_32 (offset,)=unpack('<i', code[ip:ip+4]) stack.append(ip+4) ip=ip-2+offset elif bglop==0xa7: # BGLOP_SPRITE_VICALL ip+=20 # ignore elif bglop==0xb3: # BGLOP_IFINF1 ip+=14 # assume true elif bglop==0xb8: # BGLOP_SET_MATERIAL (m,t)=unpack('<hh', code[ip:ip+4]) ip+=4 curmat=getmaterial9(bgldir, m, matlist, t, texnames) elif bglop==0xb9: # BGLOP_DRAW_TRILIST (voff,vcount,icount)=unpack('<3H', code[ip:ip+6]) ip+=6 inde=unpack('<%dH' % icount, code[ip:ip+2*icount]) ip+=2*icount if debug: print "DATA:", lod, sceneg, voff,vcount,icount if not lod in data: data[lod]=[] data[lod].append((curmat, vert[voff:voff+vcount], inde, sceneg)) partcount+=1 elif bglop==0xbd: # BGLOP_END break elif bglop==0xc4: # BGLOP_SET_MATRIX_INDIRECT (sceneg,)=unpack('<H', code[ip:ip+2]) ip+=2 else: assert 0 lodno+=1 # Shift LODs up lods.sort() lods.append(100) for i in range(len(lods)-1,0,-1): data[lods[i]]=data[lods[i-1]] data[lods[0]].pop() elif c=='TRAN': for i in range(0,size,64): tran.append(Matrix(*[unpack('<4f',bgl.read(16)) for j in range(4)])) if debug: print i/64 print tran[i/64] elif c=='ANIC': anicbase=bgl.tell() amap=bgl.read(size) elif c=='SCEN': # Assumed to be after TRAN and ANIC sections (count,)=unpack('<H', bgl.read(2)) scen=[None for i in range(count)] for i in range(count): (n,child,peer,size,offset)=unpack('<4hi', bgl.read(12)) offset=bgl.tell()-12+offset-anicbase if size==6: # Static (bglop,src,dst)=unpack('<3H', amap[offset:offset+6]) assert (bglop==0xc6) thismatrix=tran[src] else: # Animation (x,y,z,dst)=unpack('<3fh', amap[offset+size-14:offset+size]) thismatrix=TranslationMatrix(Vector(x,y,z,0)) scen[n]=(child,peer,thismatrix,-1) elif c=='PLAT': (count,)=unpack('<I', bgl.read(4)) s=[] for i in range(count): (sceneg,offset,numvert,surface)=unpack('<HhHH', bgl.read(8)) assert (numvert==3) # triangle s.append((sceneg,surface)) # Assumes in order so can ignore offset for i in range(count): (sceneg,surface)=s[i] (v0x,v0y,v0z,v1x,v1y,v1z,v2x,v2y,v2z)=unpack('9f', bgl.read(36)) if not sceneg in plat: plat[sceneg]={} plat[sceneg][((round(v0x,VROUND),round(v0y,VROUND),round(v0z,VROUND)),(round(v1x,VROUND),round(v1y,VROUND),round(v1z,VROUND)),(round(v2x,VROUND),round(v2y,VROUND),round(v2z,VROUND)))]=surface elif c=='ATTA': (count,)=unpack('<I', bgl.read(4)) s=[] for i in range(count): (sceneg,offset)=unpack('<Hh', bgl.read(4)) s.append((sceneg)) # Assumes in order so can ignore offset for i in range(count): name='' while True: c=bgl.read(1) if c=='\0': break name=name+c atta.append((name.strip(),s[i])) elif c=='ATTO': # same as FSX while bgl.tell()<end2: (unk,flags,size)=unpack('<IHH', bgl.read(8)) d=bgl.read(size) if flags==2: # Attached object attobjs.append((d[40:-5], '{%x-%x-%x-%x%x-%x%x%x%x%x%x}' % unpack('<IHH8B', d[20:36]))) elif flags==4: # Attached effect p=d[100:-5].split('\0') # params, attachpt atteffects.append((p[1], d[20:100].strip(' \0'), p[0])) elif debug: print "Unknown attach %d:\n%s" % (flags, d) else: bgl.seek(size,1) else: bgl.seek(size,1) bgl.close() # Invert Child/Peer pointers to get parents for i in range(len(scen)): (child, peer, thismatrix, parent)=scen[i] if child!=-1: # child's parent is me (xchild, xpeer, xmatrix, xparent)=scen[child] scen[child]=(xchild, xpeer, xmatrix, i) if peer!=-1: # peer's parent is my parent assert (peer>i) (xchild, xpeer, xmatrix, xparent)=scen[peer] scen[peer]=(xchild, xpeer, xmatrix, parent) if debug: print "TRAN Matrices", len(tran) for i in range(len(tran)): print i print tran[i] #print "Animation map", len(amap) #for i in range(len(amap)): # print i, '->', amap[i] print "Scene Graph", len(scen) for i in range(len(scen)): (child, peer, thismatrix, parent)=scen[i] print i, child, peer, parent print thismatrix scene=Scene.GetCurrent() lods=data.keys() lods.sort() lods.reverse() partno=0.0 for layer in range(len(lods)): for (material, vert, inde, sceneg) in data[lods[layer]]: Window.DrawProgressBar(0.5+partno/(partcount+partcount), "Adding ...") (child, peer, finalmatrix, parent)=scen[sceneg] #print lods[layer] #print sceneg, child, peer, parent while parent!=-1: (child, peer, thismatrix, parent)=scen[parent] finalmatrix=finalmatrix*thismatrix #print finalmatrix if not layer and sceneg in plat: adddata(scene, layer+1, material, vert, inde, finalmatrix, plat[sceneg]) else: adddata(scene, layer+1, material, vert, inde, finalmatrix) partno+=1 if debug: for (sceneg,verts) in plat.iteritems(): if verts: print "Unallocated platforms: sceneg=%d, %d:" % (sceneg, len(verts.keys())) for v in verts.keys(): for vt in v: print "%.4f %.4f %.4f" % vt print # Attach points attachpoints={} for (name, sceneg) in atta: (child, peer, finalmatrix, parent)=scen[sceneg] while parent!=-1: (child, peer, thismatrix, parent)=scen[parent] finalmatrix=finalmatrix*thismatrix attachpoints[name]=addattach(scene, name, finalmatrix) for (name, obj) in attobjs: attachpoints[name].addProperty('guid', obj) for (name, effect, params) in atteffects: attachpoints[name].addProperty('effectName', effect) if params: attachpoints[name].addProperty('effectParams', params) addprops(scene, lods) Window.DrawProgressBar(1, "Finished") Window.WaitCursor(0) except: bgl.close() Window.DrawProgressBar(1, "ERROR") Window.WaitCursor(0) Draw.PupMenu("ERROR%%t|Can't read %s - is this a FSX MDL format file?" % filename)
''' # Debugging me = Blender.Mesh.New() me.verts.extend([p[0:3]]) me.verts.extend([(p-d)[0:3]]) me.edges.extend([0,1]) ob = Blender.Scene.GetCurrent().objects.new(me) ''' return True, p, d # Origin, Direction # Mouse is not in any view, return None. return False, None, None # Constant function variables mouseViewRay.d = Vector(0, 0, 0) # Perspective, 3d mouseViewRay.p = Vector(0, 0, 0) mouseViewRay.fp = Vector(0, 0, 0) mouseViewRay.hms = Vector(0, 0, 0, 0) # ortho only 4d mouseViewRay.ortho_d = Vector(0, 0, 0, 0) # ortho only 4d LMB = Window.MButs['L'] def mouseup(): # Loop until click mouse_buttons = Window.GetMouseButtons() while not mouse_buttons & LMB: Blender.sys.sleep(10) mouse_buttons = Window.GetMouseButtons()
def parse_surf(self, value): i = self.i is_smooth = 0 double_sided = 0 lines = self.lines obj = self.objlist[-1] matlist = obj.matlist numsurf = int(value) NUMSURF = numsurf badface_notpoly = badface_multirefs = 0 while numsurf: flags = lines[i].split()[1][2:] flag = lines[i].split()[1] tristrip = False trifan = False if ((flag == '0x14') | (flag == '0x24') | (flag == '0x34')): tristrip = True if flag == '0x30': trifan = True if len(flags) > 1: flaghigh = int(flags[0]) flaglow = int(flags[1]) else: flaghigh = 0 flaglow = int(flags[0]) is_smooth = flaghigh & 1 twoside = flaghigh & 2 mat = lines[i + 1].split() mat = int(mat[1]) if not mat in matlist: matlist.append(mat) refs = lines[i + 2].split() refs = int(refs[1]) i += 3 face = [] faces = [] edges = [] fuv = [] fuv2 = [] fuvs = [] fuvs2 = [] rfs = refs while rfs: line = lines[i].split() v = int(line[0]) + 1 # + 1 to avoid vindex == 0 uv = [float(line[1]), float(line[2])] if len(line) > 4: uv2 = [float(line[3]), float(line[4])] fuv2.append(Vector(uv2)) face.append(v) fuv.append(Vector(uv)) rfs -= 1 i += 1 #handle triangle strip convert into triangles if tristrip == True: index = 0 even = True tricount = refs - 2 while index < tricount: facet = [] fuvt = [] fuvt2 = [] if even: facet.append(face[index]) uv = fuv[index] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[index] fuvt2.append(uv2) facet.append(face[index + 1]) uv = fuv[index + 1] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[index + 1] fuvt2.append(uv2) facet.append(face[index + 2]) uv = fuv[index + 2] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[index + 2] fuvt2.append(uv2) even = False else: facet.append(face[index]) uv = fuv[index] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[index] fuvt2.append(uv2) facet.append(face[index + 2]) uv = fuv[index + 2] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[index + 2] fuvt2.append(uv2) facet.append(face[index + 1]) uv = fuv[index + 1] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[index + 1] fuvt2.append(uv2) even = True index += 1 #Don't add degenerate triangles this messes up Blender if facet[0] != facet[1] and facet[0] != facet[2]: faces.append(facet) fuvs.append(fuvt) fuvs2.append(fuvt2) elif trifan == True: index = 1 while index < refs - 2: facet = [] fuvt = [] fuvt2 = [] facet.append(face[0]) uv = fuv[0] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[0] fuvt2.append(uv2) facet.append(face[index]) uv = fuv[index] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[index] fuvt2.append(uv2) facet.append(face[index + 1]) uv = fuv[index + 1] fuvt.append(uv) if len(fuv2) > 0: uv2 = fuv2[index + 1] fuvt2.append(uv2) index += 2 elif flaglow: # it's a line or closed line, not a polygon while len(face) >= 2: cut = face[:2] edges.append(cut) face = face[1:] if flaglow == 1 and edges: # closed line face = [edges[-1][-1], edges[0][0]] edges.append(face) else: # polygon Blender.Draw.PupMenu('Polygon found') # check for bad face, that references same vertex more than once lenface = len(face) if lenface < 3: # less than 3 vertices, not a face badface_notpoly += 1 elif sum(map(face.count, face)) != lenface: # multiple references to the same vertex badface_multirefs += 1 else: # ok, seems fine while len(face) > 4: cut = face[:4] cutuv = fuv[:4] face = face[3:] fuv = fuv[3:] face.insert(0, cut[0]) fuv.insert(0, cutuv[0]) faces.append(cut) fuvs.append(cutuv) faces.append(face) fuvs.append(fuv) obj.flist_cfg.extend([[mat, is_smooth, twoside]] * len(faces)) obj.flist_v.extend(faces) obj.flist_uv.extend(fuvs) obj.flist_uv2.extend(fuvs2) obj.elist.extend(edges) # loose edges numsurf -= 1 if badface_notpoly or badface_multirefs: inform('Object "%s" - ignoring bad faces:' % obj.name) if badface_notpoly: inform('\t%d face(s) with less than 3 vertices.' % badface_notpoly) if badface_multirefs: inform( '\t%d face(s) with multiple references to a same vertex.' % badface_multirefs) self.i = i
def getuv(): temp_data = file.read(STRUCT_SIZE_2FLOAT) new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each return Vector(unpack('<2f', temp_data))
def makeMeshMaterialCopy(matName, faces): ''' Make a new mesh with only face the faces that use this material. faces can be any iterable object - containing ints. ''' faceVertUsers = [False] * len(myContextMesh_vertls) ok = 0 for fIdx in faces: for vindex in myContextMesh_facels[fIdx]: faceVertUsers[vindex] = True if matName != None: # if matName is none then this is a set(), meaning we are using the untextured faces and do not need to store textured faces. materialFaces.add(fIdx) ok = 1 if not ok: return myVertMapping = {} vertMappingIndex = 0 vertsToUse = [ i for i in xrange(len(myContextMesh_vertls)) if faceVertUsers[i] ] myVertMapping = dict([(ii, i) for i, ii in enumerate(vertsToUse)]) tempName = '%s_%s' % (contextObName, matName ) # matName may be None. bmesh = bpy.data.meshes.new(tempName) if matName == None: img = None else: bmat = MATDICT[matName][1] bmesh.materials = [bmat] try: img = TEXTURE_DICT[bmat.name] except: img = None bmesh_verts = bmesh.verts bmesh_verts.extend([Vector()]) bmesh_verts.extend([myContextMesh_vertls[i] for i in vertsToUse]) # +1 because of DUMMYVERT face_mapping = bmesh.faces.extend([[ bmesh_verts[myVertMapping[vindex] + 1] for vindex in myContextMesh_facels[fIdx] ] for fIdx in faces], indexList=True) if bmesh.faces and (contextMeshUV or img): bmesh.faceUV = 1 for ii, i in enumerate(faces): # Mapped index- faces may have not been added- if so, then map to the correct index # BUGGY API - face_mapping is not always the right length map_index = face_mapping[ii] if map_index != None: targetFace = bmesh.faces[map_index] if contextMeshUV: # v.index-1 because of the DUMMYVERT targetFace.uv = [ contextMeshUV[vindex] for vindex in myContextMesh_facels[i] ] if img: targetFace.image = img # bmesh.transform(contextMatrix) ob = SCN_OBJECTS.new(bmesh, tempName) ''' if contextMatrix_tx: ob.setMatrix(contextMatrix_tx) ''' if contextMatrix_rot: ob.setMatrix(contextMatrix_rot) importedObjects.append(ob) bmesh.calcNormals()
def animatedensity(self, filenamelist, renderingpath, isovalue): context = self.scene.getRenderingContext() context.extensions = True context.renderPath = renderingpath #context.imageType=Render.JPEG context.sFrame = 1 context.eFrame = 1 context.sizeX = width context.sizeY = height cubeobject = cube(filenamelist[0]) cubeobject.readCube() atoms = [] ipokeytypeloc = Object.IpoKeyTypes.LOC ipokeytyperot = Object.IpoKeyTypes.ROT for i in range(len(cubeobject.atomtypes)): me = Mesh.Primitives.Icosphere( spheresubdivisions, atomicradii.get(cubeobject.atomtypes[i], 2.0)) me.materials = [ materials.get(cubeobject.atomtypes[i], materials["default"]) ] for face in me.faces: face.smooth = True obj = self.scene.objects.new(me, 'Atom') obj.setLocation(cubeobject.coord[i][0], cubeobject.coord[i][1], cubeobject.coord[i][2]) atoms.append(obj) bonds = [] for i in range(len(cubeobject.atomtypes)): for j in range(i + 1, len(cubeobject.atomtypes)): vec1 = Mathutils.Vector(cubeobject.coord[i]) vec2 = Mathutils.Vector(cubeobject.coord[j]) vec = vec2 - vec1 distcovalent = covalentradii.get( cubeobject.atomtypes[i], 2.0) + covalentradii.get( cubeobject.atomtypes[j], 2.0) if (vec.length - distcovalent) <= 0.10 * distcovalent: me = Mesh.Primitives.Tube(32, stickradius, vec.length) for face in me.faces: face.smooth = True obj = self.scene.objects.new(me, 'Cylinder') axis = Mathutils.CrossVecs(Vector([0, 0, 1]), vec) angle = Mathutils.AngleBetweenVecs(Vector([0, 0, 1]), vec) rotmat = Mathutils.RotationMatrix(angle, 4, "R", axis) obj.setMatrix(obj.matrix * rotmat) obj.setLocation((vec1 + vec2) * 0.5) bonds.append([i, j, vec, obj, vec.length]) self.isosurface(cubeobject, isovalue) context.render() filename = "RENDER/image_0000.jpg" context.saveRenderedImage(filename) for j in range(1, len(filenamelist)): print "Rendering:", j filename = "RENDER/image_%04d.jpg" % (j) for ob in self.scene.objects: if "Lobe" in ob.name: self.scene.unlink(ob) cubeobject = cube(filenamelist[j]) cubeobject.readCube() for i in range(len(atoms)): atoms[i].setLocation(cubeobject.coord[i][0], cubeobject.coord[i][1], cubeobject.coord[i][2]) atoms[i].insertIpoKey(ipokeytypeloc) for i in range(len(bonds)): vec1 = Mathutils.Vector(cubeobject.coord[bonds[i][0]]) vec2 = Mathutils.Vector(cubeobject.coord[bonds[i][1]]) vec = vec2 - vec1 dist = vec.length axis = Mathutils.CrossVecs(bonds[i][2], vec) angle = Mathutils.AngleBetweenVecs(bonds[i][2], vec) rotmat = Mathutils.RotationMatrix(angle, 4, "R", axis) bonds[i][3].setMatrix(bonds[i][3].matrix * rotmat) bonds[i][3].setLocation((vec1 + vec2) * 0.5) bonds[i][3].setSize(1.0, 1.0, dist / bonds[i][4]) bonds[i][3].insertIpoKey(ipokeytypeloc) bonds[i][3].insertIpoKey(ipokeytyperot) bonds[i][2] = vec bonds[i][4] = dist self.isosurface(cubeobject, isovalue) context.render() context.saveRenderedImage(filename)