1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
4 
5 Copyright (c) 2006-2021, assimp team
6 
7 All rights reserved.
8 
9 Redistribution and use of this software in source and binary forms,
10 with or without modification, are permitted provided that the
11 following conditions are met:
12 
13 * Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16 
17 * Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21 
22 * Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26 
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 
39 ----------------------------------------------------------------------
40 */
41 
42 /** @file FBXExportNode.h
43 * Declares the FBX::Node helper class for fbx export.
44 */
45 #ifndef AI_FBXEXPORTNODE_H_INC
46 #define AI_FBXEXPORTNODE_H_INC
47 
48 #ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
49 
50 #include "FBXExportProperty.h"
51 
52 #include <assimp/StreamWriter.h> // StreamWriterLE
53 
54 #include <string>
55 #include <vector>
56 
57 namespace Assimp {
58 namespace FBX {
59     class Node;
60 }
61 
62 class FBX::Node {
63 public:
64     // TODO: accessors
65     std::string name; // node name
66     std::vector<FBX::FBXExportProperty> properties; // node properties
67     std::vector<FBX::Node> children; // child nodes
68 
69     // some nodes always pretend they have children...
70     bool force_has_children = false;
71 
72 public: // constructors
73     /// The default class constructor.
74     Node() = default;
75 
76     /// The class constructor with the name.
Node(const std::string & n)77     Node(const std::string& n)
78     : name(n)
79     , properties()
80     , children()
81     , force_has_children( false ) {
82         // empty
83     }
84 
85     // convenience template to construct with properties directly
86     template <typename... More>
Node(const std::string & n,const More...more)87     Node(const std::string& n, const More... more)
88     : name(n)
89     , properties()
90     , children()
91     , force_has_children(false) {
92         AddProperties(more...);
93     }
94 
95 public: // functions to add properties or children
96     // add a single property to the node
97     template <typename T>
AddProperty(T value)98     void AddProperty(T value) {
99         properties.emplace_back(value);
100     }
101 
102     // convenience function to add multiple properties at once
103     template <typename T, typename... More>
AddProperties(T value,More...more)104     void AddProperties(T value, More... more) {
105         properties.emplace_back(value);
106         AddProperties(more...);
107     }
AddProperties()108     void AddProperties() {}
109 
110     // add a child node directly
AddChild(const Node & node)111     void AddChild(const Node& node) { children.push_back(node); }
112 
113     // convenience function to add a child node with a single property
114     template <typename... More>
AddChild(const std::string & name,More...more)115     void AddChild(
116         const std::string& name,
117         More... more
118     ) {
119         FBX::Node c(name);
120         c.AddProperties(more...);
121         children.push_back(c);
122     }
123 
124 public: // support specifically for dealing with Properties70 nodes
125 
126     // it really is simpler to make these all separate functions.
127     // the versions with 'A' suffixes are for animatable properties.
128     // those often follow a completely different format internally in FBX.
129     void AddP70int(const std::string& name, int32_t value);
130     void AddP70bool(const std::string& name, bool value);
131     void AddP70double(const std::string& name, double value);
132     void AddP70numberA(const std::string& name, double value);
133     void AddP70color(const std::string& name, double r, double g, double b);
134     void AddP70colorA(const std::string& name, double r, double g, double b);
135     void AddP70vector(const std::string& name, double x, double y, double z);
136     void AddP70vectorA(const std::string& name, double x, double y, double z);
137     void AddP70string(const std::string& name, const std::string& value);
138     void AddP70enum(const std::string& name, int32_t value);
139     void AddP70time(const std::string& name, int64_t value);
140 
141     // template for custom P70 nodes.
142     // anything that doesn't fit in the above can be created manually.
143     template <typename... More>
AddP70(const std::string & name,const std::string & type,const std::string & type2,const std::string & flags,More...more)144     void AddP70(
145         const std::string& name,
146         const std::string& type,
147         const std::string& type2,
148         const std::string& flags,
149         More... more
150     ) {
151         Node n("P");
152         n.AddProperties(name, type, type2, flags, more...);
153         AddChild(n);
154     }
155 
156 public: // member functions for writing data to a file or stream
157 
158     // write the full node to the given file or stream
159     void Dump(
160             const std::shared_ptr<Assimp::IOStream> &outfile,
161             bool binary, int indent);
162     void Dump(Assimp::StreamWriterLE &s, bool binary, int indent);
163 
164     // these other functions are for writing data piece by piece.
165     // they must be used carefully.
166     // for usage examples see FBXExporter.cpp.
167     void Begin(Assimp::StreamWriterLE &s, bool binary, int indent);
168     void DumpProperties(Assimp::StreamWriterLE& s, bool binary, int indent);
169     void EndProperties(Assimp::StreamWriterLE &s, bool binary, int indent);
170     void EndProperties(
171         Assimp::StreamWriterLE &s, bool binary, int indent,
172         size_t num_properties
173     );
174     void BeginChildren(Assimp::StreamWriterLE &s, bool binary, int indent);
175     void DumpChildren(Assimp::StreamWriterLE& s, bool binary, int indent);
176     void End(
177         Assimp::StreamWriterLE &s, bool binary, int indent,
178         bool has_children
179     );
180 
181 private: // internal functions used for writing
182 
183     void DumpBinary(Assimp::StreamWriterLE &s);
184     void DumpAscii(Assimp::StreamWriterLE &s, int indent);
185     void DumpAscii(std::ostream &s, int indent);
186 
187     void BeginBinary(Assimp::StreamWriterLE &s);
188     void DumpPropertiesBinary(Assimp::StreamWriterLE& s);
189     void EndPropertiesBinary(Assimp::StreamWriterLE &s);
190     void EndPropertiesBinary(Assimp::StreamWriterLE &s, size_t num_properties);
191     void DumpChildrenBinary(Assimp::StreamWriterLE& s);
192     void EndBinary(Assimp::StreamWriterLE &s, bool has_children);
193 
194     void BeginAscii(std::ostream &s, int indent);
195     void DumpPropertiesAscii(std::ostream &s, int indent);
196     void BeginChildrenAscii(std::ostream &s, int indent);
197     void DumpChildrenAscii(std::ostream &s, int indent);
198     void EndAscii(std::ostream &s, int indent, bool has_children);
199 
200 private: // data used for binary dumps
201     size_t start_pos; // starting position in stream
202     size_t end_pos; // ending position in stream
203     size_t property_start; // starting position of property section
204 
205 public: // static member functions
206 
207     // convenience function to create a node with a single property,
208     // and write it to the stream.
209     template <typename T>
WritePropertyNode(const std::string & name,const T value,Assimp::StreamWriterLE & s,bool binary,int indent)210     static void WritePropertyNode(
211         const std::string& name,
212         const T value,
213         Assimp::StreamWriterLE& s,
214         bool binary, int indent
215     ) {
216         FBX::FBXExportProperty p(value);
217         FBX::Node node(name, p);
218         node.Dump(s, binary, indent);
219     }
220 
221     // convenience function to create and write a property node,
222     // holding a single property which is an array of values.
223     // does not copy the data, so is efficient for large arrays.
224     static void WritePropertyNode(
225         const std::string& name,
226         const std::vector<double>& v,
227         Assimp::StreamWriterLE& s,
228         bool binary, int indent
229     );
230 
231     // convenience function to create and write a property node,
232     // holding a single property which is an array of values.
233     // does not copy the data, so is efficient for large arrays.
234     static void WritePropertyNode(
235         const std::string& name,
236         const std::vector<int32_t>& v,
237         Assimp::StreamWriterLE& s,
238         bool binary, int indent
239     );
240 
241 private: // static helper functions
242     static void WritePropertyNodeAscii(
243         const std::string& name,
244         const std::vector<double>& v,
245         Assimp::StreamWriterLE& s,
246         int indent
247     );
248     static void WritePropertyNodeAscii(
249         const std::string& name,
250         const std::vector<int32_t>& v,
251         Assimp::StreamWriterLE& s,
252         int indent
253     );
254     static void WritePropertyNodeBinary(
255         const std::string& name,
256         const std::vector<double>& v,
257         Assimp::StreamWriterLE& s
258     );
259     static void WritePropertyNodeBinary(
260         const std::string& name,
261         const std::vector<int32_t>& v,
262         Assimp::StreamWriterLE& s
263     );
264 
265 };
266 }
267 
268 #endif // ASSIMP_BUILD_NO_FBX_EXPORTER
269 
270 #endif // AI_FBXEXPORTNODE_H_INC
271