Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGDepthFirstAction.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //----------------------------------------------------------------------------
00040 //    Includes
00041 //----------------------------------------------------------------------------
00042 
00043 #include "OSGDepthFirstAction.h"
00044 
00045 OSG_USING_NAMESPACE
00046 
00047 //==== PUBLIC ================================================================
00048 //----------------------------------------------------------------------------
00049 //    Destructor
00050 //----------------------------------------------------------------------------
00051 
00055 DepthFirstAction::~DepthFirstAction(void)
00056 {
00057 }
00058 
00059 //----------------------------------------------------------------------------
00060 //    Create
00061 //----------------------------------------------------------------------------
00062 
00066 DepthFirstAction *
00067 DepthFirstAction::create(void)
00068 {
00069     return new DepthFirstAction();
00070 }
00071 
00072 //----------------------------------------------------------------------------
00073 //    Apply
00074 //----------------------------------------------------------------------------
00075 
00079 DepthFirstAction::ResultE
00080 DepthFirstAction::apply(NodePtr pRoot)
00081 {
00082     ResultE result = NewActionTypes::Continue;
00083 
00084     startEvent();
00085 
00086     result = startActors();
00087 
00088     if(result & NewActionTypes::Quit)
00089         return result;
00090 
00091     _nodeStack.push_back(NodeStackEntry(pRoot, 1));
00092 
00093     if((_extendLeaveActors.empty() == true) &&
00094        (_basicLeaveActors .empty() == true)    )
00095     {
00096         result = traverseEnter();
00097     }
00098     else
00099     {
00100         result = traverseEnterLeave();
00101     }
00102 
00103     if(result & NewActionTypes::Quit)
00104         return result;
00105 
00106     result = stopActors();
00107 
00108     stopEvent();
00109 
00110     return result;
00111 }
00112 
00113 //==== PROTECTED =============================================================
00114 //----------------------------------------------------------------------------
00115 //    Constructors
00116 //----------------------------------------------------------------------------
00117 
00121 DepthFirstAction::DepthFirstAction(void)
00122     : Inherited         (),
00123       _nodeStack        (),
00124       _extendEnterActors(),
00125       _extendLeaveActors(),
00126       _basicEnterActors (),
00127       _basicLeaveActors ()
00128 {
00129 }
00130 
00131 //----------------------------------------------------------------------------
00132 //    Events
00133 //----------------------------------------------------------------------------
00134 
00140 void
00141 DepthFirstAction::addExtendEvent(ExtendActorBase *pActor, UInt32 actorIndex)
00142 {
00143     ExtendActorStoreIt itActors  = beginExtend();
00144     ExtendActorStoreIt endActors = beginExtend() + actorIndex;
00145 
00146     ExtendActorStoreIt itEnter   = _extendEnterActors.begin();
00147     ExtendActorStoreIt itLeave   = _extendLeaveActors.begin();
00148 
00149     for(; itActors != endActors; ++itActors)
00150     {
00151         if((*itActors)->getEnterNodeFlag() == true)
00152             ++itEnter;
00153 
00154         if((*itActors)->getLeaveNodeFlag() == true)
00155             ++itLeave;
00156     }
00157 
00158     if(pActor->getEnterNodeFlag() == true)
00159         _extendEnterActors.insert(itEnter, pActor);
00160 
00161     if(pActor->getLeaveNodeFlag() == true)
00162         _extendLeaveActors.insert(itLeave, pActor);
00163 }
00164 
00168 void
00169 DepthFirstAction::subExtendEvent(ExtendActorBase *pActor, UInt32 actorIndex)
00170 {
00171     ExtendActorStoreIt itEnter  = _extendEnterActors.begin();
00172     ExtendActorStoreIt endEnter = _extendEnterActors.end  ();
00173 
00174     ExtendActorStoreIt itLeave  = _extendLeaveActors.begin();
00175     ExtendActorStoreIt endLeave = _extendLeaveActors.end  ();
00176 
00177     for(; itEnter != endEnter; ++itEnter)
00178     {
00179         if(*itEnter == pActor)
00180         {
00181             _extendEnterActors.erase(itEnter);
00182 
00183             break;
00184         }
00185     }
00186 
00187     for(; itLeave != endLeave; ++itLeave)
00188     {
00189         if(*itLeave == pActor)
00190         {
00191             _extendLeaveActors.erase(itLeave);
00192 
00193             break;
00194         }
00195     }
00196 }
00197 
00203 void
00204 DepthFirstAction::addBasicEvent(BasicActorBase *pActor, UInt32 actorIndex)
00205 {
00206     BasicActorStoreIt itActors  = beginBasic();
00207     BasicActorStoreIt endActors = beginBasic() + actorIndex;
00208 
00209     BasicActorStoreIt itEnter   = _basicEnterActors.begin();
00210     BasicActorStoreIt itLeave   = _basicLeaveActors.begin();
00211 
00212     for(; itActors != endActors; ++itActors)
00213     {
00214         if((*itActors)->getEnterNodeFlag() == true)
00215             ++itEnter;
00216 
00217         if((*itActors)->getLeaveNodeFlag() == true)
00218             ++itLeave;
00219     }
00220 
00221     if(pActor->getEnterNodeFlag() == true)
00222         _basicEnterActors.insert(itEnter, pActor);
00223 
00224     if(pActor->getLeaveNodeFlag() == true)
00225         _basicLeaveActors.insert(itLeave, pActor);
00226 }
00227 
00231 void
00232 DepthFirstAction::subBasicEvent(BasicActorBase *pActor, UInt32 actorIndex)
00233 {
00234     BasicActorStoreIt itEnter  = _basicEnterActors.begin();
00235     BasicActorStoreIt endEnter = _basicEnterActors.end  ();
00236 
00237     BasicActorStoreIt itLeave  = _basicLeaveActors.begin();
00238     BasicActorStoreIt endLeave = _basicLeaveActors.end  ();
00239 
00240     for(; itEnter != endEnter; ++itEnter)
00241     {
00242         if(*itEnter == pActor)
00243         {
00244             _basicEnterActors.erase(itEnter);
00245 
00246             break;
00247         }
00248     }
00249 
00250     for(; itLeave != endLeave; ++itLeave)
00251     {
00252         if(*itLeave == pActor)
00253         {
00254             _basicLeaveActors.erase(itLeave);
00255 
00256             break;
00257         }
00258     }
00259 }
00260 
00264 void
00265 DepthFirstAction::beginEditStateEvent(ActorBase *pActor, UInt32 actorId)
00266 {
00267 }
00268 
00272 void
00273 DepthFirstAction::endEditStateEvent(ActorBase *pActor, UInt32 actorId)
00274 {
00275 }
00276 
00277 //==== PRIVATE ===============================================================
00278 //----------------------------------------------------------------------------
00279 //    Helper Methods
00280 //----------------------------------------------------------------------------
00281 
00286 DepthFirstAction::ResultE
00287 DepthFirstAction::traverseEnter(void)
00288 {
00289     ResultE result = NewActionTypes::Continue;
00290     NodePtr pNode;
00291     Int32   nodePass;     // pass over the current node
00292     UInt32  multiPasses;  // requested passes over the current node
00293 
00294     while((_nodeStack.empty() == false) && !(result & NewActionTypes::Quit))
00295     {
00296         pNode    = _nodeStack.back().getNode     ();
00297         nodePass = _nodeStack.back().getPassCount();
00298 
00299         getChildrenList().setParentNode(pNode);
00300 
00301 #ifdef OSG_NEWACTION_STATISTICS
00302         getStatistics()->getElem(statNodesEnter)->inc();
00303 #endif /* OSG_NEWACTION_STATISTICS */
00304 
00305         result      = enterNode   (pNode, static_cast<UInt32>(nodePass - 1));
00306         multiPasses = getNumPasses(                                        );
00307 
00308         _nodeStack.pop_back();
00309 
00310         // only initial pass (nodePass == 1) can request multiPasses
00311         if((nodePass == 1) && (multiPasses > 1))
00312         {
00313             for(; multiPasses > 1; --multiPasses)
00314             {
00315                 _nodeStack.push_back(NodeStackEntry(pNode, multiPasses));
00316             }
00317         }
00318 
00319         pushChildren(pNode, result);
00320     }
00321 
00322     return result;
00323 }
00324 
00329 DepthFirstAction::ResultE
00330 DepthFirstAction::traverseEnterLeave(void)
00331 {
00332     ResultE result = NewActionTypes::Continue;
00333     NodePtr pNode;
00334     Int32   nodePass;     // pass over the current node
00335     UInt32  multiPasses;  // requested passes over the current node
00336 
00337     while((_nodeStack.empty() == false) && !(result & NewActionTypes::Quit))
00338     {
00339         pNode    = _nodeStack.back().getNode     ();
00340         nodePass = _nodeStack.back().getPassCount();
00341 
00342         getChildrenList().setParentNode(pNode);
00343 
00344         if(nodePass > 0)
00345         {
00346             // positive pass -> enter node
00347 
00348 #ifdef OSG_NEWACTION_STATISTICS
00349             getStatistics()->getElem(statNodesEnter)->inc();
00350 #endif /* OSG_NEWACTION_STATISTICS */
00351 
00352             result      = enterNode   (pNode, static_cast<UInt32>(nodePass - 1));
00353             multiPasses = getNumPasses(               );
00354 
00355             // only initial pass (nodePass == 1) can request multiPasses
00356             if((nodePass == 1) && (multiPasses > 1))
00357             {
00358                 // remove current node from stack
00359                 _nodeStack.pop_back();
00360 
00361                 for(; multiPasses > 1; --multiPasses)
00362                 {
00363                     _nodeStack.push_back(NodeStackEntry(pNode, multiPasses));
00364                 }
00365 
00366                 // readd current node - with negative pass -> leave
00367                 _nodeStack.push_back(NodeStackEntry(pNode, -nodePass));
00368             }
00369             else
00370             {
00371                 // change current node passCount to negative -> leave
00372                 _nodeStack.back().setPassCount(-nodePass);
00373             }
00374 
00375             pushChildren(pNode, result);
00376         }
00377         else
00378         {
00379             // negative pass -> leave node
00380 
00381 #ifdef OSG_NEWACTION_STATISTICS
00382             getStatistics()->getElem(statNodesLeave)->inc();
00383 #endif /* OSG_NEWACTION_STATISTICS */
00384 
00385             result = leaveNode(pNode, static_cast<UInt32>(-nodePass - 1));
00386 
00387             _nodeStack.pop_back();
00388         }
00389     }
00390 
00391     return result;
00392 }
00393 
00398 void
00399 DepthFirstAction::pushChildren(const NodePtr &pNode, ResultE result)
00400 {
00401     if(result & (NewActionTypes::Skip  |
00402                  NewActionTypes::Break |
00403                  NewActionTypes::Quit   ))
00404     {
00405         setChildrenListEnabled(false);
00406         setNumPasses          (1    );
00407 
00408         getExtraChildrenList().clear();
00409 
00410         return;
00411     }
00412 
00413     ChildrenList      &cl  = getChildrenList     ();
00414     ExtraChildrenList &ecl = getExtraChildrenList();
00415 
00416     if(getChildrenListEnabled() == true)
00417     {
00418         for(UInt32 i = 0, size = cl.getSize(); i < size; ++i)
00419         {
00420             if(( cl.getActive(i)                                 == true  ) &&
00421                ( cl.getChild (i)                                 != NullFC) &&
00422                ((cl.getChild (i)->getTravMask() & getTravMask()) != 0     )   )
00423             {
00424                 _nodeStack.push_back(NodeStackEntry(cl.getChild(i), 1));
00425             }
00426         }
00427     }
00428     else
00429     {
00430         MFNodePtr::const_iterator itChildren  = pNode->getMFChildren()->begin();
00431         MFNodePtr::const_iterator endChildren = pNode->getMFChildren()->end  ();
00432 
00433         for(; itChildren != endChildren; ++itChildren)
00434         {
00435             if((  *itChildren                                  != NullFC) &&
00436                (((*itChildren)->getTravMask() & getTravMask()) != 0     )   )
00437             {
00438                 _nodeStack.push_back(NodeStackEntry(*itChildren, 1));
00439             }
00440         }
00441     }
00442 
00443     for(UInt32 i = 0, size = ecl.getSize(); i < size; ++i)
00444     {
00445         if(( ecl.getActive(i)                                 == true  ) &&
00446            ( ecl.getChild (i)                                 != NullFC) &&
00447            ((ecl.getChild (i)->getTravMask() & getTravMask()) != 0     )   )
00448         {
00449             _nodeStack.push_back(NodeStackEntry(ecl.getChild(i), 1));
00450         }
00451     }
00452 
00453     setChildrenListEnabled(false);
00454     setNumPasses          (1    );
00455     ecl.clear             (     );
00456 }
00457 
00458 /*------------------------------------------------------------------------*/
00459 /*                              cvs id's                                  */
00460 
00461 #ifdef OSG_SGI_CC
00462 #pragma set woff 1174
00463 #endif
00464 
00465 #ifdef OSG_LINUX_ICC
00466 #pragma warning(disable : 177)
00467 #endif
00468 
00469 namespace
00470 {
00471     static Char8 cvsid_cpp       [] = "@(#)$Id: OSGDepthFirstAction.cpp,v 1.4 2004/09/17 14:09:42 neumannc Exp $";
00472     static Char8 cvsid_hpp       [] = OSGDEPTHFIRSTACTION_HEADER_CVSID;
00473     static Char8 cvsid_inl       [] = OSGDEPTHFIRSTACTION_INLINE_CVSID;
00474 }
00475 
00476 #ifdef OSG_LINUX_ICC
00477 #pragma warning(enable : 177)
00478 #endif
00479 
00480 #ifdef OSG_SGI_CC
00481 #pragma reset woff 1174
00482 #endif

Generated on Thu Aug 25 04:02:47 2005 for OpenSG by  doxygen 1.4.3