1 /*
2 * Copyright 2006 Sony Computer Entertainment Inc.
3 *
4 * Licensed under the MIT Open Source License, for details please see license.txt or the website
5 * http://www.opensource.org/licenses/mit-license.php
6 *
7 */
8
9 #ifndef __DAE__
10 #define __DAE__
11
12 // We use the boost filesystem library for cross-platform file system support. You'll need
13 // to have boost on your machine for this to work. For the Windows build boost is provided
14 // in the external-libs folder, but for Linux it's expected that you'll install a boost
15 // obtained via your distro's package manager. For example on Debian/Ubuntu, you can run
16 // apt-get install libboost-filesystem-dev
17 // to install the boost filesystem library on your machine.
18 //
19 // Disable the warnings we get from Boost
20 // warning C4180: qualifier applied to function type has no meaning; ignored
21 // warning C4245: 'argument' : conversion from 'int' to 'boost::filesystem::system_error_type',
22 // signed/unsigned mismatch
23 #ifdef _MSC_VER
24 #pragma warning(push)
25 #pragma warning(disable: 4180 4245)
26 #endif
27 #ifndef NO_BOOST
28 #include <boost/filesystem/convenience.hpp>
29 #endif
30 #ifdef _MSC_VER
31 #pragma warning(pop)
32 #endif
33
34 #include <dae/daeTypes.h>
35 #include <dae/daeError.h>
36 #include <dae/daeDatabase.h>
37 #include <dae/daeIOPlugin.h>
38 #include <dae/daeAtomicType.h>
39 #include <dae/daeMetaElement.h>
40 #include <dae/daeIDRef.h>
41 #include <dae/daeURI.h>
42 #include <dae/daeUtils.h>
43 #include <dae/daeRawResolver.h>
44 #include <dae/daeSIDResolver.h>
45
46 // needed for backward compatibility
47 #ifdef COLLADA_DOM_SUPPORT150
48 namespace ColladaDOM150 {
49 class domCOLLADA;
50 typedef daeSmartRef<domCOLLADA> domCOLLADARef;
51 }
52 #endif
53 #ifdef COLLADA_DOM_SUPPORT141
54 namespace ColladaDOM141 {
55 class domCOLLADA;
56 typedef daeSmartRef<domCOLLADA> domCOLLADARef;
57 }
58 #endif
59
60 typedef daeElement domCOLLADAProxy;
61 typedef daeSmartRef<daeElement> domCOLLADAProxyRef;
62
63 class daeDatabase;
64
65 // The DAE class is the core interface via which you interact with the DOM. It
66 // has methods to load/save documents, get the root element of each document,
67 // etc. Although internally the DOM works exclusively with URIs, the methods of
68 // the DAE class that take document paths can take URIs or OS-specific file
69 // paths.
70 class DLLSPEC DAE
71 {
72 public:
73 // Constructor. If no database or IO plugin are provided, a default database and
74 // IO plugin will be used.
75 // \param specversion the collada specification to load into memory. For example: "1.4.1" or "1.5.0". If NULL, then the highest version found will be loaded.
76 DAE(daeDatabase* database = NULL, daeIOPlugin* ioPlugin = NULL, const char* specversion = NULL)
77 : atomicTypes(*this),
78 baseUri(*this, cdom::getCurrentDirAsUri().c_str())
79 {
80 // See the end of the thread linked below for an explanation of why we have the DAE
81 // constructor set up this way. Basically, I'm going to be changing the build output
82 // location, and when this happens people sometimes continue to link against the old
83 // libraries by accident (e.g. if they just do an svn update). By introducing a new
84 // function that gets called from a function in a header file, I'm ensuring that someone
85 // who tries linking against old libraries will get a link error. This may not sound
86 // very nice, but it's certainly better than getting bizarre runtime crashes.
87 // https://collada.org/public_forum/viewtopic.php?t=771&sid=f13c34f2d17ca720c5021bccbe5128b7
88 init(database, ioPlugin,specversion);
89 dummyFunction1();
90 }
91
92 virtual ~DAE();
93
94 // Release all memory used by the DOM. You never need to call this explicitly. It's
95 // called automatically when all DAE objects go out of scope.
96 // Deletes directory returned by cdom::getSafeTmpDir().
97 static void cleanup();
98
99 public:
100 // Database setup
101 virtual daeDatabase* getDatabase();
102 virtual daeInt setDatabase(daeDatabase* database);
103
104 // IO Plugin setup
105 virtual daeIOPlugin* getIOPlugin();
106 virtual daeInt setIOPlugin(daeIOPlugin* plugin);
107
108 // Creates a new document, returning null on failure. Cast to ColladaDOMXXX::domCOLLADA
109 virtual domCOLLADAProxy* add(const std::string& path);
110 // Opens an existing document, returning null on failure. Cast to ColladaDOMXXX::domCOLLADA
111 virtual domCOLLADAProxy* open(const std::string& path);
112 // Opens a document from memory, returning null on failure. Cast to ColladaDOMXXX::domCOLLADA
113 virtual domCOLLADAProxy* openFromMemory(const std::string& path, daeString buffer);
114 #ifdef COLLADA_DOM_SUPPORT141
add141(const std::string & path)115 virtual ColladaDOM141::domCOLLADA* add141(const std::string& path) {
116 return (ColladaDOM141::domCOLLADA*)add(path);
117 }
open141(const std::string & path)118 virtual ColladaDOM141::domCOLLADA* open141(const std::string& path) {
119 return (ColladaDOM141::domCOLLADA*)open(path);
120 }
121 // Opens a document from memory, returning null on failure.
openFromMemory141(const std::string & path,daeString buffer)122 virtual ColladaDOM141::domCOLLADA* openFromMemory141(const std::string& path, daeString buffer) {
123 return (ColladaDOM141::domCOLLADA*)openFromMemory(path,buffer);
124 }
125 #endif
126 #ifdef COLLADA_DOM_SUPPORT150
add150(const std::string & path)127 virtual ColladaDOM150::domCOLLADA* add150(const std::string& path) {
128 return (ColladaDOM150::domCOLLADA*)add(path);
129 }
open150(const std::string & path)130 virtual ColladaDOM150::domCOLLADA* open150(const std::string& path) {
131 return (ColladaDOM150::domCOLLADA*)open(path);
132 }
133 // Opens a document from memory, returning null on failure.
openFromMemory150(const std::string & path,daeString buffer)134 virtual ColladaDOM150::domCOLLADA* openFromMemory150(const std::string& path, daeString buffer) {
135 return (ColladaDOM150::domCOLLADA*)openFromMemory(path,buffer);
136 }
137 #endif
138
139 // Write a document to the path specified by the document's URI, returning false on failure.
140 virtual bool write(const std::string& path);
141 // Write a document to the path specified in the second parameter, returning false on failure.
142 virtual bool writeTo(const std::string& docPath, const std::string& pathToWriteTo);
143 // Write a document to memory, returning false on failure.
144 virtual bool writeToMemory(const std::string& docPath, std::vector<char>& output);
145
146 // Writes all documents, returning false if any document failed to write.
147 virtual bool writeAll();
148 // Close a specific document, unloading all memory used by the document. Returns false on failure.
149 virtual void close(const std::string& path);
150 // Remove all loaded documents. Always returns DAE_OK.
151 virtual daeInt clear();
152
153 // Returns the total number of documents.
154 virtual int getDocCount();
155 // Returns the i'th document .
156 virtual daeDocument* getDoc(int i);
157 // Returns a document matching the path.
158 virtual daeDocument* getDoc(const std::string& path);
159
160 // Get the root daeElement object corresponding to a particular document. Cast to ColladaDOMXXX::domCOLLADA
161 virtual domCOLLADAProxy* getRoot(const std::string& path);
162 // Set the root daeElement object corresponding to a particular document, returning false on failure.
163 virtual bool setRoot(const std::string& path, domCOLLADAProxy* root);
164 #ifdef COLLADA_DOM_SUPPORT141
getRoot141(const std::string & path)165 virtual ColladaDOM141::domCOLLADA* getRoot141(const std::string& path) {
166 return (ColladaDOM141::domCOLLADA*)getRoot(path);
167 }
setRoot141(const std::string & path,ColladaDOM141::domCOLLADA * root)168 virtual bool setRoot141(const std::string& path, ColladaDOM141::domCOLLADA* root) {
169 return setRoot(path,(domCOLLADAProxy*)root);
170 }
171 #endif
172 #ifdef COLLADA_DOM_SUPPORT150
getRoot150(const std::string & path)173 virtual ColladaDOM150::domCOLLADA* getRoot150(const std::string& path) {
174 return (ColladaDOM150::domCOLLADA*)getRoot(path);
175 }
setRoot150(const std::string & path,ColladaDOM150::domCOLLADA * root)176 virtual bool setRoot150(const std::string& path, ColladaDOM150::domCOLLADA* root) {
177 return setRoot(path,(domCOLLADAProxy*)root);
178 }
179 #endif
180
181 // Returns the Collada version, i.e. 1.4, 1.5, etc. Note that this _isn't_ the
182 // same as the DOM version (1.3, 2.0, ...).
183 virtual daeString getDomVersion();
184
185 // Returns the (modifiable) list of atomic type objects.
186 daeAtomicTypeList& getAtomicTypes();
187
188 // Get/set a daeMetaElement object given the meta object's type ID.
189 daeMetaElement* getMeta(daeInt typeID);
190 void setMeta(daeInt typeID, daeMetaElement& meta);
191
192 // Get all daeMetaElement objects.
193 daeMetaElementRefArray& getAllMetas();
194
195 // Returns the list of URI resolvers. You can modify the list to add new resolvers.
196 daeURIResolverList& getURIResolvers();
197
198 // The base URI used for resolving relative URI references.
199 daeURI& getBaseURI();
200 void setBaseURI(const daeURI& uri);
201 void setBaseURI(const std::string& uri);
202
203 // Returns the list of ID reference resolvers. You can modify the list to add new
204 // resolvers.
205 daeIDRefResolverList& getIDRefResolvers();
206
207 // Meant for internal DOM use only.
208 daeRawRefCache& getRawRefCache();
209 daeSidRefCache& getSidRefCache();
210
211 // These functions specify the client's character encoding for the DOM. The
212 // default is Utf8, but if you specify Latin1 then the DOM will use libxml's
213 // character conversion functions to convert to Utf8 when writing data and
214 // convert to Latin1 when reading data. This can help with the handling of
215 // non-ASCII characters on Windows. Only when using libxml for xml I/O does
216 // any character conversion occur.
217 //
218 // Most people can probably just ignore this completely. If you have trouble
219 // with non-ASCII characters on Windows, try setting the char encoding to
220 // Latin1 to see if that helps.
221 //
222 // Frankly this certainly isn't the best way of handling non-ASCII character
223 // support on Windows, so this interface is a likely target for significant
224 // changes in the future.
225 //
226 // See this Sourceforge thread for more info:
227 // http://sourceforge.net/tracker/index.php?func=detail&aid=1818473&group_id=157838&atid=805426
228 //
229 enum charEncoding {
230 Utf8,
231 Latin1
232 };
233
234 // Global encoding setting. Defaults to Utf8. Set this if you want to make a
235 // char encoding change and apply it to all DAE objects.
236 static charEncoding getGlobalCharEncoding();
237 static void setGlobalCharEncoding(charEncoding encoding);
238
239 // Local encoding setting. If set, overrides the global setting. Useful for setting
240 // a specific char encoding for a single DAE object but not for all DAE objects.
241 charEncoding getCharEncoding();
242 void setCharEncoding(charEncoding encoding);
243
244 // Deprecated. Alternative methods are given.
245 virtual daeInt load(daeString uri, daeString docBuffer = NULL); // Use open
246 virtual daeInt save(daeString uri, daeBool replace=true); // Use write
247 virtual daeInt save(daeUInt documentIndex, daeBool replace=true); // Use write
248 virtual daeInt saveAs(daeString uriToSaveTo, daeString docUri, daeBool replace=true); // Use writeTo
249 virtual daeInt saveAs(daeString uriToSaveTo, daeUInt documentIndex=0, daeBool replace=true); // Use writeTo
250 virtual daeInt unload(daeString uri); // Use close
251
252 virtual domCOLLADAProxy* getDom(daeString uri); // use getRoot, Cast to ColladaDOMXXX::domCOLLADA
253 virtual daeInt setDom(daeString uri, domCOLLADAProxy* dom); // use setRoot,
254 #ifdef COLLADA_DOM_SUPPORT141
getDom141(daeString uri)255 virtual ColladaDOM141::domCOLLADA* getDom141(daeString uri) {
256 return (ColladaDOM141::domCOLLADA*)getDom(uri);
257 }
setDom141(daeString uri,ColladaDOM141::domCOLLADA * dom)258 virtual daeInt setDom141(daeString uri, ColladaDOM141::domCOLLADA* dom) {
259 return setDom(uri,(domCOLLADAProxy*)dom);
260 }
261 #endif
262 #ifdef COLLADA_DOM_SUPPORT150
getDom150(daeString uri)263 virtual ColladaDOM150::domCOLLADA* getDom150(daeString uri) {
264 return (ColladaDOM150::domCOLLADA*)getDom(uri);
265 }
setDom150(daeString uri,ColladaDOM150::domCOLLADA * dom)266 virtual daeInt setDom150(daeString uri, ColladaDOM150::domCOLLADA* dom) {
267 return setDom(uri,(domCOLLADAProxy*)dom);
268 }
269 #endif
270
271 virtual daeString getColladaNamespace();
272
273 private:
274 void init(daeDatabase* database, daeIOPlugin* ioPlugin, const char* specversion);
275 void dummyFunction1();
276 std::string makeFullUri(const std::string& path);
277 domCOLLADAProxy* openCommon(const std::string& path, daeString buffer);
278 bool writeCommon(const std::string& docPath, const std::string& pathToWriteTo, bool replace);
279
280 daeDatabase *database;
281 daeIOPlugin *plugin;
282 bool defaultDatabase;
283 bool defaultPlugin;
284 daeAtomicTypeList atomicTypes;
285 daeMetaElementRefArray metas;
286 daeURI baseUri;
287 daeURIResolverList uriResolvers;
288 daeIDRefResolverList idRefResolvers;
289 daeRawRefCache rawRefCache;
290 daeSidRefCache sidRefCache;
291 daeString COLLADA_VERSION, COLLADA_NAMESPACE; // dynamic
292
293 std::auto_ptr<charEncoding> localCharEncoding;
294 static charEncoding globalCharEncoding;
295 };
296
297
298 template <typename T>
daeSafeCast(daeElement * element)299 inline T *daeSafeCast(daeElement *element)
300 {
301 if (element && element->typeID() == T::ID())
302 return (T*)element;
303 return NULL;
304 }
305
306
307 #endif // __DAE_INTERFACE__
308