00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <OSGSplitGraphOp.h>
00045 #include <OSGDirectionalLight.h>
00046 #include <OSGSpotLight.h>
00047 #include <OSGLight.h>
00048 #include <OSGPointLight.h>
00049 #include <OSGSwitch.h>
00050 #include <OSGDistanceLOD.h>
00051 #include <OSGBillboard.h>
00052 #include <OSGMaterialGroup.h>
00053 #include <OSGComponentTransform.h>
00054 #include <OSGPrimitiveIterator.h>
00055 #include <OSGGeometry.h>
00056
00057 OSG_USING_NAMESPACE
00058
00059
00060
00061
00062
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 SplitGraphOp::SplitGraphOp(const char* name, UInt16 max_polygons):
00082 GraphOp(name), _max_polygons(max_polygons)
00083 {
00084 }
00085
00086 SplitGraphOp::~SplitGraphOp(void)
00087 {
00088 }
00089
00090 GraphOp* SplitGraphOp::create()
00091 {
00092 SplitGraphOp * inst = new SplitGraphOp();
00093 return inst;
00094 }
00095
00096 bool SplitGraphOp::traverse(NodePtr& root)
00097 {
00098 return GraphOp::traverse(root);
00099 }
00100
00101 void SplitGraphOp::setParams(const std::string params)
00102 {
00103 ParamSet ps(params);
00104
00105 ps("max_polygons", _max_polygons);
00106
00107 std::string out = ps.getUnusedParams();
00108 if(out.length())
00109 {
00110 FWARNING(("SplitGraphOp doesn't have parameters '%s'.\n",
00111 out.c_str()));
00112 }
00113 }
00114
00115 std::string SplitGraphOp::usage(void)
00116 {
00117 return
00118 "Split: Split large geometries into smaller ones\n"
00119 "Params: name (type, default)\n"
00120 " max_polygons (UInt32, 1000): maximum number of polygons allowed per Geo\n";
00121 }
00122
00123 void SplitGraphOp::setMaxPolygons(UInt16 max_polygons)
00124 {
00125 _max_polygons = max_polygons;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 Action::ResultE SplitGraphOp::traverseEnter(NodePtr& node)
00138 {
00139 if (isLeaf(node)) return Action::Skip;
00140
00141 SwitchPtr switch_ = SwitchPtr::dcast(node->getCore());
00142 if (switch_!=NullFC) return Action::Skip;
00143
00144 DistanceLODPtr dlod = DistanceLODPtr::dcast(node->getCore());
00145 if (dlod!=NullFC) return Action::Skip;
00146
00147 return Action::Continue;
00148 }
00149
00150 #define addPoints( INDEX , LENGTH ) \
00151 for (UInt32 k=0; k<LENGTH; k++) \
00152 { \
00153 int posInd=it.getPositionIndex(k+INDEX); \
00154 if (pni[geoIndex]) \
00155 { \
00156 if (pni[geoIndex][posInd]==-1) \
00157 { \
00158 pnts[geoIndex]->push_back(it.getPosition(k+INDEX)); \
00159 pni[geoIndex][posInd]=pnts[geoIndex]->size()-1; \
00160 } \
00161 } \
00162 int normInd=it.getNormalIndex(k+INDEX); \
00163 if (nni[geoIndex]) \
00164 { \
00165 if (nni[geoIndex][normInd]==-1) \
00166 { \
00167 normals[geoIndex]->push_back(it.getNormal(k+INDEX)); \
00168 nni[geoIndex][normInd]=normals[geoIndex]->size()-1; \
00169 } \
00170 } \
00171 int colInd=it.getColorIndex(k+INDEX); \
00172 if (cni[geoIndex]) \
00173 { \
00174 if (cni[geoIndex][colInd]==-1) \
00175 { \
00176 colors[geoIndex]->push_back(it.getColor(k+INDEX)); \
00177 cni[geoIndex][colInd]=colors[geoIndex]->size()-1; \
00178 } \
00179 } \
00180 int scolInd=it.getSecondaryColorIndex(k+INDEX); \
00181 if (sni[geoIndex]) \
00182 { \
00183 if (sni[geoIndex][scolInd]==-1) \
00184 { \
00185 scolors[geoIndex]->push_back(it.getSecondaryColor(k+INDEX));\
00186 sni[geoIndex][scolInd]=scolors[geoIndex]->size()-1; \
00187 } \
00188 } \
00189 int texInd=it.getTexCoordsIndex(k+INDEX); \
00190 if (tni[geoIndex]) \
00191 { \
00192 if (tni[geoIndex][texInd]==-1) \
00193 { \
00194 tex[geoIndex]->push_back(it.getTexCoords(k+INDEX)); \
00195 tni[geoIndex][texInd]=tex[geoIndex]->size()-1; \
00196 } \
00197 } \
00198 int tex1Ind=it.getTexCoordsIndex1(k+INDEX); \
00199 if (t1ni[geoIndex]) \
00200 { \
00201 if (t1ni[geoIndex][tex1Ind]==-1) \
00202 { \
00203 tex1[geoIndex]->push_back(it.getTexCoords1(k+INDEX)); \
00204 t1ni[geoIndex][tex1Ind]=tex1[geoIndex]->size()-1; \
00205 } \
00206 } \
00207 int tex2Ind=it.getTexCoordsIndex2(k+INDEX); \
00208 if (t2ni[geoIndex]) \
00209 { \
00210 if (t2ni[geoIndex][tex2Ind]==-1) \
00211 { \
00212 tex2[geoIndex]->push_back(it.getTexCoords2(k+INDEX)); \
00213 t2ni[geoIndex][tex2Ind]=tex2[geoIndex]->size()-1; \
00214 } \
00215 } \
00216 int tex3Ind=it.getTexCoordsIndex3(k+INDEX); \
00217 if (t3ni[geoIndex]) \
00218 { \
00219 if (t3ni[geoIndex][tex3Ind]==-1) \
00220 { \
00221 tex3[geoIndex]->push_back(it.getTexCoords3(k+INDEX)); \
00222 t3ni[geoIndex][tex3Ind]=tex3[geoIndex]->size()-1; \
00223 } \
00224 } \
00225 if (indices[geoIndex]!=NullFC) \
00226 { \
00227 if (geos[geoIndex]->getIndexMapping().size()<2) \
00228 { \
00229 indices[geoIndex]->push_back(pni[geoIndex][posInd]); \
00230 } \
00231 else \
00232 { \
00233 UInt32 * offsets = new UInt32 [ geos[geoIndex]->getIndexMapping().size() ]; \
00234 Int16 mind; \
00235 if ( ( mind = geos[geoIndex]->calcMappingIndex( Geometry::MapPosition ) ) >= 0 ) \
00236 offsets[ mind ] = pni[geoIndex][posInd]; \
00237 if ( ( mind = geos[geoIndex]->calcMappingIndex( Geometry::MapNormal ) ) >= 0 ) \
00238 offsets[ mind ] = nni[geoIndex][normInd]; \
00239 if ( ( mind = geos[geoIndex]->calcMappingIndex( Geometry::MapColor ) ) >= 0 ) \
00240 offsets[ mind ] = cni[geoIndex][colInd]; \
00241 if ( ( mind = geos[geoIndex]->calcMappingIndex( Geometry::MapSecondaryColor ) ) >= 0 ) \
00242 offsets[ mind ] = sni[geoIndex][scolInd]; \
00243 if ( ( mind = geos[geoIndex]->calcMappingIndex( Geometry::MapTexCoords ) ) >= 0 ) \
00244 offsets[ mind ] = tni[geoIndex][texInd]; \
00245 if ( ( mind = geos[geoIndex]->calcMappingIndex( Geometry::MapTexCoords1 ) ) >= 0 ) \
00246 offsets[ mind ] = t1ni[geoIndex][tex1Ind]; \
00247 if ( ( mind = geos[geoIndex]->calcMappingIndex( Geometry::MapTexCoords2 ) ) >= 0 ) \
00248 offsets[ mind ] = t2ni[geoIndex][tex2Ind]; \
00249 if ( ( mind = geos[geoIndex]->calcMappingIndex( Geometry::MapTexCoords3 ) ) >= 0 ) \
00250 offsets[ mind ] = t3ni[geoIndex][tex3Ind]; \
00251 for (UInt32 j=0; j<geos[geoIndex]->getIndexMapping().size(); j++) \
00252 indices[geoIndex]->push_back(offsets[j]); \
00253 delete [] offsets; \
00254 } \
00255 } \
00256 }
00257
00258 #define setupAttr( type , arr1 , arr2 , getmethod ) \
00259 if (geo->getmethod()!=NullFC && geo->getmethod()->size()>0) \
00260 { \
00261 arr1[i] = type::dcast(geo->getmethod()->getType().createFieldContainer()); \
00262 beginEditCP(arr1[i]); \
00263 arr2[i] = new int[geo->getmethod()->size()]; \
00264 for (UInt32 j=0; j<geo->getmethod()->size(); j++) \
00265 arr2[i][j]=-1; \
00266 } else { arr2[i]=0; arr1[i]=NullFC; }
00267
00268 Action::ResultE SplitGraphOp::traverseLeave(NodePtr& node, Action::ResultE res)
00269 {
00270 std::vector<NodePtr>::iterator it = node->getMFChildren()->getValues().begin();
00271 std::vector<NodePtr>::iterator en = node->getMFChildren()->getValues().end ();
00272 std::vector<NodePtr> toAdd;
00273 std::vector<NodePtr> toSub;
00274
00275 for ( ; it != en; ++it )
00276 {
00277 bool special=isInExcludeList(*it);
00278 bool leaf=isLeaf(*it);
00279
00280 if (!special && leaf)
00281 {
00282 if (splitNode(*it, toAdd))
00283 toSub.push_back(*it);
00284 }
00285 }
00286
00287 it = toAdd.begin();
00288 en = toAdd.end ();
00289
00290 for ( ; it != en; ++it )
00291 {
00292 beginEditCP(node, Node::ChildrenFieldMask);
00293 node->addChild(*it);
00294 endEditCP (node, Node::ChildrenFieldMask);
00295 }
00296
00297 it = toSub.begin();
00298 en = toSub.end ();
00299
00300 for ( ; it != en; ++it )
00301 {
00302 beginEditCP(node, Node::ChildrenFieldMask);
00303 addRefCP(*it);
00304 node->subChild(*it);
00305 endEditCP (node, Node::ChildrenFieldMask);
00306 }
00307 return res;
00308 }
00309
00310 bool SplitGraphOp::splitNode(NodePtr& node, std::vector<NodePtr> &split)
00311 {
00312
00313 if (!isLeaf(node) || isInExcludeList(node) ||
00314 !node->getCore()->getType().isDerivedFrom(Geometry::getClassType())) return false;
00315
00316 GeometryPtr geo = GeometryPtr::dcast(node->getCore());
00317
00318 if ( geo->getPositions() == NullFC || geo->getPositions()->size() == 0 ||
00319 geo->getLengths() == NullFC || geo->getLengths()->size() == 0 ||
00320 geo->getTypes() == NullFC || geo->getTypes()->size() == 0 ) return false;
00321
00322
00323 std::vector<Pnt3f> centers;
00324 int ind;
00325
00326 PrimitiveIterator it(geo);
00327
00328 while (!it.isAtEnd())
00329 {
00330 switch(it.getType())
00331 {
00332 case GL_POINTS:
00333 case GL_LINES:
00334 case GL_LINE_STRIP:
00335 case GL_LINE_LOOP:
00336 case GL_TRIANGLE_FAN:
00337 case GL_TRIANGLE_STRIP:
00338 case GL_QUAD_STRIP:
00339 case GL_POLYGON:
00340 {
00341 Pnt3f center(0,0,0);
00342 for (UInt32 i=0; i<it.getLength(); i++)
00343 center+=(Vec3f)it.getPosition(i);
00344 center/=Real32(it.getLength());
00345 centers.push_back(center);
00346 }
00347 break;
00348
00349 case GL_TRIANGLES:
00350 ind=0;
00351 while(it.getLength()-ind>=3)
00352 {
00353 Pnt3f center(0,0,0);
00354 for (UInt32 i=0; i<3; i++, ind++)
00355 center+=(Vec3f)it.getPosition(ind);
00356 center/=3;
00357 centers.push_back(center);
00358 }
00359 break;
00360
00361 case GL_QUADS:
00362 ind=0;
00363 while(it.getLength()-ind>=4)
00364 {
00365 Pnt3f center(0,0,0);
00366 for (UInt32 i=0; i<4; i++, ind++)
00367 center+=(Vec3f)it.getPosition(ind);
00368 center/=4;
00369 centers.push_back(center);
00370 }
00371 break;
00372
00373
00374 default:
00375 SWARNING << "SplitGraphOp::splitLeave: encountered "
00376 << "unknown primitive type "
00377 << it.getType()
00378 << ", ignoring!" << std::endl;
00379 break;
00380 }
00381
00382 ++it;
00383 }
00384
00385 std::vector<int> order;
00386 for (UInt32 i=0; i<centers.size(); i++)
00387 order.push_back(i);
00388
00389 Pnt3fComparator comp(centers);
00390 std::sort(order.begin(), order.end(), comp);
00391
00392
00393 int ngeos=int(ceil((double)centers.size()/(double)_max_polygons));
00394
00395 if (ngeos<=1) return false;
00396
00397 GeometryPtr *geos = new GeometryPtr[ngeos];
00398 GeoPTypesPtr *types = new GeoPTypesPtr[ngeos];
00399 GeoPLengthsPtr *lens = new GeoPLengthsPtr[ngeos];
00400 GeoPositionsPtr *pnts = new GeoPositionsPtr[ngeos];
00401 GeoNormalsPtr *normals = new GeoNormalsPtr[ngeos];
00402 GeoColorsPtr *colors = new GeoColorsPtr[ngeos];
00403 GeoColorsPtr *scolors = new GeoColorsPtr[ngeos];
00404 GeoTexCoordsPtr *tex = new GeoTexCoordsPtr[ngeos];
00405 GeoTexCoordsPtr *tex1 = new GeoTexCoordsPtr[ngeos];
00406 GeoTexCoordsPtr *tex2 = new GeoTexCoordsPtr[ngeos];
00407 GeoTexCoordsPtr *tex3 = new GeoTexCoordsPtr[ngeos];
00408 GeoIndicesPtr *indices = new GeoIndicesPtr[ngeos];
00409
00410 int **pni = new int*[ngeos];
00411 int **nni = new int*[ngeos];
00412 int **cni = new int*[ngeos];
00413 int **sni = new int*[ngeos];
00414 int **tni = new int*[ngeos];
00415 int **t1ni = new int*[ngeos];
00416 int **t2ni = new int*[ngeos];
00417 int **t3ni = new int*[ngeos];
00418
00419 for (Int32 i=0; i<ngeos; i++)
00420 {
00421 geos[i] = Geometry::create();
00422
00423 beginEditCP(geos[i]);
00424
00425 geos[i]->setMaterial(geo->getMaterial());
00426
00427 if(geo->getMFIndexMapping() != NULL)
00428 geos[i]->getMFIndexMapping()->setValues(*(geo->getMFIndexMapping()));
00429
00430 types[i] = GeoPTypesPtr::dcast(geo->getTypes()->getType().createFieldContainer());
00431 lens[i] = GeoPLengthsPtr::dcast(geo->getLengths()->getType().createFieldContainer());
00432
00433 if (geo->getIndices()!=NullFC)
00434 {
00435 indices[i] = GeoIndicesPtr::dcast(geo->getIndices()->getType().createFieldContainer());
00436 beginEditCP(indices[i]);
00437 }
00438 else
00439 indices[i] = NullFC;
00440
00441 beginEditCP(types[i]);
00442 beginEditCP(lens[i]);
00443
00444 setupAttr( GeoPositionsPtr , pnts , pni , getPositions );
00445 setupAttr( GeoNormalsPtr , normals , nni , getNormals );
00446 setupAttr( GeoColorsPtr , colors , cni , getColors );
00447 setupAttr( GeoColorsPtr , scolors , sni , getSecondaryColors );
00448 setupAttr( GeoTexCoordsPtr , tex , tni , getTexCoords );
00449 setupAttr( GeoTexCoordsPtr , tex1 , t1ni , getTexCoords1 );
00450 setupAttr( GeoTexCoordsPtr , tex2 , t2ni , getTexCoords2 );
00451 setupAttr( GeoTexCoordsPtr , tex3 , t3ni , getTexCoords3 );
00452 }
00453
00454 ind=0;
00455 it.setToBegin();
00456
00457 while (!it.isAtEnd())
00458 {
00459 switch(it.getType())
00460 {
00461 case GL_POINTS:
00462 case GL_LINES:
00463 case GL_LINE_STRIP:
00464 case GL_LINE_LOOP:
00465 case GL_TRIANGLE_FAN:
00466 case GL_TRIANGLE_STRIP:
00467 case GL_QUAD_STRIP:
00468 case GL_POLYGON:
00469 {
00470 int geoIndex=order[ind]/_max_polygons;
00471
00472 types[geoIndex]->push_back(it.getType());
00473 lens[geoIndex]->push_back(it.getLength());
00474
00475 addPoints( 0 , it.getLength() );
00476 ++ind;
00477 } break;
00478
00479 case GL_TRIANGLES:
00480 {
00481 UInt32 i=0;
00482 while(it.getLength()-i>=3)
00483 {
00484 i+=3;
00485 ++ind;
00486 }
00487 } break;
00488
00489 case GL_QUADS:
00490 {
00491 UInt32 i=0;
00492 while(it.getLength()-i>=4)
00493 {
00494 i+=4;
00495 ++ind;
00496 }
00497 } break;
00498
00499
00500 default:
00501 SWARNING << "SplitGraphOp::splitLeave: encountered "
00502 << "unknown primitive type "
00503 << it.getType()
00504 << ", ignoring!" << std::endl;
00505 break;
00506 }
00507 ++it;
00508 }
00509
00510 ind=0;
00511 it.setToBegin();
00512
00513 while (!it.isAtEnd())
00514 {
00515 switch(it.getType())
00516 {
00517 case GL_POINTS:
00518 case GL_LINES:
00519 case GL_LINE_STRIP:
00520 case GL_LINE_LOOP:
00521 case GL_TRIANGLE_FAN:
00522 case GL_TRIANGLE_STRIP:
00523 case GL_QUAD_STRIP:
00524 case GL_POLYGON:
00525 {
00526 ++ind;
00527 } break;
00528
00529 case GL_TRIANGLES:
00530 {
00531 UInt32 i=0;
00532 int geoIndex;
00533 while(it.getLength()-i>=3)
00534 {
00535 geoIndex = order[ind]/_max_polygons;
00536 if (types[geoIndex]->size()>0 && types[geoIndex]->getValue(types[geoIndex]->size()-1) == GL_TRIANGLES)
00537 {
00538 int lind;
00539 if ((lind=lens[geoIndex]->size()-1)>=0)
00540 lens[geoIndex]->setValue(lens[geoIndex]->getValue(lind)+3, lind);
00541 else
00542 lens[geoIndex]->push_back(3);
00543 }
00544 else
00545 {
00546 types[geoIndex]->push_back(GL_TRIANGLES);
00547 lens[geoIndex]->push_back(3);
00548 }
00549
00550 addPoints( i ,3 );
00551 i+=3;
00552 ++ind;
00553 }
00554 } break;
00555
00556 case GL_QUADS:
00557 {
00558 UInt32 i=0;
00559 while(it.getLength()-i>=4)
00560 {
00561 i+=4;
00562 ++ind;
00563 }
00564 } break;
00565
00566
00567 default:
00568 SWARNING << "SplitGraphOp::splitLeave: encountered "
00569 << "unknown primitive type "
00570 << it.getType()
00571 << ", ignoring!" << std::endl;
00572 break;
00573 }
00574 ++it;
00575 }
00576
00577 ind=0;
00578 it.setToBegin();
00579
00580 while (!it.isAtEnd())
00581 {
00582 switch(it.getType())
00583 {
00584 case GL_POINTS:
00585 case GL_LINES:
00586 case GL_LINE_STRIP:
00587 case GL_LINE_LOOP:
00588 case GL_TRIANGLE_FAN:
00589 case GL_TRIANGLE_STRIP:
00590 case GL_QUAD_STRIP:
00591 case GL_POLYGON:
00592 {
00593 ++ind;
00594 } break;
00595
00596 case GL_TRIANGLES:
00597 {
00598 UInt32 i=0;
00599 while(it.getLength()-i>=3)
00600 {
00601 i+=3;
00602 ++ind;
00603 }
00604 } break;
00605
00606 case GL_QUADS:
00607 {
00608 UInt32 i=0;
00609 int geoIndex;
00610 while(it.getLength()-i>=4)
00611 {
00612 geoIndex = order[ind]/_max_polygons;
00613 if (types[geoIndex]->size()>0 && types[geoIndex]->getValue(types[geoIndex]->size()-1) == GL_QUADS)
00614 {
00615 int lind;
00616 if ((lind=lens[geoIndex]->size()-1)>=0)
00617 lens[geoIndex]->setValue(lens[geoIndex]->getValue(lind)+4, lind);
00618 else
00619 lens[geoIndex]->push_back(4);
00620 }
00621 else
00622 {
00623 types[geoIndex]->push_back(GL_QUADS);
00624 lens[geoIndex]->push_back(4);
00625 }
00626
00627 addPoints( i , 4 );
00628 i+=4;
00629 ++ind;
00630 }
00631 } break;
00632
00633 default:
00634 SWARNING << "SplitGraphOp::splitLeave: encountered "
00635 << "unknown primitive type "
00636 << it.getType()
00637 << ", ignoring!" << std::endl;
00638 break;
00639 }
00640 ++it;
00641 }
00642
00643 for (Int32 i=0; i<ngeos; i++)
00644 {
00645 geos[i]->setTypes(types[i]);
00646 geos[i]->setLengths(lens[i]);
00647 geos[i]->setPositions(pnts[i]);
00648
00649
00650
00651 endEditCP(types[i]);
00652 endEditCP(lens[i]);
00653 endEditCP(pnts[i]);
00654
00655 if (indices[i]!=NullFC)
00656 {
00657 geos[i]->setIndices(indices[i]);
00658 endEditCP(indices[i]);
00659 }
00660
00661 if (normals[i]!=NullFC)
00662 {
00663 geos[i]->setNormals(normals[i]);
00664 endEditCP(normals[i]);
00665 }
00666
00667 if (colors[i]!=NullFC)
00668 {
00669 geos[i]->setColors(colors[i]);
00670 endEditCP(colors[i]);
00671 }
00672
00673 if (scolors[i]!=NullFC)
00674 {
00675 geos[i]->setSecondaryColors(scolors[i]);
00676 endEditCP(scolors[i]);
00677 }
00678
00679 if (tex[i]!=NullFC)
00680 {
00681 geos[i]->setTexCoords(tex[i]);
00682 endEditCP(tex[i]);
00683 }
00684
00685 if (tex1[i]!=NullFC)
00686 {
00687 geos[i]->setTexCoords1(tex1[i]);
00688 endEditCP(tex1[i]);
00689 }
00690
00691 if (tex2[i]!=NullFC)
00692 {
00693 geos[i]->setTexCoords2(tex2[i]);
00694 endEditCP(tex2[i]);
00695 }
00696
00697 if (tex3[i]!=NullFC)
00698 {
00699 geos[i]->setTexCoords3(tex3[i]);
00700 endEditCP(tex3[i]);
00701 }
00702
00703 endEditCP(geos[i]);
00704
00705 if (node->getParent()!=NullFC)
00706 {
00707 NodePtr n=Node::create();
00708 beginEditCP(n, Node::CoreFieldMask);
00709 n->setCore(geos[i]);
00710 endEditCP (n, Node::CoreFieldMask);
00711 split.push_back(n);
00712 }
00713 }
00714
00715 for (Int32 i=0; i<ngeos; i++)
00716 {
00717 if (pni[i]) delete [] pni[i];
00718 if (nni[i]) delete [] nni[i];
00719 if (cni[i]) delete [] cni[i];
00720 if (sni[i]) delete [] sni[i];
00721 if (tni[i]) delete [] tni[i];
00722 if (t1ni[i]) delete [] t1ni[i];
00723 if (t2ni[i]) delete [] t2ni[i];
00724 if (t3ni[i]) delete [] t3ni[i];
00725 }
00726
00727 delete [] pni;
00728 delete [] nni;
00729 delete [] cni;
00730 delete [] sni;
00731 delete [] tni;
00732 delete [] t1ni;
00733 delete [] t2ni;
00734 delete [] t3ni;
00735
00736 return true;
00737 }
00738
00739 bool SplitGraphOp::isLeaf(NodePtr& node)
00740 {
00741 if (node->getMFChildren()->getValues().begin()==
00742 node->getMFChildren()->getValues().end()) return true;
00743 else return false;
00744 }
00745
00748 bool SplitGraphOp::isGroup(NodePtr& node)
00749 {
00750 if( node->getCore()->getType().isDerivedFrom( Group::getClassType() ) &&
00751 !node->getCore()->getType().isDerivedFrom( Transform::getClassType() ) &&
00752 !node->getCore()->getType().isDerivedFrom( ComponentTransform::getClassType() ) &&
00753 !node->getCore()->getType().isDerivedFrom( Switch::getClassType() ) &&
00754 !node->getCore()->getType().isDerivedFrom( MaterialGroup::getClassType() ) &&
00755 !node->getCore()->getType().isDerivedFrom( DistanceLOD::getClassType() ) &&
00756 !node->getCore()->getType().isDerivedFrom( Billboard::getClassType() ))
00757 return true;
00758 else return false;
00759 }