/// obj2sdf will load a Wavefront .obj file that may contain many parts/materials /// it will split into separate obj files for each part/material and /// create an sdf file with visuals/collisions pointing to the new obj files /// this will make it easier to load complex obj files into pybullet /// see for example export in data/kitchens/fathirmutfak.sdf #include #include #include #define ASSERT_EQ(a,b) assert((a)==(b)); #include"Wavefront/tiny_obj_loader.h" #include #include "Bullet3Common/b3FileUtils.h" #include "../Utils/b3ResourcePath.h" #include "Bullet3Common/b3CommandLineArgs.h" #define MAX_PATH_LEN 1024 std::string StripExtension( const std::string & sPath ) { for( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ ) { if( *i == '.' ) { return std::string( sPath.begin(), i.base() - 1 ); } // if we find a slash there is no extension if( *i == '\\' || *i == '/' ) break; } // we didn't find an extension return sPath; } int main(int argc, char* argv[]) { b3CommandLineArgs args(argc,argv); char* fileName; args.GetCmdLineArgument("fileName",fileName); if (fileName==0) { printf("required --fileName=\"name\""); exit(0); } std::string matLibName = StripExtension(fileName); printf("fileName = %s\n", fileName); if (fileName==0) { printf("Please use --fileName=\"pathToObj\"."); exit(0); } char fileNameWithPath[MAX_PATH_LEN]; bool fileFound = (b3ResourcePath::findResourcePath(fileName,fileNameWithPath,MAX_PATH_LEN))>0; char materialPrefixPath[MAX_PATH_LEN]; b3FileUtils::extractPath(fileNameWithPath,materialPrefixPath,MAX_PATH_LEN); std::vector shapes; std::string err = tinyobj::LoadObj(shapes, fileNameWithPath, materialPrefixPath); char sdfFileName[MAX_PATH_LEN]; sprintf(sdfFileName,"%s%s.sdf",materialPrefixPath,"newsdf"); FILE* sdfFile = fopen(sdfFileName,"w"); if (sdfFile==0) { printf("Fatal error: cannot create sdf file %s\n",sdfFileName); exit(0); } fprintf(sdfFile, "\n\t\n\t0 0 -9.8\n"); for (int s=0;s<(int)shapes.size();s++) { tinyobj::shape_t& shape = shapes[s]; if (shape.name.length()) { printf("object name = %s\n", shape.name.c_str()); } char objFileName[MAX_PATH_LEN]; if (strlen(materialPrefixPath)>0) { sprintf(objFileName,"%s/part%d.obj",materialPrefixPath,s); } else { sprintf(objFileName,"part%d.obj",s); } FILE* f = fopen(objFileName,"w"); if (f==0) { printf("Fatal error: cannot create part obj file %s\n",objFileName); exit(0); } fprintf(f,"# Exported using automatic converter by Erwin Coumans\n"); if (matLibName.length()) { fprintf(f,"mtllib %s.mtl\n", matLibName.c_str()); } else { fprintf(f,"mtllib bedroom.mtl\n"); } int faceCount = shape.mesh.indices.size(); int vertexCount = shape.mesh.positions.size(); tinyobj::material_t mat = shape.material; if (shape.name.length()) { const char* objName = shape.name.c_str(); printf("mat.name = %s\n", objName); fprintf(f,"#object %s\n\n",objName); } for (int v=0;v=int(shape.mesh.indices.size())) { continue; } fprintf(f,"f %d/%d/%d %d/%d/%d %d/%d/%d\n", shape.mesh.indices[face]+1,shape.mesh.indices[face]+1,shape.mesh.indices[face]+1, shape.mesh.indices[face+1]+1,shape.mesh.indices[face+1]+1,shape.mesh.indices[face+1]+1, shape.mesh.indices[face+2]+1,shape.mesh.indices[face+2]+1,shape.mesh.indices[face+2]+1); } fclose(f); float kdRed=mat.diffuse[0]; float kdGreen=mat.diffuse[1]; float kdBlue=mat.diffuse[2]; char objSdfPartFileName[MAX_PATH_LEN]; sprintf(objSdfPartFileName,"part%d.obj",s); fprintf(sdfFile,"\t\t\n" "\t\t\t1\n" "\t\t\t0 0 0 0 0 0\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t0\n" "\t\t\t\n" "\t\t\t0.166667\n" "\t\t\t0\n" "\t\t\t0\n" "\t\t\t0.166667\n" "\t\t\t0\n" "\t\t\t0.166667\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t1 1 1\n" "\t\t\t\t%s\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t \n" "\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\t1 1 1\n" "\t\t\t\t\t%s\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\n" "\t\t\t\t1 0 0 1\n" "\t\t\t\t%f %f %f 1\n" "\t\t\t\t0.1 0.1 0.1 1\n" "\t\t\t\t0 0 0 0\n" "\t\t\t \n" "\t\t\t \n" "\t\t\t \n" "\t\t\t\n",objSdfPartFileName,s,s, objSdfPartFileName,objSdfPartFileName, kdRed, kdGreen, kdBlue); } fprintf(sdfFile,"\t\n\n"); fclose(sdfFile); return 0; }