/src/assimp/code/AssetLib/FBX/FBXExportNode.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Open Asset Import Library (assimp) |
3 | | ---------------------------------------------------------------------- |
4 | | |
5 | | Copyright (c) 2006-2025, 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 | | #ifndef ASSIMP_BUILD_NO_EXPORT |
41 | | #ifndef ASSIMP_BUILD_NO_FBX_EXPORTER |
42 | | |
43 | | #include "FBXExportNode.h" |
44 | | #include "FBXCommon.h" |
45 | | |
46 | | #include <assimp/StreamWriter.h> // StreamWriterLE |
47 | | #include <assimp/Exceptional.h> // DeadlyExportError |
48 | | #include <assimp/ai_assert.h> |
49 | | #include <assimp/StringUtils.h> // ai_snprintf |
50 | | |
51 | | #include <string> |
52 | | #include <ostream> |
53 | | #include <sstream> // ostringstream |
54 | | #include <memory> // shared_ptr |
55 | | |
56 | | namespace Assimp { |
57 | | |
58 | | // AddP70<type> helpers... there's no usable pattern here, |
59 | | // so all are defined as separate functions. |
60 | | // Even "animatable" properties are often completely different |
61 | | // from the standard (nonanimated) property definition, |
62 | | // so they are specified with an 'A' suffix. |
63 | | |
64 | 42.7k | void FBX::Node::AddP70int(const std::string& cur_name, int32_t value) { |
65 | 42.7k | FBX::Node n("P"); |
66 | 42.7k | n.AddProperties(cur_name, "int", "Integer", "", value); |
67 | 42.7k | AddChild(n); |
68 | 42.7k | } |
69 | | |
70 | 47.9k | void FBX::Node::AddP70bool(const std::string& cur_name, bool value) { |
71 | 47.9k | FBX::Node n("P"); |
72 | 47.9k | n.AddProperties(cur_name, "bool", "", "", int32_t(value)); |
73 | 47.9k | AddChild(n); |
74 | 47.9k | } |
75 | | |
76 | 7.01k | void FBX::Node::AddP70double(const std::string &cur_name, double value) { FBX::Node n("P"); |
77 | 7.01k | n.AddProperties(cur_name, "double", "Number", "", value); |
78 | 7.01k | AddChild(n); |
79 | 7.01k | } |
80 | | |
81 | 2.15k | void FBX::Node::AddP70numberA(const std::string &cur_name, double value) { |
82 | 2.15k | FBX::Node n("P"); |
83 | 2.15k | n.AddProperties(cur_name, "Number", "", "A", value); |
84 | 2.15k | AddChild(n); |
85 | 2.15k | } |
86 | | |
87 | | void FBX::Node::AddP70color( |
88 | 1.11k | const std::string &cur_name, double r, double g, double b) { |
89 | 1.11k | FBX::Node n("P"); |
90 | 1.11k | n.AddProperties(cur_name, "ColorRGB", "Color", "", r, g, b); |
91 | 1.11k | AddChild(n); |
92 | 1.11k | } |
93 | | |
94 | | void FBX::Node::AddP70colorA( |
95 | 2.16k | const std::string &cur_name, double r, double g, double b) { |
96 | 2.16k | FBX::Node n("P"); |
97 | 2.16k | n.AddProperties(cur_name, "Color", "", "A", r, g, b); |
98 | 2.16k | AddChild(n); |
99 | 2.16k | } |
100 | | |
101 | | void FBX::Node::AddP70vector( |
102 | 5.46k | const std::string &cur_name, double x, double y, double z) { |
103 | 5.46k | FBX::Node n("P"); |
104 | 5.46k | n.AddProperties(cur_name, "Vector3D", "Vector", "", x, y, z); |
105 | 5.46k | AddChild(n); |
106 | 5.46k | } |
107 | | |
108 | | void FBX::Node::AddP70vectorA( |
109 | 87 | const std::string &cur_name, double x, double y, double z) { |
110 | 87 | FBX::Node n("P"); |
111 | 87 | n.AddProperties(cur_name, "Vector", "", "A", x, y, z); |
112 | 87 | AddChild(n); |
113 | 87 | } |
114 | | |
115 | | void FBX::Node::AddP70string( |
116 | 763 | const std::string &cur_name, const std::string &value) { |
117 | 763 | FBX::Node n("P"); |
118 | 763 | n.AddProperties(cur_name, "KString", "", "", value); |
119 | 763 | AddChild(n); |
120 | 763 | } |
121 | | |
122 | | void FBX::Node::AddP70enum( |
123 | 43.5k | const std::string &cur_name, int32_t value) { |
124 | 43.5k | FBX::Node n("P"); |
125 | 43.5k | n.AddProperties(cur_name, "enum", "", "", value); |
126 | 43.5k | AddChild(n); |
127 | 43.5k | } |
128 | | |
129 | | void FBX::Node::AddP70time( |
130 | 763 | const std::string &cur_name, int64_t value) { |
131 | 763 | FBX::Node n("P"); |
132 | 763 | n.AddProperties(cur_name, "KTime", "Time", "", value); |
133 | 763 | AddChild(n); |
134 | 763 | } |
135 | | |
136 | | |
137 | | // public member functions for writing nodes to stream |
138 | | |
139 | | void FBX::Node::Dump( |
140 | | const std::shared_ptr<Assimp::IOStream> &outfile, |
141 | 1.08k | bool binary, int indent) { |
142 | 1.08k | if (binary) { |
143 | 1.08k | Assimp::StreamWriterLE outstream(outfile); |
144 | 1.08k | DumpBinary(outstream); |
145 | 1.08k | } else { |
146 | 0 | std::ostringstream ss; |
147 | 0 | DumpAscii(ss, indent); |
148 | 0 | std::string s = ss.str(); |
149 | 0 | outfile->Write(s.c_str(), s.size(), 1); |
150 | 0 | } |
151 | 1.08k | } |
152 | | |
153 | | void FBX::Node::Dump( |
154 | | Assimp::StreamWriterLE &outstream, |
155 | | bool binary, int indent |
156 | 145k | ) { |
157 | 145k | if (binary) { |
158 | 145k | DumpBinary(outstream); |
159 | 145k | } else { |
160 | 0 | std::ostringstream ss; |
161 | 0 | DumpAscii(ss, indent); |
162 | 0 | outstream.PutString(ss.str()); |
163 | 0 | } |
164 | 145k | } |
165 | | |
166 | | |
167 | | // public member functions for low-level writing |
168 | | |
169 | | void FBX::Node::Begin( |
170 | | Assimp::StreamWriterLE &s, |
171 | | bool binary, int indent |
172 | 1.83k | ) { |
173 | 1.83k | if (binary) { |
174 | 1.83k | BeginBinary(s); |
175 | 1.83k | } else { |
176 | | // assume we're at the correct place to start already |
177 | 0 | (void)indent; |
178 | 0 | std::ostringstream ss; |
179 | 0 | BeginAscii(ss, indent); |
180 | 0 | s.PutString(ss.str()); |
181 | 0 | } |
182 | 1.83k | } |
183 | | |
184 | | void FBX::Node::DumpProperties( |
185 | | Assimp::StreamWriterLE& s, |
186 | | bool binary, int indent |
187 | 1.03k | ) { |
188 | 1.03k | if (binary) { |
189 | 1.03k | DumpPropertiesBinary(s); |
190 | 1.03k | } else { |
191 | 0 | std::ostringstream ss; |
192 | 0 | DumpPropertiesAscii(ss, indent); |
193 | 0 | s.PutString(ss.str()); |
194 | 0 | } |
195 | 1.03k | } |
196 | | |
197 | | void FBX::Node::EndProperties( |
198 | | Assimp::StreamWriterLE &s, |
199 | | bool binary, int indent |
200 | 1.30k | ) { |
201 | 1.30k | EndProperties(s, binary, indent, properties.size()); |
202 | 1.30k | } |
203 | | |
204 | | void FBX::Node::EndProperties( |
205 | | Assimp::StreamWriterLE &s, |
206 | | bool binary, int indent, |
207 | | size_t num_properties |
208 | 1.57k | ) { |
209 | 1.57k | if (binary) { |
210 | 1.57k | EndPropertiesBinary(s, num_properties); |
211 | 1.57k | } else { |
212 | | // nothing to do |
213 | 0 | (void)indent; |
214 | 0 | } |
215 | 1.57k | } |
216 | | |
217 | | void FBX::Node::BeginChildren( |
218 | | Assimp::StreamWriterLE &s, |
219 | | bool binary, int indent |
220 | 1.83k | ) { |
221 | 1.83k | if (binary) { |
222 | | // nothing to do |
223 | 1.83k | } else { |
224 | 0 | std::ostringstream ss; |
225 | 0 | BeginChildrenAscii(ss, indent); |
226 | 0 | s.PutString(ss.str()); |
227 | 0 | } |
228 | 1.83k | } |
229 | | |
230 | | void FBX::Node::DumpChildren( |
231 | | Assimp::StreamWriterLE& s, |
232 | | bool binary, int indent |
233 | 0 | ) { |
234 | 0 | if (binary) { |
235 | 0 | DumpChildrenBinary(s); |
236 | 0 | } else { |
237 | 0 | std::ostringstream ss; |
238 | 0 | DumpChildrenAscii(ss, indent); |
239 | 0 | if (ss.tellp() > 0) |
240 | 0 | s.PutString(ss.str()); |
241 | 0 | } |
242 | 0 | } |
243 | | |
244 | | void FBX::Node::End( |
245 | | Assimp::StreamWriterLE &s, |
246 | | bool binary, int indent, |
247 | | bool has_children |
248 | 1.83k | ) { |
249 | 1.83k | if (binary) { |
250 | 1.83k | EndBinary(s, has_children); |
251 | 1.83k | } else { |
252 | 0 | std::ostringstream ss; |
253 | 0 | EndAscii(ss, indent, has_children); |
254 | 0 | if (ss.tellp() > 0) |
255 | 0 | s.PutString(ss.str()); |
256 | 0 | } |
257 | 1.83k | } |
258 | | |
259 | | |
260 | | // public member functions for writing to binary fbx |
261 | | |
262 | | void FBX::Node::DumpBinary(Assimp::StreamWriterLE &s) |
263 | 556k | { |
264 | | // write header section (with placeholders for some things) |
265 | 556k | BeginBinary(s); |
266 | | |
267 | | // write properties |
268 | 556k | DumpPropertiesBinary(s); |
269 | | |
270 | | // go back and fill in property related placeholders |
271 | 556k | EndPropertiesBinary(s, properties.size()); |
272 | | |
273 | | // write children |
274 | 556k | DumpChildrenBinary(s); |
275 | | |
276 | | // finish, filling in end offset placeholder |
277 | 556k | EndBinary(s, force_has_children || !children.empty()); |
278 | 556k | } |
279 | | |
280 | | |
281 | | // public member functions for writing to ascii fbx |
282 | | |
283 | | void FBX::Node::DumpAscii(std::ostream &s, int indent) |
284 | 0 | { |
285 | | // write name |
286 | 0 | BeginAscii(s, indent); |
287 | | |
288 | | // write properties |
289 | 0 | DumpPropertiesAscii(s, indent); |
290 | |
|
291 | 0 | if (force_has_children || !children.empty()) { |
292 | | // begin children (with a '{') |
293 | 0 | BeginChildrenAscii(s, indent + 1); |
294 | | // write children |
295 | 0 | DumpChildrenAscii(s, indent + 1); |
296 | 0 | } |
297 | | |
298 | | // finish (also closing the children bracket '}') |
299 | 0 | EndAscii(s, indent, force_has_children || !children.empty()); |
300 | 0 | } |
301 | | |
302 | | |
303 | | // private member functions for low-level writing to fbx |
304 | | |
305 | | void FBX::Node::BeginBinary(Assimp::StreamWriterLE &s) |
306 | 559k | { |
307 | | // remember start pos so we can come back and write the end pos |
308 | 559k | this->start_pos = s.Tell(); |
309 | | |
310 | | // placeholders for end pos and property section info |
311 | 559k | s.PutU8(0); // end pos |
312 | 559k | s.PutU8(0); // number of properties |
313 | 559k | s.PutU8(0); // total property section length |
314 | | |
315 | | // node name |
316 | 559k | s.PutU1(uint8_t(name.size())); // length of node name |
317 | 559k | s.PutString(name); // node name as raw bytes |
318 | | |
319 | | // property data comes after here |
320 | 559k | this->property_start = s.Tell(); |
321 | 559k | } |
322 | | |
323 | | void FBX::Node::DumpPropertiesBinary(Assimp::StreamWriterLE& s) |
324 | 557k | { |
325 | 1.44M | for (auto &p : properties) { |
326 | 1.44M | p.DumpBinary(s); |
327 | 1.44M | } |
328 | 557k | } |
329 | | |
330 | | void FBX::Node::EndPropertiesBinary( |
331 | | Assimp::StreamWriterLE &s, |
332 | | size_t num_properties |
333 | 559k | ) { |
334 | 559k | if (num_properties == 0) { return; } |
335 | 513k | size_t pos = s.Tell(); |
336 | 513k | ai_assert(pos > property_start); |
337 | 513k | size_t property_section_size = pos - property_start; |
338 | 513k | s.Seek(start_pos + 8); // 8 bytes of uint64_t of end_pos |
339 | 513k | s.PutU8(num_properties); |
340 | 513k | s.PutU8(property_section_size); |
341 | 513k | s.Seek(pos); |
342 | 513k | } |
343 | | |
344 | | void FBX::Node::DumpChildrenBinary(Assimp::StreamWriterLE& s) |
345 | 556k | { |
346 | 556k | for (FBX::Node& child : children) { |
347 | 409k | child.DumpBinary(s); |
348 | 409k | } |
349 | 556k | } |
350 | | |
351 | | void FBX::Node::EndBinary( |
352 | | Assimp::StreamWriterLE &s, |
353 | | bool has_children |
354 | 559k | ) { |
355 | | // if there were children, add a null record |
356 | 559k | if (has_children) { s.PutString(Assimp::FBX::NULL_RECORD_STRING); } |
357 | | |
358 | | // now go back and write initial pos |
359 | 559k | this->end_pos = s.Tell(); |
360 | 559k | s.Seek(start_pos); |
361 | 559k | s.PutU8(end_pos); |
362 | 559k | s.Seek(end_pos); |
363 | 559k | } |
364 | | |
365 | | |
366 | | void FBX::Node::BeginAscii(std::ostream& s, int indent) |
367 | 0 | { |
368 | 0 | s << '\n'; |
369 | 0 | for (int i = 0; i < indent; ++i) { s << '\t'; } |
370 | 0 | s << name << ": "; |
371 | 0 | } |
372 | | |
373 | | void FBX::Node::DumpPropertiesAscii(std::ostream &s, int indent) |
374 | 0 | { |
375 | 0 | for (size_t i = 0; i < properties.size(); ++i) { |
376 | 0 | if (i > 0) { s << ", "; } |
377 | 0 | properties[i].DumpAscii(s, indent); |
378 | 0 | } |
379 | 0 | } |
380 | | |
381 | | void FBX::Node::BeginChildrenAscii(std::ostream& s, int indent) |
382 | 0 | { |
383 | | // only call this if there are actually children |
384 | 0 | s << " {"; |
385 | 0 | (void)indent; |
386 | 0 | } |
387 | | |
388 | | void FBX::Node::DumpChildrenAscii(std::ostream& s, int indent) |
389 | 0 | { |
390 | | // children will need a lot of padding and corralling |
391 | 0 | if (children.size() || force_has_children) { |
392 | 0 | for (size_t i = 0; i < children.size(); ++i) { |
393 | | // no compression in ascii files, so skip this node if it exists |
394 | 0 | if (children[i].name == "EncryptionType") { continue; } |
395 | | // the child can dump itself |
396 | 0 | children[i].DumpAscii(s, indent); |
397 | 0 | } |
398 | 0 | } |
399 | 0 | } |
400 | | |
401 | 0 | void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children) { |
402 | 0 | if (!has_children) { return; } // nothing to do |
403 | 0 | s << '\n'; |
404 | 0 | for (int i = 0; i < indent; ++i) { s << '\t'; } |
405 | 0 | s << "}"; |
406 | 0 | } |
407 | | |
408 | | // private helpers for static member functions |
409 | | |
410 | | // ascii property node from vector of doubles |
411 | | void FBX::Node::WritePropertyNodeAscii( |
412 | | const std::string& name, |
413 | | const std::vector<double>& v, |
414 | | Assimp::StreamWriterLE& s, |
415 | 0 | int indent){ |
416 | 0 | char buffer[32]; |
417 | 0 | FBX::Node node(name); |
418 | 0 | node.Begin(s, false, indent); |
419 | 0 | std::string vsize = ai_to_string(v.size()); |
420 | | // *<size> { |
421 | 0 | s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n"); |
422 | | // indent + 1 |
423 | 0 | for (int i = 0; i < indent + 1; ++i) { s.PutChar('\t'); } |
424 | | // a: value,value,value,... |
425 | 0 | s.PutString("a: "); |
426 | 0 | int count = 0; |
427 | 0 | for (size_t i = 0; i < v.size(); ++i) { |
428 | 0 | if (i > 0) { s.PutChar(','); } |
429 | 0 | int len = ai_snprintf(buffer, sizeof(buffer), "%f", v[i]); |
430 | 0 | count += len; |
431 | 0 | if (count > 2048) { s.PutChar('\n'); count = 0; } |
432 | 0 | if (len < 0 || len > 31) { |
433 | | // this should never happen |
434 | 0 | throw DeadlyExportError("failed to convert double to string"); |
435 | 0 | } |
436 | 0 | for (int j = 0; j < len; ++j) { s.PutChar(buffer[j]); } |
437 | 0 | } |
438 | | // } |
439 | 0 | s.PutChar('\n'); |
440 | 0 | for (int i = 0; i < indent; ++i) { s.PutChar('\t'); } |
441 | 0 | s.PutChar('}'); s.PutChar(' '); |
442 | 0 | node.End(s, false, indent, false); |
443 | 0 | } |
444 | | |
445 | | // ascii property node from vector of int32_t |
446 | | void FBX::Node::WritePropertyNodeAscii( |
447 | | const std::string& name, |
448 | | const std::vector<int32_t>& v, |
449 | | Assimp::StreamWriterLE& s, |
450 | | int indent |
451 | 0 | ){ |
452 | 0 | char buffer[32]; |
453 | 0 | FBX::Node node(name); |
454 | 0 | node.Begin(s, false, indent); |
455 | 0 | std::string vsize = ai_to_string(v.size()); |
456 | | // *<size> { |
457 | 0 | s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n"); |
458 | | // indent + 1 |
459 | 0 | for (int i = 0; i < indent + 1; ++i) { s.PutChar('\t'); } |
460 | | // a: value,value,value,... |
461 | 0 | s.PutString("a: "); |
462 | 0 | int count = 0; |
463 | 0 | for (size_t i = 0; i < v.size(); ++i) { |
464 | 0 | if (i > 0) { s.PutChar(','); } |
465 | 0 | int len = ai_snprintf(buffer, sizeof(buffer), "%d", v[i]); |
466 | 0 | count += len; |
467 | 0 | if (count > 2048) { s.PutChar('\n'); count = 0; } |
468 | 0 | if (len < 0 || len > 31) { |
469 | | // this should never happen |
470 | 0 | throw DeadlyExportError("failed to convert double to string"); |
471 | 0 | } |
472 | 0 | for (int j = 0; j < len; ++j) { s.PutChar(buffer[j]); } |
473 | 0 | } |
474 | | // } |
475 | 0 | s.PutChar('\n'); |
476 | 0 | for (int i = 0; i < indent; ++i) { s.PutChar('\t'); } |
477 | 0 | s.PutChar('}'); s.PutChar(' '); |
478 | 0 | node.End(s, false, indent, false); |
479 | 0 | } |
480 | | |
481 | | // binary property node from vector of doubles |
482 | | // TODO: optional zip compression! |
483 | | void FBX::Node::WritePropertyNodeBinary( |
484 | | const std::string& name, |
485 | | const std::vector<double>& v, |
486 | | Assimp::StreamWriterLE& s |
487 | 1.03k | ){ |
488 | 1.03k | FBX::Node node(name); |
489 | 1.03k | node.BeginBinary(s); |
490 | 1.03k | s.PutU1('d'); |
491 | 1.03k | s.PutU4(uint32_t(v.size())); // number of elements |
492 | 1.03k | s.PutU4(0); // no encoding (1 would be zip-compressed) |
493 | 1.03k | s.PutU4(uint32_t(v.size()) * 8); // data size |
494 | 6.19M | for (auto it = v.begin(); it != v.end(); ++it) { s.PutF8(*it); } |
495 | 1.03k | node.EndPropertiesBinary(s, 1); |
496 | 1.03k | node.EndBinary(s, false); |
497 | 1.03k | } |
498 | | |
499 | | // binary property node from vector of int32_t |
500 | | // TODO: optional zip compression! |
501 | | void FBX::Node::WritePropertyNodeBinary( |
502 | | const std::string& name, |
503 | | const std::vector<int32_t>& v, |
504 | | Assimp::StreamWriterLE& s |
505 | 472 | ){ |
506 | 472 | FBX::Node node(name); |
507 | 472 | node.BeginBinary(s); |
508 | 472 | s.PutU1('i'); |
509 | 472 | s.PutU4(uint32_t(v.size())); // number of elements |
510 | 472 | s.PutU4(0); // no encoding (1 would be zip-compressed) |
511 | 472 | s.PutU4(uint32_t(v.size()) * 4); // data size |
512 | 949k | for (auto it = v.begin(); it != v.end(); ++it) { s.PutI4(*it); } |
513 | 472 | node.EndPropertiesBinary(s, 1); |
514 | 472 | node.EndBinary(s, false); |
515 | 472 | } |
516 | | |
517 | | // public static member functions |
518 | | |
519 | | // convenience function to create and write a property node, |
520 | | // holding a single property which is an array of values. |
521 | | // does not copy the data, so is efficient for large arrays. |
522 | | void FBX::Node::WritePropertyNode( |
523 | | const std::string& name, |
524 | | const std::vector<double>& v, |
525 | | Assimp::StreamWriterLE& s, |
526 | | bool binary, int indent |
527 | 1.03k | ){ |
528 | 1.03k | if (binary) { |
529 | 1.03k | FBX::Node::WritePropertyNodeBinary(name, v, s); |
530 | 1.03k | } else { |
531 | 0 | FBX::Node::WritePropertyNodeAscii(name, v, s, indent); |
532 | 0 | } |
533 | 1.03k | } |
534 | | |
535 | | // convenience function to create and write a property node, |
536 | | // holding a single property which is an array of values. |
537 | | // does not copy the data, so is efficient for large arrays. |
538 | | void FBX::Node::WritePropertyNode( |
539 | | const std::string& name, |
540 | | const std::vector<int32_t>& v, |
541 | | Assimp::StreamWriterLE& s, |
542 | | bool binary, int indent |
543 | 472 | ){ |
544 | 472 | if (binary) { |
545 | 472 | FBX::Node::WritePropertyNodeBinary(name, v, s); |
546 | 472 | } else { |
547 | 0 | FBX::Node::WritePropertyNodeAscii(name, v, s, indent); |
548 | 0 | } |
549 | 472 | } |
550 | | |
551 | | } // namespace Assimp |
552 | | |
553 | | #endif // ASSIMP_BUILD_NO_FBX_EXPORTER |
554 | | #endif // ASSIMP_BUILD_NO_EXPORT |