MStatus MayaFileTranslator::writer( const MFileObject& file, const MString& options, FileAccessMode mode){ //-------------------détection des options transmises par le script MEL--------------- // this will store our option strings MStringArray optionList; // seperate the option string options.split(' ', optionList); // check all of the options int len = optionList.length(); for( int i = 0; i < len; ++i ){ MString Option = optionList[i]; // if we recognised option 1 if( Option == "vertexcolorFlag" ) { // check for true or false if(optionList[++i]=="0") Flags.vertex_colors=0; else Flags.vertex_colors=1; } // if we recognised our second option if( Option == "vertexnormalFlag" ) { // check for true or false if(optionList[++i]=="0") Flags.Normals=0; else Flags.Normals=1; } // if we recognised our third option if( Option == "brushFX" ) { // check for true or false if(optionList[++i]=="0") Flags.use_vertex_colors=1; else Flags.use_vertex_colors=0; } } //----------------------------------fin------------------------ //export Selected Objects if(mode == kExportActiveAccessMode) { //liste des objets sélectionnés MSelectionList selection; MGlobal::getActiveSelectionList( selection ); //MStringArray strings; //MDagPath dagPath; MObject components; MDagPath path; //----- // int temp; //MGlobal::displayInfo("Début exportation des objets sélectionnés"); // ouverture du fichier [BB3D] MString output_filename = file.fullName(); ::output.open(output_filename.asChar(),ios::out |ios::binary); // ecriture header fichier ::output << "BB3D"; // mise en place du Header fichier B3D StartChunck(); // sauv garde de la position du début de fichier //write_int(1);// mise en place d'une valeur entière quelconque pour mise en place ultérieure de la longeur du fichier write_int(1);//écriture de la version BB3D #ifdef OLD_TEXS // écriture des textures si présentent [TEXS]|detection des textures à enregistrer| + fermeture texs ::output << "TEXS";//header Brush StartChunck(); OutputTextures(selection); EndChunck(); // écriture des matériaux [BRUS]|detection des materiaux à enregistrer| +fermeture brus //Matid.clear(); OutputMaterials(selection); #else //nouvelles textures #endif //------------------------------------fin materials---------------------------------- #ifdef SCENE_ROOT // algo des nodes [NODE] réplication de la hierarchie, ::output << "NODE"; // mise en place du Header fichier B3D StartChunck(); //write_int(1);// mise en place d'une valeur quelconque ::output << "Scene Root";//nom du Node ::output << char(0x00);//fin de chaîne //écriture des coordonnées spatiales //transaltion write_float(0);// translation x write_float(0);// translation y write_float(0);// translation z write_float(1);//scale x write_float(1);//scale y write_float(1);//scale z write_float(0);// rotation x write_float(0);// rotation y write_float(0);// rotation z write_float(0);// rotation w #else #endif int pos_objet=0,pos_nouvel_objet; MString nom_objet_precedent; // create an iterator to go through all transforms //MItDag it(MItDag::depth, MFn::kTransform); MItDag it(MItDag::kDepthFirst, MFn::kTransform); // keep looping until done int position_hierarchie=0; int pos=0; while(!it.isDone()) { MString temp; MDagPath path; it.getPath(path); MFnTransform trans(path); MObject obj=it.item(); MStringArray chemin_split; MString chemin=path.fullPathName(); chemin.split((char)'|',chemin_split); pos=chemin_split.length(); //temp=pos; //MGlobal::displayInfo(temp); if(obj.apiType()== MFn::kTransform && path.child(0).apiType()== MFn::kMesh){ //MGlobal::displayInfo("Transform trouvé avec child Kmesh"); //écriture du node avec transform //incrément de la hierarchie if(pos<position_hierarchie || pos==position_hierarchie){ //MGlobal::displayInfo("fermeture des nodes précédents"); for(int i=position_hierarchie;i>pos-1;i--){ //temp = i; //MGlobal::displayInfo(temp); EndChunck(); }//fin for }//fin if //MGlobal::displayInfo("Ouverture node"); ::output << "NODE"; // mise en place du Header node StartChunck(); MString nom_objet; nom_objet=chemin_split[chemin_split.length()-1]; ::output << nom_objet.substring(0,nom_objet.length());//nom du Node ::output << char(0x00);//caractêre de fin de chaîne MVector Translation; // get the transforms local translation Translation = trans.getTranslation(MSpace::kTransform); float temp=(float)Translation.x; //écriture des coordonnées spaciales //transaltion write_float(temp);// translation x temp=(float)Translation.y; write_float(temp);// translation y temp=-(float)Translation.z; write_float(temp);// translation z double scale[3]; trans.getScale(scale); temp=(float)scale[0]; write_float(temp); temp=(float)scale[1]; write_float(temp); temp=(float)scale[2]; write_float(temp); MQuaternion Rotation; trans.getRotation(Rotation,MSpace::kTransform); temp=(float)Rotation.w; write_float(temp); temp=(float)Rotation.x; write_float(temp); temp=(float)Rotation.y; write_float(temp); temp=(float)Rotation.z; write_float(temp); path.getPath(path); if(selection.hasItem(path)!=MStatus::kSuccess){ //MGlobal::displayInfo("présent dans la liste de selection"); //---------exportation du mesh //mais avec des nodes vides, pour les mesh non sélectionnés //----------------------------ecriture mesh si objet polygonal présent ::output << "MESH"; // mise en place du Header mesh StartChunck(); MPointArray vertexArray;// coordonnées des point format double x,y,z; MIntArray vertexList;// stockage des indexs des points pour les triangles MVector Normal;//stockage d'une normal d'un vertex //----------------------coordonnées Vertexs (normal & color si présent et demandés) //master brush //write_int(0xffffffff); write_int(-1);//-1 master brush MFnMesh meshFn(path.child(0)); // crée une fonction pour le mesh MItMeshVertex polyperVertex(path, MObject::kNullObj);// crée une fonction pour le mesh , mais avec les fonctions de itmesh //récupération des coordonnées des points //obtient les coordonnées des vertex en mode global //meshFn.getPoints(vertexArray,MSpace::kObject); meshFn.getPoints(vertexArray,MSpace::kTransform); //MFloatArray uArray; //MFloatArray vArray; //meshFn.getUVs(uArray,vArray);//getUVs( MFloatArray& uArray, MFloatArray& vArray,const MString * uvSet = NULL ) MIntArray uvCounts,uvIds; meshFn.getAssignedUVs(uvCounts,uvIds,0); //ecriture VRTS ::output<<"VRTS"; StartChunck(); //flags 0=none just vertices coords 1=normal values present, 2=rgba values present //The way the flags work, is that you combine them. //1 = Vertex Normal //2 = Vertex Color //3 = Vertex Normal + Color int flag_normal_colors=0; //info = "Normals "; //info += Flags.Normals; //Affich(info); //info = "vertex colors "; //info += Flags.vertex_colors; //Affich(info); flag_normal_colors = Flags.Normals+((Flags.use_vertex_colors && Flags.vertex_colors)*2); //info = flag_normal_colors; //Affich(info); write_int(flag_normal_colors);//présence normale //int tex_coord_sets ;texture coords per vertex (eg: 1 for simple U/V) max=8 write_int(1);//uv simple // int tex_coord_set_size ;components per set (eg: 2 for simple U/V) max=4 write_int(2);//2 coordonées textures float x,y,z,normx,normy,normz;//,normx,normy,normz; for (unsigned int i=0;i<vertexArray.length();i++){ x =float(vertexArray[i].x); // - pour replacer l'axe X dans le sens de celui de blitz y =float(vertexArray[i].y); z =-float(vertexArray[i].z);// - //vertices coords write_float(x); write_float(y); write_float(z); //récupère la normale du point if(flag_normal_colors==1 || flag_normal_colors==3){ meshFn.getVertexNormal(i, Normal ,MSpace::kObject); normx=float(Normal.x); normy=float(Normal.y); normz=float(Normal.z); write_float(normx); write_float(normy); write_float(normz); } //----------------------------------------- //vertex_colors_present=1; if (flag_normal_colors == 2 || flag_normal_colors==3){ MStringArray colorsets; MColorArray color; //status = meshFn.getColorSetNames(colorsets); meshFn.getColorSetNames(colorsets); MColor couleur; MString colorset = colorsets[0]; //récupère la couleur moyenne des faces connectés au point meshFn.getVertexColors(color,&colorset); //polyperVertex.getColor //int a; //meshFn.getColor(a,couleur); //meshFn.getColors(color); couleur=color[i]; float col=float(couleur.r); //R ::output.write((char*)&couleur.r,sizeof(couleur.r)); //write_float(col); col=float(couleur.g); //G ::output.write((char*)&couleur.g,sizeof(couleur.g)); //write_float(col); col=float(couleur.b); //B ::output.write((char*)&couleur.b,sizeof(couleur.b)); //write_float(col); col=float(couleur.a); //Alpha ::output.write((char*)&couleur.a,sizeof(couleur.a)); //write_float(col); } //----------------------------------------- //float tempo; float u,v; MFloatArray uArray; MFloatArray vArray; MIntArray FaceIds; polyperVertex.getUVs(uArray,vArray,FaceIds); //meshFn.getUV(i*2,u,v); u=uArray[0]; v=vArray[0]; //tempo = uArray[0]; //write_float(tempo); //tempo = vArray[0]; //write_float(tempo); write_float(u); write_float(-v); polyperVertex.next(); }//fin for //-----------------fermeture coordonées Vertex EndChunck(); // ----------------------------------export des triangles #ifdef OLD_TRIS //ecriture TRIS ::output<<"TRIS"; StartChunck(); //brush ID write_int(-1);//write_int(0); //MItMeshPolygon itPolygon( path, MObject::kNullObj ); MItMeshPolygon itPolygon(path.child(0)); for ( /* nothing */; !itPolygon.isDone(); itPolygon.next() ) { // Get triangulation of this poly. int numTriangles; itPolygon.numTriangles(numTriangles); while ( numTriangles-- ) { //MGlobal::displayInfo(" triangle"); MStatus status; MIntArray polygonVertices; itPolygon.getVertices( polygonVertices ); MPointArray nonTweaked; // object-relative vertex indices for each triangle MIntArray triangleVertices; // face-relative vertex indices for each triangle MIntArray localIndex; status = itPolygon.getTriangle( numTriangles, nonTweaked, triangleVertices, MSpace::kObject ); if ( status == MS::kSuccess ) { //traitement du triangle // Get face-relative vertex indices for this triangle //int temp=triangleVertices[0]; write_int(triangleVertices[0]); write_int(triangleVertices[2]); write_int(triangleVertices[1]); //::output.write((char*)&triangleVertices[0],sizeof(triangleVertices[0])); //::output.write((char*)&triangleVertices[2],sizeof(triangleVertices[2])); //::output.write((char*)&triangleVertices[1],sizeof(triangleVertices[1])); } // fin if };// fin while }; //fin for EndChunck(); #else unsigned int instancenumbers; MObjectArray shaders; MIntArray indices; //MFnMesh Fn(path.instanceNumber); meshFn.getConnectedShaders(instancenumbers,shaders,indices); MString info="shaders.lenght "; info += shaders.length(); Affich(info); for (int i=-1;i<shaders.length();i++){//création de tris en fonction du nombre de brush appliqué //___________ouput tris________ info = "shader "; info += i; Affich(info); //ecriture TRIS ::output<<"TRIS"; StartChunck(); //trouver le brush id par rapport à matid //recup nom shader et compare à matid MString nameshader; nameshader=GetShaderName(shaders[i]); info = "Matid id lenght"; info += Matid.length(); Affich(info); int BrushId=0; for (int b=0;b<Matid.length();b++){ if (nameshader==Matid[b]){ BrushId=b; } } //brush ID write_int(BrushId); //write_int(-1);//default info= "BrushId "; info += BrushId; Affich(info); info = Matid[BrushId]; Affich(info); MItMeshPolygon itPolygon(path.child(0)); int d=0; for ( /* nothing */; !itPolygon.isDone(); itPolygon.next() ) { nameshader=GetShaderName(shaders[indices[d]]); if(nameshader==Matid[BrushId]){ // Get triangulation of this poly. int numTriangles; itPolygon.numTriangles(numTriangles); while ( numTriangles-- ) { //MGlobal::displayInfo(" triangle"); MStatus status; MIntArray polygonVertices; itPolygon.getVertices( polygonVertices ); MPointArray nonTweaked; // object-relative vertex indices for each triangle MIntArray triangleVertices; // face-relative vertex indices for each triangle MIntArray localIndex; status = itPolygon.getTriangle( numTriangles, nonTweaked, triangleVertices, MSpace::kObject ); if ( status == MS::kSuccess ) { write_int(triangleVertices[0]); write_int(triangleVertices[2]); write_int(triangleVertices[1]); } // fin if };// fin while } d++; } for (int i=0;i<indices.length();i++){ //info = " indice "; //info += indices[i]; //Affich(info); nameshader=GetShaderName(shaders[indices[i]]); if(nameshader==Matid[BrushId]){ //info=nameshader; //Affich(info); //*********************ecrire triangle******* } } EndChunck(); } //for (int i=0;i<Matid.length();i++){ // info = Matid[i]; // Affich(info); //} //Affich("fin objet"); #endif //---------------------fermeture mesh EndChunck(); //------------------------------------------------------------ } position_hierarchie=pos; } // move on to next node it.next(); }//fin while //fermeture du node //fermeture fichier //fermeture de tous les nodes ouverts //for (int i=posfichier.length();i>0;i--){ #ifdef SCENE_ROOT EndChunck(); #else #endif //} //écriture de la longueur du fichier output.close(); Matid.clear(); Texid.clear(); nb_Tex_by_Brush.clear(); Texids_by_brush.clear(); } else //export all polygonal scene objects { } return MS::kSuccess; }
//--------------------------------------------------------------- void LightExporter::exportLights ( SceneElement* sceneElement ) { // If we have a external reference, we don't need to export the data here. if ( !sceneElement->getIsLocal() ) return; if ( !sceneElement->getIsExportNode () ) return; // Check if it is a light. SceneElement::Type sceneElementType = sceneElement->getType(); if ( sceneElementType == SceneElement::LIGHT ) { // Get the current dag path MDagPath dagPath = sceneElement->getPath(); // Check if the current scene element isn't already exported. SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph(); if ( sceneGraph->findExportedElement ( dagPath ) ) return; // Check if the current element is an instance. // We don't need to export instances, because we export the original instanced element. bool isInstance = ( dagPath.isInstanced() && dagPath.instanceNumber() > 0 ); // If the original instanced element isn't already exported, we have to export it now. if ( isInstance ) { // Get the original instanced element. MDagPath instancedPath; dagPath.getPath ( instancedPath, 0 ); // Check if the original instanced element is already exported. SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph(); SceneElement* exportedElement = sceneGraph->findExportedElement ( instancedPath ); if (exportedElement == 0) { // Export the original instanced element and push it in the exported scene graph. if (exportLight(instancedPath)) { SceneElement* instancedSceneElement = sceneGraph->findElement(instancedPath); SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph(); sceneGraph->addExportedElement(instancedSceneElement); } } } else { // Export the element and push it in the exported scene graph. if ( exportLight ( dagPath ) ) { SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph(); sceneGraph->addExportedElement( sceneElement ); } } } // Recursive call for all the child elements for ( uint i=0; i<sceneElement->getChildCount(); ++i ) { SceneElement* childElement = sceneElement->getChild ( i ); exportLights ( childElement ); } }
void maTranslator::writeDagNodes(fstream& f) { fParentingRequired.clear(); MItDag dagIter; dagIter.traverseUnderWorld(true); MDagPath worldPath; dagIter.getPath(worldPath); // // We step over the world node before starting the loop, because it // doesn't get written out. // for (dagIter.next(); !dagIter.isDone(); dagIter.next()) { MDagPath path; dagIter.getPath(path); // // If the node has already been written, then all of its descendants // must have been written, or at least checked, as well, so prune // this branch of the tree from the iteration. // MFnDagNode dagNodeFn(path); if (dagNodeFn.isFlagSet(fCreateFlag)) { dagIter.prune(); continue; } // // If this is a default node, it will be written out later, so skip // it. // if (dagNodeFn.isDefaultNode()) continue; // // If this node is not writable, and is not a shared node, then mark // it as having been written, and skip it. // if (!dagNodeFn.canBeWritten() && !dagNodeFn.isShared()) { dagNodeFn.setFlag(fCreateFlag, true); continue; } unsigned int numParents = dagNodeFn.parentCount(); if (dagNodeFn.isFromReferencedFile()) { // // We don't issue 'creatNode' commands for nodes from referenced // files, but if the node has any parents which are not from // referenced files, other than the world, then make a note that // we'll need to issue extra 'parent' commands for it later on. // unsigned int i; for (i = 0; i < numParents; i++) { MObject altParent = dagNodeFn.parent(i); MFnDagNode altParentFn(altParent); if (!altParentFn.isFromReferencedFile() && (altParentFn.object() != worldPath.node())) { fParentingRequired.append(path); break; } } } else { // // Find the node's parent. // MDagPath parentPath = worldPath; if (path.length() > 1) { // // Get the parent's path. // parentPath = path; parentPath.pop(); // // If the parent is in the underworld, then find the closest // ancestor which is not. // if (parentPath.pathCount() > 1) { // // The first segment of the path contains whatever // portion of the path exists in the world. So the closest // worldly ancestor is simply the one at the end of that // first path segment. // path.getPath(parentPath, 0); } } MFnDagNode parentNodeFn(parentPath); if (parentNodeFn.isFromReferencedFile()) { // // We prefer to parent to a non-referenced node. So if this // node has any other parents, which are not from referenced // files and have not already been processed, then we'll // skip this instance and wait for an instance through one // of those parents. // unsigned i; for (i = 0; i < numParents; i++) { if (dagNodeFn.parent(i) != parentNodeFn.object()) { MObject altParent = dagNodeFn.parent(i); MFnDagNode altParentFn(altParent); if (!altParentFn.isFromReferencedFile() && !altParentFn.isFlagSet(fCreateFlag)) { break; } } } if (i < numParents) continue; // // This node only has parents within referenced files, so // create it without a parent and note that we need to issue // 'parent' commands for it later on. // writeCreateNode(f, path, worldPath); fParentingRequired.append(path); } else { writeCreateNode(f, path, parentPath); // // Let's see if this node has any parents from referenced // files, or any parents other than this one which are not // from referenced files. // unsigned int i; bool hasRefParents = false; bool hasOtherNonRefParents = false; for (i = 0; i < numParents; i++) { if (dagNodeFn.parent(i) != parentNodeFn.object()) { MObject altParent = dagNodeFn.parent(i); MFnDagNode altParentFn(altParent); if (altParentFn.isFromReferencedFile()) hasRefParents = true; else hasOtherNonRefParents = true; // // If we've already got positives for both tests, // then there's no need in continuing. // if (hasRefParents && hasOtherNonRefParents) break; } } // // If this node has parents from referenced files, then // make note that we will have to issue 'parent' commands // later on. // if (hasRefParents) fParentingRequired.append(path); // // If this node has parents other than this one which are // not from referenced files, then make note that the // parenting for the other instances still has to be done. // if (hasOtherNonRefParents) { fInstanceChildren.append(path); fInstanceParents.append(parentPath); } } // // Write out the node's 'addAttr', 'setAttr' and 'lockNode' // commands. // writeNodeAttrs(f, path.node(), true); writeLockNode(f, path.node()); } // // Mark the node as having been written. // dagNodeFn.setFlag(fCreateFlag, true); } // // Write out the parenting for instances. // writeInstances(f); }