fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / GraphOp / OSGMaterialMergeGraphOp.cpp
bloba1743489cedc5349641299f425338cd303c7834f
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
40 /***************************************************************************\
41 * Includes *
42 \***************************************************************************/
44 #include <sstream>
46 #include "OSGMaterialMergeGraphOp.h"
47 #include "OSGGraphOpFactory.h"
48 #include "OSGFieldContainerUtils.h"
49 #include "OSGMaterial.h"
51 #include <boost/next_prior.hpp>
53 OSG_BEGIN_NAMESPACE
55 /***************************************************************************\
56 * Description *
57 \***************************************************************************/
59 /*! \class OSG::MaterialMergeGraphOp
60 \ingroup GrpSystemNodeCoresDrawablesGeometry
62 Merges equivalent materials in a scene.
65 namespace
68 //! Register the GraphOp with the factory
69 static bool registerOp(void)
71 GraphOpRefPtr newOp = MaterialMergeGraphOp::create();
73 GraphOpFactory::the()->registerOp(newOp);
74 return true;
77 static OSG::StaticInitFuncWrapper registerOpWrapper(registerOp);
79 } // namespace
81 MaterialMergeGraphOp::MaterialMergeGraphOp(const char* name) :
82 GraphOp (name),
83 _materialMap( )
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))
107 return false;
110 SINFO << "Number of materials before merge: "
111 << _materialMap.size() << std::endl;
113 // Now do the merge.
114 MaterialObjectMap::iterator mmIt = _materialMap.begin();
116 for (; mmIt != _materialMap.end(); ++mmIt)
118 Material *currentMat = mmIt->first;
119 MaterialObjectList &currentList = 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);
144 mmWalker = nextStep;
148 SINFO << "Number of materials after merge: " << _materialMap.size() << std::endl;
149 return true;
153 void MaterialMergeGraphOp::setParams(const std::string params)
155 ParamSet ps(params);
157 std::string out = ps.getUnusedParams();
158 if(out.length())
160 FWARNING(("MaterialMergeGraphOp doesn't have parameters '%s'.\n",
161 out.c_str()));
165 std::string MaterialMergeGraphOp::usage(void)
167 return
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))
177 return Action::Skip;
179 if(isInPreserveList(node))
180 return Action::Continue;
182 MaterialDrawable *md = dynamic_cast<MaterialDrawable *>(node->getCore());
183 if(md != NULL)
185 addObject(MaterialObject(md));
186 return Action::Continue;
189 MaterialGroup *mg = dynamic_cast<MaterialGroup *>(node->getCore());
190 if(mg != NULL)
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)
202 return res;
205 void MaterialMergeGraphOp::addObject(MaterialObject m)
207 Material *mat = m.getMaterial();
208 if (mat == NULL)
209 return;
211 _materialMap[mat].push_back(m);
214 OSG_END_NAMESPACE