//----------------------------
// 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);
}
Beispiel #2
0
void MergeGraphOp::processTransformations(Node * const node)
{
    MFUnrecChildNodePtr::const_iterator mfit = node->getMFChildren()->begin();
    MFUnrecChildNodePtr::const_iterator mfen = node->getMFChildren()->end  ();
    std::vector<Node *> toAdd;
    std::vector<Node *> toSub;
    
    for ( ; mfit != mfen; ++mfit )
    {
        bool special=isInExcludeList(*mfit);
        bool leaf=isLeaf(*mfit);
        bool empty=true;
        
        //if a transformation:
        if ((*mfit)->getCore()->getType().isDerivedFrom(
                Transform::getClassType()))
        {        
            if (!leaf && !special)
            {
                //try to apply it to children geometries
                //move all "moveable" children one level up
                //if empty after that, delete it
                MFUnrecChildNodePtr::const_iterator it2 = 
                    (*mfit)->getMFChildren()->begin();
                MFUnrecChildNodePtr::const_iterator en2 = 
                    (*mfit)->getMFChildren()->end  ();
                
                for ( ; it2 != en2; ++it2 )
                {
                    if (!isInExcludeList(*it2))
                    {
                        //check if geometry
                        if ((*it2)->getCore()->getType().isDerivedFrom(
                                Geometry::getClassType()))
                        {
                            if(!isLeaf(*it2))
                            {
                                //hmm...bad tree...
                                empty=false;
                            }
                            else
                            {                                
                                //it is a leaf geometry, so apply the transformation
                                Geometry *geo_old = 
                                    dynamic_cast<Geometry *>(
                                        (*it2)->getCore());
                                //GeometryPtr geo = geo_old->clone();
                                GeometryUnrecPtr geo = 
                                    dynamic_pointer_cast<Geometry>(
                                        OSG::deepClone(geo_old, "Material"));

                                Transform *t = 
                                    dynamic_cast<Transform *>(
                                        (*mfit)->getCore());

                                GeoPnt3fProperty *pos  = dynamic_cast<GeoPnt3fProperty *>(geo->getPositions());
                                GeoVec3fProperty *norm = dynamic_cast<GeoVec3fProperty *>(geo->getNormals());
                                GeoColor3fProperty *color = dynamic_cast<GeoColor3fProperty *>(geo->getColors());
                                GeoColor3fProperty *scolor = dynamic_cast<GeoColor3fProperty *>(geo->getSecondaryColors());
                                GeoVec3fProperty *texcoord0 = dynamic_cast<GeoVec3fProperty *>(geo->getTexCoords());
                                GeoVec3fProperty *texcoord1 = dynamic_cast<GeoVec3fProperty *>(geo->getTexCoords1());
                                GeoVec3fProperty *texcoord2 = dynamic_cast<GeoVec3fProperty *>(geo->getTexCoords2());
                                GeoVec3fProperty * texcoord3 = dynamic_cast<GeoVec3fProperty *>(geo->getTexCoords3());

                                Matrix m=t->getMatrix();

                                if(pos!=NULL) 
                                {
                                    for(UInt32 i = 0; i < pos->size(); ++i)
                                    {
                                        Pnt3f p=pos->getValue(i);
                                        m.multFull(p, p);
                                        pos->setValue(p,i);
                                    }
                                }
                                
                                if(norm!=NULL)
                                {
                                    for(UInt32 i = 0; i < norm->size(); ++i)
                                    {
                                        Vec3f n=norm->getValue(i);
                                        m.mult(n, n);
                                        n.normalize();
                                        norm->setValue(n,i);
                                    }
                                }

                                if(color != NULL && _color_is_vector)
                                {
                                    for(UInt32 i = 0; i < color->size(); ++i)
                                    {
                                        Color3f c = color->getValue(i);
                                        Vec3f v;
                                        v.setValue(c.getValuesRGB());
                                        m.mult(v, v);
                                        v.normalize();
                                        c.setValuesRGB(v[0], v[1], v[2]);
                                        color->setValue(c,i);
                                    }
                                }

                                if(scolor != NULL && _secondary_color_is_vector)
                                {
                                    for(UInt32 i = 0; i < scolor->size(); ++i)
                                    {
                                        Color3f c = scolor->getValue(i);
                                        Vec3f v;
                                        v.setValue(c.getValuesRGB());
                                        m.mult(v, v);
                                        v.normalize();
                                        c.setValuesRGB(v[0], v[1], v[2]);
                                        scolor->setValue(c,i);
                                    }
                                }

                                if(texcoord0 != NULL && _texcoord0_is_vector)
                                {
                                    for(UInt32 i = 0; i < texcoord0->size(); ++i)
                                    {
                                        Vec3f v = texcoord0->getValue(i);
                                        m.mult(v, v);
                                        v.normalize();
                                        texcoord0->setValue(v,i);
                                    }
                                }

                                if(texcoord1 != NULL && _texcoord1_is_vector)
                                {
                                    for(UInt32 i = 0; i < texcoord1->size(); ++i)
                                    {
                                        Vec3f v = texcoord1->getValue(i);
                                        m.mult(v, v);
                                        v.normalize();
                                        texcoord1->setValue(v,i);
                                    }
                                }

                                if(texcoord2 != NULL && _texcoord2_is_vector)
                                {
                                    for(UInt32 i = 0; i < texcoord2->size(); ++i)
                                    {
                                        Vec3f v = texcoord2->getValue(i);
                                        m.mult(v, v);
                                        v.normalize();
                                        texcoord2->setValue(v,i);
                                    }
                                }

                                if (texcoord3 != NULL && _texcoord3_is_vector)
                                {
                                    for(UInt32 i = 0; i < texcoord3->size(); i++)
                                    {
                                        Vec3f v = texcoord3->getValue(i);
                                        m.mult(v, v);
                                        v.normalize();
                                        texcoord3->setValue(v,i);
                                    }
                                }
                                (*it2)->setCore(geo);
                                toAdd.push_back(*it2);
                            }
                        } else empty=false;
                    } else empty=false;
                }                
            }
            
            //now check whether we have to remove it
            if ((empty||leaf) && !special)
            {
                toSub.push_back(*mfit);
                continue;
            }
            
            if (leaf && special)
            {
                //what to do?
            }
            if (!leaf && special)
            {
                //what to do?
            }
            continue;
        }
    }
    
    std::vector<Node *>::const_iterator vit = toAdd.begin();
    std::vector<Node *>::const_iterator ven = toAdd.end  ();
    
    for ( ; vit != ven; ++vit )
    {
        node->addChild(*vit);
    }
    
    vit = toSub.begin();
    ven = toSub.end  ();
    
    for ( ; vit != ven; ++vit )
    {
        node->subChild(*vit);
    }
}