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; }
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; }
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); } }
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); } }
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 }