OSGMergeGraphOp.cpp

Go to the documentation of this file.
00001
00002 /*---------------------------------------------------------------------------*\
00003  *                                OpenSG                                     *
00004  *                                                                           *
00005  *                                                                           *
00006  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00007  *                                                                           *
00008  *                            www.opensg.org                                 *
00009  *                                                                           *
00010  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00011  *                                                                           *
00012 \*---------------------------------------------------------------------------*/
00013 /*---------------------------------------------------------------------------*\
00014  *                                License                                    *
00015  *                                                                           *
00016  * This library is free software; you can redistribute it and/or modify it   *
00017  * under the terms of the GNU Library General Public License as published    *
00018  * by the Free Software Foundation, version 2.                               *
00019  *                                                                           *
00020  * This library is distributed in the hope that it will be useful, but       *
00021  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00023  * Library General Public License for more details.                          *
00024  *                                                                           *
00025  * You should have received a copy of the GNU Library General Public         *
00026  * License along with this library; if not, write to the Free Software       *
00027  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00028  *                                                                           *
00029 \*---------------------------------------------------------------------------*/
00030 /*---------------------------------------------------------------------------*\
00031  *                                Changes                                    *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037  *                                                                           *
00038 \*---------------------------------------------------------------------------*/
00039
00040
00041 /***************************************************************************\
00042 *                             Includes                                    *
00043 \***************************************************************************/
00044
00045 #include <boost/bind.hpp>
00046
00047 #include "OSGMergeGraphOp.h"
00048 #include "OSGDirectionalLight.h"
00049 #include "OSGSpotLight.h"
00050 #include "OSGLight.h"
00051 #include "OSGPointLight.h"
00052 #include "OSGSwitch.h"
00053 #include "OSGDistanceLOD.h"
00054 #include "OSGBillboard.h"
00055 #include "OSGMaterialGroup.h"
00056 #include "OSGComponentTransform.h"
00057 #include "OSGPrimitiveIterator.h"
00058 #include "OSGGeometry.h"
00059 #include "OSGGeoFunctions.h"
00060 #include "OSGGraphOpFactory.h"
00061
00062 // need to implement the merge methods amz
00063 #define OSG2_MERGE_MISSING
00064 
00065 OSG_USING_NAMESPACE
00066
00067 /***************************************************************************\
00068  *                            Description                                  *
00069 \***************************************************************************/
00070
00078
00079 static bool registerOp(void)
00080 {
00081     GraphOpRefPtr newOp = MergeGraphOp::create();
00082
00083     GraphOpFactory::the()->registerOp(newOp);
00084     return true;
00085 }
00086 static OSG::StaticInitFuncWrapper registerOpWrapper(registerOp);
00087
00088 /***************************************************************************\
00089  *                           Instance methods                              *
00090 \***************************************************************************/
00091
00092 /*-------------------------------------------------------------------------*\
00093  -  public                                                                 -
00094 \*-------------------------------------------------------------------------*/
00095
00096
00097 /*------------- constructors & destructors --------------------------------*/
00098
00099 MergeGraphOp::MergeGraphOp(const char* name): GraphOp(name),
00100     _secondary_color_is_vector(false),
00101     _texcoord0_is_vector(false),
00102     _texcoord1_is_vector(false),
00103     _texcoord2_is_vector(false),
00104     _texcoord3_is_vector(false)
00105 {
00106 }
00107
00108 MergeGraphOp::~MergeGraphOp(void)
00109 {
00110 }
00111
00112 MergeGraphOpTransitPtr
00113 MergeGraphOp::create(void)
00114 {
00115     return MergeGraphOpTransitPtr(new MergeGraphOp);
00116 }
00117
00118 GraphOpTransitPtr MergeGraphOp::clone(void)
00119 {
00120     return GraphOpTransitPtr(new MergeGraphOp);
00121 }
00122
00123 UInt32 countNodes(Node * const node)
00124 {
00125     if (node == NULL)
00126         return 0;
00127
00128     UInt32 total = 1;
00129     for (UInt32 i = 0; i < node->getNChildren(); ++i)
00130         total += countNodes(node->getChild(i));
00131     return total;
00132 }
00133
00134 bool MergeGraphOp::traverse(Node * node)
00135 {
00136     // This is a hack and should be treated as such.
00137     // The fact that it helps means there is something wrong with
00138     // the merger. FIXME!!!
00139     UInt32 next = countNodes(node);
00140     SINFO << "MergeGraphOp::traverse: Number of nodes before merge: "
00141           << next << endLog;
00142     bool result = true;
00143     UInt32 current;
00144     do {
00145         current = next;
00146         result &= mergeOnce(node);
00147         if (!result)
00148             break;
00149         next = countNodes(node);
00150     } while (next < current);
00151
00152     SINFO << "MergeGraphOp::traverse: Number of nodes after merge: "
00153           << current << endLog;
00154
00155     return result;
00156 }
00157
00158 void MergeGraphOp::setParams(const std::string params)
00159 {
00160     ParamSet ps(params);
00161
00162     ps("color_is_vector", _color_is_vector);
00163     ps("secondary_color_is_vector", _secondary_color_is_vector);
00164     ps("texcoord_is_vector", _texcoord0_is_vector);
00165     ps("texcoord0_is_vector", _texcoord0_is_vector);
00166     ps("texcoord1_is_vector", _texcoord1_is_vector);
00167     ps("texcoord2_is_vector", _texcoord2_is_vector);
00168     ps("texcoord3_is_vector", _texcoord3_is_vector);
00169
00170     std::string out = ps.getUnusedParams();
00171     if(out.length())
00172     {
00173         FWARNING(("MergeGraphOp doesn't have parameters '%s'.\n",
00174                 out.c_str()));
00175     }
00176 }
00177
00178 std::string MergeGraphOp::usage(void)
00179 {
00180     return
00181     "Merge: merge all geometries in a subtree\n"
00182     "  Tries to merge all Geometries in a subtree into the minimal number.\n"
00183     "  of Nodes. Flattens Transformations and transforms indices on the way.\n"
00184     "Params: name (type, default)\n"
00185     " (The following params are useful for transforming tangent space vectors.)\n"
00186     "  color_is_vector  (bool, false): transform color as if it were a normal\n"
00187     "  secondary_color_is_vector  (bool, false): transform secondary color as if it were a normal\n"
00188     "  texcoord_is_vector  (bool, false): transform texcoord0 as if it were a normal\n"
00189     "  texcoord0_is_vector  (bool, false): transform texcoord0 as if it were a normal\n"
00190     "  texcoord1_is_vector  (bool, false): transform texcoord1 as if it were a normal\n"
00191     "  texcoord2_is_vector  (bool, false): transform texcoord2 as if it were a normal\n"
00192     "  texcoord3_is_vector  (bool, false): transform texcoord3 as if it were a normal\n"
00193     ;
00194 }
00195
00196 /*-------------------------------------------------------------------------*\
00197  -  private                                                                -
00198 \*-------------------------------------------------------------------------*/
00199
00200 bool MergeGraphOp::mergeOnce(Node * node)
00201 {
00202     std::list<Node const *> tempList;
00203     tempList.clear();
00204     tempList.splice(tempList.end(),_excludeListNodes);
00205     makeExcludeList(node);
00206     bool result = GraphOp::traverse(node);
00207     _excludeListNodes.clear();
00208     _excludeListNodes.splice(_excludeListNodes.end(),tempList);
00209     return result;
00210 }
00211
00212 void MergeGraphOp::makeExcludeList(Node * node)
00213 {
00214     /*
00215     ::traverse(node,
00216         osgTypedMethodFunctor1ObjPtrCPtrRef<Action::ResultE,
00217         MergeGraphOp,
00218         NodePtr>(this,&MergeGraphOp::excludeListEnter),
00219         osgTypedMethodFunctor2ObjPtrCPtrRef<Action::ResultE,
00220         MergeGraphOp,
00221         NodePtr,
00222         Action::ResultE>(this,&MergeGraphOp::excludeListLeave));
00223     */
00224     ::traverse(node,
00225                boost::bind(&MergeGraphOp::excludeListEnter, this, _1    ),
00226                boost::bind(&MergeGraphOp::excludeListLeave, this, _1, _2) );
00227 }
00228
00229
00230 Action::ResultE MergeGraphOp::excludeListEnter(Node * const node)
00231 {
00232 //    if (node==NULL) ; else ;    
00233     return Action::Continue;
00234 }
00235
00236 Action::ResultE MergeGraphOp::excludeListLeave(Node * const node, Action::ResultE res)
00237 {
00238     DirectionalLight *dlight = dynamic_cast<DirectionalLight *>(node->getCore());
00239     if (dlight!=NULL)
00240         addToExcludeList(dlight->getBeacon());
00241
00242     Light *light = dynamic_cast<Light *>(node->getCore());
00243     if (light!=NULL)
00244         addToExcludeList(light->getBeacon());
00245
00246     PointLight *plight = dynamic_cast<PointLight *>(node->getCore());
00247     if (plight!=NULL)
00248         addToExcludeList(plight->getBeacon());
00249
00250     SpotLight *slight = dynamic_cast<SpotLight *>(node->getCore());
00251     if (slight!=NULL)
00252         addToExcludeList(slight->getBeacon());
00253
00254     return res;
00255 }
00256
00257 Action::ResultE MergeGraphOp::traverseEnter(Node * const node)
00258 {
00259     Switch *switch_ = dynamic_cast<Switch *>(node->getCore());
00260     if (switch_!=NULL) return Action::Skip;
00261
00262     DistanceLOD *dlod = dynamic_cast<DistanceLOD *>(node->getCore());
00263     if (dlod!=NULL) return Action::Skip;
00264
00265     //leaf, don't enter, cause no job here
00266     if (isLeaf(node)) return Action::Skip;
00267
00268     return Action::Continue;
00269 }
00270
00271 Action::ResultE MergeGraphOp::traverseLeave(Node * const node, Action::ResultE res)
00272 {
00273     processGroups(node);
00274     processTransformations(node);
00275     processGeometries(node);
00276     return res;
00277 }
00278
00279 bool MergeGraphOp::isLeaf(Node * const node)
00280 {
00281     if (node->getMFChildren()->begin() ==
00282         node->getMFChildren()->end  ()) return true;
00283     else return false;
00284 }
00285
00288 bool MergeGraphOp::isGroup(Node * const node)
00289 {
00290     if(  node->getCore()->getType().isDerivedFrom( Group::getClassType()              ) &&
00291         !node->getCore()->getType().isDerivedFrom( Transform::getClassType()          ) &&
00292         !node->getCore()->getType().isDerivedFrom( ComponentTransform::getClassType() ) &&
00293         !node->getCore()->getType().isDerivedFrom( Switch::getClassType()             ) &&
00294         !node->getCore()->getType().isDerivedFrom( MaterialGroup::getClassType()      ) &&
00295         !node->getCore()->getType().isDerivedFrom( DistanceLOD::getClassType()        ) &&
00296         !node->getCore()->getType().isDerivedFrom( Billboard::getClassType()          ))
00297         return true;
00298     else return false;
00299 }
00300
00301 void MergeGraphOp::processGroups(Node * const node)
00302 {
00303     MFUnrecChildNodePtr::const_iterator mfit = node->getMFChildren()->begin();
00304     MFUnrecChildNodePtr::const_iterator mfen = node->getMFChildren()->end  ();
00305     std::vector<Node *> toAdd;
00306     std::vector<Node *> toSub;
00307
00308     for ( ; mfit != mfen; ++mfit )
00309     {
00310         bool special=isInExcludeList(*mfit);
00311         bool leaf=isLeaf(*mfit);
00312
00313         if (isGroup(*mfit))
00314         {
00315             if (!leaf && !special)
00316             {
00317                 MFUnrecChildNodePtr::const_iterator it2 =
00318                     (*mfit)->getMFChildren()->begin();
00319                 MFUnrecChildNodePtr::const_iterator en2 =
00320                     (*mfit)->getMFChildren()->end  ();
00321
00322                 for ( ; it2 != en2; ++it2 )
00323                 {
00324                     toAdd.push_back(*it2);
00325                 }
00326             }
00327
00328             if (!special)
00329             {
00330                 toSub.push_back(*mfit);
00331                 continue;
00332             }
00333
00334             if (leaf && special)
00335             {
00336                 //what to do?
00337             }
00338             if (!leaf && special)
00339             {
00340                 //what to do?
00341             }
00342             continue;
00343         }
00344         else if ((*mfit)->getCore()->getType().isDerivedFrom(
00345                      MaterialGroup::getClassType() ))
00346         {
00347             MaterialGroup *mg =
00348                 dynamic_cast<MaterialGroup *>((*mfit)->getCore());
00349
00350             MFUnrecChildNodePtr::const_iterator it2 =
00351                 (*mfit)->getMFChildren()->begin();
00352             MFUnrecChildNodePtr::const_iterator en2 =
00353                 (*mfit)->getMFChildren()->end  ();
00354
00355             bool empty=true;
00356
00357             for ( ; it2 != en2; ++it2 )
00358             {
00359                 if (!isInExcludeList(*it2))
00360                 {
00361                     //check if geometry
00362                     if ((*it2)->getCore()->getType().isDerivedFrom(
00363                             Geometry::getClassType()))
00364                     {
00365                         if(!isLeaf(*it2))
00366                         {
00367                             //hmm...bad tree...
00368                             empty=false;
00369                         }
00370                         else
00371                         {
00372                             //it is a leaf geometry, so apply the transformation
00373                             Geometry *geo =
00374                                 dynamic_cast<Geometry *>((*it2)->getCore());
00375
00376                             geo->setMaterial(mg->getMaterial());
00377
00378                             toAdd.push_back(*it2);
00379                         }
00380                     }
00381                     else
00382                     {
00383                         empty=false;
00384                     }
00385                 }
00386                 else
00387                 {
00388                     empty=false;
00389                 }
00390             }
00391
00392             if (empty)
00393                 toSub.push_back(*mfit);
00394         }
00395     }
00396
00397     std::vector<Node *>::const_iterator vit = toAdd.begin();
00398     std::vector<Node *>::const_iterator ven = toAdd.end  ();
00399
00400     for ( ; vit != ven; ++vit )
00401     {
00402         node->addChild(*vit);
00403     }
00404
00405     vit = toSub.begin();
00406     ven = toSub.end  ();
00407
00408     for ( ; vit != ven; ++vit )
00409     {
00410         node->subChild(*vit);
00411     }
00412 }
00413
00414 void MergeGraphOp::processTransformations(Node * const node)
00415 {
00416     MFUnrecChildNodePtr::const_iterator mfit = node->getMFChildren()->begin();
00417     MFUnrecChildNodePtr::const_iterator mfen = node->getMFChildren()->end  ();
00418     std::vector<Node *> toAdd;
00419     std::vector<Node *> toSub;
00420
00421     for ( ; mfit != mfen; ++mfit )
00422     {
00423         bool special=isInExcludeList(*mfit);
00424         bool leaf=isLeaf(*mfit);
00425         bool empty=true;
00426
00427         //if a transformation:
00428         if ((*mfit)->getCore()->getType().isDerivedFrom(
00429                 Transform::getClassType()))
00430         {
00431             if (!leaf && !special)
00432             {
00433                 //try to apply it to children geometries
00434                 //move all "moveable" children one level up
00435                 //if empty after that, delete it
00436                 MFUnrecChildNodePtr::const_iterator it2 =
00437                     (*mfit)->getMFChildren()->begin();
00438                 MFUnrecChildNodePtr::const_iterator en2 =
00439                     (*mfit)->getMFChildren()->end  ();
00440
00441                 for ( ; it2 != en2; ++it2 )
00442                 {
00443                     if (!isInExcludeList(*it2))
00444                     {
00445                         //check if geometry
00446                         if ((*it2)->getCore()->getType().isDerivedFrom(
00447                                 Geometry::getClassType()))
00448                         {
00449                             if(!isLeaf(*it2))
00450                             {
00451                                 //hmm...bad tree...
00452                                 empty=false;
00453                             }
00454                             else
00455                             {
00456                                 //it is a leaf geometry, so apply the transformation
00457                                 Geometry *geo_old =
00458                                     dynamic_cast<Geometry *>(
00459                                         (*it2)->getCore());
00460                                 //GeometryPtr geo = geo_old->clone();
00461                                 GeometryUnrecPtr geo =
00462                                     dynamic_pointer_cast<Geometry>(
00463                                         OSG::deepClone(geo_old, "Material"));
00464
00465                                 Transform *t =
00466                                     dynamic_cast<Transform *>(
00467                                         (*mfit)->getCore());
00468
00469                                 GeoPnt3fProperty *pos  = dynamic_cast<GeoPnt3fProperty *>(geo->getPositions());
00470                                 GeoVec3fProperty *norm = dynamic_cast<GeoVec3fProperty *>(geo->getNormals());
00471                                 GeoColor3fProperty *color = dynamic_cast<GeoColor3fProperty *>(geo->getColors());
00472                                 GeoColor3fProperty *scolor = dynamic_cast<GeoColor3fProperty *>(geo->getSecondaryColors());
00473                                 GeoVec3fProperty *texcoord0 = dynamic_cast<GeoVec3fProperty *>(geo->getTexCoords());
00474                                 GeoVec3fProperty *texcoord1 = dynamic_cast<GeoVec3fProperty *>(geo->getTexCoords1());
00475                                 GeoVec3fProperty *texcoord2 = dynamic_cast<GeoVec3fProperty *>(geo->getTexCoords2());
00476                                 GeoVec3fProperty * texcoord3 = dynamic_cast<GeoVec3fProperty *>(geo->getTexCoords3());
00477
00478                                 Matrix m=t->getMatrix();
00479
00480                                 if (pos!=NULL)
00481                                 {
00482                                     for (UInt32 i=0; i<pos->getSize(); i++)
00483                                     {
00484                                         Pnt3f p=pos->getValue(i);
00485                                         m.multFull(p, p);
00486                                         pos->setValue(p,i);
00487                                     }
00488                                 }
00489
00490                                 if (norm!=NULL)
00491                                 {
00492                                     for (UInt32 i=0; i<norm->getSize(); i++)
00493                                     {
00494                                         Vec3f n=norm->getValue(i);
00495                                         m.mult(n, n);
00496                                         n.normalize();
00497                                         norm->setValue(n,i);
00498                                     }
00499                                 }
00500
00501                                 if (color!=NULL && _color_is_vector)
00502                                 {
00503                                     for (UInt32 i=0; i<color->getSize(); i++)
00504                                     {
00505                                         Color3f c = color->getValue(i);
00506                                         Vec3f v;
00507                                         v.setValue(c.getValuesRGB());
00508                                         m.mult(v, v);
00509                                         v.normalize();
00510                                         c.setValuesRGB(v[0], v[1], v[2]);
00511                                         color->setValue(c,i);
00512                                     }
00513                                 }
00514
00515                                 if (scolor!=NULL && _secondary_color_is_vector)
00516                                 {
00517                                     for (UInt32 i=0; i<scolor->getSize(); i++)
00518                                     {
00519                                         Color3f c = scolor->getValue(i);
00520                                         Vec3f v;
00521                                         v.setValue(c.getValuesRGB());
00522                                         m.mult(v, v);
00523                                         v.normalize();
00524                                         c.setValuesRGB(v[0], v[1], v[2]);
00525                                         scolor->setValue(c,i);
00526                                     }
00527                                 }
00528
00529                                 if (texcoord0!=NULL && _texcoord0_is_vector)
00530                                 {
00531                                     for (UInt32 i=0; i<texcoord0->getSize(); i++)
00532                                     {
00533                                         Vec3f v=texcoord0->getValue(i);
00534                                         m.mult(v, v);
00535                                         v.normalize();
00536                                         texcoord0->setValue(v,i);
00537                                     }
00538                                 }
00539
00540                                 if (texcoord1!=NULL && _texcoord1_is_vector)
00541                                 {
00542                                     for (UInt32 i=0; i<texcoord1->getSize(); i++)
00543                                     {
00544                                         Vec3f v=texcoord1->getValue(i);
00545                                         m.mult(v, v);
00546                                         v.normalize();
00547                                         texcoord1->setValue(v,i);
00548                                     }
00549                                 }
00550
00551                                 if (texcoord2!=NULL && _texcoord2_is_vector)
00552                                 {
00553                                     for (UInt32 i=0; i<texcoord2->getSize(); i++)
00554                                     {
00555                                         Vec3f v=texcoord2->getValue(i);
00556                                         m.mult(v, v);
00557                                         v.normalize();
00558                                         texcoord2->setValue(v,i);
00559                                     }
00560                                 }
00561
00562                                 if (texcoord3!=NULL && _texcoord3_is_vector)
00563                                 {
00564                                     for (UInt32 i=0; i<texcoord3->getSize(); i++)
00565                                     {
00566                                         Vec3f v=texcoord3->getValue(i);
00567                                         m.mult(v, v);
00568                                         v.normalize();
00569                                         texcoord3->setValue(v,i);
00570                                     }
00571                                 }
00572                                 (*it2)->setCore(geo);
00573                                 toAdd.push_back(*it2);
00574                             }
00575                         } else empty=false;
00576                     } else empty=false;
00577                 }
00578             }
00579
00580             //now check whether we have to remove it
00581             if ((empty||leaf) && !special)
00582             {
00583                 toSub.push_back(*mfit);
00584                 continue;
00585             }
00586
00587             if (leaf && special)
00588             {
00589                 //what to do?
00590             }
00591             if (!leaf && special)
00592             {
00593                 //what to do?
00594             }
00595             continue;
00596         }
00597     }
00598
00599     std::vector<Node *>::const_iterator vit = toAdd.begin();
00600     std::vector<Node *>::const_iterator ven = toAdd.end  ();
00601
00602     for ( ; vit != ven; ++vit )
00603     {
00604         node->addChild(*vit);
00605     }
00606
00607     vit = toSub.begin();
00608     ven = toSub.end  ();
00609
00610     for ( ; vit != ven; ++vit )
00611     {
00612         node->subChild(*vit);
00613     }
00614 }
00615
00616 void MergeGraphOp::processGeometries(Node * const node)
00617 {
00618     MFUnrecChildNodePtr::const_iterator mfit = node->getMFChildren()->begin();
00619     MFUnrecChildNodePtr::const_iterator mfen = node->getMFChildren()->end  ();
00620
00621     std::vector<Node        *> toSub;
00622     std::vector<NodeUnrecPtr > toAdd;
00623
00624     for ( ; mfit != mfen; ++mfit )
00625     {
00626         bool special=isInExcludeList(*mfit);
00627
00628         if ((*mfit)->getCore()->getType().isDerivedFrom(
00629                 Geometry::getClassType()))
00630         {
00631 #ifndef OSG2_MERGE_MISSING
00632             Geometry *geo = dynamic_cast<Geometry *>((*mfit)->getCore());
00633 #endif
00634             //if a geometry, try to merge it in another geometry
00635             //if successfull, delete it.
00636             //check also if it is added for exclusion
00637
00638             bool inSubList=false;
00639
00640             std::vector<Node *>::const_iterator it3=toSub.begin();
00641             std::vector<Node *>::const_iterator en3=toSub.end();
00642
00643             for ( ; it3 != en3; ++it3 )
00644                 if (*it3==*mfit) { inSubList=true; break; }
00645
00646             if (!special && !inSubList)
00647             {
00648                 //ok, try
00649                 MFUnrecChildNodePtr::const_iterator it2=mfit+1;
00650                 Geometry *new_geo=NULL;
00651                 for ( ; it2!=mfen; ++it2)
00652                 {
00653                     if (!isInExcludeList(*it2) && (*it2)->getCore()->getType().isDerivedFrom(Geometry::getClassType()))
00654                     {
00655 #ifndef OSG2_MERGE_MISSING
00656                         Geometry *geo2 = dynamic_cast<Geometry *>((*it2)->getCore());
00657                         if (geo->isMergeable(geo2))
00658                         {
00659                             // HACK merge crashes when indices == NULL!
00660                             if(geo->getIndices() == NULL)
00661                                 OSG::createSharedIndex(geo);
00662                             if(geo2->getIndices() == NULL)
00663                                 OSG::createSharedIndex(geo2);
00664                             if (new_geo==NULL)
00665                             {
00666                                 new_geo=Geometry::create();
00667                                 if (new_geo->merge(geo))
00668                                     toSub.push_back(*it);
00669                                 else FWARNING(("MergeGraphOp: processGeometries problem 1\n"));
00670
00671                                 if (new_geo->merge(geo2))
00672                                     toSub.push_back(*it2);
00673                                 else FWARNING(("MergeGraphOp: processGeometries problem 2\n"));
00674                             }
00675                             else
00676                             {
00677                                 if (new_geo->merge(geo2))
00678                                     toSub.push_back(*it2);
00679                             }
00680                         }
00681 #endif
00682                     }
00683                 }
00684                 if (new_geo!=NULL)
00685                 {
00686                     NodeUnrecPtr new_node=Node::create();
00687                     new_node->setCore(new_geo);
00688
00689                     toAdd.push_back(new_node);
00690                 }
00691             }
00692             else
00693             {
00694                 //hmm...have to skip it
00695             }
00696         }
00697     }
00698
00699     std::vector<NodeUnrecPtr>::const_iterator ait = toAdd.begin();
00700     std::vector<NodeUnrecPtr>::const_iterator aen = toAdd.end  ();
00701
00702     for ( ; ait != aen; ++ait )
00703     {
00704         node->addChild(*ait);
00705     }
00706
00707     std::vector<Node *>::const_iterator sit = toSub.begin();
00708     std::vector<Node *>::const_iterator sen = toSub.end  ();
00709
00710     for ( ; sit != sen; ++sit )
00711     {
00712         node->subChild(*sit);
00713     }
00714 }