1 //-*****************************************************************************
2 //
3 // Copyright (c) 2013,
4 // Sony Pictures Imageworks Inc. and
5 // Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following disclaimer
16 // in the documentation and/or other materials provided with the
17 // distribution.
18 // * Neither the name of Sony Pictures Imageworks, nor
19 // Industrial Light & Magic, nor the names of their contributors may be used
20 // to endorse or promote products derived from this software without specific
21 // prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //-*****************************************************************************
36
37 #include <Alembic/AbcCoreAbstract/All.h>
38 #include <Alembic/AbcCoreOgawa/All.h>
39 #include <Alembic/Util/All.h>
40
41 #include <Alembic/AbcCoreAbstract/Tests/Assert.h>
42
43 #include <iostream>
44 #include <vector>
45
46 //-*****************************************************************************
47 namespace AO = Alembic::AbcCoreOgawa;
48
49 namespace ABCA = Alembic::AbcCoreAbstract;
testArrayPropHashes(bool iUseMMap)50 void testArrayPropHashes(bool iUseMMap)
51 {
52 std::string archiveName = "arrayHashTest.abc";
53 {
54 AO::WriteArchive w;
55 ABCA::ArchiveWriterPtr a = w(archiveName, ABCA::MetaData());
56 ABCA::ObjectWriterPtr archive = a->getTop();
57 ABCA::ObjectWriterPtr child;
58
59 // add a time sampling for later use
60 std::vector < double > timeSamps(1,-4.0);
61 ABCA::TimeSamplingType tst(3.0);
62 ABCA::TimeSampling ts(tst, timeSamps);
63 a->addTimeSampling(ts);
64
65 // 2 objects without any properties whatsoever
66 archive->createChild(ABCA::ObjectHeader("emptyA", ABCA::MetaData()));
67 archive->createChild(ABCA::ObjectHeader("emptyB", ABCA::MetaData()));
68
69 // 2 objects with with the same property with no samples
70 child = archive->createChild(ABCA::ObjectHeader(
71 "1propA", ABCA::MetaData()));
72 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
73 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
74
75 child = archive->createChild(ABCA::ObjectHeader(
76 "1propB", ABCA::MetaData()));
77 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
78 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
79
80 // 2 objects with with the same property with a differnt name from above
81 child = archive->createChild(ABCA::ObjectHeader(
82 "1propAName", ABCA::MetaData()));
83 child->getProperties()->createArrayProperty("null", ABCA::MetaData(),
84 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
85
86 child = archive->createChild(ABCA::ObjectHeader(
87 "1propBName", ABCA::MetaData()));
88 child->getProperties()->createArrayProperty("null", ABCA::MetaData(),
89 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
90
91 // 2 objects with with the same property with a differnt MetaData
92 ABCA::MetaData m;
93 m.set("Bleep", "bloop");
94 child = archive->createChild(ABCA::ObjectHeader(
95 "1propAMeta", ABCA::MetaData()));
96 child->getProperties()->createArrayProperty("empty", m,
97 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
98
99 child = archive->createChild(ABCA::ObjectHeader(
100 "1propBMeta", ABCA::MetaData()));
101 child->getProperties()->createArrayProperty("empty", m,
102 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
103
104 // 2 objects with with the same property with a different POD
105 child = archive->createChild(ABCA::ObjectHeader(
106 "1propAPod", ABCA::MetaData()));
107 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
108 ABCA::DataType(Alembic::Util::kFloat32POD, 1), 0);
109
110 child = archive->createChild(ABCA::ObjectHeader(
111 "1propBPod", ABCA::MetaData()));
112 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
113 ABCA::DataType(Alembic::Util::kFloat32POD, 1), 0);
114
115 // 2 objects with with the same property with a different extent
116 child = archive->createChild(ABCA::ObjectHeader(
117 "1propAExtent", ABCA::MetaData()));
118 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
119 ABCA::DataType(Alembic::Util::kInt32POD, 2), 0);
120
121 child = archive->createChild(ABCA::ObjectHeader(
122 "1propBExtent", ABCA::MetaData()));
123 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
124 ABCA::DataType(Alembic::Util::kInt32POD, 2), 0);
125
126 // 2 objects with with the same property with a differnt time sampling
127 child = archive->createChild(ABCA::ObjectHeader(
128 "1propATS", ABCA::MetaData()));
129 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
130 ABCA::DataType(Alembic::Util::kInt32POD, 1), 1);
131
132 child = archive->createChild(ABCA::ObjectHeader(
133 "1propBTS", ABCA::MetaData()));
134 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
135 ABCA::DataType(Alembic::Util::kInt32POD, 1), 1);
136
137 // 2 objects with 1 sample
138 ABCA::ArrayPropertyWriterPtr awp;
139 std::vector <Alembic::Util::int32_t> vali(4, 0);
140 Alembic::Util::Dimensions dims(4);
141 ABCA::DataType i32d(Alembic::Util::kInt32POD, 1);
142
143 child = archive->createChild(ABCA::ObjectHeader(
144 "1propA1Samp", ABCA::MetaData()));
145 awp = child->getProperties()->createArrayProperty("int",
146 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
147 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dims));
148
149 child = archive->createChild(ABCA::ObjectHeader(
150 "1propB1Samp", ABCA::MetaData()));
151 awp = child->getProperties()->createArrayProperty("int",
152 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
153 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dims));
154
155 // 2 objects with 2 samples, no repeats
156 std::vector <Alembic::Util::int32_t> valiB(4, 1);
157
158 child = archive->createChild(ABCA::ObjectHeader(
159 "1propA2Samp", ABCA::MetaData()));
160 awp = child->getProperties()->createArrayProperty("int",
161 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
162 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dims));
163 awp->setSample(ABCA::ArraySample(&(valiB.front()), i32d, dims));
164
165 child = archive->createChild(ABCA::ObjectHeader(
166 "1propB2Samp", ABCA::MetaData()));
167 awp = child->getProperties()->createArrayProperty("int",
168 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
169 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dims));
170 awp->setSample(ABCA::ArraySample(&(valiB.front()), i32d, dims));
171
172 // 2 objects with 4 samples, with repeats
173 child = archive->createChild(ABCA::ObjectHeader(
174 "1propA4Samp", ABCA::MetaData()));
175 awp = child->getProperties()->createArrayProperty("int",
176 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
177 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dims));
178 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dims));
179 awp->setSample(ABCA::ArraySample(&(valiB.front()), i32d, dims));
180 awp->setSample(ABCA::ArraySample(&(valiB.front()), i32d, dims));
181
182 child = archive->createChild(ABCA::ObjectHeader(
183 "1propB4Samp", ABCA::MetaData()));
184 awp = child->getProperties()->createArrayProperty("int",
185 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
186 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dims));
187 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dims));
188 awp->setSample(ABCA::ArraySample(&(valiB.front()), i32d, dims));
189 awp->setSample(ABCA::ArraySample(&(valiB.front()), i32d, dims));
190
191 // 2 objects with 1 samplem different dimensions
192 Alembic::Util::Dimensions dimsB;
193 dimsB.setRank(2);
194 dimsB[0] = 2;
195 dimsB[1] = 2;
196
197 child = archive->createChild(ABCA::ObjectHeader(
198 "1propA1Dims", ABCA::MetaData()));
199 awp = child->getProperties()->createArrayProperty("int",
200 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
201 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dimsB));
202
203 child = archive->createChild(ABCA::ObjectHeader(
204 "1propB1Dims", ABCA::MetaData()));
205 awp = child->getProperties()->createArrayProperty("int",
206 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
207 awp->setSample(ABCA::ArraySample(&(vali.front()), i32d, dimsB));
208
209 // 2 objects with with the same 2 properties with no samples
210 child = archive->createChild(ABCA::ObjectHeader(
211 "2propA", ABCA::MetaData()));
212 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
213 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
214 child->getProperties()->createArrayProperty("null", ABCA::MetaData(),
215 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
216
217 child = archive->createChild(ABCA::ObjectHeader(
218 "2propB", ABCA::MetaData()));
219 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
220 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
221 child->getProperties()->createArrayProperty("null", ABCA::MetaData(),
222 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
223
224 // 2 objects with with the same 2 properties created in opposite order
225 child = archive->createChild(ABCA::ObjectHeader(
226 "2propASwap", ABCA::MetaData()));
227 child->getProperties()->createArrayProperty("null", ABCA::MetaData(),
228 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
229 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
230 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
231
232 child = archive->createChild(ABCA::ObjectHeader(
233 "2propBSwap", ABCA::MetaData()));
234 child->getProperties()->createArrayProperty("null", ABCA::MetaData(),
235 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
236 child->getProperties()->createArrayProperty("empty", ABCA::MetaData(),
237 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
238 }
239
240 {
241 AO::ReadArchive r(1, iUseMMap);
242 ABCA::ArchiveReaderPtr a = r( archiveName );
243 ABCA::ObjectReaderPtr archive = a->getTop();
244
245 TESTING_ASSERT(archive->getNumChildren() == 26);
246
247 // every 2 hashes should be the same
248 for (size_t i = 0; i < archive->getNumChildren(); i += 2)
249 {
250 Alembic::Util::Digest dA, dB;
251 TESTING_ASSERT(archive->getChild(i)->getPropertiesHash(dA) &&
252 archive->getChild(i+1)->getPropertiesHash(dB));
253 TESTING_ASSERT(dA == dB);
254 }
255
256 // make sure that every 2 child objects have different properties hashes
257 for (size_t i = 0; i < archive->getNumChildren() / 2; ++i)
258 {
259 Alembic::Util::Digest dA;
260 archive->getChild(i*2)->getPropertiesHash(dA);
261 for (size_t j = i + 1; j < archive->getNumChildren() / 2; ++j)
262 {
263 Alembic::Util::Digest dB;
264 archive->getChild(j*2)->getPropertiesHash(dB);
265 TESTING_ASSERT(dA != dB);
266 }
267 }
268 }
269 }
270
testScalarPropHashes(bool iUseMMap)271 void testScalarPropHashes(bool iUseMMap)
272 {
273 std::string archiveName = "scalarHashTest.abc";
274 {
275 AO::WriteArchive w;
276 ABCA::ArchiveWriterPtr a = w(archiveName, ABCA::MetaData());
277 ABCA::ObjectWriterPtr archive = a->getTop();
278 ABCA::ObjectWriterPtr child;
279
280 // add a time sampling for later use
281 std::vector < double > timeSamps(1,-4.0);
282 ABCA::TimeSamplingType tst(3.0);
283 ABCA::TimeSampling ts(tst, timeSamps);
284 a->addTimeSampling(ts);
285
286 // 2 objects without any properties whatsoever
287 archive->createChild(ABCA::ObjectHeader("emptyA", ABCA::MetaData()));
288 archive->createChild(ABCA::ObjectHeader("emptyB", ABCA::MetaData()));
289
290 // 2 objects with with the same property with no samples
291 child = archive->createChild(ABCA::ObjectHeader(
292 "1propA", ABCA::MetaData()));
293 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
294 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
295
296 child = archive->createChild(ABCA::ObjectHeader(
297 "1propB", ABCA::MetaData()));
298 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
299 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
300
301 // 2 objects with with the same property with a differnt name from above
302 child = archive->createChild(ABCA::ObjectHeader(
303 "1propAName", ABCA::MetaData()));
304 child->getProperties()->createScalarProperty("null", ABCA::MetaData(),
305 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
306
307 child = archive->createChild(ABCA::ObjectHeader(
308 "1propBName", ABCA::MetaData()));
309 child->getProperties()->createScalarProperty("null", ABCA::MetaData(),
310 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
311
312 // 2 objects with with the same property with a differnt MetaData
313 ABCA::MetaData m;
314 m.set("Bleep", "bloop");
315 child = archive->createChild(ABCA::ObjectHeader(
316 "1propAMeta", ABCA::MetaData()));
317 child->getProperties()->createScalarProperty("empty", m,
318 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
319
320 child = archive->createChild(ABCA::ObjectHeader(
321 "1propBMeta", ABCA::MetaData()));
322 child->getProperties()->createScalarProperty("empty", m,
323 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
324
325 // 2 objects with with the same property with a different POD
326 child = archive->createChild(ABCA::ObjectHeader(
327 "1propAPod", ABCA::MetaData()));
328 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
329 ABCA::DataType(Alembic::Util::kFloat32POD, 1), 0);
330
331 child = archive->createChild(ABCA::ObjectHeader(
332 "1propBPod", ABCA::MetaData()));
333 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
334 ABCA::DataType(Alembic::Util::kFloat32POD, 1), 0);
335
336 // 2 objects with with the same property with a different extent
337 child = archive->createChild(ABCA::ObjectHeader(
338 "1propAExtent", ABCA::MetaData()));
339 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
340 ABCA::DataType(Alembic::Util::kInt32POD, 2), 0);
341
342 child = archive->createChild(ABCA::ObjectHeader(
343 "1propBExtent", ABCA::MetaData()));
344 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
345 ABCA::DataType(Alembic::Util::kInt32POD, 2), 0);
346
347 // 2 objects with with the same property with a differnt time sampling
348 child = archive->createChild(ABCA::ObjectHeader(
349 "1propATS", ABCA::MetaData()));
350 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
351 ABCA::DataType(Alembic::Util::kInt32POD, 1), 1);
352
353 child = archive->createChild(ABCA::ObjectHeader(
354 "1propBTS", ABCA::MetaData()));
355 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
356 ABCA::DataType(Alembic::Util::kInt32POD, 1), 1);
357
358 // 2 objects with 1 sample
359 ABCA::ScalarPropertyWriterPtr swp;
360 Alembic::Util::int32_t vali = 0;
361 ABCA::DataType i32d(Alembic::Util::kInt32POD, 1);
362
363 child = archive->createChild(ABCA::ObjectHeader(
364 "1propA1Samp", ABCA::MetaData()));
365 swp = child->getProperties()->createScalarProperty("int",
366 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
367 swp->setSample(&vali);
368
369 child = archive->createChild(ABCA::ObjectHeader(
370 "1propB1Samp", ABCA::MetaData()));
371 swp = child->getProperties()->createScalarProperty("int",
372 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
373 swp->setSample(&vali);
374
375 // 2 objects with 2 samples, no repeats
376 Alembic::Util::int32_t valiB = 1;
377
378 child = archive->createChild(ABCA::ObjectHeader(
379 "1propA2Samp", ABCA::MetaData()));
380 swp = child->getProperties()->createScalarProperty("int",
381 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
382 swp->setSample(&vali);
383 swp->setSample(&valiB);
384
385 child = archive->createChild(ABCA::ObjectHeader(
386 "1propB2Samp", ABCA::MetaData()));
387 swp = child->getProperties()->createScalarProperty("int",
388 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
389 swp->setSample(&vali);
390 swp->setSample(&valiB);
391
392 // 2 objects with 4 samples, with repeats
393 child = archive->createChild(ABCA::ObjectHeader(
394 "1propA4Samp", ABCA::MetaData()));
395 swp = child->getProperties()->createScalarProperty("int",
396 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
397 swp->setSample(&vali);
398 swp->setSample(&vali);
399 swp->setSample(&valiB);
400 swp->setSample(&valiB);
401
402 child = archive->createChild(ABCA::ObjectHeader(
403 "1propB4Samp", ABCA::MetaData()));
404 swp = child->getProperties()->createScalarProperty("int",
405 ABCA::MetaData(), ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
406 swp->setSample(&vali);
407 swp->setSample(&vali);
408 swp->setSample(&valiB);
409 swp->setSample(&valiB);
410
411 // 2 objects with with the same 2 properties with no samples
412 child = archive->createChild(ABCA::ObjectHeader(
413 "2propA", ABCA::MetaData()));
414 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
415 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
416 child->getProperties()->createScalarProperty("null", ABCA::MetaData(),
417 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
418
419 child = archive->createChild(ABCA::ObjectHeader(
420 "2propB", ABCA::MetaData()));
421 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
422 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
423 child->getProperties()->createScalarProperty("null", ABCA::MetaData(),
424 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
425
426 // 2 objects with with the same 2 properties created in opposite order
427 child = archive->createChild(ABCA::ObjectHeader(
428 "2propASwap", ABCA::MetaData()));
429 child->getProperties()->createScalarProperty("null", ABCA::MetaData(),
430 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
431 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
432 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
433
434 child = archive->createChild(ABCA::ObjectHeader(
435 "2propBSwap", ABCA::MetaData()));
436 child->getProperties()->createScalarProperty("null", ABCA::MetaData(),
437 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
438 child->getProperties()->createScalarProperty("empty", ABCA::MetaData(),
439 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
440 }
441
442 {
443 AO::ReadArchive r(1, iUseMMap);
444 ABCA::ArchiveReaderPtr a = r( archiveName );
445 ABCA::ObjectReaderPtr archive = a->getTop();
446
447 TESTING_ASSERT(archive->getNumChildren() == 24);
448
449 // every 2 hashes should be the same
450 for (size_t i = 0; i < archive->getNumChildren(); i += 2)
451 {
452 Alembic::Util::Digest dA, dB;
453 TESTING_ASSERT(archive->getChild(i)->getPropertiesHash(dA) &&
454 archive->getChild(i+1)->getPropertiesHash(dB));
455 TESTING_ASSERT(dA == dB);
456 }
457
458 // make sure that every 2 child objects have different properties hashes
459 for (size_t i = 0; i < archive->getNumChildren() / 2; ++i)
460 {
461 Alembic::Util::Digest dA;
462 archive->getChild(i*2)->getPropertiesHash(dA);
463 for (size_t j = i + 1; j < archive->getNumChildren() / 2; ++j)
464 {
465 Alembic::Util::Digest dB;
466 archive->getChild(j*2)->getPropertiesHash(dB);
467 TESTING_ASSERT(dA != dB);
468 }
469 }
470 }
471 }
472
testCompoundPropHashes(bool iUseMMap)473 void testCompoundPropHashes(bool iUseMMap)
474 {
475 std::string archiveName = "compoundHashTest.abc";
476 {
477 AO::WriteArchive w;
478 ABCA::ArchiveWriterPtr a = w(archiveName, ABCA::MetaData());
479 ABCA::ObjectWriterPtr archive = a->getTop();
480 ABCA::ObjectWriterPtr child;
481
482 // 2 objects without any properties whatsoever
483 archive->createChild(ABCA::ObjectHeader("emptyA", ABCA::MetaData()));
484 archive->createChild(ABCA::ObjectHeader("emptyB", ABCA::MetaData()));
485
486 // 2 objects with with the same property with no samples
487 child = archive->createChild(ABCA::ObjectHeader(
488 "1propA", ABCA::MetaData()));
489 child->getProperties()->createCompoundProperty("empty",
490 ABCA::MetaData());
491
492 child = archive->createChild(ABCA::ObjectHeader(
493 "1propB", ABCA::MetaData()));
494 child->getProperties()->createCompoundProperty("empty",
495 ABCA::MetaData());
496
497 // 2 objects with with the same property with a differnt name from above
498 child = archive->createChild(ABCA::ObjectHeader(
499 "1propAName", ABCA::MetaData()));
500 child->getProperties()->createCompoundProperty("null",
501 ABCA::MetaData());
502
503 child = archive->createChild(ABCA::ObjectHeader(
504 "1propBName", ABCA::MetaData()));
505 child->getProperties()->createCompoundProperty("null",
506 ABCA::MetaData());
507
508 // 2 objects with with the same property with a different MetaData
509 ABCA::MetaData m;
510 m.set("Bleep", "bloop");
511 child = archive->createChild(ABCA::ObjectHeader(
512 "1propAMeta", ABCA::MetaData()));
513 child->getProperties()->createCompoundProperty("empty", m);
514
515 child = archive->createChild(ABCA::ObjectHeader(
516 "1propBMeta", ABCA::MetaData()));
517 child->getProperties()->createCompoundProperty("empty", m);
518
519 // 2 objects with compound that has a child compound
520 child = archive->createChild(ABCA::ObjectHeader(
521 "1propAChild", ABCA::MetaData()));
522 child->getProperties()->createCompoundProperty("withChild",
523 ABCA::MetaData())->createCompoundProperty("child",
524 ABCA::MetaData());
525
526 child = archive->createChild(ABCA::ObjectHeader(
527 "1propBChild", ABCA::MetaData()));
528 child->getProperties()->createCompoundProperty("withChild",
529 ABCA::MetaData())->createCompoundProperty("child",
530 ABCA::MetaData());
531
532 // 2 objects with compound that has various children
533 ABCA::CompoundPropertyWriterPtr childProp;
534 child = archive->createChild(ABCA::ObjectHeader(
535 "1propAProps", ABCA::MetaData()));
536 childProp = child->getProperties()->createCompoundProperty("child",
537 ABCA::MetaData());
538 childProp->createCompoundProperty("child", ABCA::MetaData());
539 childProp->createScalarProperty("empty", ABCA::MetaData(),
540 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
541
542 child = archive->createChild(ABCA::ObjectHeader(
543 "1propBProps", ABCA::MetaData()));
544 childProp = child->getProperties()->createCompoundProperty("child",
545 ABCA::MetaData());
546 childProp->createCompoundProperty("child", ABCA::MetaData());
547 childProp->createScalarProperty("empty", ABCA::MetaData(),
548 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
549
550 // 2 objects with compound that has hierarchy
551 ABCA::CompoundPropertyWriterPtr grandChildProp;
552 child = archive->createChild(ABCA::ObjectHeader(
553 "1propAHier", ABCA::MetaData()));
554 childProp = child->getProperties()->createCompoundProperty("child",
555 ABCA::MetaData());
556 grandChildProp = childProp->createCompoundProperty("child",
557 ABCA::MetaData());
558 childProp->createScalarProperty("empty", ABCA::MetaData(),
559 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
560 grandChildProp->createScalarProperty("empty", ABCA::MetaData(),
561 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
562 grandChildProp->createCompoundProperty("child", ABCA::MetaData());
563
564 child = archive->createChild(ABCA::ObjectHeader(
565 "1propBHier", ABCA::MetaData()));
566 childProp = child->getProperties()->createCompoundProperty("child",
567 ABCA::MetaData());
568 grandChildProp = childProp->createCompoundProperty("child",
569 ABCA::MetaData());
570 childProp->createScalarProperty("empty", ABCA::MetaData(),
571 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
572 grandChildProp->createScalarProperty("empty", ABCA::MetaData(),
573 ABCA::DataType(Alembic::Util::kInt32POD, 1), 0);
574 grandChildProp->createCompoundProperty("child", ABCA::MetaData());
575 }
576
577 {
578 AO::ReadArchive r(1, iUseMMap);
579 ABCA::ArchiveReaderPtr a = r( archiveName );
580 ABCA::ObjectReaderPtr archive = a->getTop();
581
582 TESTING_ASSERT(archive->getNumChildren() == 14);
583
584 // every 2 hashes should be the same
585 for (size_t i = 0; i < archive->getNumChildren(); i += 2)
586 {
587 Alembic::Util::Digest dA, dB;
588 TESTING_ASSERT(archive->getChild(i)->getPropertiesHash(dA) &&
589 archive->getChild(i+1)->getPropertiesHash(dB));
590 TESTING_ASSERT(dA == dB);
591 }
592
593 // make sure that every 2 child objects have different properties hashes
594 for (size_t i = 0; i < archive->getNumChildren() / 2; ++i)
595 {
596 Alembic::Util::Digest dA;
597 archive->getChild(i*2)->getPropertiesHash(dA);
598 for (size_t j = i + 1; j < archive->getNumChildren() / 2; ++j)
599 {
600 Alembic::Util::Digest dB;
601 archive->getChild(j*2)->getPropertiesHash(dB);
602 TESTING_ASSERT(dA != dB);
603 }
604 }
605 }
606 }
607
testObjectHashes(bool iUseMMap)608 void testObjectHashes(bool iUseMMap)
609 {
610 std::string archiveName = "objectHashTest.abc";
611 {
612 AO::WriteArchive w;
613 ABCA::ArchiveWriterPtr a = w(archiveName, ABCA::MetaData());
614 ABCA::ObjectWriterPtr archive = a->getTop();
615 ABCA::ObjectWriterPtr child;
616
617 // 2 objects without any children whatsoever
618 archive->createChild(ABCA::ObjectHeader("emptyA", ABCA::MetaData()));
619 archive->createChild(ABCA::ObjectHeader("emptyB", ABCA::MetaData()));
620
621 // 2 objects with one child object
622 child = archive->createChild(ABCA::ObjectHeader("1ChildA",
623 ABCA::MetaData()));
624 child->createChild(ABCA::ObjectHeader("child", ABCA::MetaData()));
625
626 child = archive->createChild(ABCA::ObjectHeader("1ChildB",
627 ABCA::MetaData()));
628 child->createChild(ABCA::ObjectHeader("child", ABCA::MetaData()));
629
630 // 2 objects with one child object with a different name
631 child = archive->createChild(ABCA::ObjectHeader("1ChildAName",
632 ABCA::MetaData()));
633 child->createChild(ABCA::ObjectHeader("empty", ABCA::MetaData()));
634
635 child = archive->createChild(ABCA::ObjectHeader("1ChildBName",
636 ABCA::MetaData()));
637 child->createChild(ABCA::ObjectHeader("empty", ABCA::MetaData()));
638
639 // 2 objects with one child object with different MetaData
640 ABCA::MetaData m;
641 m.set("Bleep", "bloop");
642 child = archive->createChild(ABCA::ObjectHeader("1ChildAMeta",
643 ABCA::MetaData()));
644 child->createChild(ABCA::ObjectHeader("child", m));
645
646 child = archive->createChild(ABCA::ObjectHeader("1ChildBMeta",
647 ABCA::MetaData()));
648 child->createChild(ABCA::ObjectHeader("child", m));
649
650 // 2 objects with one child object additional prop
651 child = archive->createChild(ABCA::ObjectHeader("1ChildAProp",
652 ABCA::MetaData()));
653 child->createChild(ABCA::ObjectHeader("child", ABCA::MetaData())
654 )->getProperties()->createCompoundProperty("child",
655 ABCA::MetaData());
656
657 child = archive->createChild(ABCA::ObjectHeader("1ChildBProp",
658 ABCA::MetaData()));
659 child->createChild(ABCA::ObjectHeader("child", ABCA::MetaData())
660 )->getProperties()->createCompoundProperty("child",
661 ABCA::MetaData());
662
663 // 2 objects with one child object with additional grand child
664 child = archive->createChild(ABCA::ObjectHeader("1ChildAChild",
665 ABCA::MetaData()));
666 child->createChild(ABCA::ObjectHeader("child", ABCA::MetaData())
667 )->createChild(ABCA::ObjectHeader("grandchild", ABCA::MetaData()));
668
669 child = archive->createChild(ABCA::ObjectHeader("1ChildBChild",
670 ABCA::MetaData()));
671 child->createChild(ABCA::ObjectHeader("child", ABCA::MetaData())
672 )->createChild(ABCA::ObjectHeader("grandchild", ABCA::MetaData()));
673
674 // 2 objects with two children objects
675 child = archive->createChild(ABCA::ObjectHeader("2ChildA",
676 ABCA::MetaData()));
677 child->createChild(ABCA::ObjectHeader("childA", ABCA::MetaData()));
678 child->createChild(ABCA::ObjectHeader("childB", ABCA::MetaData()));
679
680 child = archive->createChild(ABCA::ObjectHeader("2ChildB",
681 ABCA::MetaData()));
682 child->createChild(ABCA::ObjectHeader("childA", ABCA::MetaData()));
683 child->createChild(ABCA::ObjectHeader("childB", ABCA::MetaData()));
684
685 // 2 objects with two children objects with swapped children
686 child = archive->createChild(ABCA::ObjectHeader("2ChildASwap",
687 ABCA::MetaData()));
688 child->createChild(ABCA::ObjectHeader("childB", ABCA::MetaData()));
689 child->createChild(ABCA::ObjectHeader("childA", ABCA::MetaData()));
690
691 child = archive->createChild(ABCA::ObjectHeader("2ChildBSwap",
692 ABCA::MetaData()));
693 child->createChild(ABCA::ObjectHeader("childB", ABCA::MetaData()));
694 child->createChild(ABCA::ObjectHeader("childA", ABCA::MetaData()));
695 }
696
697 {
698 AO::ReadArchive r(1, iUseMMap);
699 ABCA::ArchiveReaderPtr a = r( archiveName );
700 ABCA::ObjectReaderPtr archive = a->getTop();
701
702 TESTING_ASSERT(archive->getNumChildren() == 16);
703
704 // every 2 hashes should be the same
705 for (size_t i = 0; i < archive->getNumChildren(); i += 2)
706 {
707 Alembic::Util::Digest dA, dB;
708 TESTING_ASSERT(archive->getChild(i)->getChildrenHash(dA) &&
709 archive->getChild(i+1)->getChildrenHash(dB));
710 TESTING_ASSERT(dA == dB);
711 }
712
713 // make sure that every 2 child objects have different properties hashes
714 for (size_t i = 0; i < archive->getNumChildren() / 2; ++i)
715 {
716 Alembic::Util::Digest dA;
717 archive->getChild(i*2)->getChildrenHash(dA);
718 for (size_t j = i + 1; j < archive->getNumChildren() / 2; ++j)
719 {
720 Alembic::Util::Digest dB;
721 archive->getChild(j*2)->getChildrenHash(dB);
722 TESTING_ASSERT(dA != dB);
723 }
724 }
725 }
726 }
727
testStringHashes(bool iUseMMap)728 void testStringHashes(bool iUseMMap)
729 {
730 std::string archiveName = "stringsHashTest.abc";
731 {
732 AO::WriteArchive w;
733 ABCA::ArchiveWriterPtr a = w(archiveName, ABCA::MetaData());
734 ABCA::ObjectWriterPtr archive = a->getTop();
735 ABCA::CompoundPropertyWriterPtr props = archive->getProperties();
736
737 ABCA::DataType wdtype(Alembic::Util::kWstringPOD, 1);
738 ABCA::ArrayPropertyWriterPtr wstrWrtPtr =
739 props->createArrayProperty("wstr", ABCA::MetaData(), wdtype, 0);
740
741 std::vector < Alembic::Util::wstring > wvals(4);
742 wvals[0] = L"Mash potatoes ";
743 wvals[1] = L"with some delicious gravy.";
744 wvals[2] = L"";
745 wvals[3] = L"\uf8e4 \uf8e2 \uf8d3";
746
747 for (size_t i = 0; i < wvals.size(); ++i)
748 {
749 Alembic::Util::Dimensions wdims(i);
750 wstrWrtPtr->setSample(
751 ABCA::ArraySample(&(wvals.front()), wdtype, wdims));
752 }
753
754 ABCA::DataType sdtype(Alembic::Util::kStringPOD, 1);
755 ABCA::ArrayPropertyWriterPtr strWrtPtr =
756 props->createArrayProperty("str", ABCA::MetaData(), sdtype, 0);
757
758 std::vector < Alembic::Util::string > svals(4);
759 svals[0] = "Sunday, Monday";
760 svals[1] = "Tuesday, Wednesday, Thursday";
761 svals[2] = "";
762 svals[3] = "Some other days";
763
764 for (size_t i = 0; i < svals.size(); ++i)
765 {
766 Alembic::Util::Dimensions sdims(i);
767 strWrtPtr->setSample(
768 ABCA::ArraySample(&(svals.front()), sdtype, sdims));
769 }
770 }
771
772 {
773 AO::ReadArchive r(1, iUseMMap);
774 ABCA::ArchiveReaderPtr a = r( archiveName );
775 ABCA::ObjectReaderPtr archive = a->getTop();
776 ABCA::CompoundPropertyReaderPtr parent = archive->getProperties();
777 ABCA::ArrayPropertyReaderPtr wap = parent->getArrayProperty("wstr");
778 std::vector< ABCA::ArraySampleKey > keys(wap->getNumSamples());
779 for (size_t i = 0; i < wap->getNumSamples(); ++i)
780 {
781 wap->getKey( (ABCA::index_t) i, keys[i] );
782 }
783
784 for (size_t i = 0; i < keys.size(); ++i)
785 {
786 for (size_t j = i+1; j < keys.size(); ++j)
787 {
788 TESTING_ASSERT( keys[i] != keys[j] );
789 }
790 }
791
792 ABCA::ArrayPropertyReaderPtr sap = parent->getArrayProperty("str");
793 keys.resize(sap->getNumSamples());
794 for (size_t i = 0; i < sap->getNumSamples(); ++i)
795 {
796 sap->getKey( (ABCA::index_t) i, keys[i] );
797 }
798
799 for (size_t i = 0; i < keys.size(); ++i)
800 {
801 for (size_t j = i+1; j < keys.size(); ++j)
802 {
803 TESTING_ASSERT( keys[i] != keys[j] );
804 }
805 }
806 }
807 }
808
runTests(bool iUseMMap)809 void runTests(bool iUseMMap)
810 {
811 testArrayPropHashes(iUseMMap);
812 testScalarPropHashes(iUseMMap);
813 testCompoundPropHashes(iUseMMap);
814 testObjectHashes(iUseMMap);
815 testStringHashes(iUseMMap);
816 }
817
main(int argc,char * argv[])818 int main ( int argc, char *argv[] )
819 {
820 runTests(true); // Use mmap
821 runTests(false); // Use streams
822 return 0;
823 }
824