def hairWidthUpdate(scn, obj,res=0.04, widthFactor=1.0): #luckily both normal and vertex index of object remains the same! N=len(obj.verts) origWidth = vdist(obj.verts[1].co,obj.verts[0].co)/res diff= (widthFactor-origWidth)*res/2 for i in xrange(0,N/2): vec=vmul(vnorm(vsub(obj.verts[i*2+1].co,obj.verts[i*2].co)), diff) obj.verts[i*2].co=vsub(obj.verts[i*2].co,vec) obj.verts[i*2+1].co=vadd(obj.verts[i*2+1].co,vec) obj.verts[i*2].update(updateNor=0) obj.verts[i*2+1].update(updateNor=0)
def setupRigJoint(words, obj, verts, locations): key = words[0] typ = words[1] if typ == 'joint': loc = mh2proxy.calcJointPos(obj, words[2]) locations[key] = loc elif typ == 'vertex': v = int(words[2]) locations[key] = verts[v].co elif typ == 'position': x = locations[words[2]] y = locations[words[3]] z = locations[words[4]] locations[key] = [x[0], y[1], z[2]] elif typ == 'line': k1 = float(words[2]) k2 = float(words[4]) locations[key] = vadd(vmul(locations[words[3]], k1), vmul(locations[words[5]], k2)) elif typ == 'offset': x = float(words[3]) y = float(words[4]) z = float(words[5]) locations[key] = vadd(locations[words[2]], [x, y, z]) elif typ == 'voffset': v = int(words[2]) x = float(words[3]) y = float(words[4]) z = float(words[5]) try: loc = verts[v].co except: loc = verts[v] locations[key] = vadd(loc, [x, y, z]) elif typ == 'front': raw = locations[words[2]] head = locations[words[3]] tail = locations[words[4]] offs = map(float, words[5].strip().lstrip('[').rstrip(']').split(',')) vec = aljabr.vsub(tail, head) vec2 = aljabr.vdot(vec, vec) vraw = aljabr.vsub(raw, head) x = aljabr.vdot(vec, vraw) / vec2 rvec = aljabr.vmul(vec, x) nloc = aljabr.vadd(head, rvec, offs) locations[key] = nloc else: raise NameError("Unknown %s" % typ)
def updatePrism(mesh, o, e, index, p): dir = aljabr.vsub(e, o) # direction vector from o to e if dir == [0.0, 0.0, 0.0]: dir = [0.0, 1.0, 0.0] len = aljabr.vlen(dir) # distance from o to e if len == 0: len = 1 scale = 0.5 # the thickness is 10% of the length i = aljabr.vadd(o, aljabr.vmul(dir, 0.25)) # the thickest part is 25% from o n = aljabr.vmul(dir, 1.0 / len) # the normalized direction q = aljabr.axisAngleToQuaternion( n, pi / 2.0) # a quaternion to rotate the point p1 to obtain the other points p1 = p # a random point in the plane defined by 0,0,0 and n p1 = aljabr.vmul(aljabr.vnorm(p1), scale) # the point scaled to the thickness p2 = aljabr.quaternionVectorTransform(q, p1) # the other points p3 = aljabr.quaternionVectorTransform(q, p2) p4 = aljabr.quaternionVectorTransform(q, p3) p1 = aljabr.vadd(i, p1) # translate by i since we were working in the origin p2 = aljabr.vadd(i, p2) p3 = aljabr.vadd(i, p3) p4 = aljabr.vadd(i, p4) # The 6 vertices mesh.verts[index].co = o mesh.verts[index + 1].co = p1 mesh.verts[index + 2].co = p2 mesh.verts[index + 3].co = p3 mesh.verts[index + 4].co = p4 mesh.verts[index + 5].co = e
def __updateHumanMesh(self, joint, src=None, dst=None): # copy angles bvhName = mhToBvhMapping.get(joint.name, '') if bvhName: bvhJoint = self.__skeleton.getJoint(bvhName) joint.rotation = bvhJoint.rotation[:] else: joint.rotation = [0.0, 0.0, 0.0] joint.calcTransform(False) if not src: src = gui3d.app.selectedHuman.meshStored if not dst: dst = gui3d.app.selectedHuman.meshData.verts nsrc = gui3d.app.selectedHuman.meshStoredNormals for i in joint.bindedVects: #dst[i].co = aljabr.mtransform(joint.transform, aljabr.mtransform(joint.inverseTransform, src[i])) dst[i].co = aljabr.mtransform(joint.transform, aljabr.vsub(src[i], joint.position)) dst[i].no = aljabr.mtransform(joint.normalTransform, nsrc[i]) for child in joint.children: self.__updateHumanMesh(child, src, dst)
def __updatePrism(self, mesh, o, e, index, p): dir = aljabr.vsub(e, o) # direction vector from o to e len = aljabr.vlen(dir) # distance from o to e scale = 0.5 # the thickness is 10% of the length i = aljabr.vadd(o, aljabr.vmul(dir, 0.25)) # the thickest part is 25% from o n = aljabr.vmul(dir, 1.0 / len) # the normalized direction q = aljabr.axisAngleToQuaternion(n, pi / 2.0) # a quaternion to rotate the point p1 to obtain the other points p1 = p # a random point in the plane defined by 0,0,0 and n p1 = aljabr.vmul(aljabr.vnorm(p1), scale) # the point scaled to the thickness p2 = aljabr.quaternionVectorTransform(q, p1) # the other points p3 = aljabr.quaternionVectorTransform(q, p2) p4 = aljabr.quaternionVectorTransform(q, p3) p1 = aljabr.vadd(i, p1) # translate by i since we were working in the origin p2 = aljabr.vadd(i, p2) p3 = aljabr.vadd(i, p3) p4 = aljabr.vadd(i, p4) # The 6 vertices mesh.verts[index].co = o mesh.verts[index+1].co = p1 mesh.verts[index+2].co = p2 mesh.verts[index+3].co = p3 mesh.verts[index+4].co = p4 mesh.verts[index+5].co = e
def saveHairs(self,path): """ Save a file containing the info needed to build the hairstyle, strating from the hair guides and using some parameters. """ try: fileDescriptor = open(path, "w") except: print "Impossible to save %s"%(path) return fileDescriptor.write("written by makehair 1.0\n") fileDescriptor.write("version %s\n"%(self.version)) fileDescriptor.write("tags ") for tag in self.tags: fileDescriptor.write("%s "%(tag)) fileDescriptor.write("\n") fileDescriptor.write("tipMagnet %f\n"%(self.tipMagnet)) fileDescriptor.write("numberOfHairsClump %i\n"%(self.numberOfHairsClump)) fileDescriptor.write("numberOfHairsMultiStrand %i\n"%(self.numberOfHairsMultiStrand)) fileDescriptor.write("randomFactClump %f\n"%(self.randomFactClump)) fileDescriptor.write("randomFactMultiStrand %f\n"%(self.randomFactMultiStrand)) fileDescriptor.write("randomPercentage %f\n"%(self.randomPercentage)) fileDescriptor.write("hairDiameterClump %f\n"%(self.hairDiameterClump)) fileDescriptor.write("hairDiameterMultiStrand %f\n"%(self.hairDiameterMultiStrand)) fileDescriptor.write("sizeClump %f\n"%(self.sizeClump)) fileDescriptor.write("sizeMultiStrand %f\n"%(self.sizeMultiStrand)) fileDescriptor.write("blendDistance %f\n"%(self.blendDistance)) fileDescriptor.write("tipcolor %f %f %f\n"%(self.tipColor[0],self.tipColor[1],self.tipColor[2])) fileDescriptor.write("rootcolor %f %f %f\n"%(self.rootColor[0],self.rootColor[1],self.rootColor[2])) for guideGroup in self.guideGroups: fileDescriptor.write("guideGroup %s\n"%(guideGroup.name)) for guide in guideGroup.guides: fileDescriptor.write("guide %s "%(guide.name)) #Write points coord for cP in guide.controlPoints: fileDescriptor.write("%f %f %f "%(cP[0],cP[1],cP[2])) fileDescriptor.write("\n") for guideGroup in self.guideGroups: print "guidegroup",guideGroup.name for guide in guideGroup.guides: fileDescriptor.write("delta %s "%(guide.name)) #Write points nearest body verts for cP in guide.controlPoints: distMin = 1000 for i in range(len(self.humanVerts)): #later we optimize this using octree v = self.humanVerts[i] dist = aljabr.vdist(cP,v) if dist < distMin: distMin = dist nearVert = v nearVertIndex = i delta = aljabr.vsub(cP,nearVert) fileDescriptor.write("%i %f %f %f "%(nearVertIndex, delta[0],delta[1],delta[2])) fileDescriptor.write("\n") fileDescriptor.close()
def projectLighting(self): mesh = gui3d.app.selectedHuman.mesh mesh.setShadeless(1) dstImg = mh.Image(width=1024, height=1024, bitsPerPixel=24) dstW = dstImg.width dstH = dstImg.height for v in mesh.verts: ld = vnorm(vsub((-10.99, 20.0, 20.0,), v.co)) s = vdot(v.no, ld) s = max(0, min(255, int(s*255))) v.setColor([s, s, s, 255]) for g in mesh.faceGroups: if g.name.startswith("joint") or g.name.startswith("helper"): continue for f in g.faces: co = [(mesh.uvValues[i][0]*dstW, dstH-(mesh.uvValues[i][1]*dstH)) for i in f.uv] c = [v.color for v in f.verts] RasterizeTriangle(dstImg, co[0], co[1], co[2], ColorShader(c[:3])) RasterizeTriangle(dstImg, co[2], co[3], co[0], ColorShader((c[2], c[3], c[0]))) #dstImg.resize(128, 128); dstImg.save(os.path.join(mh.getPath(''), 'data', 'skins', 'lighting.png')) gui3d.app.selectedHuman.setTexture(os.path.join(mh.getPath(''), 'data', 'skins', 'lighting.png')) mesh.setColor([255, 255, 255, 255])
def setupRigJoint (words, obj, verts, locations): key = words[0] typ = words[1] if typ == 'joint': loc = mh2proxy.calcJointPos(obj, words[2]) locations[key] = loc elif typ == 'vertex': v = int(words[2]) locations[key] = verts[v].co elif typ == 'position': x = locations[words[2]] y = locations[words[3]] z = locations[words[4]] locations[key] = [x[0],y[1],z[2]] elif typ == 'line': k1 = float(words[2]) k2 = float(words[4]) locations[key] = vadd(vmul(locations[words[3]], k1), vmul(locations[words[5]], k2)) elif typ == 'offset': x = float(words[3]) y = float(words[4]) z = float(words[5]) locations[key] = vadd(locations[words[2]], [x,y,z]) elif typ == 'voffset': v = int(words[2]) x = float(words[3]) y = float(words[4]) z = float(words[5]) try: loc = verts[v].co except: loc = verts[v] locations[key] = vadd(loc, [x,y,z]) elif typ == 'front': raw = locations[words[2]] head = locations[words[3]] tail = locations[words[4]] offs = map(float, words[5].strip().lstrip('[').rstrip(']').split(',')) vec = aljabr.vsub(tail, head) vec2 = aljabr.vdot(vec, vec) vraw = aljabr.vsub(raw, head) x = aljabr.vdot(vec, vraw) / vec2 rvec = aljabr.vmul(vec, x) nloc = aljabr.vadd(head, rvec, offs) locations[key] = nloc else: raise NameError("Unknown %s" % typ)
def moveOriginToFloor(config): if config.feetonground: the.Origin = the.Locations['floor'] for key in the.Locations.keys(): the.Locations[key] = aljabr.vsub(the.Locations[key], the.Origin) else: the.Origin = [0,0,0] return
def moveOriginToFloor(config): if config.feetonground: the.Origin = the.Locations['floor'] for key in the.Locations.keys(): the.Locations[key] = aljabr.vsub(the.Locations[key], the.Origin) else: the.Origin = [0, 0, 0] return
def writeBone(fp, bone, orig, extra, pad, stuff): (name, children) = bone head = stuff.boneInfo.heads[name] vec = aljabr.vsub(head, orig) printNode(fp, name, vec, extra, pad) for child in children: writeBone(fp, child, head, '', pad + ' ', stuff) fp.write('\n%s </node>' % pad) return
def writeBone(fp, bone, orig, extra, pad, stuff): (name, children) = bone head = stuff.boneInfo.heads[name] vec = aljabr.vsub(head, orig) printNode(fp, name, vec, extra, pad) for child in children: writeBone(fp, child, head, '', pad+' ', stuff) fp.write('\n%s </node>' % pad) return
def placeShadowCamera(self, ribfile): direction = aljabr.vsub(self.lookAt, self.position) #print "VIEW",self.lookAt, self.position #print "DIRECTION: ", direction self.shadowProjection(ribfile) if self.roll: self.shadowRotate(ribfile,-self.roll, 0.0, 0.0, 1.0); self.pointToAim(ribfile, direction); self.shadowTranslate(ribfile, -self.position[0], -self.position[1], -self.position[2])
def __calcJointOffsets(self, mesh, joint, parent=None): """ This function calculates the position and offset for a joint and calls itself for each 'child' joint in the hierarchical joint structure. Parameters ---------- mesh: *Object3D*. The object whose information is to be used for the calculation. joint: *Joint Object*. The joint object to be processed by this function call. parent: *Joint Object*. The parent joint object or 'None' if not specified. """ # Calculate joint positions g = mesh.getFaceGroup(joint.name) verts = [] for f in g.faces: for v in f.verts: verts.append(v.co) joint.position = centroid(verts) joint.transform[3], joint.transform[7], joint.transform[11] = joint.position # Calculate offset if parent: joint.offset = vsub(joint.position, parent.position) else: joint.offset = joint.position[:] """ # Calculate direction direction = vnorm(joint.offset) axis = vnorm(vcross([0.0, 0.0, 1.0], direction)) angle = acos(vdot([0.0, 0.0, 1.0], direction)) joint.direction = axisAngleToQuaternion(axis, angle) # Calculate rotation if parent: v1 = vmul(vnorm(parent.offset), -1.0) v2 = vnorm(joint.offset) axis = vnorm(vcross(v1, v2)) angle = acos(vdot(v1, v2)) joint.rotation = axisAngleToQuaternion(axis, angle) """ # Update counters and set index joint.index = self.joints self.joints += 1 if not joint.children: self.endEffectors += 1 # Calculate child offsets for child in joint.children: self.__calcJointOffsets(mesh, child, joint)
def placeShadowCamera(self, ribfile): direction = aljabr.vsub(self.lookAt, self.position) #print "VIEW",self.lookAt, self.position #print "DIRECTION: ", direction self.shadowProjection(ribfile) if self.roll: self.shadowRotate(ribfile, -self.roll, 0.0, 0.0, 1.0) self.pointToAim(ribfile, direction) self.shadowTranslate(ribfile, -self.position[0], -self.position[1], -self.position[2])
def appendRigBones(boneList, obj, prefix, layer, body, config): for data in boneList: (bone0, head, tail, roll, parent0, options) = data if bone0 in body: continue bone = prefix + bone0 if parent0 == "-": parent = None elif parent0 in body: parent = parent0 else: parent = prefix + parent0 flags = F_DEF|F_CON for (key, value) in options.items(): if key == "-nc": flags &= ~F_CON elif key == "-nd": flags &= ~F_DEF elif key == "-res": flags |= F_RES elif key == "-circ": name = "Circ"+value[0] config.customShapes[name] = (key, int(value[0])) addPoseInfo(bone, ("CS", name), config) flags |= F_WIR elif key == "-box": name = "Box" + value[0] config.customShapes[name] = (key, int(value[0])) addPoseInfo(bone, ("CS", name), config) flags |= F_WIR elif key == "-ik": try: pt = options["-pt"] except KeyError: pt = None log.debug("%s %s", value, pt) value.append(pt) addPoseInfo(bone, ("IK", value), config) elif key == "-ik": pass config.armatureBones.append((bone, roll, parent, flags, layer, NoBB)) the.RigHead[bone] = aljabr.vsub(head, the.Origin) the.RigTail[bone] = aljabr.vsub(tail, the.Origin)
def appendRigBones(boneList, obj, prefix, layer, body, config): for data in boneList: (bone0, head, tail, roll, parent0, options) = data if bone0 in body: continue bone = prefix + bone0 if parent0 == "-": parent = None elif parent0 in body: parent = parent0 else: parent = prefix + parent0 flags = F_DEF | F_CON for (key, value) in options.items(): if key == "-nc": flags &= ~F_CON elif key == "-nd": flags &= ~F_DEF elif key == "-res": flags |= F_RES elif key == "-circ": name = "Circ" + value[0] config.customShapes[name] = (key, int(value[0])) addPoseInfo(bone, ("CS", name), config) flags |= F_WIR elif key == "-box": name = "Box" + value[0] config.customShapes[name] = (key, int(value[0])) addPoseInfo(bone, ("CS", name), config) flags |= F_WIR elif key == "-ik": try: pt = options["-pt"] except KeyError: pt = None log.debug("%s %s", value, pt) value.append(pt) addPoseInfo(bone, ("IK", value), config) elif key == "-ik": pass config.armatureBones.append((bone, roll, parent, flags, layer, NoBB)) the.RigHead[bone] = aljabr.vsub(head, the.Origin) the.RigTail[bone] = aljabr.vsub(tail, the.Origin)
def __calcJointOffsets(self, mesh, joint, parent=None): """ This function calculates the position and offset for a joint and calls itself for each 'child' joint in the hierarchical joint structure. Parameters ---------- mesh: *Object3D*. The object whose information is to be used for the calculation. joint: *Joint Object*. The joint object to be processed by this function call. parent: *Joint Object*. The parent joint object or 'None' if not specified. """ # Calculate joint positions g = mesh.getFaceGroup(joint.name) verts = [] for f in g.faces: for v in f.verts: verts.append(v.co) joint.position = centroid(verts) joint.transform[3], joint.transform[7], joint.transform[ 11] = joint.position # Calculate offset if parent: joint.offset = vsub(joint.position, parent.position) else: joint.offset = joint.position[:] """ # Calculate direction direction = vnorm(joint.offset) axis = vnorm(vcross([0.0, 0.0, 1.0], direction)) angle = acos(vdot([0.0, 0.0, 1.0], direction)) joint.direction = axisAngleToQuaternion(axis, angle) # Calculate rotation if parent: v1 = vmul(vnorm(parent.offset), -1.0) v2 = vnorm(joint.offset) axis = vnorm(vcross(v1, v2)) angle = acos(vdot(v1, v2)) joint.rotation = axisAngleToQuaternion(axis, angle) """ # Update counters and set index joint.index = self.joints self.joints += 1 if not joint.children: self.endEffectors += 1 # Calculate child offsets for child in joint.children: self.__calcJointOffsets(mesh, child, joint)
def addPrism(mesh, o=[0.0, 0.0, 0.0], e=[0.0, 1.0, 0.0], name='prism'): fg = mesh.createFaceGroup(name) dir = aljabr.vsub(e, o) # direction vector from o to e if dir == [0.0, 0.0, 0.0]: dir = [0.0, 1.0, 0.0] len = aljabr.vlen(dir) # distance from o to e if len == 0: len = 1 scale = 0.5 # the thickness is 10% of the length i = aljabr.vadd(o, aljabr.vmul(dir, 0.25)) # the thickest part is 25% from o n = aljabr.vmul(dir, 1.0 / len) # the normalized direction q = aljabr.axisAngleToQuaternion( n, pi / 2.0) # a quaternion to rotate the point p1 to obtain the other points p = p1 = aljabr.randomPointFromNormal( n) # a random point in the plane defined by 0,0,0 and n p1 = aljabr.vmul(aljabr.vnorm(p1), scale) # the point scaled to the thickness p2 = aljabr.quaternionVectorTransform(q, p1) # the other points p3 = aljabr.quaternionVectorTransform(q, p2) p4 = aljabr.quaternionVectorTransform(q, p3) p1 = aljabr.vadd(i, p1) # translate by i since we were working in the origin p2 = aljabr.vadd(i, p2) p3 = aljabr.vadd(i, p3) p4 = aljabr.vadd(i, p4) # The 6 vertices v = [] v.append(mesh.createVertex(o)) # 0 0 v.append(mesh.createVertex(p1)) # 1 /|\ v.append(mesh.createVertex(p2)) # 2 /.2.\ v.append(mesh.createVertex(p3)) # 3 1` | `3 v.append(mesh.createVertex(p4)) # 4 \`.4.`/ v.append(mesh.createVertex(e)) # 5 \ | / # \|/ # 5 # The 8 faces fg.createFace((v[0], v[1], v[4], v[0])) fg.createFace((v[0], v[4], v[3], v[0])) fg.createFace((v[0], v[3], v[2], v[0])) fg.createFace((v[0], v[2], v[1], v[0])) fg.createFace((v[5], v[4], v[1], v[5])) fg.createFace((v[5], v[1], v[2], v[5])) fg.createFace((v[5], v[2], v[3], v[5])) fg.createFace((v[5], v[3], v[4], v[5])) return p
def addPrism(mesh, o=[0.0, 0.0, 0.0], e=[0.0, 1.0, 0.0], name='prism'): fg = mesh.createFaceGroup(name) dir = aljabr.vsub(e, o) # direction vector from o to e if dir == [0.0, 0.0, 0.0]: dir = [0.0, 1.0, 0.0] len = aljabr.vlen(dir) # distance from o to e if len == 0: len = 1 scale = 0.5 # the thickness is 10% of the length i = aljabr.vadd(o, aljabr.vmul(dir, 0.25)) # the thickest part is 25% from o n = aljabr.vmul(dir, 1.0 / len) # the normalized direction q = aljabr.axisAngleToQuaternion(n, pi / 2.0) # a quaternion to rotate the point p1 to obtain the other points p = p1 = aljabr.randomPointFromNormal(n) # a random point in the plane defined by 0,0,0 and n p1 = aljabr.vmul(aljabr.vnorm(p1), scale) # the point scaled to the thickness p2 = aljabr.quaternionVectorTransform(q, p1) # the other points p3 = aljabr.quaternionVectorTransform(q, p2) p4 = aljabr.quaternionVectorTransform(q, p3) p1 = aljabr.vadd(i, p1) # translate by i since we were working in the origin p2 = aljabr.vadd(i, p2) p3 = aljabr.vadd(i, p3) p4 = aljabr.vadd(i, p4) # The 6 vertices v = [] v.append(mesh.createVertex(o)) # 0 0 v.append(mesh.createVertex(p1)) # 1 /|\ v.append(mesh.createVertex(p2)) # 2 /.2.\ v.append(mesh.createVertex(p3)) # 3 1` | `3 v.append(mesh.createVertex(p4)) # 4 \`.4.`/ v.append(mesh.createVertex(e)) # 5 \ | / # \|/ # 5 # The 8 faces fg.createFace((v[0], v[1], v[4], v[0])) fg.createFace((v[0], v[4], v[3], v[0])) fg.createFace((v[0], v[3], v[2], v[0])) fg.createFace((v[0], v[2], v[1], v[0])) fg.createFace((v[5], v[4], v[1], v[5])) fg.createFace((v[5], v[1], v[2], v[5])) fg.createFace((v[5], v[2], v[3], v[5])) fg.createFace((v[5], v[3], v[4], v[5])) return p
def chooseTraslSamples(self): direction = aljabr.vnorm(self.angle) similarity = {} if self.angle != [0.0,0.0,0.0]: for sample in self.examplesTrasl: direction2 = aljabr.vnorm(sample) sampleDistance1 = aljabr.vdist(direction,direction2) sampleDistance2 = math.fabs(aljabr.vlen(aljabr.vsub(self.angle,sample))) similarity[sampleDistance1+sampleDistance2] = sample d = similarity.keys() d.sort() nearestSample1 = similarity[d[0]] nearestSample2 = similarity[d[1]] nearestSample3 = similarity[d[2]] factor1,factor2,factor3 = self.equalize(d[0],d[1],d[2]) return (nearestSample1,nearestSample2,nearestSample3,factor1,factor2,factor3) else: return ([0,0,0],[0,0,0],[0,0,0],0,0,0)
def updateBackground(self): if self.backgroundImage.hasTexture(): reference = gui3d.app.selectedHuman.getPosition() diff = vsub(reference, self.reference) self.leftTop = vadd(self.leftTop, diff) self.rightBottom = vadd(self.rightBottom, diff) leftTop = gui3d.app.modelCamera.convertToScreen(*self.leftTop) rightBottom = gui3d.app.modelCamera.convertToScreen(*self.rightBottom) self.backgroundImage.setPosition([leftTop[0], leftTop[1], 8]) self.backgroundWidth = rightBottom[0]-leftTop[0] self.backgroundHeight = rightBottom[1]-leftTop[1] self.backgroundImage.mesh.resize(self.backgroundWidth, self.backgroundHeight) self.reference = reference
def saveJointDeltas(path): """ Parameters ---------- path: *path*. The file system path to the file to be written. prefix: *string*. The group name of the faces to export. """ activeObjs = Blender.Object.GetSelected() obj = activeObjs[0].getData(mesh=True) vertsGroupsNames = obj.getVertGroupNames() try: fileDescriptor = open(path, "w") except: print "Unable to open %s", (path) return None for name in vertsGroupsNames: if name.split('-')[0] == "joint": diamondIndices = obj.getVertsFromGroup(name) n = closerVert(diamondIndices) v = [obj.verts[n].co[0], obj.verts[n].co[1], obj.verts[n].co[2]] for i in diamondIndices: diamondVert = [ obj.verts[i].co[0], obj.verts[i].co[1], obj.verts[i].co[2] ] delta = aljabr.vsub(diamondVert, v) #index od base vert, index of joint vert, coord 0, coord1 and coord2 of the delta vector fileDescriptor.write("%d %d %f %f %f\n" % (n, i, delta[0], delta[1], delta[2])) else: print name, name.split('-')[0] fileDescriptor.close() return 1
def setShapeScale(words): key = words[1] scales = None try: scales = rig_panel_25.FaceShapeKeyScale[key] except: pass try: scales = rig_body_25.BodyShapeKeyScale[key] except: pass if not scales: raise NameError("No scale for %s" % key) (p1, p2, length0) = scales x1 = the.Locations[p1] x2 = the.Locations[p2] dist = aljabr.vsub(x1, x2) length = aljabr.vlen(dist) scale = length/length0 #print("Scale %s %f %f" % (key, length, scale)) return scale
def setShapeScale(words): key = words[1] scales = None try: scales = rig_panel_25.FaceShapeKeyScale[key] except: pass try: scales = rig_body_25.BodyShapeKeyScale[key] except: pass if not scales: raise NameError("No scale for %s" % key) (p1, p2, length0) = scales x1 = the.Locations[p1] x2 = the.Locations[p2] dist = aljabr.vsub(x1, x2) length = aljabr.vlen(dist) scale = length / length0 #print("Scale %s %f %f" % (key, length, scale)) return scale
def saveJointDeltas(path): """ Parameters ---------- path: *path*. The file system path to the file to be written. prefix: *string*. The group name of the faces to export. """ activeObjs = Blender.Object.GetSelected() obj = activeObjs[0].getData(mesh=True) vertsGroupsNames = obj.getVertGroupNames() try: fileDescriptor = open(path, "w") except: print "Unable to open %s",(path) return None for name in vertsGroupsNames: if name.split('-')[0] == "joint": diamondIndices = obj.getVertsFromGroup(name) n = closerVert(diamondIndices) v = [obj.verts[n].co[0],obj.verts[n].co[1],obj.verts[n].co[2]] for i in diamondIndices: diamondVert = [obj.verts[i].co[0],obj.verts[i].co[1],obj.verts[i].co[2]] delta = aljabr.vsub(diamondVert,v) #index od base vert, index of joint vert, coord 0, coord1 and coord2 of the delta vector fileDescriptor.write("%d %d %f %f %f\n" % (n, i, delta[0],delta[1],delta[2])) else: print name, name.split('-')[0] fileDescriptor.close() return 1
def newSetupJoints (obj, joints): the.Locations = {} for (key, typ, data) in joints: #print(key) if typ == 'j': loc = mh2proxy.calcJointPos(obj, data) the.Locations[key] = loc the.Locations[data] = loc elif typ == 'v': v = int(data) the.Locations[key] = obj.verts[v].co elif typ == 'x': the.Locations[key] = [float(data[0]), float(data[2]), -float(data[1])] elif typ == 'vo': v = int(data[0]) loc = obj.verts[v].co the.Locations[key] = [loc[0]+float(data[1]), loc[1]+float(data[3]), loc[2]-float(data[2])] elif typ == 'vl': ((k1, v1), (k2, v2)) = data loc1 = obj.verts[int(v1)].co loc2 = obj.verts[int(v2)].co the.Locations[key] = vadd(vmul(loc1, k1), vmul(loc2, k2)) elif typ == 'f': (raw, head, tail, offs) = data rloc = the.Locations[raw] hloc = the.Locations[head] tloc = the.Locations[tail] #print(raw, rloc) vec = aljabr.vsub(tloc, hloc) vec2 = aljabr.vdot(vec, vec) vraw = aljabr.vsub(rloc, hloc) x = aljabr.vdot(vec, vraw) / vec2 rvec = aljabr.vmul(vec, x) nloc = aljabr.vadd(hloc, rvec, offs) #print(key, nloc) the.Locations[key] = nloc elif typ == 'b': the.Locations[key] = the.Locations[data] elif typ == 'p': x = the.Locations[data[0]] y = the.Locations[data[1]] z = the.Locations[data[2]] the.Locations[key] = [x[0],y[1],z[2]] elif typ == 'vz': v = int(data[0]) z = obj.verts[v].co[2] loc = the.Locations[data[1]] the.Locations[key] = [loc[0],loc[1],z] elif typ == 'X': r = the.Locations[data[0]] (x,y,z) = data[1] r1 = [float(x), float(y), float(z)] the.Locations[key] = aljabr.vcross(r, r1) elif typ == 'l': ((k1, joint1), (k2, joint2)) = data the.Locations[key] = vadd(vmul(the.Locations[joint1], k1), vmul(the.Locations[joint2], k2)) elif typ == 'o': (joint, offsSym) = data if type(offsSym) == str: offs = the.Locations[offsSym] else: offs = offsSym the.Locations[key] = vadd(the.Locations[joint], offs) else: raise NameError("Unknown %s" % typ) return
def onShow(self, event): gui3d.TaskView.onShow(self, event) human = gui3d.app.selectedHuman human.hide() if not self.mesh: self.mesh = module3d.Object3D('texture_tool') self.mesh.uvValues = [] self.mesh.indexBuffer = [] # create group fg = self.mesh.createFaceGroup('texture_tool') self.mesh.area = 0.0 for f in human.mesh.faces: verts = [self.mesh.createVertex(v.co) for v in f.verts] uv = [human.mesh.uvValues[i] for i in f.uv] face = fg.createFace(verts, uv) face.area = vlen(vcross(vsub(verts[2].co, verts[0].co), vsub(verts[3].co, verts[1].co))) / 2.0 face.uvArea = vlen(vcross(vsub(uv[2] + [0.0], uv[0] + [0.0]), vsub(uv[3] + [0.0], uv[1] + [0.0]))) / 2.0 self.mesh.area += face.area for f in self.mesh.faces: index = min(510, max(0, int(f.uvArea*510.0/(f.area/self.mesh.area)))) if index > 255: f.setColor([255 - (index - 255), 255 - (index - 255), 255, 255]) else: f.setColor([255, index, index, 255]) self.mesh.texture = human.mesh.texture self.mesh.setCameraProjection(0) self.mesh.setShadeless(1) self.mesh.updateIndexBuffer() self.object = self.addObject(gui3d.Object([0, 0, 0], self.mesh, True)) else: self.mesh.area = 0.0 for f in self.mesh.faces: for i, v in enumerate(f.verts): v.co = human.mesh.faces[f.idx].verts[i].co[:] verts = f.verts f.area = vlen(vcross(vsub(verts[2].co, verts[0].co), vsub(verts[3].co, verts[1].co))) / 2.0 self.mesh.area += f.area for f in self.mesh.faces: index = min(510, max(0, int(f.uvArea*510.0/(f.area/self.mesh.area)))) if index > 255: f.setColor([255 - (index - 255), 255 - (index - 255), 255, 255]) else: f.setColor([255, index, index, 255]) self.mesh.update() if self.textured.selected: self.object.setTexture(human.mesh.texture)
def saveTranslationTarget(obj, targetPath, groupToSave=None, epsilon=0.001): """ This function analyses an object to determine the differences between the current set of vertices and the vertices contained in the *originalVerts* list, writing the differences out to disk as a morphing target file. Parameters ---------- obj: *3d object*. The object from which the current set of vertices is to be determined. originalVerts: *list of list*. The positions of vertices in the base reference mesh. This is a list of 3 coordinates of the form: [[x1,y1,z1],[x2,y2,z2],[x3,y3,z3],...[xn,yn,zn]] targetPath: *string*. The file system path to the output file into which the morphing targets will be written. groupToSave: *faceGroup*. It's possible to save only the changes made to a specific part of the mesh object by indicating the face group to save. epsilon: *float*. The distance that a vertex has to have been moved for it to be considered 'moved' by this function. The difference between the original vertex position and the current vertex position is compared to this value. If that difference is greater than the value of epsilon, the vertex is considered to have been modified and will be saved in the output file as a morph target. """ modifiedFacesIndices = {} modifiedVertsIndices = [] originalVerts = files3d.loadVertsCoo(obj.path) if not groupToSave: vertsToSave = xrange(len(obj.verts)) else: pass # TODO verts from group objVerts = obj.verts nVertsExported = 0 if objVerts: for index in vertsToSave: originalVertex = originalVerts[index] targetVertex = objVerts[index] sharedFaces = obj.verts[index].sharedFaces delta = aljabr.vsub(targetVertex.co, originalVertex) dist = aljabr.vdist(originalVertex, targetVertex.co) if dist > epsilon: nVertsExported += 1 dataToExport = [index, delta[0], delta[1], delta[2]] modifiedVertsIndices.append(dataToExport) # for f in sharedFaces: # modifiedFacesIndices[f.idx] = f.idx try: fileDescriptor = open(targetPath, 'w') except: print 'Unable to open %s'%(targetPath) return None # for fidx in modifiedFacesIndices.values(): # fileDescriptor.write("%i " % (fidx)) # fileDescriptor.write("\n") for data in modifiedVertsIndices: fileDescriptor.write('%d %f %f %f\n' % (data[0], data[1], data[2], data[3])) fileDescriptor.close() if nVertsExported == 0: print 'Warning%t|Zero verts exported in file ' + targetPath
def newSetupJoints(obj, joints): the.Locations = {} for (key, typ, data) in joints: #print(key) if typ == 'j': loc = mh2proxy.calcJointPos(obj, data) the.Locations[key] = loc the.Locations[data] = loc elif typ == 'v': v = int(data) the.Locations[key] = obj.verts[v].co elif typ == 'x': the.Locations[key] = [ float(data[0]), float(data[2]), -float(data[1]) ] elif typ == 'vo': v = int(data[0]) loc = obj.verts[v].co the.Locations[key] = [ loc[0] + float(data[1]), loc[1] + float(data[3]), loc[2] - float(data[2]) ] elif typ == 'vl': ((k1, v1), (k2, v2)) = data loc1 = obj.verts[int(v1)].co loc2 = obj.verts[int(v2)].co the.Locations[key] = vadd(vmul(loc1, k1), vmul(loc2, k2)) elif typ == 'f': (raw, head, tail, offs) = data rloc = the.Locations[raw] hloc = the.Locations[head] tloc = the.Locations[tail] #print(raw, rloc) vec = aljabr.vsub(tloc, hloc) vec2 = aljabr.vdot(vec, vec) vraw = aljabr.vsub(rloc, hloc) x = aljabr.vdot(vec, vraw) / vec2 rvec = aljabr.vmul(vec, x) nloc = aljabr.vadd(hloc, rvec, offs) #print(key, nloc) the.Locations[key] = nloc elif typ == 'b': the.Locations[key] = the.Locations[data] elif typ == 'p': x = the.Locations[data[0]] y = the.Locations[data[1]] z = the.Locations[data[2]] the.Locations[key] = [x[0], y[1], z[2]] elif typ == 'vz': v = int(data[0]) z = obj.verts[v].co[2] loc = the.Locations[data[1]] the.Locations[key] = [loc[0], loc[1], z] elif typ == 'X': r = the.Locations[data[0]] (x, y, z) = data[1] r1 = [float(x), float(y), float(z)] the.Locations[key] = aljabr.vcross(r, r1) elif typ == 'l': ((k1, joint1), (k2, joint2)) = data the.Locations[key] = vadd(vmul(the.Locations[joint1], k1), vmul(the.Locations[joint2], k2)) elif typ == 'o': (joint, offsSym) = data if type(offsSym) == str: offs = the.Locations[offsSym] else: offs = offsSym the.Locations[key] = vadd(the.Locations[joint], offs) else: raise NameError("Unknown %s" % typ) return
def projectBackground(self): if not hasattr(self, "leftTop"): gui3d.app.prompt("Warning", "You need to load a background before you can project it.", "OK") return mesh = gui3d.app.selectedHuman.getSeedMesh() # for all quads, project vertex to screen # if one vertex falls in bg rect, project screen quad into uv quad # warp image region into texture leftTop = gui3d.app.modelCamera.convertToScreen(*self.leftTop) rightBottom = gui3d.app.modelCamera.convertToScreen(*self.rightBottom) r = [leftTop[0], leftTop[1], rightBottom[0], rightBottom[1]] srcImg = mh.Image(self.backgroundImage.getTexture()) dstImg = mh.Image(gui3d.app.selectedHuman.getTexture()) srcW = srcImg.width srcH = srcImg.height dstW = dstImg.width dstH = dstImg.height eye = gui3d.app.modelCamera.eye focus = gui3d.app.modelCamera.focus transform = mesh.object3d.transform eye = mtransform(transform, eye) focus = mtransform(transform, focus) camera = vnorm(vsub(eye, focus)) for g in mesh.faceGroups: if g.name.startswith("joint") or g.name.startswith("helper"): continue for f in g.faces: # From hdusel in regard of issue 183: As agreed with marc I'll change the # call from packed to discrete because packed structs # are not available on Python 2.6.1 which is mandatory for MakeHuman to run # on OS X 10.5.x # # src = [gui3d.app.modelCamera.convertToScreen(*v.co, obj=mesh.object3d) for v in f.verts] # src = [gui3d.app.modelCamera.convertToScreen(v.co[0], v.co[1], v.co[2], obj=mesh.object3d) for v in f.verts] if any([pointInRect(p, r) for p in src]): for i, v in enumerate(f.verts): src[i][2] = max(0.0, vdot(v.no, camera)) if any([v[2] >= 0.0 for v in src]): for i, v in enumerate(f.verts): src[i][2] = max(0.0, vdot(v.no, camera)) co = [(mesh.uvValues[i][0]*dstW, dstH-(mesh.uvValues[i][1]*dstH)) for i in f.uv] uva = [((v[0]-leftTop[0])/(rightBottom[0] - leftTop[0]), (v[1]-leftTop[1])/(rightBottom[1] - leftTop[1]), v[2]) for v in src] RasterizeTriangle(dstImg, co[0], co[1], co[2], UvAlphaShader(dstImg, srcImg, (uva[:3]))) RasterizeTriangle(dstImg, co[2], co[3], co[0], UvAlphaShader(dstImg, srcImg, ((uva[2], uva[3], uva[0])))) dstImg.save(os.path.join(mh.getPath(''), 'data', 'skins', 'projection.tga')) gui3d.app.selectedHuman.setTexture(os.path.join(mh.getPath(''), 'data', 'skins', 'projection.tga'))