def traverse_dict(self, d): kids_dict = self.kids_dict exp_objs = self.exp_objs keys = d.keys() keys.sort() # sort for predictable output keys.reverse() for k in keys: objname = k[2:] klen = len(d[k]) kids_dict[objname] = klen if self.dont_export(objname): d.pop(k) parent = Object.Get(objname).getParent() if parent: kids_dict[parent.name] -= 1 REPORT_DATA['noexport'].append(objname) continue if klen: self.traverse_dict(d[k]) exp_objs.insert(0, objname) else: if k.find('Em', 0) == 0: # Empty w/o children d.pop(k) parent = Object.Get(objname).getParent() if parent: kids_dict[parent.name] -= 1 else: exp_objs.insert(0, objname)
def set_up(self, args): camera_target = Object.Get('camera_target') camera_target.RotX = math.radians(args['rotation_x']) camera_target.RotY = -math.radians(args['rotation_y']) camera_target.RotZ = math.radians(args['rotation_z']) camera = Camera.Get('camera') camera.angle = args['camera_lens_angle'] camera_ob = Object.Get('camera') camera_ob.LocX = args['camera_distance']
def _calculate_edge_width_and_height(self): # cache -> to decorator? if self._width is not None and self._height is not None: return ob = Object.Get(self.tex_ob_name) me = ob.getData(mesh=True) tex_group = VertexGroup(me, self.name) tex_corner = VertexGroup(me, self.name + '_corner') connected_edges = tex_corner.find_connected_edges() common_edges = connected_edges.intersection(tex_group.edges) cross_product = cross(tex_corner.vertices.pop(), common_edges) face_normal = tex_group.faces.pop().no common_edges = list(common_edges) if vectors_on_same_side(cross_product, face_normal): e1, e2 = common_edges[0], common_edges[1] else: e1, e2 = common_edges[1], common_edges[0] # TODO: it would be better to use avg of edges # (top/bottom, left/right) here self._width, self._height = get_length(e1, ob), get_length(e2, ob)
def main(param_file): Window.WaitCursor(1) camera_parameters = load_camera(param_file) emode = int(Window.EditMode()) if emode: Window.EditMode(0) scene = Scene.GetCurrent() camera_data = create_camera(camera_parameters) scene.objects.new(camera_data) camera = Object.Get(camera_data.name) pose_camera(camera, camera_parameters) scene.objects.camera = camera context = scene.getRenderingContext() context.imageSizeX(int(camera_parameters.getroot().get('Width'))) context.imageSizeY(int(camera_parameters.getroot().get('Height'))) scene.update() Window.RedrawAll() if emode: Window.EditMode(1) Window.WaitCursor(0)
def drawvc(ec): emptyname, coord = ec if Object.Get(emptyname) in G.selection: c = COLOR_VERTSEL else: c = COLOR_VERTUNSEL BGL.glColor4f(c[0], c[1], c[2], c[3]) BGL.glVertex2f(G.zoom * (coord[0] + x0), G.zoom * (coord[1] + y0))
def __init__(self): self.obj = None try: self.obj = Object.Get(PanelRegionHandler.NAME) # Suppress regeneration of panels in v3.0x Scene.GetCurrent().clearScriptLinks(PanelRegionHandler.NAME) except: pass
def endDocument(self): """ Invoked when mesh processing is done. Used for realizing the mesh from collected vertex/faces and texturizing info. """ # report print("Finished loading file, constructing mesh...") Blender.Window.DrawProgressBar(0.9, "Building mesh...") # build object meshtools.create_mesh(self.verts, self.faces, self.objName, self.faceuvs, self.uvs) print("Done, object built") # load corresponding images and set texture Blender.Window.DrawProgressBar(0.95, "Loading/Applying Texture...") colorTex, specTex = None, None # convert images into textures if self.colorTexture: colTexFName = FindTexture(self.path, self.colorTexture) if colTexFName != None: colorImg = Image.Load(colTexFName) colorTex = Texture.New(self.objName + ".col.tx") colorTex.type = Texture.Types.IMAGE colorTex.image = colorImg if self.specTexture: specTexFName = FindTexture(self.path, self.specTexture) if specTexFName != None: specImg = Image.Load(specTexFName) specTex = Texture.New(self.objName + ".spe.tx") specTex.type = Texture.Types.IMAGE specTex.image = specImg # make material with them and all other previously collected data mat = Material.New(self.objName + ".mat") mat.mode |= Material.Modes.TEXFACE | Material.Modes.SHADOW | Material.Modes.TRACEABLE | Material.Modes.ZTRANSP mat.specTransp = 1.0 if self.alpha : mat.alpha = self.alpha if self.rgbCol : mat.rgbCol = self.rgbCol if self.amb : mat.amb = self.amb if self.emit : mat.emit = self.emit if self.spec : mat.spec = self.spec if self.specCol : mat.specCol = self.specCol if colorTex: mat.setTexture(0, colorTex, Texture.TexCo.UV, Texture.MapTo.COL) if specTex: mat.setTexture(1, specTex, Texture.TexCo.UV, Texture.MapTo.SPEC) # apply to mesh obj = Object.Get(self.objName) mesh = obj.data # mesh.mode = NMesh.Modes.NOVNORMALSFLIP # uncomment the following if you want models automatically sub-surfaced """for currFace in mesh.faces: currFace.smooth = 1 mesh.setSubDivLevels([1,2]) mesh.setMode("SubSurf", "TwoSided")""" mesh.setMode("TwoSided") mesh.addMaterial(mat) mesh.update(1) # Done, notify user Blender.Window.DrawProgressBar(1.0, "Done.")
def _adapt_proportions(self, args, image): ob = Object.Get(self.name).getParent() width, height = image.getSize() fac = height / 0.8 box_width = width / fac box_height = height / fac box_depth = max(float(args['box_depth']) / fac, 0.001) ob.setSize(box_depth, box_width, box_height)
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 cleanMeshes(): objs = Object.Get() for o in objs: if o.getType( ) == 'Mesh': #Applies all scales and rotations (imitates CTRL+A behaviour) me = o.getData() mat = Mathutils.Matrix(o.matrix[0][:], o.matrix[1][:], o.matrix[2][:], [.0, .0, .0, 1.0]) me.transform(mat) me.update() o.setEuler(0.0, 0.0, 0.0) o.setSize(1.0, 1.0, 1.0)
def processdummy(model, parent): d = Object.Get(model) dt = d.getType() putlog(NBLog.INFO, "Processing %s (%s)" % (model, dt)) if dt != 'Empty': putlog(NBLog.CRITICAL, "Internal error: Can't process this type here!") return dummy = Dummy() if parent != "NULL": dummy.setParent(parent) dummy.setName(model) dummyloc = d.getLocation() dummy.setPosition(dummyloc) return dummy
def removeUnknownsFromCoords(): """ Checks that all names of empties in G.coordmap actually exist in the scene. If they don't, they're pruned from the map. """ global G for emptyname in G.coordmap.keys(): try: Object.Get(emptyname) except AttributeError: del G.coordmap[emptyname]
def processobject(model, parent, mfile): global scnobjchilds # Process this object #putlog(NBLog.DEBUG, "Processing object %s" % model) thismod = Object.Get(model) mtype = thismod.getType() if mtype == 'Empty': dummy = processdummy(model, parent) mfile.addObject(dummy) elif mtype == 'Mesh': # FIXME: Parent # new Trimesh class doesn't require processtrimesh #trimesh = processtrimesh(model, parent, 1) mfile.addObject(Trimesh(Object.Get(model), parent)) elif mtype == 'Armature': # Special code to handle armature: We process the armature's # children "by hand" to make them parent to the armature's # parent instead of the armature. try: childs = scnobjchilds[model] putlog(NBLog.DEBUG, "%s armature children: %s" % (model, join(childs, ", "))) for mchild in childs: processobject(mchild, parent, mfile) return except KeyError: return else: putlog(NBLog.CRITICAL, "Can't handle object of type %s" % mtype) # Process the children try: children = scnobjchilds[model] except KeyError: return processdownfrom(model, mfile)
def redrawScene(): """ Redraws the Scene. """ # Hide Armature from 3D-view # Disabled because the user might wish to view the armature movement. # for ob in scene.objects: # if ob.type == 'Armature': # ob.layers = [] # ob.makeDisplayList() # Set last frame of timeline to the last frame of the motion last imported. #frames = [ob for ob in scene.objects if ob.name == armature_name][0].getAction().getFrameNumbers() frames = Object.Get(armature_name).getProperty('num_frames').getData() scene.getRenderingContext().endFrame(frames) scene.update(1)
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 execute(self, input_image_path, blender_object): im = Image.Load(input_image_path) im_width, im_height = im.getSize() im_size_ratio = im_width / im_height tex_width = blender_object.texface.width tex_height = blender_object.texface.height tex_size_ratio = tex_width / tex_height ob = Object.Get(blender_object.name).getParent() if tex_size_ratio > im_size_ratio: # scale width scaling_ratio = im_size_ratio / tex_size_ratio ob.SizeY *= scaling_ratio else: # scale height scaling_ratio = tex_size_ratio / im_size_ratio ob.SizeZ *= scaling_ratio return im
def centerNew(): objs = Object.Get() for o in objs: #Make all objects use 'Center New' if o.getType() == 'Mesh': me = o.getData() mat = o.getMatrix() me.transform(mat) me.update() mat = Blender.Mathutils.Matrix([1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]) o.setMatrix(mat) bb = o.getBoundBox() cu = [bb[0][n] + (bb[-2][n] - bb[0][n]) / 2.0 for n in [0, 1, 2]] mat = o.getMatrix() mat = Blender.Mathutils.Matrix(mat[0][:], mat[1][:], mat[2][:], [-cu[0], -cu[1], -cu[2], 1.0]) me.transform(mat) me.update() mat = Blender.Mathutils.Matrix(mat[0][:], mat[1][:], mat[2][:], [cu[0], cu[1], cu[2], 1.0]) o.setMatrix(mat)
def calibrate(camera=None): """ Performs calibration. """ # TODO: Add warnings about insufficient numbers of points if camera == None: camera = G.selection[0] if G.coplanar: target_type = 'coplanar' else: target_type = 'noncoplanar' if G.fullopt: optimization_type = 'full' else: optimization_type = 'three-param' origin_offset = (G.ofsx, G.ofsy, G.ofsz) calcoords = [] for (emptyname, imgcoords) in G.coordmap.items(): m = Object.Get(emptyname).getMatrix('worldspace') xs = m[3][0] ys = m[3][1] zs = m[3][2] xi = imgcoords[0] yi = G.ih - imgcoords[1] # note the change to the y-axis there! #print xs, ys, zs, xi, yi calcoords.append((xs, ys, zs, xi, yi)) cp = Tsai.CameraParameters(image_dim=(G.iw, G.ih)) try: cp = Tsai.calibrate(target_type, optimization_type, calcoords, cp, origin_offset) except Tsai.CalibrationError, msg: menuError(msg) return
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 set_up(self, args, images): cd_lid = Object.Get('cd_lid') cd_lid.RotZ -= math.radians(args['lid_rotation'])
def _remove_floor(self, scene): scene.objects.unlink(Object.Get('floor'))
def eventHandler(event, value): """ General GUI event handler. @param event: Event type. @param value: Value of the event. """ global G if event == Draw.WHEELDOWNMOUSE: setZoom(getWMCoords(), G.zoom * (1.0 - ZOOM_DELTA)) elif event == Draw.WHEELUPMOUSE: setZoom(getWMCoords(), G.zoom * (1.0 + ZOOM_DELTA)) elif event == Draw.MIDDLEMOUSE: if value: G.mousepos = Window.GetMouseCoords() else: G.mousepos = None elif event == Draw.MOUSEX or event == Draw.MOUSEY: mouseButs = Window.GetMouseButtons() if (mouseButs & Draw.MIDDLEMOUSE) and (G.mousepos is not None): nx, ny = Window.GetMouseCoords() dx, dy = nx - G.mousepos[0], ny - G.mousepos[1] G.mousepos = (nx, ny) G.imgpos = [int(G.imgpos[0] + dx), int(G.imgpos[1] + dy)] Draw.Redraw(1) elif G.mode == MODE_ADD: Draw.Redraw(1) elif G.mode == MODE_GRAB: G.havebupclik = True nx, ny = Window.GetMouseCoords() dx, dy = (nx - G.grabpos[0]) / G.zoom, (ny - G.grabpos[1]) / G.zoom G.grabpos = [nx, ny] def translate(x): name = x.getName() if G.coordmap.has_key(name): c = G.coordmap[name] G.coordmap[name] = (c[0] + dx, c[1] + dy) map(translate, G.selection) ## autocalibration.. gets stuck some times.. #if G.last_camera: # calibrate(G.last_camera) Draw.Redraw(1) elif (event == Draw.LEFTMOUSE) or (event == Draw.RETKEY): if (G.mode == MODE_ADD) and (value == 1): x, y = map(int, getWMCoords()) x -= 10 y += 10 G.coordmap[G.curempty.getName()] = wc2ic((x, y)) G.mode = MODE_NORMAL Draw.Redraw(1) elif (G.mode == MODE_GRAB) and (value == 1): G.mode = MODE_NORMAL Draw.Redraw(1) elif (event == Draw.RIGHTMOUSE) and (value == 1): if G.mode == MODE_NORMAL: xi, yi = wc2ic(getWMCoords()) closest = None for (emptyname, coord) in G.coordmap.items(): dist = math.sqrt((coord[0] - xi)**2 + (coord[1] - yi)**2) * G.zoom if (closest == None) or (dist < closest[0]): closest = (dist, emptyname) if closest[0] < MAX_SELECT_DIST: obj = Object.Get(closest[1]) kq = Window.GetKeyQualifiers() if (kq & Window.Qual.LSHIFT) or (kq & Window.Qual.RSHIFT): obj.select(True) else: map(lambda x: x.select(False), G.selection) obj.select(True) Window.RedrawAll() elif (event == Draw.AKEY) and (value == 1): if G.mode == MODE_NORMAL: someSelected = False for (emptyname, coord) in G.coordmap.items(): if Object.Get(emptyname).isSelected(): someSelected = True break newselect = (someSelected == False) map(lambda x: Object.Get(x[0]).select(newselect), G.coordmap.items()) Window.RedrawAll() elif (event == Draw.GKEY) and (value == 1): if G.mode == MODE_NORMAL: G.mode = MODE_GRAB G.grabpos = Window.GetMouseCoords() Draw.Redraw(1) elif event == Draw.UPARROWKEY and value == 1: p = Window.GetMouseCoords() Window.SetMouseCoords(p[0], p[1] + 1) elif event == Draw.DOWNARROWKEY and value == 1: p = Window.GetMouseCoords() Window.SetMouseCoords(p[0], p[1] - 1) elif event == Draw.LEFTARROWKEY and value == 1: p = Window.GetMouseCoords() Window.SetMouseCoords(p[0] - 1, p[1]) elif event == Draw.RIGHTARROWKEY and value == 1: p = Window.GetMouseCoords() Window.SetMouseCoords(p[0] + 1, p[1]) elif event == Draw.XKEY and value == 1: if len(G.selection) > 0: result = Draw.PupMenu('OK?%t|Erase selected') if result == 1: buttonEventHandler(BUTTON_DELETE) elif event == Draw.SPACEKEY and value == 1: if (G.curempty is not None) and not (G.coordmap.has_key( G.curempty.getName())): buttonEventHandler(BUTTON_ADD) elif event == Draw.ZKEY and value == 1: x, y, w, h = getWinRect() setZoom((w / 2, h / 2), 1.0) elif event == Draw.RKEY and value == 1: Draw.Redraw(1)
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 CloneCamera(self, camera, name_suffix): dataName = camera.getName() + "_DATA" + name_suffix objectName = camera.getName() + name_suffix # NOTE: this try: except: may not be needed. If the cameraObject # below is a copy of the original camera, then its cameraData # is not what we recover or construct here. try: # try to recover existing camera and camera data objects # if these throw an exception its because the names do not # exist and we need to create the first instance print "Looking for data: ", dataName cameraData = Camera.Get(dataName) #print "------- OLD: ", cameraData #cameraData.copy(camera.getData()) #print "------- NEW: ", cameraData #self.UpdateCameraData(cameraData, camera.getData()) print "Got data" except: # NO DATA exists (CONSTRUCT IT) # cameraData = camera.copy() #copy.copy(camera.getData()) #Camera.New("persp") cameraData = camera.getData().copy() # try to match the camera data and camera object names cameraData.name = dataName print "+++++ CONSTRUCTED CAMERA DATA" # NOTE: If we copy the camera Object below rather than construct a new # camera, then the copy links to the original camera data. # Presumably this is fine. Since stereo rigs should have the same # focal distance, lense size, etc as the original camera. # We should consider removing the dependency on recovering the # camera data above. I left it in there now because it adds very # little computation but is a huge life saver if somethign is # wrong. # NOTE: In fact, I can use the shiftX to make the stereo # "Asymmetric Frustrum Parallel Axis Projection Stereo" # (see: http://www.orthostereo.com/geometryopengl.html) try: print "Looking for object: ", objectName cameraObject = Object.Get(objectName) print "Got object" #cameraObject.setName(objectName) self.scene.objects.link(cameraObject) print "+++++ RELINKED", objectName except: # Copy.copy will create a new object, but it will have # all the settings of the original camera. Also, it is NOT # linked to the scene by default #print "BEFOR COPY" #self.PrintAllBlenderCameras() #EB cameraObject = copy.copy(camera) #EB cameraObject.setName(objectName) #print "AFTER COPY" #self.PrintAllBlenderCameras() #print "BEFORE LINK" #self.PrintSceneCameras() #EB self.scene.objects.link(cameraObject) #print "AFTER LINK" #self.PrintSceneCameras() #EB print "++++++ COPIED CAMERA OBJECT" ##### ALTERNATIVE (COMMENT ALL ABOVE (Up to but excluding "except:") TO USE) ##### # this automatically links the camera object into the scene cameraObject = self.scene.objects.new(cameraData) cameraObject.setName(objectName) print "+++++ CONSTRUCTED Camera", cameraObject # Good, I dont need to recapture the cameraData object in the try-catch # above. If I clone the camera object the cameraData belongs to the # original camera. I only need this to get the dept of field (dofDist) # property so I can the crop sizes on the cameras using a parameter # camera separation! cameraData = cameraObject.getData() print "CameraData \'", cameraData.name, "\' DoF: ", cameraData.dofDist, "\t", cameraObject.getData( ).dofDist # TODO: copy all setting of orginal camera into clone return [cameraObject, cameraData]
def processtrimesh(sobj, parent, details): """Process the Object named sobj and return a Trimesh. If details is true, also generates texture and such, otherwise just location, scale and orientation. DEPRECIATED - this should not be used - especially not with the new Trimesh """ # Get the Object block of the current object. obj = Object.Get(sobj) putlog(NBLog.INFO, "Processing %s (%s)" % (sobj, obj.getType())) if obj.getType() != 'Mesh': putlog(NBLog.CRITICAL, "Internal error: can only deal with meshes!") return # get the Mesh block of the Object. mesh = obj.getData() if not mesh: putlog(NBLog.CRITICAL, "Can't get the corresponding mesh. This is strange!") return # Create a new Trimesh to be output. trimesh = Trimesh() trimesh.setParent(model) trimesh.setName(sobj) # Get the object's information. # Location. objloc = obj.getLocation() trimesh.setPosition(objloc) # Rotation r = obj.getEuler() trimesh.setOrientation(r) # Scaling. s = obj.size # Is there a getter for this? Goddamnit. trimesh.setScale(s) if details: # Materials. objmats = obj.getMaterials() if len(objmats) >= 1: putlog(NBLog.SPAM, "Object has material(s).") # We only take the first material, for now. # (We'll do something more elegant later on...) m = objmats[0] trimesh.setWireColor(m.rgbCol) trimesh.setSpecularColor(m.specCol) # Texture texture = Props.getobjecttex(sobj) trimesh.setTexture(texture) # Tilefade tilefade = Props.getobjecttilefade(sobj) trimesh.setTileFade(tilefade) # Get vertex list trimesh.setVerts(mesh.verts) # Get each Face (and Texvert). for f in mesh.faces: trimesh.addFace(f) # Then return it. putlog(NBLog.INFO, "Done: %d vertices, %d faces, %d texverts" % trimesh.stat()) return trimesh
def PrintAllBlenderCameras(self): cams = [ ob.getName() for ob in Object.Get() if ob.getType() == 'Camera' ] print "ALL CAMS IN BLENDER: ", ", ".join(cams)
# The Theory: Now we're f*****g with the Ipo channel here. # We figure out what object the channel corresponds to. # (that seems to be the REALLY DAMN DIFFICULT part right now.) # Then, we just eval the ipo on keyframes OR at set intervals # (depending on what mode we're working on) # and stick those in the Animation's OrientationList and # PositionList. Which is even easier because orientations # are stored in Blender in quaternions already in this case. # And now: How the F**K do we figure out what object the # damn ipo moves? anode.setName(boneipo) # WRONG! DEAD WRONG! print "Getting %s\n" % bone aob = Object.Get(bone) # That dies because the f*****g animation channel names # do NOT correspond with the f*****g bone names and there's # NO f*****g way to find 'em out. (brought to you by Amuse the Greppers, inc) aobtype = aob.getType() if aobtype == 'Empty': anode.setType('dummy') elif aobtype == 'Mesh': anode.setType('trimesh') else: putlog( NBLog.WARNING, "%s is unknown object type (%s), assuming dummy" % (aob, aobtype)) anode.setType('dummy')
def loadanimnode(file, words, data): def getipo(object): try: ipo=Ipo.Get(object.name) except NameError: ipo=Ipo.New('Object', object.name) object.setIpo(ipo) return ipo def getcurves(ipo, list): retlist=[] for curvename in list: curve=ipo.getCurve(curvename) if curve == None: curve=ipo.addCurve(curvename) curve.setInterpolation('Linear') retlist.append(curve) return retlist def getfloatlines(file, words): retlist=[] # Another inconsistency between Torlack's and BioWare's model files # Torlack's decompiler writes the count as with vertices and faces if len(words)==2: count=int(words[1]) while count>0: retlist.append(map(float, file.readline().split())) count-=1 else: line=file.readline().split() while line[0]!='endlist': retlist.append(map(float, line)) line=file.readline().split() return retlist def positionkey(file, words, data): positions=getfloatlines(file, words) if len(positions): ipo=getipo(data['node']) loc=getcurves(ipo, ['LocX', 'LocY', 'LocZ']) if len(loc[0].bezierPoints)==0: origloc=data['node'].loc for i in range(3): loc[i].addBezier((1.0, origloc[i])) for point in positions: time=data['fps']*point[0]+data['animnextframe'] for i in range(3): loc[i].addBezier((time, point[i+1])) for curve in loc: curve.update() def orientationkey(file, words, data): orientations=getfloatlines(file, words) if len(orientations): ipo=getipo(data['node']) rot=getcurves(ipo, ['RotX', 'RotY', 'RotZ']) if len(rot[0].bezierPoints)==0: origrot=map(rad2decadeg, data['node'].getEuler()) for i in range(3): rot[i].addBezier((1.0, origrot[i])) for point in orientations: time=data['fps']*point[0]+data['animnextframe'] prot=map(rad2decadeg, nwn2euler(point[1:5])) for i in range(3): rot[i].addBezier((time, prot[i])) for curve in rot: # This flag tells that we do NOT want radian->degree conversion. # Skipping it breaks the curves since we're adding new points to # existing curves. # 2005-05-15 by w4: this used to be curve.update(1), but looks # like the new Blender API no longer wants any arguments to update(). # This MAY break the whole thing. I couldn't find docs for update()... curve.update() data['node']=Object.Get(words[2]) animnodedict={'positionkey': positionkey, 'orientationkey': orientationkey, 'endnode': linereaderbreak} linereader(file, animnodedict, data, False)
def buildParticles(grains,particles,q): import csv from Blender import Camera, Lamp, Material, Mesh, Object, Constraint scene = bpy.data.scenes.active ############################################################## # Get rid of all object from default scene print 'Removing objects in current scene' for ob in scene.objects: if ((cmp(ob.getName(),'Lamp')==0), (cmp(ob.getName(),'Cube')==0), (cmp(ob.getName(),'Camera')==0)): scene.objects.unlink(ob) print str(ob) + 'removed' print 'Adding new objects' ############################################################## # add mesh at origin to focus camera on # me = Mesh.Primitives.UVsphere(3,3,0) origin = scene.objects.new(me,'Origin') ############################################################## # add a camera and set it up # camdata = Camera.New('ortho') # create new ortho camera data # camdata.scale = 25.0 # set scale value for ortho view cam = scene.objects.new(camdata) # add a new camera object from the data scene.objects.camera = cam # make this camera the active camera # This makes the camera follow the origin ob = Object.Get('Camera') const = ob.constraints.append(Constraint.Type.TRACKTO) const[Constraint.Settings.TARGET] = origin const.__setitem__(Constraint.Settings.TRACK, Constraint.Settings.TRACKNEGZ) const.__setitem__(Constraint.Settings.UP, Constraint.Settings.UPY) ############################################################## # add a lamp and set it up # lampdata = Lamp.New() lampdata.setEnergy(1.0) # lampdata.setType('Sun') lamp = scene.objects.new(lampdata) lamp.setLocation(10.0,-10.0,10.0) lamp.setEuler(0.0,0.0,0.0) ############################################################## # get particle data # for pt in range(particles): me = Mesh.Primitives.UVsphere(q,q,grains[pt,0,3]) # create a new sphere of (segments,rings,diameter) ob = scene.objects.new(me,'Grain' + str(pt)) # add a new mesh-type object to the scene ob.setLocation (grains[pt,0,0], grains[pt,0,1], grains[pt,0,2]) # position the object in the scene # smooth the mesh faces = me.faces # Get the faces. for f in faces: # Loop through them. f.smooth = 1 # Smooth each face. # set the material mat = Material.New('Mat') # create a new Material called 'Mat' mat.rgbCol = [grains[pt,0,4], grains[pt,0,5], grains[pt,0,6]] # change the color of the sphere mat.setAlpha(0.8) # mat.alpha = 0.2 -- almost transparent mat.emit = 0.5 # equivalent to mat.setEmit(0.8) mat.mode |= Material.Modes.ZTRANSP # turn on Z-Buffer transparency mat.setAdd(1) me.materials += [mat]
def main(argv): # get the args passed to blender after "--", all of which are ignored by blender specifically # so python may receive its own arguments if '--' not in argv: argv = [] # as if no args are passed else: argv = argv[argv.index('--')+1: ] # get all args after "--" # When --help or no args are given, print this help usage_text = 'Run blender with this script:' usage_text += ' blender -P AnimateGrains.py -- [options]' parser = optparse.OptionParser(usage = usage_text) # Possible types are: string, int, long, choice, float and complex. parser.add_option('-d', '--directory', dest='data_file_dir', help='This is the directory of the data files', metavar='string') parser.add_option('-s', '--start', dest='file_start', help='This is the first file of data positions', metavar='int') parser.add_option('-f', '--finish', dest='file_end', help='This is the last file of data positions', metavar='int') parser.add_option('-e', '--export', dest='export_dir', help='This is the directory to export renders to', metavar='string') parser.add_option('-q', '--quality', dest='q', help='This is the quality of the individual spheres', metavar='int') parser.add_option('-t', '--particles', dest='particles', help='This is the file containing the contacts', metavar='int') parser.add_option('-r', '--render', dest='render', help='Render an image to the specified path', metavar='string') parser.add_option('-c', '--chain', dest='chain_mode', help='Only show particles in a force chain', metavar='string') options, args = parser.parse_args(argv) # we don't use the args ############################################################## # force a quit if required input not given # if not argv: parser.print_help() sys.exit() if not options.file_start: print 'Error: --start="some file" argument not given, aborting.' parser.print_help() sys.exit() if not options.file_end: print 'Error: --finish="some file" argument not given, aborting.' parser.print_help() sys.exit() if not options.particles: print 'Error: --particles="some number" argument not given, aborting.' parser.print_help() sys.exit() if not options.data_file_dir: print 'Error: --data_file_dir="some file" argument not given, aborting.' parser.print_help() sys.exit() ############################################################## # inputs # data_file_dir = options.data_file_dir file_start = int(options.file_start) file_end = int(options.file_end) particles = int(options.particles) if options.q: q = int(options.q) else: q = 10; if options.render: render = options.render else: render = 'no' if options.export_dir: export_dir = options.export_dir else: export_dir = '//renders/' if options.chain_mode: chain_mode = options.chain_mode else: chain_mode = 'off' # off or on threshold = 0.001 from Blender.Scene import Render # Get the active scene, since there can be multiple ones scene = bpy.data.scenes.active context = scene.getRenderingContext() context.extensions = True context.sizePreset(Render.PREVIEW) context.imageType = Render.AVIRAW # Get data from source files grains = getParticleData(particles,file_end,file_start,data_file_dir) if chain_mode != 'off': print 'Loading contact files' from numpy import zeros chain = zeros((file_end-file_start+1,particles)) for data in range(file_start,file_end+1): A, B = getContactData(data,particles,file_end,file_start,data_file_dir) chain = force_chain(A, B, threshold, grains, data-file_start, particles,chain) else: chain = 'off' # Build initial particles and materials buildParticles(grains,particles,q) # Create IpoCurve for each particle from Blender import Object, Camera print 'Creating IpoCurves for particles' context.sFrame = 1 context.eFrame = file_end - file_start for pt in range(particles): object = Object.Get('Grain' + str(pt)) makeParticleIpo(object, scene.render.sFrame, scene.render.eFrame, 1, grains, pt, chain) # Create IpoCurve for camera object object = Object.Get('Camera') print 'Creating IpoCurve for camera object' makeCameraObjectIpo(object, scene.render.sFrame, scene.render.eFrame, 1) # Create IpoCurve for camera camera! object = Camera.Get('Camera') print 'Creating IpoCurve for camera lens' makeCameraLensIpo(object, scene.render.sFrame, scene.render.eFrame, 1) # Render movie if render == 'yes' or render == 'y': print 'Rendering movie' context.renderPath = export_dir context.renderAnim() else: print 'Not rendering a movie'