changed: gcc8 base update
[opensg.git] / Source / System / FileIO / Collada / OSGColladaGlobal.cpp
blob2500e50c31477c96a0f5fa71a0dae75e2d958cbe
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2009 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 \*---------------------------------------------------------------------------*/
39 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
40 #pragma GCC diagnostic ignored "-Wold-style-cast"
41 #endif
43 #include "OSGColladaGlobal.h"
45 #if defined(OSG_WITH_COLLADA) || defined(OSG_DO_DOC)
47 #include "OSGColladaLog.h"
48 #include "OSGColladaCOLLADA.h"
49 #include "OSGColladaInstInfo.h"
50 #include "OSGColladaElementFactory.h"
51 #include "OSGColladaOptions.h"
53 #include "OSGNode.h"
55 /*! \class OSG::ColladaGlobal
56 This is the entry point for the Collada loader from which the loading
57 process is started.
58 You can think of it as representing the <COLLADA> tag in a document.
61 OSG_BEGIN_NAMESPACE
63 StatElemDesc<StatIntElem> ColladaGlobal::statNGeometryCreated(
64 "Collada::NGeometryCreated",
65 "Number of OpenSG geometries created by the collada loader",
66 StatElemDescBase::RESET_ALWAYS);
67 StatElemDesc<StatIntElem> ColladaGlobal::statNGeometryUsed(
68 "Collada::NGeometryUsed",
69 "Number of OpenSG geometries in the scene created by the collada loader",
70 StatElemDescBase::RESET_ALWAYS);
71 StatElemDesc<StatIntElem> ColladaGlobal::statNMaterialCreated(
72 "Collada::NMaterialCreated",
73 "Number of OpenSG materials created by the collada loader",
74 StatElemDescBase::RESET_ALWAYS);
75 StatElemDesc<StatIntElem> ColladaGlobal::statNMaterialUsed(
76 "Collada::NMaterialUsed",
77 "Number of OpenSG materials in the scene created by the collada loader",
78 StatElemDescBase::RESET_ALWAYS);
79 StatElemDesc<StatIntElem> ColladaGlobal::statNLightCreated(
80 "Collada::NLightCreated",
81 "Number of OpenSG lights created by the collada loader",
82 StatElemDescBase::RESET_ALWAYS);
83 StatElemDesc<StatIntElem> ColladaGlobal::statNLightUsed(
84 "Collada::NLightUsed",
85 "Number of OpenSG lights in the scene created by the collada loader",
86 StatElemDescBase::RESET_ALWAYS);
87 StatElemDesc<StatIntElem> ColladaGlobal::statNTextureCreated(
88 "Collada::NTextureCreated",
89 "Number of OpenSG textures created by the collada loader",
90 StatElemDescBase::RESET_ALWAYS);
91 StatElemDesc<StatIntElem> ColladaGlobal::statNTextureUsed(
92 "Collada::NTextureUsed",
93 "Number of OpenSG textures in the scene created by the collada loader",
94 StatElemDescBase::RESET_ALWAYS);
96 StatCollector *
97 ColladaGlobal::getStatCollector(void)
99 return _statColl;
102 void
103 ColladaGlobal::setStatCollector(StatCollector *statColl)
105 _statColl = statColl;
108 ColladaGlobalTransitPtr
109 ColladaGlobal::create(void)
111 return ColladaGlobalTransitPtr(new Self);
114 /*! Read the file \a fileName using a new DAE database.
116 NodeTransitPtr
117 ColladaGlobal::read(std::istream &is, const std::string &fileName)
119 NodeTransitPtr rootN;
121 _pathHandler.clearPathList();
122 _pathHandler.clearBaseFile();
124 _pathHandler.push_frontCurrentDir( );
125 _pathHandler.setBaseFile (fileName.c_str());
127 _docPath = fileName;
129 _dae = new DAE;
130 _dae->open(fileName.c_str());
132 rootN = doRead();
134 _docPath. clear();
135 _dae ->clear();
136 delete _dae;
137 _dae = NULL;
139 return rootN;
142 /*! Read the file \a fileName from the existing DAE database \a dae.
143 The given \a fileName must already be loaded into the DAE.
145 Useful if multiple documents are stored in one DAE database or
146 if an application needs to access the DAE itself to extract
147 data that is not processed by the loader.
149 NodeTransitPtr
150 ColladaGlobal::read(DAE *dae, const std::string &fileName)
152 NodeTransitPtr rootN(NULL);
154 _pathHandler.clearPathList();
155 _pathHandler.clearBaseFile();
157 _pathHandler.push_frontCurrentDir( );
158 _pathHandler.setBaseFile (fileName.c_str());
160 _docPath = fileName;
161 _dae = dae;
163 rootN = doRead();
165 _docPath.clear();
166 _dae = NULL;
168 return rootN;
171 void
172 ColladaGlobal::addElement(ColladaElement *elem)
174 _elemStore.push_back(elem);
178 * Helper function for de-mangling filepaths. Removes leading filepath
179 * separators and replaces escaped url characters (i.e. "%20" with " " (a
180 * single space))
183 std::string ColladaGlobal::fixFilepath(std::string filepath)
186 std::string escaped[] = {"%20", "%22", "%3C", "%3E", "%23", "%25", "%7B",
187 "%7D", "%7C", "%5E", "%7E", "%5B", "%5D", "%60"};
189 std::string replacements[] = {" ","\"","<",">","#","%","{",
190 "}","|","^","~","[","]","`"};
192 // removing leading file path separators
193 while(filepath[0] == '/' || filepath[0] == '\\')
195 filepath = filepath.substr(1);
198 // remove escaped characters and replace
199 size_t pos = 0;
201 for(UInt32 i = 0; i < 14; ++i)
203 for(;;)
205 pos = filepath.find(escaped[i], pos);
207 if(pos == std::string::npos)
209 break;
211 else
213 filepath = filepath.replace(pos, 3, replacements[i]);
218 return filepath;
221 // re-formats an image filepath so that it can be read properly
222 std::string ColladaGlobal::fixImageFilepath(std::string szImgPath)
224 if(szImgPath.substr(0, 5) == "file:")
226 szImgPath = szImgPath.substr(4);
229 return fixFilepath(szImgPath);
232 std::string ColladaGlobal::uriToNativePath(const std::string &uriRef,
233 cdom::systemType type )
235 std::string scheme, authority, path, query, fragment;
237 cdom::parseUriRef(uriRef, scheme, authority, path, query, fragment);
239 // Make sure we have a file scheme URI, or that it doesn't have a scheme
240 if (!scheme.empty() && scheme != "file")
241 return "";
243 std::string filePath;
245 #if 0
246 fprintf(stderr, "foo %s ==> | %s | %s | %s | %s | %s | \n",
247 uriRef.c_str(),
248 scheme.c_str(),
249 authority.c_str(),
250 path.c_str(),
251 query.c_str(),
252 fragment.c_str());
253 #endif
255 // if(authority.empty() == false && path.empty() == true)
256 // path.swap(authority);
258 if(type == cdom::Windows)
260 if(!authority.empty())
261 filePath += std::string("\\\\") + authority; // UNC path
263 // Replace two leading slashes with one leading slash, so that
264 // ///otherComputer/file.dae becomes //otherComputer/file.dae and
265 // //folder/file.dae becomes /folder/file.dae
266 if(path.length() >= 2 && path[0] == '/' && path[1] == '/')
267 path.erase(0, 1);
269 // Convert "/C:/" to "C:/"
270 if(path.length() >= 3 && path[0] == '/' && path[2] == ':')
271 path.erase(0, 1);
273 // Convert forward slashes to back slashes
274 path = cdom::replace(path, "/", "\\");
276 else
278 filePath += authority;
281 filePath += path;
283 // Replace %20 with space
284 filePath = cdom::replace(filePath, "%20", " ");
286 return filePath;
289 ColladaGlobal::ColladaGlobal(void)
290 : Inherited ()
291 , _instQueue ()
292 , _loaderState()
293 , _elemStore ()
294 , _options ()
295 , _statColl (NULL)
296 , _pathHandler()
297 , _docPath ()
298 , _docRoot ()
299 , _dae (NULL)
300 , _rootN (NULL)
301 , _globalsAtt (NULL)
305 ColladaGlobal::~ColladaGlobal(void)
307 delete _dae;
308 _dae = NULL;
311 /*! Read the file stored in _docPath from the DAE _dae.
313 NodeTransitPtr
314 ColladaGlobal::doRead(void)
316 NodeTransitPtr rootN(NULL);
318 if(_statColl == NULL)
319 _statColl = new StatCollector;
321 // force creation of the statistic elements
322 _statColl->getElem(statNGeometryCreated, true);
323 _statColl->getElem(statNGeometryUsed, true);
324 _statColl->getElem(statNMaterialCreated, true);
325 _statColl->getElem(statNMaterialUsed, true);
326 _statColl->getElem(statNLightCreated, true);
327 _statColl->getElem(statNLightUsed, true);
328 _statColl->getElem(statNTextureCreated, true);
329 _statColl->getElem(statNTextureUsed, true);
331 _statColl->reset (StatElemDescBase::RESET_ALWAYS);
333 _globalsAtt = GlobalsAttachment::create();
334 _docRoot = dynamic_cast<domCOLLADA *>(_dae->getRoot(_docPath));
336 if(_docRoot != NULL)
338 ColladaCOLLADARefPtr colCOL = dynamic_pointer_cast<ColladaCOLLADA>(
339 ColladaElementFactory::the()->create(_docRoot, this));
341 colCOL->read(NULL);
343 for(UInt32 i = 0; _instQueue.empty() == false; ++i)
345 if(i > 10)
347 SWARNING << "ColladaGlobal::doRead: InstanceQueue loop "
348 << "maximum iteration count reached." << std::endl;
349 break;
352 InstanceQueue workQueue;
353 workQueue.swap(_instQueue);
355 InstanceQueueIt iqIt = workQueue.begin();
356 InstanceQueueIt iqEnd = workQueue.end ();
358 for(; iqIt != iqEnd; ++iqIt)
359 (*iqIt)->process();
362 else
364 SWARNING << "ColladaGlobal::read: collada-dom failed to obtain "
365 << "document root for file [" << _docPath << "]."
366 << std::endl;
369 if(_globalsAtt->getMFElements()->empty() == false)
370 _rootN->addAttachment(_globalsAtt);
372 rootN = _rootN;
374 _docRoot = NULL;
375 _globalsAtt = NULL;
376 _instQueue .clear();
377 _loaderState.clear();
378 _elemStore .clear();
380 #ifndef OSG_COLLADA_SILENT
381 std::string statString;
382 _statColl->putToString(statString);
384 OSG_COLLADA_LOG(("ColladaGlobal:read: Statistics\n%s\n",
385 statString.c_str()));
386 #endif // OSG_COLLADA_SILENT
388 return rootN;
391 OSG_END_NAMESPACE
393 #endif // OSG_WITH_COLLADA