1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 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 \*---------------------------------------------------------------------------*/
40 /***************************************************************************\
42 \***************************************************************************/
46 #include "OSGMaterialMergeGraphOp.h"
47 #include "OSGGraphOpFactory.h"
48 #include "OSGFieldContainerUtils.h"
49 #include "OSGMaterial.h"
51 #include <boost/next_prior.hpp>
55 /***************************************************************************\
57 \***************************************************************************/
59 /*! \class OSG::MaterialMergeGraphOp
60 \ingroup GrpSystemNodeCoresDrawablesGeometry
62 Merges equivalent materials in a scene.
68 //! Register the GraphOp with the factory
69 static bool registerOp(void)
71 GraphOpRefPtr newOp
= MaterialMergeGraphOp::create();
73 GraphOpFactory::the()->registerOp(newOp
);
77 static OSG::StaticInitFuncWrapper
registerOpWrapper(registerOp
);
81 MaterialMergeGraphOp::MaterialMergeGraphOp(const char* name
) :
87 MaterialMergeGraphOp::~MaterialMergeGraphOp(void)
91 MaterialMergeGraphOpTransitPtr
92 MaterialMergeGraphOp::create(void)
94 return MaterialMergeGraphOpTransitPtr(new MaterialMergeGraphOp
);
97 GraphOpTransitPtr
MaterialMergeGraphOp::clone(void)
99 return GraphOpTransitPtr(new MaterialMergeGraphOp
);
102 bool MaterialMergeGraphOp::traverse(Node
*node
)
104 // Find the materials.
105 if(!GraphOp::traverse(node
))
110 SINFO
<< "Number of materials before merge: "
111 << _materialMap
.size() << std::endl
;
114 MaterialObjectMap::iterator mmIt
= _materialMap
.begin();
116 for (; mmIt
!= _materialMap
.end(); ++mmIt
)
118 Material
*currentMat
= mmIt
->first
;
119 MaterialObjectList
¤tList
= mmIt
->second
;
120 MaterialObjectMap::iterator mmWalker
= boost::next(mmIt
);
122 while(mmWalker
!= _materialMap
.end())
124 // Store the next iterator in case we have to delete
125 // 'walker' from the map.
126 MaterialObjectMap::iterator nextStep
= boost::next(mmWalker
);
128 if(compareContainerEqual(currentMat
, mmWalker
->first
))
130 // Set the new objects to have the current material,
131 // and move the objects to the current list.
132 MaterialObjectList::iterator mlIt
= mmWalker
->second
.begin();
133 MaterialObjectList::iterator mlEnd
= mmWalker
->second
.end ();
135 for (; mlIt
!= mlEnd
; ++mlIt
)
137 mlIt
->setMaterial(currentMat
);
138 currentList
.push_back(*mlIt
);
141 _materialMap
.erase(mmWalker
);
148 SINFO
<< "Number of materials after merge: " << _materialMap
.size() << std::endl
;
153 void MaterialMergeGraphOp::setParams(const std::string params
)
157 std::string out
= ps
.getUnusedParams();
160 FWARNING(("MaterialMergeGraphOp doesn't have parameters '%s'.\n",
165 std::string
MaterialMergeGraphOp::usage(void)
168 "MaterialMerge: merge Materials in given subtree\n"
169 " Tries to find and merge equiavlent Materials to reduce the number\n"
170 " of Materials used.\n"
174 Action::ResultE
MaterialMergeGraphOp::traverseEnter(Node
* const node
)
176 if(isInExcludeList(node
))
179 if(isInPreserveList(node
))
180 return Action::Continue
;
182 MaterialDrawable
*md
= dynamic_cast<MaterialDrawable
*>(node
->getCore());
185 addObject(MaterialObject(md
));
186 return Action::Continue
;
189 MaterialGroup
*mg
= dynamic_cast<MaterialGroup
*>(node
->getCore());
192 addObject(MaterialObject(mg
));
193 return Action::Continue
;
196 // Otherwise, keep looking.
197 return Action::Continue
;
200 Action::ResultE
MaterialMergeGraphOp::traverseLeave(Node
* const node
, Action::ResultE res
)
205 void MaterialMergeGraphOp::addObject(MaterialObject m
)
207 Material
*mat
= m
.getMaterial();
211 _materialMap
[mat
].push_back(m
);