//---------------------------- // Function name: read //---------------------------- // //Parameters: //p: Scene &image, const char *fileName //GlobalVars: //g: //Returns: //r:bool // Caution //c: //Assumations: //a: //Describtions: //d: read the image from the given file //SeeAlso: //s: // //------------------------------ NodeTransitPtr OBJSceneFileType::read( std::istream &is, const Char8 *, Resolver ) const { NodeUnrecPtr rootPtr, nodePtr; std::string elem; std::map<std::string, DataElem>::const_iterator elemI; Vec3f vec3r; Pnt3f pnt3r; Vec2f vec2r; Real32 x,y,z; GeoPnt3fPropertyUnrecPtr coordPtr = GeoPnt3fProperty::create(); GeoVec2fPropertyUnrecPtr texCoordPtr = GeoVec2fProperty::create(); GeoVec3fPropertyUnrecPtr normalPtr = GeoVec3fProperty::create(); GeometryUnrecPtr geoPtr; GeoIntegralPropertyUnrecPtr posIndexPtr, texIndexPtr, normalIndexPtr; GeoIntegralPropertyUnrecPtr lensPtr; GeoIntegralPropertyUnrecPtr typePtr; DataElem dataElem; DataElem lastDataElem; Char8 strBuf[8192], *token, *nextToken; Int32 strBufSize = sizeof(strBuf)/sizeof(Char8); Int32 index, posIndex = 0, indexType; Int32 i,j,n,primCount[3]; std::list<Mesh> meshList; std::map<std::string, SimpleTexturedMaterialUnrecPtr> mtlMap; std::map<std::string, SimpleTexturedMaterialUnrecPtr>::iterator mtlI; Mesh emptyMesh; Face emptyFace; TiePoint emptyTie; Int32 indexMask, meshIndexMask; std::list<Face>::iterator faceI; std::list<Mesh>::iterator meshI; bool isSingleIndex; // create the first mesh entry meshList.push_back(emptyMesh); meshI = meshList.begin(); if(is) { primCount[0] = 0; primCount[1] = 0; primCount[2] = 0; for(is >> elem; is.eof() == false; is >> elem) { if(elem[0] == '#' || elem[0] == '$') { is.ignore(INT_MAX, '\n'); } else { SceneFileHandler::the()->updateReadProgress(); elemI = _dataElemMap.find(elem); dataElem = ((elemI == _dataElemMap.end()) ? UNKNOWN_DE : elemI->second ); switch (dataElem) { case OBJECT_DE: case GROUP_DE: case SMOOTHING_GROUP_DE: is.ignore(INT_MAX, '\n'); break; case VERTEX_DE: primCount[0]++; is >> x >> y >> z; pnt3r.setValues(x,y,z); coordPtr->addValue(pnt3r); break; case VERTEX_TEXTURECOORD_DE: primCount[1]++; is >> x >> y; vec2r.setValues(x,y); texCoordPtr->addValue(vec2r); break; case VERTEX_NORMAL_DE: primCount[2]++; is >> x >> y >> z; vec3r.setValues(x,y,z); normalPtr->addValue(vec3r); break; case LIB_MTL_DE: is >> elem; readMTL ( elem.c_str(), mtlMap ); is.ignore(INT_MAX, '\n'); break; case USE_MTL_DE: is >> elem; if (meshI->faceList.empty() == false) { meshList.push_front(emptyMesh); meshI = meshList.begin(); } mtlI = mtlMap.find(elem); if (mtlI == mtlMap.end()) { FFATAL (("Unkown mtl %s\n", elem.c_str())); } else { meshI->mtlPtr = mtlI->second; } break; case FACE_DE: meshI->faceList.push_front(emptyFace); faceI = meshI->faceList.begin(); is.get(strBuf,strBufSize); token = strBuf; indexType = 0; while(token && *token) { // some tools use line continuation for long // face definitions - these use a \ at the line // end if(*token == '\\') { is.ignore(1, '\n'); is.get(strBuf,strBufSize); token = strBuf; indexType = 0; continue; } for (; *token == '/'; token++) indexType++; for (; isspace(*token); token++) indexType = 0; index = strtol(token, &nextToken, 10); if (token == nextToken) break; if (indexType == 0) faceI->tieVec.push_back(emptyTie); if (index >= 0) index--; else index = primCount[indexType] + index; faceI->tieVec.back().index[indexType] = index; token = nextToken; } break; case UNKNOWN_DE: default: // don't warn about 3rd tex coord if(lastDataElem != VERTEX_TEXTURECOORD_DE) { FWARNING (( "Unkown obj data elem: %s\n", elem.c_str())); } is.ignore(INT_MAX, '\n'); break; } lastDataElem = dataElem; } } #if 0 std::cerr << "------------------------------------------------" << std::endl; i = 0; for (meshI = meshList.begin(); meshI != meshList.end(); meshI++) { std::cerr << "Mesh " << i << " faceCount :" << meshI->faceList.size() << std::endl; j = 0 ; for ( faceI = meshI->faceList.begin(); faceI != meshI->faceList.end(); faceI++) std::cerr << "MESH " << i << "face: " << j++ << "tie num: " << faceI->tieVec.size() << std::endl; i++; } std::cerr << "------------------------------------------------" << std::endl; #endif // create Geometry objects for (meshI = meshList.begin(); meshI != meshList.end(); meshI++) { geoPtr = Geometry::create(); posIndexPtr = NULL; texIndexPtr = NULL; normalIndexPtr = NULL; lensPtr = GeoUInt32Property::create(); typePtr = GeoUInt8Property ::create(); // create and check mesh index mask meshIndexMask = 0; isSingleIndex = true; if ( meshI->faceList.empty() == false) { for ( faceI = meshI->faceList.begin(); faceI != meshI->faceList.end(); faceI++) { indexMask = 0; n = UInt32(faceI->tieVec.size()); for (i = 0; i < n; i++) { for (j = 0; j < 3; j++) { if ((index = (faceI->tieVec[i].index[j])) >= 0) { indexMask |= (1 << j); if (j) isSingleIndex &= (posIndex == index); else posIndex = index; } } } if (meshIndexMask == 0) { meshIndexMask = indexMask; } else if (meshIndexMask != indexMask) { // consider this real-world example: // [...] // f 1603//1747 1679//1744 1678//1743 // s 1 // f 9/1/10 5/2/9 1680/3/1748 1681/4/174 // [...] // Some faces contain texture coords and others do not. // The old version did just skip this geometry. // This version should continue if there's at least // the vertex index // I've seen the change in the maskIndex only after a smooth group, // so it's perhaps smarter to not ignore the smooth group further up in this code if( !(indexMask & 1) ) { // if there are vertex indices there's no reason to get in here FFATAL (( "IndexMask unmatch, can not create geo\n")); meshIndexMask = 0; break; } else { // consider the minimum similarities of mesh masks meshIndexMask &= indexMask; } } } } else { FWARNING (("Mesh with empty faceList\n")); } // fill the geo properties if (meshIndexMask) { geoPtr->setPositions ( coordPtr ); posIndexPtr = GeoUInt32Property::create(); if(!isSingleIndex) geoPtr->setIndex(posIndexPtr, Geometry::PositionsIndex); geoPtr->setLengths ( lensPtr ); geoPtr->setTypes ( typePtr ); if ( (meshIndexMask & 2) && texCoordPtr->size() > 0 ) { geoPtr->setTexCoords ( texCoordPtr ); texIndexPtr = GeoUInt32Property::create(); if(!isSingleIndex) geoPtr->setIndex(texIndexPtr, Geometry::TexCoordsIndex); } else { geoPtr->setTexCoords ( NULL ); } if ( (meshIndexMask & 4) && normalPtr->size() > 0 ) { geoPtr->setNormals ( normalPtr ); normalIndexPtr = GeoUInt32Property::create(); if(!isSingleIndex) geoPtr->setIndex(normalIndexPtr, Geometry::NormalsIndex); } else { geoPtr->setNormals ( NULL ); } if (meshI->mtlPtr == NULL) { meshI->mtlPtr = SimpleTexturedMaterial::create(); meshI->mtlPtr->setDiffuse( Color3f( .8f, .8f, .8f ) ); meshI->mtlPtr->setSpecular( Color3f( 1.f, 1.f, 1.f ) ); meshI->mtlPtr->setShininess( 20.f ); } geoPtr->setMaterial ( meshI->mtlPtr ); for ( faceI = meshI->faceList.begin(); faceI != meshI->faceList.end(); faceI++) { n = UInt32(faceI->tieVec.size()); // add the lens entry lensPtr->push_back(n); // add the type entry typePtr->push_back(GL_POLYGON); // create the index values for (i = 0; i < n; i++) { if (isSingleIndex) { posIndexPtr->push_back(faceI->tieVec[i].index[0]); } else { posIndexPtr->push_back(faceI->tieVec[i].index[0]); if(texIndexPtr != NULL) texIndexPtr->push_back(faceI->tieVec[i].index[1]); if(normalIndexPtr != NULL) normalIndexPtr->push_back(faceI->tieVec[i].index[2]); } } } if(isSingleIndex) { geoPtr->setIndex(posIndexPtr, Geometry::PositionsIndex); geoPtr->setIndex(posIndexPtr, Geometry::NormalsIndex ); geoPtr->setIndex(posIndexPtr, Geometry::TexCoordsIndex); } // need to port the geometry functions ... createSharedIndex( geoPtr ); // check if we have normals // need to port the geometry functions ... if(geoPtr->getNormals() == NULL) calcVertexNormals(geoPtr); // create and link the node nodePtr = Node::create(); nodePtr->setCore( geoPtr ); if (meshList.size() > 1) { if (rootPtr == NULL) { rootPtr = Node::create(); GroupUnrecPtr tmpPtr = Group::create(); rootPtr->setCore ( tmpPtr ); rootPtr->addChild(nodePtr); } else { rootPtr->addChild(nodePtr); } } else { rootPtr = nodePtr; } } } } SceneFileHandler::the()->updateReadProgress(100); commitChanges(); return NodeTransitPtr(rootPtr); }
NodeTransitPtr RAWSceneFileType::read( std::istream &is, const Char8 *, Resolver ) const { NodeTransitPtr root; GeometryUnrecPtr geo; GeoPnt3fPropertyUnrecPtr points; GeoVec3fPropertyUnrecPtr normals; GeoIntegralPropertyUnrecPtr index; GeoIntegralPropertyUnrecPtr lens; GeoIntegralPropertyUnrecPtr type; Vec3f vec[3]; UInt32 i = 0, n, triCount = 0; Real32 x,y,z; if(is) { root = Node ::create(); geo = Geometry::create(); root->setCore( geo ); points = GeoPnt3fProperty::create(); geo->setPositions(points); normals = GeoVec3fProperty::create(); geo->setNormals(normals); triCount = i = 0; while(1) { is >> x >> y >> z; if(is.eof()) { break; } else { points->editFieldPtr()->push_back(Pnt3f(x, y, z)); vec[i].setValues(x,y,z); std::cerr << x << " " << y << " " << z << std::endl; if(i == 2) { vec[0] -= vec[1]; vec[1] -= vec[2]; vec[0].crossThis(vec[1]); vec[0].normalize(); normals->editFieldPtr()->push_back(vec[0]); normals->editFieldPtr()->push_back(vec[0]); normals->editFieldPtr()->push_back(vec[0]); i = 0; triCount++; } else { i++; } } } if(triCount != 0) { index = GeoUInt32Property::create(); geo->setIndex(index, Geometry::PositionsIndex); geo->setIndex(index, Geometry::NormalsIndex ); n = triCount * 3; for(i = 0; i < n; i++) index->push_back(i); lens = GeoUInt32Property::create(); geo->setLengths(lens); lens->push_back(n); type = GeoUInt8Property::create(); geo->setTypes(type); type->push_back(GL_TRIANGLES); } SimpleMaterialUnrecPtr mat = SimpleMaterial::create(); mat->setDiffuse (Color3f( .8f, .8f, .8f)); mat->setSpecular (Color3f( 1.f, 1.f, 1.f )); mat->setShininess(20.f ); geo->setMaterial(mat); } if(triCount) { SNOTICE << triCount << " triangle read " << std::endl; } commitChanges(); return root; }