Action::ResultE OOCOSGFeeder::enter(NodePtr& node) { GeometryPtr geo = GeometryPtr::dcast(node->getCore()); if(geo == NullFC) return Action::Continue; GeoPositionsPtr pos = geo->getPositions(); UInt32 pntindexbase; if(_poss.find(pos) != _poss.end()) { pntindexbase = _poss[pos]; pos = NullFC; } else { pntindexbase = _pntindexbase; _poss[pos] = _pntindexbase; _pntindexbase += pos->getSize(); } UInt32 matind = MaterialPool::addMaterial(geo->getMaterial()); if(pos != NullFC) { if(_pfunc != NULL) { Pnt3f p; UInt32 s = pos->getSize(); for(UInt32 i = 0; i < s; ++i) { if(_npts != 0) { ++_pntprog; Real32 prog = _pntprog / (Real32)_npts; if(prog > _nextpntprog) { PLOG << _nextpntprog * 100 << "%.."; _nextpntprog += 0.1; } } pos->getValue(p, i); _pfunc(_rec, p); } } } if(_tfunc != NULL) { TriangleIterator it, end = geo->endTriangles(); for(it = geo->beginTriangles(); it != end; ++it) { if(_ntris != 0) { ++_triprog; Real32 prog = _triprog / (Real32)_ntris; if(prog > _nexttriprog) { PLOG << _nexttriprog * 100 << "%.."; _nexttriprog += 0.1; } } _tfunc(_rec, it.getPositionIndex(0) + pntindexbase, it.getPositionIndex(1) + pntindexbase, it.getPositionIndex(2) + pntindexbase, matind); } } return Action::Continue; }
bool SplitGraphOp::splitNode(NodePtr& node, std::vector<NodePtr> &split) { //split it only if it is a non special geometry leaf if (!isLeaf(node) || isInExcludeList(node) || !node->getCore()->getType().isDerivedFrom(Geometry::getClassType())) return false; GeometryPtr geo = GeometryPtr::dcast(node->getCore()); if ( geo->getPositions() == NullFC || geo->getPositions()->size() == 0 || geo->getLengths() == NullFC || geo->getLengths()->size() == 0 || geo->getTypes() == NullFC || 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; GeometryPtr *geos = new GeometryPtr[ngeos]; GeoPTypesPtr *types = new GeoPTypesPtr[ngeos]; GeoPLengthsPtr *lens = new GeoPLengthsPtr[ngeos]; GeoPositionsPtr *pnts = new GeoPositionsPtr[ngeos]; GeoNormalsPtr *normals = new GeoNormalsPtr[ngeos]; GeoColorsPtr *colors = new GeoColorsPtr[ngeos]; GeoColorsPtr *scolors = new GeoColorsPtr[ngeos]; GeoTexCoordsPtr *tex = new GeoTexCoordsPtr[ngeos]; GeoTexCoordsPtr *tex1 = new GeoTexCoordsPtr[ngeos]; GeoTexCoordsPtr *tex2 = new GeoTexCoordsPtr[ngeos]; GeoTexCoordsPtr *tex3 = new GeoTexCoordsPtr[ngeos]; GeoIndicesPtr *indices = new GeoIndicesPtr[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(); beginEditCP(geos[i]); // Keep open until the end geos[i]->setMaterial(geo->getMaterial()); if(geo->getMFIndexMapping() != NULL) geos[i]->editMFIndexMapping()->setValues(*(geo->getMFIndexMapping())); types[i] = GeoPTypesPtr::dcast(geo->getTypes()->getType().createFieldContainer()); lens[i] = GeoPLengthsPtr::dcast(geo->getLengths()->getType().createFieldContainer()); if (geo->getIndices()!=NullFC) { indices[i] = GeoIndicesPtr::dcast(geo->getIndices()->getType().createFieldContainer()); beginEditCP(indices[i]); // Keep open until the end } else indices[i] = NullFC; beginEditCP(types[i]); // Keep open until the end beginEditCP(lens[i]); // Keep open until the end setupAttr( GeoPositionsPtr , pnts , pni , getPositions ); setupAttr( GeoNormalsPtr , normals , nni , getNormals ); setupAttr( GeoColorsPtr , colors , cni , getColors ); setupAttr( GeoColorsPtr , scolors , sni , getSecondaryColors ); setupAttr( GeoTexCoordsPtr , tex , tni , getTexCoords ); setupAttr( GeoTexCoordsPtr , tex1 , t1ni , getTexCoords1 ); setupAttr( GeoTexCoordsPtr , tex2 , t2ni , getTexCoords2 ); setupAttr( GeoTexCoordsPtr , 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 endEditCP(types[i]); endEditCP(lens[i]); endEditCP(pnts[i]); if (indices[i]!=NullFC) { geos[i]->setIndices(indices[i]); endEditCP(indices[i]); } if (normals[i]!=NullFC) { geos[i]->setNormals(normals[i]); endEditCP(normals[i]); } if (colors[i]!=NullFC) { geos[i]->setColors(colors[i]); endEditCP(colors[i]); } if (scolors[i]!=NullFC) { geos[i]->setSecondaryColors(scolors[i]); endEditCP(scolors[i]); } if (tex[i]!=NullFC) { geos[i]->setTexCoords(tex[i]); endEditCP(tex[i]); } if (tex1[i]!=NullFC) { geos[i]->setTexCoords1(tex1[i]); endEditCP(tex1[i]); } if (tex2[i]!=NullFC) { geos[i]->setTexCoords2(tex2[i]); endEditCP(tex2[i]); } if (tex3[i]!=NullFC) { geos[i]->setTexCoords3(tex3[i]); endEditCP(tex3[i]); } endEditCP(geos[i]); if (node->getParent()!=NullFC) { NodePtr n=Node::create(); beginEditCP(n, Node::CoreFieldMask); n->setCore(geos[i]); endEditCP (n, Node::CoreFieldMask); 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; }