Action::ResultE GeometryMergeGraphOp::traverseEnter(Node * const node)
{
    if(isInExcludeList(node))
        return Action::Skip;
    
    return Action::Continue;
}
Action::ResultE MaterialGroupPushGraphOp::traverseEnter(Node * const node)
{
    if(isInExcludeList(node))
        return Action::Skip;

    return Action::Continue;
}
/*! Find push targets in subtree.
 */
Action::ResultE TransformPushGraphOp::traverseTargetsEnter(Node * const node)
{
    NodeCore *core = node->getCore();
    
    if(core == NULL)
    {
        // warn about broken subtree, but do not prevent push, just skip it
        FWARNING(("TransformPushGraphOp::traverseTargetsEnter: "
                  "Found node without core!\n"));
        return Action::Skip;
    }
    
    if(isInExcludeList(node) || isInPreserveList(node))
    {
        // prevent the push as the transform can not be moved into this branch.
        _pushPossible = false;
        
        return Action::Quit;
    }
    
    if(core->getType().isDerivedFrom(Transform::getClassType()))
    {
        _pushTargets.push_back(node);
        
        return Action::Skip;
    }
       
    if(core->getType().isDerivedFrom(Geometry ::getClassType()))
    {
        Geometry *geo = dynamic_cast<Geometry *>(core);
        
        if(geo != NULL && validTargetGeo(geo))
        {
            // found a push target in this branch, store it and stop searching
            _pushTargets.push_back(node);
        
            return Action::Skip;
        }
        else
        {
            // prevent the push as the transform can not be moved into this branch.
            _pushPossible = false;
        
            return Action::Quit;
        }
    }
    
    if(core->getType().isDerivedFrom(Group::getClassType()))
    {
        // keep searching children for push targets
        return Action::Continue;
    }
    
    // unknown core type, be conservative and prevent the push
    _pushPossible = false;
    
    return Action::Quit;
}
Esempio n. 4
0
Action::ResultE SplitGraphOp::traverseLeave(NodePtr& node, Action::ResultE res)
{
    std::vector<NodePtr>::iterator it = node->editMFChildren()->getValues().begin();
    std::vector<NodePtr>::iterator en = node->editMFChildren()->getValues().end  ();
    std::vector<NodePtr> toAdd;
    std::vector<NodePtr> toSub;

    for ( ; it != en; ++it )
    {
        bool special=isInExcludeList(*it);
        bool leaf=isLeaf(*it);

        if (!special && leaf)
        {
            if (splitNode(*it, toAdd))
                toSub.push_back(*it);
        }
    }

    it = toAdd.begin();
    en = toAdd.end  ();

    for ( ; it != en; ++it )
    {
        beginEditCP(node, Node::ChildrenFieldMask);
        node->addChild(*it);
        endEditCP  (node, Node::ChildrenFieldMask);
    }

    it = toSub.begin();
    en = toSub.end  ();

    for ( ; it != en; ++it )
    {
        beginEditCP(node, Node::ChildrenFieldMask);
        addRefCP(*it);
        node->subChild(*it);
        endEditCP  (node, Node::ChildrenFieldMask);
    }
    return res;
}
/*! Find push targets in subtree.
 */
Action::ResultE MaterialGroupPushGraphOp::traverseTargetsEnter(Node * const node)
{
    NodeCore *core = node->getCore();
    
    if(core == NULL)
    {
        // warn about broken subtree, but do not prevent push, just skip it
        FWARNING(("MaterialGroupPushGraphOp::traverseTargetsEnter: "
                  "Found node without core!\n"));
        return Action::Skip;
    }
    
    if(isInExcludeList(node) || isInPreserveList(node))
    {
        // prevent the push as the mat group can not be moved into this branch.
        _pushPossible = false;
        
        return Action::Quit;
    }
    
    if(core->getType().isDerivedFrom(MaterialDrawable::getClassType()))
    {
        // found a push target in this branch, store it and stop searching
        _pushTargets.push_back(node);
        
        return Action::Skip;
    }
    
    if( core->getType().isDerivedFrom(Group        ::getClassType()) &&
       !core->getType().isDerivedFrom(MaterialGroup::getClassType())   )
    {
        // keep searching children for push targets
        return Action::Continue;
    }
    
    // unknown core type, be conservative and prevent the push
    _pushPossible = false;
    
    return Action::Quit;
}
Action::ResultE MaterialGroupPushGraphOp::traverseLeave(
    Node * const node, Action::ResultE res)
{
    if(isInExcludeList(node))
        return Action::Skip;
    
    if(isInPreserveList(node))
        return Action::Continue;
    
    MaterialGroup *mg = dynamic_cast<MaterialGroup *>(node->getCore());
    
    if(mg == NULL)
        return Action::Continue;
    
    // if not a leaf, search children recursively to find push targets
    if(!node->getMFChildren()->empty())
    {
        _pushPossible = true;
        _pushTargets.clear();
        
        OSG::traverse(
            *(node->getMFChildren()),
            boost::bind(
                &MaterialGroupPushGraphOp::traverseTargetsEnter, this, _1));
        
        if(_pushPossible == true)
        {
            // push MaterialGroup into targets
            pushMaterialGroup(mg);
            
            // replace MaterialGroup with group
            GroupUnrecPtr replaceCore = Group::create();
            node->setCore(replaceCore);
        }
    }

    return Action::Continue;
}
Action::ResultE SplitGraphOp::traverseLeave(Node * const node, Action::ResultE res)
{
    MFUnrecChildNodePtr::const_iterator mfit = node->getMFChildren()->begin();
    MFUnrecChildNodePtr::const_iterator mfen = node->getMFChildren()->end  ();

    std::vector<NodeUnrecPtr  > toAdd;
    std::vector<Node         *> toSub;

    for ( ; mfit != mfen; ++mfit )
    {
        bool special=isInExcludeList(*mfit);
        bool leaf=isLeaf(*mfit);
        
        if (!special && leaf)
        {
            if (splitNode(*mfit, toAdd))
                toSub.push_back(*mfit);
        }
    }

    std::vector<NodeUnrecPtr>::const_iterator vait = toAdd.begin();
    std::vector<NodeUnrecPtr>::const_iterator vaen = toAdd.end  ();
    
    for ( ; vait != vaen; ++vait )
    {
        node->addChild(*vait);
    }
    
    std::vector<Node *>::const_iterator vsit = toSub.begin();
    std::vector<Node *>::const_iterator vsen = toSub.end  ();
    
    for ( ; vsit != vsen; ++vsit )
    {
        node->subChild(*vsit);
    }
    return res;
}
Esempio n. 8
0
void MergeGraphOp::processGeometries(Node * const node)
{
    MFUnrecChildNodePtr::const_iterator mfit = node->getMFChildren()->begin();
    MFUnrecChildNodePtr::const_iterator mfen = node->getMFChildren()->end  ();

    std::vector<Node        *> toSub;
    std::vector<NodeUnrecPtr > toAdd;
    
    for ( ; mfit != mfen; ++mfit )
    {
        bool special=isInExcludeList(*mfit);
        
        if ((*mfit)->getCore()->getType().isDerivedFrom(
                Geometry::getClassType()))
        {
#ifndef OSG2_MERGE_MISSING
            Geometry *geo = dynamic_cast<Geometry *>((*mfit)->getCore());
#endif
            //if a geometry, try to merge it in another geometry
            //if successfull, delete it.
            //check also if it is added for exclusion

            bool inSubList=false;

            std::vector<Node *>::const_iterator it3=toSub.begin();
            std::vector<Node *>::const_iterator en3=toSub.end();

            for ( ; it3 != en3; ++it3 ) 
                if (*it3==*mfit) { inSubList=true; break; }

            if (!special && !inSubList)
            {
                //ok, try
                MFUnrecChildNodePtr::const_iterator it2=mfit+1;
                Geometry *new_geo=NULL;
                for ( ; it2!=mfen; ++it2)
                {
                    if (!isInExcludeList(*it2) && (*it2)->getCore()->getType().isDerivedFrom(Geometry::getClassType()))
                    {
#ifndef OSG2_MERGE_MISSING
                        Geometry *geo2 = dynamic_cast<Geometry *>((*it2)->getCore());
                        if (geo->isMergeable(geo2))
                        {
                            // HACK merge crashes when indices == NULL!
                            if(geo->getIndices() == NULL)
                                OSG::createSharedIndex(geo);
                            if(geo2->getIndices() == NULL)
                                OSG::createSharedIndex(geo2);
                            if (new_geo==NULL)
                            {
                                new_geo=Geometry::create();
                                if (new_geo->merge(geo))
                                    toSub.push_back(*it);
                                else FWARNING(("MergeGraphOp: processGeometries problem 1\n"));

                                if (new_geo->merge(geo2))
                                    toSub.push_back(*it2);
                                else FWARNING(("MergeGraphOp: processGeometries problem 2\n"));
                            }
                            else
                            {
                                if (new_geo->merge(geo2))
                                    toSub.push_back(*it2);
                            }
                        }
#endif
                    }
                }
                if (new_geo!=NULL)
                {
                    NodeUnrecPtr new_node=Node::create();
                    new_node->setCore(new_geo);

                    toAdd.push_back(new_node);
                }
            }
            else
            {
                //hmm...have to skip it
            }
        }
    }
    
    std::vector<NodeUnrecPtr>::const_iterator ait = toAdd.begin();
    std::vector<NodeUnrecPtr>::const_iterator aen = toAdd.end  ();
    
    for ( ; ait != aen; ++ait )
    {
        node->addChild(*ait);
    }

    std::vector<Node *>::const_iterator sit = toSub.begin();
    std::vector<Node *>::const_iterator sen = toSub.end  ();
    
    for ( ; sit != sen; ++sit )
    {
        node->subChild(*sit);
    }
}
Esempio n. 9
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);
    }
}
Esempio n. 10
0
void MergeGraphOp::processGroups(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);
        
        if (isGroup(*mfit))
        {
            if (!leaf && !special)
            {
                MFUnrecChildNodePtr::const_iterator it2 = 
                    (*mfit)->getMFChildren()->begin();
                MFUnrecChildNodePtr::const_iterator en2 = 
                    (*mfit)->getMFChildren()->end  ();
                
                for ( ; it2 != en2; ++it2 )
                {
                    toAdd.push_back(*it2);
                }                
            }
            
            if (!special)
            {
                toSub.push_back(*mfit);
                continue;
            }
            
            if (leaf && special)
            {
                //what to do?
            }
            if (!leaf && special)
            {
                //what to do?
            }
            continue;
        }
        else if ((*mfit)->getCore()->getType().isDerivedFrom( 
                     MaterialGroup::getClassType() ))
        {
            MaterialGroup *mg = 
                dynamic_cast<MaterialGroup *>((*mfit)->getCore());
            
            MFUnrecChildNodePtr::const_iterator it2 = 
                (*mfit)->getMFChildren()->begin();
            MFUnrecChildNodePtr::const_iterator en2 = 
                (*mfit)->getMFChildren()->end  ();
            
            bool empty=true;
            
            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 = 
                                dynamic_cast<Geometry *>((*it2)->getCore());

                            geo->setMaterial(mg->getMaterial());

                            toAdd.push_back(*it2);                            
                        }
                    } 
                    else 
                    {
                        empty=false;
                    }
                } 
                else 
                {
                    empty=false;                
                }
            }
            
            if (empty) 
                toSub.push_back(*mfit);
        }
    }
    
    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);
    }
}
Action::ResultE GeometryMergeGraphOp::traverseLeave(
        Node * const node, Action::ResultE res)
{
    if(isInExcludeList(node))
        return Action::Skip;

    NodeCore *core = node->getCore();
    
    // skip cores with a dependency on the children number/order
    // TODO: find a way to make this extendable
    if(core == NULL                                               ||
       core->getType().isDerivedFrom(DistanceLOD::getClassType()) ||
       core->getType().isDerivedFrom(ScreenLOD  ::getClassType()) ||
       core->getType().isDerivedFrom(Switch     ::getClassType()) ||
       core->getType().isDerivedFrom(MultiCore  ::getClassType())   )
    {
        return Action::Continue;
    }
    
    typedef std::vector<NodeUnrecPtr> NodeStore;
    NodeStore addStore;     // nodes to add as children to current one
    NodeStore subStore;     // nodes (children) to remove from current one
    
    typedef std::vector<Node *    > MergeGroup; // geometries that can be merged
    typedef std::vector<MergeGroup> MergeList;  // list of merge groups
    
    MergeList                            ml;
    Node::MFChildrenType::const_iterator childIt  =
            node->getMFChildren()->begin();
    Node::MFChildrenType::const_iterator childEnd =
            node->getMFChildren()->end  ();
    
    // group geometry children that are mergeable
    for(; childIt != childEnd; ++childIt)
    {
        if((*childIt)->getCore()->getType() != Geometry::getClassType())
            continue;
        
        if(isInExcludeList(*childIt) || isInPreserveList(*childIt))
            continue;
        
        Geometry *geo = dynamic_cast<Geometry *>((*childIt)->getCore());
        Material *mat = geo->getMaterial();
        
        MergeList::iterator mlIt  = ml.begin();
        MergeList::iterator mlEnd = ml.end  ();
        
        bool done = false;
        
        for(; mlIt != mlEnd && !done; ++mlIt)
        {
            Geometry *mlGeo =
                    dynamic_cast<Geometry *>(mlIt->front()->getCore());
            Material *mlMat = mlGeo->getMaterial();
            
            if(compareContainerEqual(mlMat, mat) &&
               mergeableGeo         (mlGeo, geo)   )
            {
                mlIt->push_back(*childIt);
                done = true;
            }
        }
        
        if(!done)
        {
            ml       .push_back(MergeGroup());
            ml.back().push_back(*childIt    );
        }
    }
    
    // merge geometry in the same group and replace obsolete children with
    // new geometry
    MergeList::iterator mlIt  = ml.begin();
    MergeList::iterator mlEnd = ml.end  ();
    
    for(; mlIt != mlEnd; ++mlIt)
    {
        // only one geometry in merge group -> nothing to do
        if(mlIt->size() <= 1)
            continue;
        
        FINFO(("GeometryMergeGraphOp::traverseLeave: Merging [%" PRISize "] "
               "Geometries.\n", mlIt->size()));
        
        GeometryUnrecPtr     geo1;
        GeometryUnrecPtr     geo2;
        NodeUnrecPtr         newNode = Node::create();
        MergeGroup::iterator mgIt    = mlIt->begin();
        MergeGroup::iterator mgEnd   = mlIt->end  ();
        
        geo1 = dynamic_cast<Geometry *>((*mgIt)->getCore());

        // remove the first geo as well
        subStore.push_back(*mgIt);

        ++mgIt;
        
        for(UInt32 i = 0; mgIt != mgEnd; ++mgIt, ++i)
        {
            geo2 = dynamic_cast<Geometry *>((*mgIt)->getCore());
            
            if(i > _mergeThreshold && (mgIt + 1) != mgEnd)
            {
                newNode->setCore(geo1);
                addStore.push_back(newNode);
                
                i       = 0;
                newNode = Node::create();
                geo1    = dynamic_cast<Geometry *>((*mgIt)->getCore());
                ++mgIt;
            }
            
            geo1 = mergeGeo(geo1, geo2);
            geo1->setMaterial(geo2->getMaterial());
            
            subStore.push_back(*mgIt);
        }
        
       newNode->setCore(geo1);
       addStore.push_back(newNode);
    }
    
    // add newly created geometries to current node
    NodeStore::const_iterator storeIt  = subStore.begin();
    NodeStore::const_iterator storeEnd = subStore.end  ();
    
    for(; storeIt != storeEnd; ++storeIt)
       node->subChild(*storeIt);
    
    storeIt  = addStore.begin();
    storeEnd = addStore.end  ();
    
    for(; storeIt != storeEnd; ++storeIt)
       node->addChild(*storeIt);
    
    return Action::Continue;
}
bool SplitGraphOp::splitNode(Node * const node, std::vector<NodeUnrecPtr> &split)
{
    // PORTME
    return false;
#if 0
    //split it only if it is a non special geometry leaf
    if (!isLeaf(node) || isInExcludeList(node) ||
        !node->getCore()->getType().isDerivedFrom(Geometry::getClassType())) return false;

    Geometry *geo = dynamic_cast<Geometry *>(node->getCore());

    if ( geo->getPositions() == NULL || geo->getPositions()->size() == 0 ||
         geo->getLengths()   == NULL || geo->getLengths()->size() == 0 ||
         geo->getTypes()     == NULL || geo->getTypes()->size() == 0 ) return false;

    //get all center points
    std::vector<Pnt3f> centers;
    int ind;

    PrimitiveIterator it(geo);

    while (!it.isAtEnd())
    {
        switch(it.getType())
        {
        case GL_POINTS:
        case GL_LINES:
        case GL_LINE_STRIP:
        case GL_LINE_LOOP:
        case GL_TRIANGLE_FAN:
        case GL_TRIANGLE_STRIP:
        case GL_QUAD_STRIP:
        case GL_POLYGON:
            {
                Pnt3f center(0,0,0);
                for (UInt32 i=0; i<it.getLength(); i++)
                    center+=(Vec3f)it.getPosition(i);
                center/=Real32(it.getLength());
                centers.push_back(center);                
            } 
            break;
            
        case GL_TRIANGLES:
            ind=0;
            while(it.getLength()-ind>=3)
            {
                Pnt3f center(0,0,0);
                for (UInt32 i=0; i<3; i++, ind++)
                    center+=(Vec3f)it.getPosition(ind);
                center/=3;
                centers.push_back(center);
            } 
            break;
            
        case GL_QUADS:
            ind=0;
            while(it.getLength()-ind>=4)
            {
                Pnt3f center(0,0,0);
                for (UInt32 i=0; i<4; i++, ind++)
                    center+=(Vec3f)it.getPosition(ind);
                center/=4;
                centers.push_back(center);
            } 
            break;

            
        default:
            SWARNING << "SplitGraphOp::splitLeave: encountered " 
                     << "unknown primitive type " 
                     << it.getType()
                     << ", ignoring!" << std::endl;
            break;
        }   
        
        ++it;        
    }    
    
    std::vector<int> order;    
    for (UInt32 i=0; i<centers.size(); i++)
        order.push_back(i);

    Pnt3fComparator comp(centers);
    std::sort(order.begin(), order.end(), comp);

    //now we need (centers.size()/_max_polygons) amount of new geometries
    int ngeos=int(ceil((double)centers.size()/(double)_max_polygons));

    if (ngeos<=1) return false;

    Geometry       **geos    = new Geometry *[ngeos];
    GeoPTypes      **types   = new GeoPTypes *[ngeos];
    GeoPLengths    **lens    = new GeoPLengths *[ngeos];
    GeoPositions   **pnts    = new GeoPositions *[ngeos];
    GeoNormals     **normals = new GeoNormals *[ngeos];
    GeoColors      **colors  = new GeoColors *[ngeos];
    GeoColors      **scolors = new GeoColors *[ngeos];
    GeoTexCoords   **tex     = new GeoTexCoords *[ngeos];
    GeoTexCoords   **tex1    = new GeoTexCoords *[ngeos];
    GeoTexCoords   **tex2    = new GeoTexCoords *[ngeos];
    GeoTexCoords   **tex3    = new GeoTexCoords *[ngeos];
    GeoIndices     **indices = new GeoIndices *[ngeos];

    int **pni  = new int*[ngeos];
    int **nni  = new int*[ngeos];
    int **cni  = new int*[ngeos];
    int **sni  = new int*[ngeos];
    int **tni  = new int*[ngeos];
    int **t1ni = new int*[ngeos];
    int **t2ni = new int*[ngeos];
    int **t3ni = new int*[ngeos];

    for (Int32 i=0; i<ngeos; i++)
    {
        geos[i]  = Geometry::create();

        geos[i]->setMaterial(geo->getMaterial());

        if(geo->getMFIndexMapping() != NULL)
            geos[i]->getMFIndexMapping()->setValues(*(geo->getMFIndexMapping()));

        types[i]   = dynamic_cast<GeoPTypes *>(geo->getTypes()->getType().createFieldContainer());
        lens[i]    = dynamic_cast<GeoPLengths *>(geo->getLengths()->getType().createFieldContainer());

        if (geo->getIndices()!=NULL)
        {
            indices[i]  = dynamic_cast<GeoIndices *>(geo->getIndices()->getType().createFieldContainer());
        }
        else
            indices[i]  = NULL;

        setupAttr( GeoPositions * , pnts    , pni  , getPositions       );
        setupAttr( GeoNormals *   , normals , nni  , getNormals         );
        setupAttr( GeoColors *    , colors  , cni  , getColors          );
        setupAttr( GeoColors *    , scolors , sni  , getSecondaryColors );
        setupAttr( GeoTexCoords * , tex     , tni  , getTexCoords       );        
        setupAttr( GeoTexCoords * , tex1    , t1ni , getTexCoords1      );
        setupAttr( GeoTexCoords * , tex2    , t2ni , getTexCoords2      );
        setupAttr( GeoTexCoords * , tex3    , t3ni , getTexCoords3      );
    }

    ind=0;
    it.setToBegin();

    while (!it.isAtEnd())
    {
        switch(it.getType())
        {
        case GL_POINTS:
        case GL_LINES:
        case GL_LINE_STRIP:
        case GL_LINE_LOOP:
        case GL_TRIANGLE_FAN:
        case GL_TRIANGLE_STRIP:
        case GL_QUAD_STRIP:
        case GL_POLYGON:
            {
                int geoIndex=order[ind]/_max_polygons;

                types[geoIndex]->push_back(it.getType());
                lens[geoIndex]->push_back(it.getLength());

                addPoints( 0 , it.getLength() );
                ++ind;
            } break;
            
        case GL_TRIANGLES:
            {
                UInt32 i=0;                
                while(it.getLength()-i>=3)
                {                    
                    i+=3;
                    ++ind;
                }
            } break;
            
        case GL_QUADS:
            {
                UInt32 i=0;
                while(it.getLength()-i>=4)
                {
                    i+=4;
                    ++ind;
                }
            } break;

            
        default:
            SWARNING << "SplitGraphOp::splitLeave: encountered " 
                     << "unknown primitive type " 
                     << it.getType()
                     << ", ignoring!" << std::endl;
            break;
        }
        ++it;        
    }

    ind=0;
    it.setToBegin();

    while (!it.isAtEnd())
    {
        switch(it.getType())
        {
        case GL_POINTS:
        case GL_LINES:
        case GL_LINE_STRIP:
        case GL_LINE_LOOP:
        case GL_TRIANGLE_FAN:
        case GL_TRIANGLE_STRIP:
        case GL_QUAD_STRIP:
        case GL_POLYGON:
            {
                ++ind;
            } break;
            
        case GL_TRIANGLES:
            {
                UInt32 i=0;
                int geoIndex;
                while(it.getLength()-i>=3)
                {                    
                    geoIndex = order[ind]/_max_polygons;
                    if (types[geoIndex]->size()>0 && types[geoIndex]->getValue(types[geoIndex]->size()-1) == GL_TRIANGLES)
                    {
                        int lind;
                        if ((lind=lens[geoIndex]->size()-1)>=0)
                            lens[geoIndex]->setValue(lens[geoIndex]->getValue(lind)+3, lind);
                        else
                            lens[geoIndex]->push_back(3);
                    }
                    else
                    {
                        types[geoIndex]->push_back(GL_TRIANGLES);
                        lens[geoIndex]->push_back(3);
                    }

                    addPoints( i ,3 );
                    i+=3;
                    ++ind;
                }
            } break;
            
        case GL_QUADS:
            {
                UInt32 i=0;
                while(it.getLength()-i>=4)
                {
                    i+=4;
                    ++ind;
                }
            } break;

            
        default:
            SWARNING << "SplitGraphOp::splitLeave: encountered " 
                     << "unknown primitive type " 
                     << it.getType()
                     << ", ignoring!" << std::endl;
            break;
        }        
        ++it;        
    }

    ind=0;
    it.setToBegin();

    while (!it.isAtEnd())
    {
        switch(it.getType())
        {
        case GL_POINTS:
        case GL_LINES:
        case GL_LINE_STRIP:
        case GL_LINE_LOOP:
        case GL_TRIANGLE_FAN:
        case GL_TRIANGLE_STRIP:
        case GL_QUAD_STRIP:
        case GL_POLYGON:
            {
                ++ind;
            } break;
            
        case GL_TRIANGLES:
            {
                UInt32 i=0;
                while(it.getLength()-i>=3)
                {
                    i+=3;
                    ++ind;
                }
            } break;
            
        case GL_QUADS:
            {
                UInt32 i=0;
                int geoIndex;
                while(it.getLength()-i>=4)
                {                    
                    geoIndex = order[ind]/_max_polygons;
                    if (types[geoIndex]->size()>0 && types[geoIndex]->getValue(types[geoIndex]->size()-1) == GL_QUADS)
                    {
                        int lind;
                        if ((lind=lens[geoIndex]->size()-1)>=0)
                            lens[geoIndex]->setValue(lens[geoIndex]->getValue(lind)+4, lind);
                        else
                            lens[geoIndex]->push_back(4);
                    }
                    else
                    {
                        types[geoIndex]->push_back(GL_QUADS);
                        lens[geoIndex]->push_back(4);
                    }

                    addPoints( i , 4 );
                    i+=4;
                    ++ind;
                }
            } break;
            
        default:
            SWARNING << "SplitGraphOp::splitLeave: encountered " 
                     << "unknown primitive type " 
                     << it.getType()
                     << ", ignoring!" << std::endl;
            break;
        }        
        ++it;        
    }

    for (Int32 i=0; i<ngeos; i++)
    {
        geos[i]->setTypes(types[i]);
        geos[i]->setLengths(lens[i]);
        geos[i]->setPositions(pnts[i]);

        // Now close the open FCs

        if (indices[i]!=NULL)
        {
            geos[i]->setIndices(indices[i]);
        }

        if (normals[i]!=NULL)
        {
            geos[i]->setNormals(normals[i]);
        }

        if (colors[i]!=NULL)
        {
            geos[i]->setColors(colors[i]);
        }
        
        if (scolors[i]!=NULL)
        {
            geos[i]->setSecondaryColors(scolors[i]);
        }
        
        if (tex[i]!=NULL)
        {
            geos[i]->setTexCoords(tex[i]);
        }
       
        if (tex1[i]!=NULL)
        {
            geos[i]->setTexCoords1(tex1[i]);
        }
        
        if (tex2[i]!=NULL)
        {
            geos[i]->setTexCoords2(tex2[i]);
        }
        
        if (tex3[i]!=NULL)
        {
            geos[i]->setTexCoords3(tex3[i]);
        }

        if (node->getParent()!=NULL)
        {
            Node *n=Node::create();
            n->setCore(geos[i]);
            split.push_back(n);
        }
    }

    for (Int32 i=0; i<ngeos; i++)
    {
        if (pni[i]) delete [] pni[i];
        if (nni[i]) delete [] nni[i];
        if (cni[i]) delete [] cni[i];
        if (sni[i]) delete [] sni[i];
        if (tni[i]) delete [] tni[i];
        if (t1ni[i]) delete [] t1ni[i];
        if (t2ni[i]) delete [] t2ni[i];
        if (t3ni[i]) delete [] t3ni[i];
    }

    delete [] pni;
    delete [] nni;
    delete [] cni;
    delete [] sni;
    delete [] tni;
    delete [] t1ni;
    delete [] t2ni;
    delete [] t3ni;

    return true;
#endif
}