예제 #1
0
파일: osgbake.py 프로젝트: tetron/osgexport
    def bakeFrames(self, tobake):
        myipoName = tobake.getName()
        debug('Baking frames for scene %s material %s to ipo %s' %
              (bpy.data.scenes.active.getName(), self.material.getName(),
               myipoName))
        ipos = self.getCurves(tobake)
        #TODO: Gui setup idea: myOffset
        # reset action to start at frame 1 or at location
        myOffset = 0  #=1-staframe
        #loop through frames in the animation. Often, there is rollup and the mocap starts late
        staframe, endframe, curframe = getRangeFromIpo(self.material.getIpo())
        for frame in range(staframe, endframe + 1):
            #tell Blender to advace to frame
            Blender.Set(
                'curframe', frame
            )  # computes the constrained location of the 'real' objects

            #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen
            key = self.getColor(
                self.material
            )  #a key is a set of specifed exact channel values (LocRotScale) for a certain frame
            myframe = frame + myOffset
            Blender.Set('curframe', myframe)

            time = Blender.Get('curtime')  #for BezTriple
            ipos = addPoint(time, key,
                            ipos)  #add this data at this time to the ipos
            debug('%s %i %.3f %.2f %.2f %.2f %.2f' %
                  (myipoName, myframe, time, key[0], key[1], key[2], key[3]))
        Blender.Set('curframe', staframe)
        return tobake
예제 #2
0
def getImageFilesFromStateSet(stateset):
    list = []
    if DEBUG: debug("stateset %s" % str(stateset))
    if stateset is not None and len(stateset.texture_attributes) > 0:
        for unit, attributes in stateset.texture_attributes.items():
            for a in attributes:
                if a.className() == "Texture2D":
                    list.append(a.source_image)
    return list
예제 #3
0
파일: osgbake.py 프로젝트: tetron/osgexport
def getRangeFromIpo(ipo):
    first_frame = 1
    last_frame = 1
    for channel in ipo:
        for key in channel.bezierPoints:
            if key.vec[1][0] > last_frame:
                last_frame = int(key.vec[1][0])
    debug("range of ipo %s : %s %s " % (ipo.name, first_frame, last_frame))
    return (first_frame, last_frame, first_frame)
예제 #4
0
def getRangeFromIpo(ipo):
    first_frame = 1
    last_frame = 1
    for channel in ipo:
        for key in channel.bezierPoints:
            if key.vec[1][0] > last_frame:
                last_frame = int(key.vec[1][0])
    debug("range of ipo %s : %s %s " % (ipo.name, first_frame,last_frame))
    return (first_frame, last_frame, first_frame)
예제 #5
0
 def getLocRot(self, ob, space):
     if space in xrange(len(COORDINATE_SYSTEMS)):
         if space == COORD_LOCAL:
             key = self.getLocLocal(ob)
             return key
         elif space == COORD_REAL:
             key = self.getLocReal(ob)
             return key
         else: #hey, programmers make mistakes too.
             debug('Fatal Error: getLoc called with %i' % space)
     return
예제 #6
0
파일: osgbake.py 프로젝트: tetron/osgexport
 def getLocRot(self, ob, space):
     if space in xrange(len(COORDINATE_SYSTEMS)):
         if space == COORD_LOCAL:
             key = self.getLocLocal(ob)
             return key
         elif space == COORD_REAL:
             key = self.getLocReal(ob)
             return key
         else:  #hey, programmers make mistakes too.
             debug('Fatal Error: getLoc called with %i' % space)
     return
예제 #7
0
    def getTypeOfIpo(self, ipo):
        if DEBUG: debug("%s curvs consts %s" % (ipo.name, str(ipo.curveConsts)))
        try:
            ipo.curveConsts['MA_R']
            return "Material"
        except:
            pass

        try:
            ipo.curveConsts['OB_LOCX']
            return "Object"
        except:
            pass
        return None
예제 #8
0
    def createAnimationsFromList(self, animation_list):
        if DEBUG: debug("create animation from list %s" % (str(animation_list)))
        animations_result = {}
        for anim in animation_list:
            res = None
            if len(list(bpy.data.ipos)) and type(anim) is type(list(bpy.data.ipos)[0]):
                ipo2animation = BlenderIpoOrActionToAnimation(ipo = anim, config = self.config)
                res = ipo2animation.createAnimationFromIpo()

            elif len(list(bpy.data.actions)) and type(anim) is type(list(bpy.data.actions)[0]):
                action2animation = BlenderIpoOrActionToAnimation(action = anim, config = self.config)
                res = action2animation.createAnimationFromAction()
            if res is not None:
                if DEBUG: debug("animation \"%s\" created" % (res.name))
                self.animations[res.name] = res
            else:
                log("WARNING can't create animation from %s" % anim)
예제 #9
0
    def adjustUVLayerFromMaterial(self, geom, material):
        uvs = geom.uvs
        if DEBUG: debug("geometry uvs %s" % (str(uvs)))
        geom.uvs = {}

        texture_list = material.getTextures()
        if DEBUG: debug("texture list %s" % str(texture_list))

        # find a default channel if exist uv
        default_uv = None
        default_uv_key = None
        if (len(uvs)) == 1:
            default_uv_key = uvs.keys()[0]
            default_uv = uvs[default_uv_key]

        for i in range(0, len(texture_list)):
            if texture_list[i] is not None:
                uv_layer =  texture_list[i].uvlayer

                if len(uv_layer) > 0 and not uvs.has_key(uv_layer):
                    log("WARNING your material '%s' with texture '%s' use an uv layer '%s' that does not exist on the mesh '%s', use the first uv channel as fallback" % (material.getName(), texture_list[i], uv_layer, geom.name))
                if len(uv_layer) > 0 and uvs.has_key(uv_layer):
                    if DEBUG: debug("texture %s use uv layer %s" % (i, uv_layer))
                    geom.uvs[i] = TexCoordArray()
                    geom.uvs[i].array = uvs[uv_layer].array
                    geom.uvs[i].index = i
                elif default_uv:
                    if DEBUG: debug("texture %s use default uv layer %s" % (i, default_uv_key))
                    geom.uvs[i] = TexCoordArray()
                    geom.uvs[i].index = i
                    geom.uvs[i].array = default_uv.array

        # adjust uvs channels if no textures assigned
        if len(geom.uvs.keys()) == 0:
            if DEBUG: debug("no texture set, adjust uvs channels, in arbitrary order")
            index = 0
            for k in uvs.keys():
                uvs[k].index = index
                index += 1
            geom.uvs = uvs
        return
예제 #10
0
 def createAnimationFromIpo(self, name = None):
     ipo = self.ipos
     if name is None:
         name = "unknown"
     ipos_baked = ipo
     if self.config.anim_bake.lower() == "force":
         ipotype = self.getTypeOfIpo(ipo)
         if DEBUG: debug("createAnimationFromIpo ipo %s of type %s" % (str(name), str(ipotype)))
         if ipotype == "Object":
             obj = findObjectForIpo(ipo)
             baker = BakeIpoForObject(object = obj, ipo = ipo, config = None)
             ipos_baked = baker.getBakedIpos()
         elif ipotype == "Material":
             mat = findMaterialForIpo(ipo)
             baker = BakeIpoForMaterial(material = mat, ipo = ipo, config = None)
             ipos_baked = baker.getBakedIpos()
         else:
             log("WARNING dont know ipo type %s" % ipo.getName())
     animation = Animation()
     animation.setName(ipo.name + "_ipo")
     self.convertIpoToAnimation(name, animation, ipos_baked)
     self.animation = animation
     return animation
예제 #11
0
    def bakeFrames(self, tobake):
	myipoName = tobake.getName()
	debug('Baking frames for scene %s material %s to ipo %s' % (bpy.data.scenes.active.getName(),self.material.getName(),myipoName))
	ipos = self.getCurves(tobake)
	#TODO: Gui setup idea: myOffset
	# reset action to start at frame 1 or at location
	myOffset=0 #=1-staframe
	#loop through frames in the animation. Often, there is rollup and the mocap starts late
	staframe,endframe,curframe = getRangeFromIpo(self.material.getIpo())
	for frame in range(staframe, endframe+1):
		#tell Blender to advace to frame
		Blender.Set('curframe',frame) # computes the constrained location of the 'real' objects
                
		#using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen
		key = self.getColor(self.material) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame
		myframe= frame+myOffset
		Blender.Set('curframe',myframe)
		
		time = Blender.Get('curtime') #for BezTriple
		ipos = addPoint(time, key, ipos) #add this data at this time to the ipos
		debug('%s %i %.3f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3]))
	Blender.Set('curframe',staframe)
        return tobake
예제 #12
0
파일: osgbake.py 프로젝트: tetron/osgexport
    def bakeFrames(
        self, myipo
    ):  #bakes an object in a scene, returning the IPO containing the curves
        myipoName = myipo.getName()
        debug('Baking frames for scene %s object %s to ipo %s' %
              (bpy.data.scenes.active.getName(), self.object.getName(),
               myipoName))
        ipos = self.getCurves(myipo)
        #TODO: Gui setup idea: myOffset
        # reset action to start at frame 1 or at location
        myOffset = 0  #=1-staframe
        #loop through frames in the animation. Often, there is rollup and the mocap starts late
        staframe, endframe, curframe = getRangeFromIpo(self.object.getIpo())
        for frame in range(staframe, endframe + 1):
            #tell Blender to advace to frame
            Blender.Set(
                'curframe', frame
            )  # computes the constrained location of the 'real' objects

            #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen
            key = self.getLocRot(
                self.object, usrCoord
            )  #a key is a set of specifed exact channel values (LocRotScale) for a certain frame
            key = [a + b
                   for a, b in zip(key, usrDelta)]  #offset to the new location
            myframe = frame + myOffset
            Blender.Set('curframe', myframe)

            time = Blender.Get('curtime')  #for BezTriple
            ipos = addPoint(time, key,
                            ipos)  #add this data at this time to the ipos
            debug('%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f' %
                  (myipoName, myframe, time, key[0], key[1], key[2], key[3],
                   key[4], key[5], key[6], key[7], key[8]))
        Blender.Set('curframe', staframe)
        return myipo
예제 #13
0
    def bakeFrames(self, myipo): #bakes an object in a scene, returning the IPO containing the curves
        myipoName = myipo.getName()
        debug('Baking frames for scene %s object %s to ipo %s' % (bpy.data.scenes.active.getName(),self.object.getName(),myipoName))
        ipos = self.getCurves(myipo)
            #TODO: Gui setup idea: myOffset
            # reset action to start at frame 1 or at location
        myOffset=0 #=1-staframe
            #loop through frames in the animation. Often, there is rollup and the mocap starts late
        staframe,endframe,curframe = getRangeFromIpo(self.object.getIpo())
        for frame in range(staframe, endframe+1):
                    #tell Blender to advace to frame
            Blender.Set('curframe',frame) # computes the constrained location of the 'real' objects

                    #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen
            key = self.getLocRot(self.object,usrCoord) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame
            key = [a+b for a,b in zip(key, usrDelta)] #offset to the new location
            myframe= frame+myOffset
            Blender.Set('curframe',myframe)

            time = Blender.Get('curtime') #for BezTriple
            ipos = addPoint(time,key,ipos) #add this data at this time to the ipos
            debug('%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8]))
        Blender.Set('curframe',staframe)
        return myipo
예제 #14
0
    def getBakedAction(self, sample_rate = 25):
        """
            Bakes supplied action for supplied armature.
            Returns baked action.
        """
        pose = self.armature.getPose()
        armature_data = self.armature.getData();
        pose_bones = pose.bones.values()
        rest_bones = armature_data.bones

        POSE_XFORM = [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT, Blender.Object.Pose.SIZE ]
        #POSE_XFORM= [Object.Pose.LOC,Object.Pose.ROT,Object.Pose.SIZE]

        blender_fps = 25
        if sample_rate > blender_fps:
            sample_rate = blender_fps
        step = blender_fps / sample_rate

        startFrame= min(self.action.getFrameNumbers());
        endFrame= max(self.action.getFrameNumbers());


        dummy_action_name = "_" + self.action.name
        # Get the dummy action if it has no users
        try:
            baked_action = bpy.data.actions[dummy_action_name]
        except:
            baked_action = None

        if not baked_action:
            baked_action          = bpy.data.actions.new(dummy_action_name)
            baked_action.fakeUser = False
        for channel in baked_action.getChannelNames():
            baked_action.removeChannel(channel)

        old_quats={}
        old_locs={}
        old_sizes={}

        baked_locs={}
        baked_quats={}
        baked_sizes={}

        self.action.setActive(self.armature)
        frames = range(startFrame, endFrame+1, int(step))
        if frames[-1:] != endFrame :
            frames.append(endFrame)

        for current_frame in frames:

            Blender.Set('curframe', current_frame)
            time = Blender.Get('curtime') #for BezTriple
            debug('%s %i %.3f' % (self.action.name, current_frame, time))

            for i in range(len(pose_bones)):

                bone_name=pose_bones[i].name

                rest_bone=rest_bones[bone_name]
                matrix = Matrix(pose_bones[i].poseMatrix)
                rest_matrix= Matrix(rest_bone.matrix['ARMATURESPACE'])

                parent_bone=rest_bone.parent

                if parent_bone:
                    parent_pose_bone=pose.bones[parent_bone.name]
                    matrix=matrix * Matrix(parent_pose_bone.poseMatrix).invert()
                    rest_matrix=rest_matrix * Matrix(parent_bone.matrix['ARMATURESPACE']).invert()

                #print "before\n", matrix
                #print "before quat\n", pose_bones[i].quat;

                #print "localised pose matrix\n", matrix
                #print "localised rest matrix\n", rest_matrix
                matrix=matrix * Matrix(rest_matrix).invert()


                old_quats[bone_name] = Quaternion(pose_bones[i].quat);
                old_locs[bone_name] = Vector(pose_bones[i].loc);
                old_sizes[bone_name] = Vector(pose_bones[i].size);

                baked_locs[bone_name] = Vector(matrix.translationPart())
                baked_quats[bone_name] = Quaternion(matrix.toQuat())
                baked_sizes[bone_name] = Vector(matrix.scalePart())

            baked_action.setActive(self.armature)
            Blender.Set('curframe', current_frame)
            for i in range(len(pose_bones)):
                pose_bones[i].quat = baked_quats[pose_bones[i].name]
                pose_bones[i].loc = baked_locs[pose_bones[i].name]
                pose_bones[i].size = baked_sizes[pose_bones[i].name]
                pose_bones[i].insertKey(self.armature, current_frame, POSE_XFORM)

            self.action.setActive(self.armature)
            Blender.Set('curframe', current_frame)

            for name, quat in old_quats.iteritems():
                pose.bones[name].quat=quat

            for name, loc in old_locs.iteritems():
                pose.bones[name].loc=loc

        pose.update()
        self.result_action = baked_action
        return baked_action
예제 #15
0
파일: osgbake.py 프로젝트: tetron/osgexport
    def getBakedAction(self, sample_rate=25):
        """
            Bakes supplied action for supplied armature.
            Returns baked action.
        """
        pose = self.armature.getPose()
        armature_data = self.armature.getData()
        pose_bones = pose.bones.values()
        rest_bones = armature_data.bones

        POSE_XFORM = [
            Blender.Object.Pose.LOC, Blender.Object.Pose.ROT,
            Blender.Object.Pose.SIZE
        ]
        #POSE_XFORM= [Object.Pose.LOC,Object.Pose.ROT,Object.Pose.SIZE]

        blender_fps = 25
        if sample_rate > blender_fps:
            sample_rate = blender_fps
        step = blender_fps / sample_rate

        startFrame = min(self.action.getFrameNumbers())
        endFrame = max(self.action.getFrameNumbers())

        dummy_action_name = "_" + self.action.name
        # Get the dummy action if it has no users
        try:
            baked_action = bpy.data.actions[dummy_action_name]
        except:
            baked_action = None

        if not baked_action:
            baked_action = bpy.data.actions.new(dummy_action_name)
            baked_action.fakeUser = False
        for channel in baked_action.getChannelNames():
            baked_action.removeChannel(channel)

        old_quats = {}
        old_locs = {}
        old_sizes = {}

        baked_locs = {}
        baked_quats = {}
        baked_sizes = {}

        self.action.setActive(self.armature)
        frames = range(startFrame, endFrame + 1, int(step))
        if frames[-1:] != endFrame:
            frames.append(endFrame)

        for current_frame in frames:

            Blender.Set('curframe', current_frame)
            time = Blender.Get('curtime')  #for BezTriple
            debug('%s %i %.3f' % (self.action.name, current_frame, time))

            for i in range(len(pose_bones)):

                bone_name = pose_bones[i].name

                rest_bone = rest_bones[bone_name]
                matrix = Matrix(pose_bones[i].poseMatrix)
                rest_matrix = Matrix(rest_bone.matrix['ARMATURESPACE'])

                parent_bone = rest_bone.parent

                if parent_bone:
                    parent_pose_bone = pose.bones[parent_bone.name]
                    matrix = matrix * Matrix(
                        parent_pose_bone.poseMatrix).invert()
                    rest_matrix = rest_matrix * Matrix(
                        parent_bone.matrix['ARMATURESPACE']).invert()

                #print "before\n", matrix
                #print "before quat\n", pose_bones[i].quat;

                #print "localised pose matrix\n", matrix
                #print "localised rest matrix\n", rest_matrix
                matrix = matrix * Matrix(rest_matrix).invert()

                old_quats[bone_name] = Quaternion(pose_bones[i].quat)
                old_locs[bone_name] = Vector(pose_bones[i].loc)
                old_sizes[bone_name] = Vector(pose_bones[i].size)

                baked_locs[bone_name] = Vector(matrix.translationPart())
                baked_quats[bone_name] = Quaternion(matrix.toQuat())
                baked_sizes[bone_name] = Vector(matrix.scalePart())

            baked_action.setActive(self.armature)
            Blender.Set('curframe', current_frame)
            for i in range(len(pose_bones)):
                pose_bones[i].quat = baked_quats[pose_bones[i].name]
                pose_bones[i].loc = baked_locs[pose_bones[i].name]
                pose_bones[i].size = baked_sizes[pose_bones[i].name]
                pose_bones[i].insertKey(self.armature, current_frame,
                                        POSE_XFORM)

            self.action.setActive(self.armature)
            Blender.Set('curframe', current_frame)

            for name, quat in old_quats.iteritems():
                pose.bones[name].quat = quat

            for name, loc in old_locs.iteritems():
                pose.bones[name].loc = loc

        pose.update()
        self.result_action = baked_action
        return baked_action
예제 #16
0
    def createGeomForMaterialIndex(self, material_index, mesh):
        geom = Geometry()
        geom.groups = {}
        if (len(mesh.faces) == 0):
            #log("object %s has no faces, so no materials" % self.object.getName())
            log("object %s has no faces, so no materials, checking for vertexes" % self.object.getName())
            result = self.createModelWithoutFaces(mesh, geom)
            return result
            
        if len(mesh.materials):
            title = "mesh %s with material %s" % (self.object.getName(), mesh.materials[material_index])
        else:
            title = "mesh %s without material" % (self.object.getName())
        log(title)

        vertexes = []
        collected_faces = []
        for face in mesh.faces:
            if face.mat != material_index:
                continue
            f = []
            if DEBUG: fdebug = []
            for vertex in face.verts:
                index = len(vertexes)
                vertexes.append(vertex)
                f.append(index)
                if DEBUG: fdebug.append(vertex.index)
            if DEBUG: debug("true face %s" % str(fdebug))
            if DEBUG: debug("face %s" % str(f))
            collected_faces.append((face,f))

        if (len(collected_faces) == 0):
            log("object %s has no faces for sub material slot %s" % (self.object.getName(), str(material_index)))
            end_title = '-' * len(title)
            log(end_title)
            return None

        colors = {}
        if mesh.vertexColors:
            names = mesh.getColorLayerNames()
            backup_name = mesh.activeColorLayer
            for name in names:
                mesh.activeColorLayer = name
                mesh.update()
                color_array = []
                for face,f in collected_faces:
                    for i in range(0, len(face.verts)):
                        color_array.append(face.col[i])
                colors[name] = color_array
            mesh.activeColorLayer = backup_name
            mesh.update()

        uvs = {}
        if mesh.faceUV:
            names = mesh.getUVLayerNames()
            backup_name = mesh.activeUVLayer
            for name in names:
                mesh.activeUVLayer = name
                mesh.update()
                uv_array = []
                for face,f in collected_faces:
                    for i in range(0, len(face.verts)):
                        uv_array.append(face.uv[i])
                uvs[name] = uv_array
            mesh.activeUVLayer = backup_name
            mesh.update()

        normals = []
        for face,f in collected_faces:
            if face.smooth:
                for vert in face.verts:
                    normals.append(vert.no)
            else:
                for vert in face.verts:
                    normals.append(face.no)

        mapping_vertexes = []
        merged_vertexes = []
        tagged_vertexes = []
        for i in range(0,len(vertexes)):
            merged_vertexes.append(i)
            tagged_vertexes.append(False)

        def get_vertex_key(index):
            return (
                (vertexes[index].co[0], vertexes[index].co[1], vertexes[index].co[2]),
                (normals[index][0], normals[index][1], normals[index][2]),
                tuple([tuple(uvs[x][index]) for x in uvs.keys()]),
                tuple([tuple(colors[x][index]) for x in colors.keys()])
                )

        # Build a dictionary of indexes to all the vertexes that
        # are equal.
        vertex_dict = {}
        for i in range(0, len(vertexes)):
            key = get_vertex_key(i)
            if vertex_dict.has_key(key):
                vertex_dict[key].append(i)
            else:
                vertex_dict[key] = [i]

        for i in range(0, len(vertexes)):
            if tagged_vertexes[i] is True: # avoid processing more than one time a vertex
                continue
            index = len(mapping_vertexes)
            merged_vertexes[i] = index
            mapping_vertexes.append([i])
            if DEBUG: debug("process vertex %s" % i)
            vertex_indexes = vertex_dict[get_vertex_key(i)]
            for j in vertex_indexes:
                if j <= i:
                    continue
                if tagged_vertexes[j] is True: # avoid processing more than one time a vertex
                    continue
                if DEBUG: debug("   vertex %s is the same" % j)
                merged_vertexes[j] = index
                tagged_vertexes[j] = True
                mapping_vertexes[index].append(j)

        if DEBUG:
            for i in range(0, len(mapping_vertexes)):
                debug("vertex %s contains %s" % (str(i), str(mapping_vertexes[i])))

        if len(mapping_vertexes) != len(vertexes):
            log("vertexes reduced from %s to %s" % (str(len(vertexes)),len(mapping_vertexes)))
        else:
            log("vertexes %s" % str(len(vertexes)))

        faces = []
        for (original, face) in collected_faces:
            f = []
            if DEBUG: fdebug = []
            for v in face:
                f.append(merged_vertexes[v])
                if DEBUG: fdebug.append(vertexes[mapping_vertexes[merged_vertexes[v]][0]].index)
            faces.append(f)
            if DEBUG: debug("new face %s" % str(f))
            if DEBUG: debug("true face %s" % str(fdebug))
            
        log("faces %s" % str(len(faces)))

	vgroups = {}
        original_vertexes2optimized = {}
        for i in range(0, len(mapping_vertexes)):
            for k in mapping_vertexes[i]:
                index = vertexes[k].index
                if not original_vertexes2optimized.has_key(index):
                    original_vertexes2optimized[index] = []
                original_vertexes2optimized[index].append(i)

	for i in mesh.getVertGroupNames():
            verts = {}
            for idx, weight in mesh.getVertsFromGroup(i, 1):
                if weight < 0.001:
                    log( "WARNING " + str(idx) + " to has a weight too small (" + str(weight) + "), skipping vertex")
                    continue
                if original_vertexes2optimized.has_key(idx):
                    for v in original_vertexes2optimized[idx]:
                        if not verts.has_key(v):
                            verts[v] = weight
                        #verts.append([v, weight])
            if len(verts) == 0:
                log( "WARNING " + str(i) + " has not vertexes, skip it, if really unsued you should clean it")
            else:
                vertex_weight_list = [ list(e) for e in verts.items() ]
                vg = VertexGroup()
                vg.targetGroupName = i
                vg.vertexes = vertex_weight_list
                vgroups[i] = vg

        if (len(vgroups)):
            log("vertex groups %s" % str(len(vgroups)))
        geom.groups = vgroups
        
        osg_vertexes = VertexArray()
        osg_normals = NormalArray()
        osg_uvs = {}
        osg_colors = {}
        for vertex in mapping_vertexes:
            vindex = vertex[0]
            coord = vertexes[vindex].co
            osg_vertexes.array.append([coord[0], coord[1], coord[2] ])

            ncoord = normals[vindex]
            osg_normals.array.append([ncoord[0], ncoord[1], ncoord[2]])

            for name in uvs.keys():
                if not osg_uvs.has_key(name):
                    osg_uvs[name] = TexCoordArray()
                osg_uvs[name].array.append(uvs[name][vindex])

        if (len(osg_uvs)):
            log("uvs channels %s - %s" % (len(osg_uvs), str(osg_uvs.keys())))

        nlin = 0
        ntri = 0
        nquad = 0
        # counting number of lines, triangles and quads
        for face in faces:
            nv = len(face)
            if nv == 2:
                nlin = nlin + 1
            elif nv == 3:
                ntri = ntri + 1
            elif nv == 4:
                nquad = nquad + 1
            else:
                log("WARNING can't manage faces with %s vertices" % nv)

        # counting number of primitives (one for lines, one for triangles and one for quads)
        numprims = 0
        if (nlin > 0):
            numprims = numprims + 1
        if (ntri > 0):
            numprims = numprims + 1
        if (nquad > 0):
            numprims = numprims + 1

        # Now we write each primitive
        primitives = []
        if nlin > 0:
            lines = DrawElements()
            lines.type = "LINES"
            nface=0
            for face in faces:
                nv = len(face)
                if nv == 2:
                    lines.indexes.append(face[0])
                    lines.indexes.append(face[1])
                nface = nface + 1
            primitives.append(lines)

        if ntri > 0:
            triangles = DrawElements()
            triangles.type = "TRIANGLES"
            nface=0
            for face in faces:
                nv = len(face)
                if nv == 3:
                    triangles.indexes.append(face[0])
                    triangles.indexes.append(face[1])
                    triangles.indexes.append(face[2])
                nface = nface + 1
            primitives.append(triangles)

        if nquad > 0:
            quads = DrawElements()
            quads.type = "QUADS"
            nface=0
            for face in faces:
                nv = len(face)
                if nv == 4:
                    quads.indexes.append(face[0])
                    quads.indexes.append(face[1])
                    quads.indexes.append(face[2])
                    quads.indexes.append(face[3])
                nface = nface + 1
            primitives.append(quads)

        geom.uvs = osg_uvs
        geom.vertexes = osg_vertexes
        geom.normals = osg_normals
        geom.primitives = primitives
        geom.setName(self.object.getName())
        geom.stateset = self.createStateSet(material_index, mesh, geom)

        if len(mesh.materials) > 0 and mesh.materials[material_index] is not None:
            self.adjustUVLayerFromMaterial(geom, mesh.materials[material_index])

        end_title = '-' * len(title)
        log(end_title)
        return geom
예제 #17
0
    def createStateSet(self, index_material, mesh, geom):
        s = StateSet()
        if len(mesh.materials) > 0:
            mat_source = mesh.materials[index_material]
            if self.uniq_stateset.has_key(mat_source):
                #s = ShadowObject(self.uniq_stateset[mat_source])
                s = self.uniq_stateset[mat_source]
                return s

            if mat_source is not None:
                self.uniq_stateset[mat_source] = s
                m = Material()
                m.setName(mat_source.getName())
                s.setName(mat_source.getName())

                anim = createAnimationMaterialAndSetCallback(m, mat_source, self.config)
                if anim :
                    self.material_animations[anim.name] = anim

                mode = mat_source.getMode()
                if mode & Blender.Material.Modes['SHADELESS']:
                    s.modes["GL_LIGHTING"] = "OFF"

                refl = mat_source.getRef()
                m.diffuse = (mat_source.R * refl, mat_source.G * refl, mat_source.B * refl, mat_source.alpha)

                # if alpha not 1 then we set the blending mode on
                if DEBUG: debug("state material alpha %s" % str(mat_source.alpha))
                if mat_source.alpha != 1.0:
                    s.modes["GL_BLEND"] = "ON"

                ambient_factor = mat_source.getAmb()
                m.ambient = (mat_source.R * ambient_factor, mat_source.G * ambient_factor, mat_source.B * ambient_factor, 1)

                spec = mat_source.getSpec()
                m.specular = (mat_source.specR * spec, mat_source.specG * spec, mat_source.specB * spec, 1)

                emissive_factor = mat_source.getEmit()
                m.emission = (mat_source.R * emissive_factor, mat_source.G * emissive_factor, mat_source.B * emissive_factor, 1)
                m.shininess = (mat_source.getHardness() / 512.0) * 128.0

                s.attributes.append(m)

                texture_list = mat_source.getTextures()
                if DEBUG: debug("texture list %s" % str(texture_list))

                for i in range(0, len(texture_list)):
                    if texture_list[i] is not None:
                        t = self.createTexture2D(texture_list[i])
                        if DEBUG: debug("texture %s %s" % (i, texture_list[i]))
                        if t is not None:
                            if not s.texture_attributes.has_key(i):
                                s.texture_attributes[i] = []
                            s.texture_attributes[i].append(t)
                            try:
                                if t.source_image.getDepth() > 24: # there is an alpha
                                    s.modes["GL_BLEND"] = "ON"
                            except:
                                log("can't read the source image file for texture %s" % t)
                if DEBUG: debug("state set %s" % str(s))
        return s
예제 #18
0
    def exportKeyframeSplitRotationTranslationScale(self, ipo, fps):
        SUPPORTED_IPOS = (
            'RotX', 'RotY', 'RotZ',
            'QuatW', 'QuatX', 'QuatY', 'QuatZ',
            'LocX', 'LocY', 'LocZ',
            'ScaleX', 'ScaleY', 'ScaleZ',
            'R', 'G', 'B', 'Alpha'
            )

        channels         = []
        channel_times    = {'EulerX': set(), 'EulerY': set(), 'EulerZ': set(), 'Rotation': set(), 'Translation': set(), 'Scale': set(), 'Color' : set() }
        channel_names    = {'EulerX': 'euler_x', 'EulerY': 'euler_y', 'EulerZ': 'euler_z', 'Rotation': 'rotation', 'Translation': 'translate', 'Scale': 'scale', 'Color' : 'color'}
        channel_samplers = {'EulerX': None, 'EulerY': None, 'EulerZ': None, 'Rotation': None, 'Translation': None, 'Scale': None, 'Color' : None}
        channel_ipos     = {'EulerX': [], 'EulerY': [], 'EulerZ': [], 'Rotation': [], 'Translation': [], 'Scale': [], 'Color': []}
        duration = 0

        for curve in ipo:
            if DEBUG: debug("ipo %s curve %s with %s keys" % (ipo.getName(), curve.name, len(curve.bezierPoints)))
            if curve.name not in SUPPORTED_IPOS:
                if DEBUG: debug("ipo %s curve %s not supported" % (ipo.getName(), curve.name))
                continue

            elif curve.name == "QuatX" or curve.name == "QuatY" or curve.name == "QuatZ" or curve.name == "QuatW":
                times = channel_times['Rotation']
                channel_ipos['Rotation'].append(curve)

            elif curve.name == "RotX":
                times = channel_times['EulerX']
                channel_ipos['EulerX'].append(curve)

            elif curve.name == "RotY":
                times = channel_times['EulerY']
                channel_ipos['EulerY'].append(curve)

            elif curve.name == "RotZ":
                times = channel_times['EulerZ']
                channel_ipos['EulerZ'].append(curve)

            elif curve.name == "LocX" or curve.name == "LocY" or curve.name == "LocZ":
                times = channel_times['Translation']
                channel_ipos['Translation'].append(curve)

            elif curve.name == "ScaleX" or curve.name == "ScaleY" or curve.name == "ScaleZ":
                times = channel_times['Scale']
                channel_ipos['Scale'].append(curve)

            elif curve.name == "R" or curve.name == "G" or curve.name == "B" or curve.name == "Alpha":
                times = channel_times['Color']
                channel_ipos['Color'].append(curve)

            for p in curve.bezierPoints:
                times.add(p.pt[0])

        if DEBUG: debug("ipo %s sort time for curves" % (ipo.getName()))
        for key in channel_times.iterkeys():
            time = list(channel_times[key])
            time.sort()
            channel_times[key] = time

            if len(time) > 0:
                channel_samplers[key] = Channel()
            if DEBUG: debug("ipo %s time sorted %s %s" % (ipo.getName(), key, len(time)))


        if DEBUG: debug("ipo %s fill channels" % (ipo.getName()))
        for key in channel_times.iterkeys():
            if channel_samplers[key] is None:
                if DEBUG: debug("ipo %s nothing to fill for channel %s" % (ipo.getName(), key))
                continue
            if DEBUG: debug("ipo %s fill channel %s" % (ipo.getName(), key))

            #if DEBUG: debug("ipo %s process %s " % (ipo.getName(), key))
            times = channel_times[key]

            for time in times:
                realtime = (time - 1) / fps

                if realtime > duration:
                    duration = realtime

                trans = Vector()
                quat  = Quaternion()
                scale = Vector()
                rot   = Euler()
                color   = [1,1,1,1]
                rtype = None

                # I know this can be cleaned up...
                for curve in channel_ipos[key]:
                    val       = curve[time]
                    if DEBUG: debug("ipo %s process curve %s at %s value is %s" % (ipo.getName(), curve.name, time, val))
                    bezPoints = curve.bezierPoints

                    if curve.name == 'LocX':
                        trans[0] = val
                    elif curve.name == 'LocY':
                        trans[1] = val
                    elif curve.name == 'LocZ':
                        trans[2] = val
                    elif curve.name == 'QuatW':
                        quat.w = val
                    elif curve.name == 'QuatX':
                        quat.x = val
                    elif curve.name == 'QuatY':
                        quat.y = val
                    elif curve.name == 'QuatZ':
                        quat.z = val
                    elif curve.name == 'ScaleX':
                        scale[0] = val
                    elif curve.name == 'ScaleY':
                        scale[1] = val
                    elif curve.name == 'ScaleZ':
                        scale[2] = val
                    elif curve.name == 'RotX':
                        rot.x = val * 10
                    elif curve.name == 'RotY':
                        rot.y = val * 10
                    elif curve.name == 'RotZ':
                        rot.z = val * 10
                    elif curve.name == 'R':
                        color[0] = val
                    elif curve.name == 'G':
                        color[1] = val
                    elif curve.name == 'B':
                        color[2] = val
                    elif curve.name == 'Alpha':
                        color[3] = val
                    else:
                        continue

                if key == 'Scale':
#                    if DEBUG: debug("ipo %s process %s %s %s %s %s" % (ipo.getName(), key, realtime, scale[0], scale[1], scale[2]))
                    channel_samplers[key].keys.append((realtime, scale[0], scale[1], scale[2]))
                    channel_samplers[key].type = "Vec3LinearChannel"
                    channel_samplers[key].setName("scale")

                elif key == 'Rotation':
                    quat.normalize()
                    channel_samplers[key].keys.append((realtime, quat.x, quat.y, quat.z, quat.w))
                    channel_samplers[key].type = "QuatSphericalLinearChannel"
                    channel_samplers[key].setName("quaternion")

                elif key == 'EulerX':
                    channel_samplers[key].keys.append((realtime, math.radians(rot.x)))
                    channel_samplers[key].type = "FloatLinearChannel"
                    channel_samplers[key].setName("euler_x")

                elif key == 'EulerY':
                    channel_samplers[key].keys.append((realtime, math.radians(rot.y)))
                    channel_samplers[key].type = "FloatLinearChannel"
                    channel_samplers[key].setName("euler_y")

                elif key == 'EulerZ':
                    channel_samplers[key].keys.append((realtime, math.radians(rot.z) ))
                    channel_samplers[key].type = "FloatLinearChannel"
                    channel_samplers[key].setName("euler_z")

                elif key == 'Translation':
                    channel_samplers[key].keys.append((realtime, trans[0], trans[1], trans[2]))
                    channel_samplers[key].type = "Vec3LinearChannel"
                    channel_samplers[key].setName("translate")

                elif key == 'Color':
                    channel_samplers[key].keys.append((realtime, color[0], color[1], color[2], color[3]))
                    channel_samplers[key].type = "Vec4LinearChannel"
                    channel_samplers[key].setName("diffuse")

            channels.append(channel_samplers[key])
            #print channel_samplers[key]
        return channels