1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2008 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 #include "OSGMaterialGroupPushGraphOp.h"
40 #include "OSGGraphOpFactory.h"
41 #include "OSGAction.h"
42 #include "OSGMaterialDrawable.h"
44 #include <boost/bind.hpp>
46 /*! \class OSG::MaterialGroupPushGraphOp
47 \ingroup GrpSystemNodeCoresDrawablesGeometry
49 Moves the Materials form MaterialGroups to the MaterialDrawables below
50 them and replaces the obsolete MaterialGroups with Groups.
57 static bool registerOp(void)
59 GraphOpRefPtr newOp
= MaterialGroupPushGraphOp::create();
61 GraphOpFactory::the()->registerOp(newOp
);
65 static OSG::StaticInitFuncWrapper
registerOpWrapper(registerOp
);
68 const char *MaterialGroupPushGraphOp::getClassname(void)
70 return "MaterialGroupPushGraphOp";
73 MaterialGroupPushGraphOp::MaterialGroupPushGraphOp(const char* name
)
79 MaterialGroupPushGraphOpTransitPtr
80 MaterialGroupPushGraphOp::create(void)
82 return MaterialGroupPushGraphOpTransitPtr(
83 new MaterialGroupPushGraphOp
);
86 GraphOpTransitPtr
MaterialGroupPushGraphOp::clone(void)
88 return GraphOpTransitPtr(new MaterialGroupPushGraphOp
);
91 void MaterialGroupPushGraphOp::setParams(const std::string params
)
95 std::string out
= ps
.getUnusedParams();
98 FWARNING(("MaterialGroupPushGraphOp doesn't have parameters '%s'.\n",
103 std::string
MaterialGroupPushGraphOp::usage(void)
105 return "MaterialGroupPush: Move Transform towards leafs of the scene.\n";
109 MaterialGroupPushGraphOp::~MaterialGroupPushGraphOp(void)
115 Action::ResultE
MaterialGroupPushGraphOp::traverseEnter(Node
* const node
)
117 if(isInExcludeList(node
))
120 return Action::Continue
;
123 Action::ResultE
MaterialGroupPushGraphOp::traverseLeave(
124 Node
* const node
, Action::ResultE res
)
126 if(isInExcludeList(node
))
129 if(isInPreserveList(node
))
130 return Action::Continue
;
132 MaterialGroup
*mg
= dynamic_cast<MaterialGroup
*>(node
->getCore());
135 return Action::Continue
;
137 // if not a leaf, search children recursively to find push targets
138 if(!node
->getMFChildren()->empty())
140 _pushPossible
= true;
141 _pushTargets
.clear();
144 *(node
->getMFChildren()),
146 &MaterialGroupPushGraphOp::traverseTargetsEnter
, this, _1
));
148 if(_pushPossible
== true)
150 // push MaterialGroup into targets
151 pushMaterialGroup(mg
);
153 // replace MaterialGroup with group
154 GroupUnrecPtr replaceCore
= Group::create();
155 node
->setCore(replaceCore
);
159 return Action::Continue
;
162 /*! Find push targets in subtree.
164 Action::ResultE
MaterialGroupPushGraphOp::traverseTargetsEnter(Node
* const node
)
166 NodeCore
*core
= node
->getCore();
170 // warn about broken subtree, but do not prevent push, just skip it
171 FWARNING(("MaterialGroupPushGraphOp::traverseTargetsEnter: "
172 "Found node without core!\n"));
176 if(isInExcludeList(node
) || isInPreserveList(node
))
178 // prevent the push as the mat group can not be moved into this branch.
179 _pushPossible
= false;
184 if(core
->getType().isDerivedFrom(MaterialDrawable::getClassType()))
186 // found a push target in this branch, store it and stop searching
187 _pushTargets
.push_back(node
);
192 if( core
->getType().isDerivedFrom(Group ::getClassType()) &&
193 !core
->getType().isDerivedFrom(MaterialGroup::getClassType()) )
195 // keep searching children for push targets
196 return Action::Continue
;
199 // unknown core type, be conservative and prevent the push
200 _pushPossible
= false;
205 void MaterialGroupPushGraphOp::pushMaterialGroup(MaterialGroup
*mg
)
207 PushTargetStore::iterator ptIt
= _pushTargets
.begin();
208 PushTargetStore::iterator ptEnd
= _pushTargets
.end ();
210 for(; ptIt
!= ptEnd
; ++ptIt
)
212 MaterialDrawable
*dstMD
=
213 dynamic_cast<MaterialDrawable
*>((*ptIt
)->getCore());
216 dstMD
->setMaterial(mg
->getMaterial());