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 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 getMeasure(self, human, measurementname, mode):
        measure = 0
        vindex1 = self.Measures[measurementname][0]
        for vindex2 in self.Measures[measurementname]:
            measure += aljabr.vdist(human.meshData.verts[vindex1].co, human.meshData.verts[vindex2].co)
            vindex1 = vindex2

        if mode == 'metric':
            return 10.0 * measure
        else:
            return 10.0 * measure * 0.393700787
 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 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