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
00045 #include <OSGMergeGraphOp.h>
00046 #include <OSGDirectionalLight.h>
00047 #include <OSGSpotLight.h>
00048 #include <OSGLight.h>
00049 #include <OSGPointLight.h>
00050 #include <OSGSwitch.h>
00051 #include <OSGDistanceLOD.h>
00052 #include <OSGBillboard.h>
00053 #include <OSGMaterialGroup.h>
00054 #include <OSGComponentTransform.h>
00055 #include <OSGPrimitiveIterator.h>
00056 #include <OSGGeometry.h>
00057 #include <OSGGeoFunctions.h>
00058
00059 OSG_USING_NAMESPACE
00060
00061
00062
00063
00064
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 MergeGraphOp::MergeGraphOp(const char* name): GraphOp(name),
00084 _secondary_color_is_vector(false),
00085 _texcoord0_is_vector(false),
00086 _texcoord1_is_vector(false),
00087 _texcoord2_is_vector(false),
00088 _texcoord3_is_vector(false)
00089 {
00090 }
00091
00092 MergeGraphOp::~MergeGraphOp(void)
00093 {
00094 }
00095
00096 GraphOp* MergeGraphOp::create()
00097 {
00098 MergeGraphOp* inst = new MergeGraphOp();
00099 return inst;
00100 }
00101
00102 UInt32 countNodes(const NodePtr& node)
00103 {
00104 if (node == NullFC)
00105 return 0;
00106
00107 UInt32 total = 1;
00108 for (UInt32 i = 0; i < node->getNChildren(); ++i)
00109 total += countNodes(node->getChild(i));
00110 return total;
00111 }
00112
00113 bool MergeGraphOp::traverse(NodePtr& node)
00114 {
00115
00116
00117
00118 UInt32 next = countNodes(node);
00119 SINFO << "MergeGraphOp::traverse: Number of nodes before merge: "
00120 << next << endLog;
00121 bool result = true;
00122 UInt32 current;
00123 do {
00124 current = next;
00125 result &= mergeOnce(node);
00126 if (!result)
00127 break;
00128 next = countNodes(node);
00129 } while (next < current);
00130
00131 SINFO << "MergeGraphOp::traverse: Number of nodes after merge: "
00132 << current << endLog;
00133
00134 return result;
00135 }
00136
00137 void MergeGraphOp::setParams(const std::string params)
00138 {
00139 ParamSet ps(params);
00140
00141 ps("color_is_vector", _color_is_vector);
00142 ps("secondary_color_is_vector", _secondary_color_is_vector);
00143 ps("texcoord_is_vector", _texcoord0_is_vector);
00144 ps("texcoord0_is_vector", _texcoord0_is_vector);
00145 ps("texcoord1_is_vector", _texcoord1_is_vector);
00146 ps("texcoord2_is_vector", _texcoord2_is_vector);
00147 ps("texcoord3_is_vector", _texcoord3_is_vector);
00148
00149 std::string out = ps.getUnusedParams();
00150 if(out.length())
00151 {
00152 FWARNING(("MergeGraphOp doesn't have parameters '%s'.\n",
00153 out.c_str()));
00154 }
00155 }
00156
00157 std::string MergeGraphOp::usage(void)
00158 {
00159 return
00160 "Merge: merge all geometries in a subtree\n"
00161 " Tries to merge all Geometries in a subtree into the minimal number.\n"
00162 " of Nodes. Flattens Transformations and transforms indices on the way.\n"
00163 "Params: name (type, default)\n"
00164 " (The following params are useful for transforming tangent space vectors.)\n"
00165 " color_is_vector (bool, false): transform color as if it were a normal\n"
00166 " secondary_color_is_vector (bool, false): transform secondary color as if it were a normal\n"
00167 " texcoord_is_vector (bool, false): transform texcoord0 as if it were a normal\n"
00168 " texcoord0_is_vector (bool, false): transform texcoord0 as if it were a normal\n"
00169 " texcoord1_is_vector (bool, false): transform texcoord1 as if it were a normal\n"
00170 " texcoord2_is_vector (bool, false): transform texcoord2 as if it were a normal\n"
00171 " texcoord3_is_vector (bool, false): transform texcoord3 as if it were a normal\n"
00172 ;
00173 }
00174
00175
00176
00177
00178
00179 bool MergeGraphOp::mergeOnce(NodePtr& node)
00180 {
00181 std::list<NodePtr> tempList;
00182 tempList.clear();
00183 tempList.splice(tempList.end(),_excludeListNodes);
00184 makeExcludeList(node);
00185 bool result = GraphOp::traverse(node);
00186 _excludeListNodes.clear();
00187 _excludeListNodes.splice(_excludeListNodes.end(),tempList);
00188 return result;
00189 }
00190
00191 void MergeGraphOp::makeExcludeList(NodePtr& node)
00192 {
00193 ::traverse(node,
00194 osgTypedMethodFunctor1ObjPtrCPtrRef<Action::ResultE,
00195 MergeGraphOp,
00196 NodePtr>(this,&MergeGraphOp::excludeListEnter),
00197 osgTypedMethodFunctor2ObjPtrCPtrRef<Action::ResultE,
00198 MergeGraphOp,
00199 NodePtr,
00200 Action::ResultE>(this,&MergeGraphOp::excludeListLeave));
00201 }
00202
00203
00204 Action::ResultE MergeGraphOp::excludeListEnter(NodePtr& node)
00205 {
00206 if (node==NullFC) ; else ;
00207 return Action::Continue;
00208 }
00209
00210 Action::ResultE MergeGraphOp::excludeListLeave(NodePtr& node, Action::ResultE res)
00211 {
00212 DirectionalLightPtr dlight = DirectionalLightPtr::dcast(node->getCore());
00213 if (dlight!=NullFC)
00214 addToExcludeList(dlight->getBeacon());
00215
00216 LightPtr light = LightPtr::dcast(node->getCore());
00217 if (light!=NullFC)
00218 addToExcludeList(light->getBeacon());
00219
00220 PointLightPtr plight = PointLightPtr::dcast(node->getCore());
00221 if (plight!=NullFC)
00222 addToExcludeList(plight->getBeacon());
00223
00224 SpotLightPtr slight = SpotLightPtr::dcast(node->getCore());
00225 if (slight!=NullFC)
00226 addToExcludeList(slight->getBeacon());
00227
00228 return res;
00229 }
00230
00231 Action::ResultE MergeGraphOp::traverseEnter(NodePtr& node)
00232 {
00233 SwitchPtr switch_ = SwitchPtr::dcast(node->getCore());
00234 if (switch_!=NullFC) return Action::Skip;
00235
00236 DistanceLODPtr dlod = DistanceLODPtr::dcast(node->getCore());
00237 if (dlod!=NullFC) return Action::Skip;
00238
00239
00240 if (isLeaf(node)) return Action::Skip;
00241
00242 return Action::Continue;
00243 }
00244
00245 Action::ResultE MergeGraphOp::traverseLeave(NodePtr& node, Action::ResultE res)
00246 {
00247 processGroups(node);
00248 processTransformations(node);
00249 processGeometries(node);
00250 return res;
00251 }
00252
00253 bool MergeGraphOp::isLeaf(NodePtr& node)
00254 {
00255 if (node->getMFChildren()->getValues().begin()==
00256 node->getMFChildren()->getValues().end()) return true;
00257 else return false;
00258 }
00259
00262 bool MergeGraphOp::isGroup(NodePtr& node)
00263 {
00264 if( node->getCore()->getType().isDerivedFrom( Group::getClassType() ) &&
00265 !node->getCore()->getType().isDerivedFrom( Transform::getClassType() ) &&
00266 !node->getCore()->getType().isDerivedFrom( ComponentTransform::getClassType() ) &&
00267 !node->getCore()->getType().isDerivedFrom( Switch::getClassType() ) &&
00268 !node->getCore()->getType().isDerivedFrom( MaterialGroup::getClassType() ) &&
00269 !node->getCore()->getType().isDerivedFrom( DistanceLOD::getClassType() ) &&
00270 !node->getCore()->getType().isDerivedFrom( Billboard::getClassType() ))
00271 return true;
00272 else return false;
00273 }
00274
00275 void MergeGraphOp::processGroups(NodePtr& node)
00276 {
00277 std::vector<NodePtr>::iterator it = node->getMFChildren()->getValues().begin();
00278 std::vector<NodePtr>::iterator en = node->getMFChildren()->getValues().end ();
00279 std::vector<NodePtr> toAdd;
00280 std::vector<NodePtr> toSub;
00281
00282 for ( ; it != en; ++it )
00283 {
00284 bool special=isInExcludeList(*it);
00285 bool leaf=isLeaf(*it);
00286
00287 if (isGroup(*it))
00288 {
00289 if (!leaf && !special)
00290 {
00291 std::vector<NodePtr>::iterator it2 = (*it)->getMFChildren()->getValues().begin();
00292 std::vector<NodePtr>::iterator en2 = (*it)->getMFChildren()->getValues().end ();
00293
00294 for ( ; it2 != en2; ++it2 )
00295 {
00296 toAdd.push_back(*it2);
00297 }
00298 }
00299
00300 if (!special)
00301 {
00302 toSub.push_back(*it);
00303 continue;
00304 }
00305
00306 if (leaf && special)
00307 {
00308
00309 }
00310 if (!leaf && special)
00311 {
00312
00313 }
00314 continue;
00315 }
00316 else if ((*it)->getCore()->getType().isDerivedFrom( MaterialGroup::getClassType() ))
00317 {
00318 MaterialGroupPtr mg=MaterialGroupPtr::dcast((*it)->getCore());
00319
00320 std::vector<NodePtr>::iterator it2 = (*it)->getMFChildren()->getValues().begin();
00321 std::vector<NodePtr>::iterator en2 = (*it)->getMFChildren()->getValues().end ();
00322
00323 bool empty=true;
00324
00325 for ( ; it2 != en2; ++it2 )
00326 {
00327 if (!isInExcludeList(*it2))
00328 {
00329
00330 if ((*it2)->getCore()->getType().isDerivedFrom(Geometry::getClassType()))
00331 {
00332 if(!isLeaf(*it2))
00333 {
00334
00335 empty=false;
00336 }
00337 else
00338 {
00339
00340 GeometryPtr geo = GeometryPtr::dcast((*it2)->getCore());
00341 beginEditCP(geo);
00342 geo->setMaterial(mg->getMaterial());
00343 endEditCP(geo);
00344 toAdd.push_back(*it2);
00345 }
00346 }
00347 else
00348 {
00349 empty=false;
00350 }
00351 }
00352 else
00353 {
00354 empty=false;
00355 }
00356 }
00357
00358 if (empty) toSub.push_back(*it);
00359
00360 }
00361 }
00362
00363 it = toAdd.begin();
00364 en = toAdd.end ();
00365
00366 for ( ; it != en; ++it )
00367 {
00368 beginEditCP(node, Node::ChildrenFieldMask);
00369 node->addChild(*it);
00370 endEditCP (node, Node::ChildrenFieldMask);
00371 }
00372
00373 it = toSub.begin();
00374 en = toSub.end ();
00375
00376 for ( ; it != en; ++it )
00377 {
00378 beginEditCP(node, Node::ChildrenFieldMask);
00379 node->subChild(*it);
00380 endEditCP (node, Node::ChildrenFieldMask);
00381 }
00382 }
00383
00384 void MergeGraphOp::processTransformations(NodePtr& node)
00385 {
00386 std::vector<NodePtr>::iterator it = node->getMFChildren()->getValues().begin();
00387 std::vector<NodePtr>::iterator en = node->getMFChildren()->getValues().end ();
00388 std::vector<NodePtr> toAdd;
00389 std::vector<NodePtr> toSub;
00390
00391 for ( ; it != en; ++it )
00392 {
00393 bool special=isInExcludeList(*it);
00394 bool leaf=isLeaf(*it);
00395 bool empty=true;
00396
00397
00398 if ((*it)->getCore()->getType().isDerivedFrom(Transform::getClassType()))
00399 {
00400 if (!leaf && !special)
00401 {
00402
00403
00404
00405 std::vector<NodePtr>::iterator it2 = (*it)->getMFChildren()->getValues().begin();
00406 std::vector<NodePtr>::iterator en2 = (*it)->getMFChildren()->getValues().end ();
00407
00408 for ( ; it2 != en2; ++it2 )
00409 {
00410 if (!isInExcludeList(*it2))
00411 {
00412
00413 if ((*it2)->getCore()->getType().isDerivedFrom(Geometry::getClassType()))
00414 {
00415 if(!isLeaf(*it2))
00416 {
00417
00418 empty=false;
00419 }
00420 else
00421 {
00422
00423 GeometryPtr geo_old = GeometryPtr::dcast((*it2)->getCore());
00424 GeometryPtr geo = geo_old->clone();
00425 TransformPtr t = TransformPtr::dcast((*it)->getCore());
00426 GeoPositionsPtr pos = geo->getPositions();
00427 GeoNormalsPtr norm = geo->getNormals();
00428 GeoColorsPtr color = geo->getColors();
00429 GeoColorsPtr scolor = geo->getSecondaryColors();
00430 GeoTexCoords3fPtr texcoord0 = GeoTexCoords3fPtr::dcast(geo->getTexCoords());
00431 GeoTexCoords3fPtr texcoord1 = GeoTexCoords3fPtr::dcast(geo->getTexCoords1());
00432 GeoTexCoords3fPtr texcoord2 = GeoTexCoords3fPtr::dcast(geo->getTexCoords2());
00433 GeoTexCoords3fPtr texcoord3 = GeoTexCoords3fPtr::dcast(geo->getTexCoords3());
00434 Matrix m=t->getMatrix();
00435 if (pos!=NullFC)
00436 {
00437 beginEditCP( pos );
00438 for (UInt32 i=0; i<pos->getSize(); i++)
00439 {
00440 Pnt3f p=pos->getValue(i);
00441 m.multFullMatrixPnt(p);
00442 pos->setValue(p,i);
00443 }
00444 endEditCP( pos );
00445 }
00446
00447 if (norm!=NullFC)
00448 {
00449 beginEditCP( norm );
00450 for (UInt32 i=0; i<norm->getSize(); i++)
00451 {
00452 Vec3f n=norm->getValue(i);
00453 m.multMatrixVec(n);
00454 n.normalize();
00455 norm->setValue(n,i);
00456 }
00457 endEditCP( norm );
00458 }
00459
00460 if (color!=NullFC && _color_is_vector)
00461 {
00462 beginEditCP( color );
00463 for (UInt32 i=0; i<color->getSize(); i++)
00464 {
00465 Color3f c = color->getValue(i);
00466 Vec3f v;
00467 v.setValue(c.getValuesRGB());
00468 m.multMatrixVec(v);
00469 v.normalize();
00470 c.setValuesRGB(v[0], v[1], v[2]);
00471 color->setValue(c,i);
00472 }
00473 endEditCP( color );
00474 }
00475
00476 if (scolor!=NullFC && _secondary_color_is_vector)
00477 {
00478 beginEditCP( scolor );
00479 for (UInt32 i=0; i<scolor->getSize(); i++)
00480 {
00481 Color3f c = scolor->getValue(i);
00482 Vec3f v;
00483 v.setValue(c.getValuesRGB());
00484 m.multMatrixVec(v);
00485 v.normalize();
00486 c.setValuesRGB(v[0], v[1], v[2]);
00487 scolor->setValue(c,i);
00488 }
00489 endEditCP( scolor );
00490 }
00491
00492 if (texcoord0!=NullFC && _texcoord0_is_vector)
00493 {
00494 beginEditCP( texcoord0 );
00495 for (UInt32 i=0; i<texcoord0->getSize(); i++)
00496 {
00497 Vec3f v=texcoord0->getField()[i];
00498 m.multMatrixVec(v);
00499 v.normalize();
00500 texcoord0->getField()[i] = v;
00501 }
00502 endEditCP( texcoord0 );
00503 }
00504
00505 if (texcoord1!=NullFC && _texcoord1_is_vector)
00506 {
00507 beginEditCP( texcoord1 );
00508 for (UInt32 i=0; i<texcoord1->getSize(); i++)
00509 {
00510 Vec3f v=texcoord1->getField()[i];
00511 m.multMatrixVec(v);
00512 v.normalize();
00513 texcoord1->getField()[i] = v;
00514 }
00515 endEditCP( texcoord1 );
00516 }
00517
00518 if (texcoord2!=NullFC && _texcoord2_is_vector)
00519 {
00520 beginEditCP( texcoord2 );
00521 for (UInt32 i=0; i<texcoord2->getSize(); i++)
00522 {
00523 Vec3f v=texcoord2->getField()[i];
00524 m.multMatrixVec(v);
00525 v.normalize();
00526 texcoord2->getField()[i] = v;
00527 }
00528 endEditCP( texcoord2 );
00529 }
00530
00531 if (texcoord3!=NullFC && _texcoord3_is_vector)
00532 {
00533 beginEditCP( texcoord3 );
00534 for (UInt32 i=0; i<texcoord3->getSize(); i++)
00535 {
00536 Vec3f v=texcoord3->getField()[i];
00537 m.multMatrixVec(v);
00538 v.normalize();
00539 texcoord3->getField()[i] = v;
00540 }
00541 endEditCP( texcoord3 );
00542 }
00543 beginEditCP(*it2);
00544 (*it2)->setCore(geo);
00545 endEditCP(*it2);
00546 toAdd.push_back(*it2);
00547 }
00548 } else empty=false;
00549 } else empty=false;
00550 }
00551 }
00552
00553
00554 if ((empty||leaf) && !special)
00555 {
00556 toSub.push_back(*it);
00557 continue;
00558 }
00559
00560 if (leaf && special)
00561 {
00562
00563 }
00564 if (!leaf && special)
00565 {
00566
00567 }
00568 continue;
00569 }
00570 }
00571
00572 it = toAdd.begin();
00573 en = toAdd.end ();
00574
00575 for ( ; it != en; ++it )
00576 {
00577 beginEditCP(node, Node::ChildrenFieldMask);
00578 node->addChild(*it);
00579 endEditCP (node, Node::ChildrenFieldMask);
00580 }
00581
00582 it = toSub.begin();
00583 en = toSub.end ();
00584
00585 for ( ; it != en; ++it )
00586 {
00587 beginEditCP(node, Node::ChildrenFieldMask);
00588 node->subChild(*it);
00589 endEditCP (node, Node::ChildrenFieldMask);
00590 }
00591 }
00592
00593 void MergeGraphOp::processGeometries(NodePtr& node)
00594 {
00595 std::vector<NodePtr>::iterator it = node->getMFChildren()->getValues().begin();
00596 std::vector<NodePtr>::iterator en = node->getMFChildren()->getValues().end ();
00597 std::vector<NodePtr> toSub;
00598 std::vector<NodePtr> toAdd;
00599
00600 for ( ; it != en; ++it )
00601 {
00602 bool special=isInExcludeList(*it);
00603
00604 if ((*it)->getCore()->getType().isDerivedFrom(Geometry::getClassType()))
00605 {
00606 GeometryPtr geo = GeometryPtr::dcast((*it)->getCore());
00607
00608
00609
00610
00611 bool inSubList=false;
00612
00613 std::vector<NodePtr>::iterator it3=toSub.begin();
00614 std::vector<NodePtr>::iterator en3=toSub.end();
00615
00616 for ( ; it3 != en3; ++it3 )
00617 if (*it3==*it) { inSubList=true; break; }
00618
00619 if (!special && !inSubList)
00620 {
00621
00622 std::vector<NodePtr>::iterator it2=it+1;
00623 GeometryPtr new_geo=NullFC;
00624 for ( ; it2!=en; ++it2)
00625 {
00626 if (!isInExcludeList(*it2) && (*it2)->getCore()->getType().isDerivedFrom(Geometry::getClassType()))
00627 {
00628 GeometryPtr geo2 = GeometryPtr::dcast((*it2)->getCore());
00629 if (geo->isMergeable(geo2))
00630 {
00631
00632 if(geo->getIndices() == NullFC)
00633 OSG::createSharedIndex(geo);
00634 if(geo2->getIndices() == NullFC)
00635 OSG::createSharedIndex(geo2);
00636 if (new_geo==NullFC)
00637 {
00638 new_geo=Geometry::create();
00639 if (new_geo->merge(geo))
00640 toSub.push_back(*it);
00641 else FWARNING(("MergeGraphOp: processGeometries problem 1\n"));
00642
00643 if (new_geo->merge(geo2))
00644 toSub.push_back(*it2);
00645 else FWARNING(("MergeGraphOp: processGeometries problem 2\n"));
00646 }
00647 else
00648 {
00649 if (new_geo->merge(geo2))
00650 toSub.push_back(*it2);
00651 }
00652 }
00653 }
00654 }
00655 if (new_geo!=NullFC)
00656 {
00657 NodePtr new_node=Node::create();
00658 beginEditCP(new_node);
00659 new_node->setCore(new_geo);
00660 endEditCP (new_node);
00661
00662 toAdd.push_back(new_node);
00663 }
00664 }
00665 else
00666 {
00667
00668 }
00669 }
00670 }
00671
00672 it = toAdd.begin();
00673 en = toAdd.end ();
00674
00675 for ( ; it != en; ++it )
00676 {
00677 beginEditCP(node, Node::ChildrenFieldMask);
00678 node->addChild(*it);
00679 endEditCP (node, Node::ChildrenFieldMask);
00680 }
00681
00682 it = toSub.begin();
00683 en = toSub.end ();
00684
00685 for ( ; it != en; ++it )
00686 {
00687 beginEditCP(node, Node::ChildrenFieldMask);
00688 node->subChild(*it);
00689 endEditCP (node, Node::ChildrenFieldMask);
00690 }
00691 }