Field3D
FieldMappingIO.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------//
2
3/*
4 * Copyright (c) 2009 Sony Pictures Imageworks Inc
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
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 copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the
17 * distribution. Neither the name of Sony Pictures Imageworks nor the
18 * names of its contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36//----------------------------------------------------------------------------//
37
43//----------------------------------------------------------------------------//
44
45#include "Hdf5Util.h"
46
47#include "FieldMappingIO.h"
48#include "OgIO.h"
49
50//----------------------------------------------------------------------------//
51
53
54//----------------------------------------------------------------------------//
55// Field3D namespaces
56//----------------------------------------------------------------------------//
57
58using namespace std;
59using namespace Exc;
60using namespace Hdf5Util;
61
62//----------------------------------------------------------------------------//
63
64namespace {
66 const string k_nullMappingName("NullFieldMapping");
68 const string k_matrixMappingName("MatrixFieldMapping");
69 const string k_frustumMappingName("FrustumFieldMapping");
70
71 const string k_nullMappingDataName("NullFieldMapping data");
72
73 const string k_matrixMappingDataName("MatrixFieldMapping data");
74 const string k_matrixMappingNumSamples("num_time_samples");
75 const string k_matrixMappingTime("time_");
76 const string k_matrixMappingMatrix("matrix_");
77
78 const string k_frustumMappingNumSamples("num_time_samples");
79 const string k_frustumMappingTime("time_");
80 const string k_frustumMappingScreenMatrix("screen_to_world_");
81 const string k_frustumMappingCameraMatrix("camera_to_world_");
82 const string k_frustumMappingZDistribution("z_distribution");
83}
84
85//----------------------------------------------------------------------------//
86
88NullFieldMappingIO::read(hid_t mappingGroup)
89{
90 string nfmData;
91 if (!readAttribute(mappingGroup, k_nullMappingDataName, nfmData)) {
92 Msg::print(Msg::SevWarning, "Couldn't read attribute " + k_nullMappingDataName);
93 return NullFieldMapping::Ptr();
94 }
96}
97
98//----------------------------------------------------------------------------//
99
101NullFieldMappingIO::read(const OgIGroup &mappingGroup)
102{
104 mappingGroup.findAttribute<string>(k_nullMappingDataName);
105 if (!data.isValid()) {
106 Msg::print(Msg::SevWarning, "Couldn't read attribute " +
107 k_nullMappingDataName);
108 return NullFieldMapping::Ptr();
109 }
111}
112
113//----------------------------------------------------------------------------//
114
115bool
116NullFieldMappingIO::write(hid_t mappingGroup, FieldMapping::Ptr /* nm */)
117{
118 string nfmAttrData("NullFieldMapping has no data");
119 if (!writeAttribute(mappingGroup, k_nullMappingDataName, nfmAttrData)) {
120 Msg::print(Msg::SevWarning, "Couldn't add attribute " + k_nullMappingDataName);
121 return false;
122 }
123 return true;
124}
125
126//----------------------------------------------------------------------------//
127
128bool
129NullFieldMappingIO::write(OgOGroup &mappingGroup, FieldMapping::Ptr /* nm */)
130{
131 string nfmAttrData("NullFieldMapping has no data");
132 OgOAttribute<string> data(mappingGroup, k_nullMappingDataName, nfmAttrData);
133 return true;
134}
135
136//----------------------------------------------------------------------------//
137
139{
140 return k_nullMappingName;
141}
142
143//----------------------------------------------------------------------------//
144// MatrixFieldMapping
145//----------------------------------------------------------------------------//
146
148MatrixFieldMappingIO::read(hid_t mappingGroup)
149{
150 M44d mtx;
151 int numSamples=0;
152
154
155 // For backward compatibility, we first try to read the non-time-varying
156 // mapping.
157
158 try {
159 readAttribute(mappingGroup, k_matrixMappingDataName, 16, mtx.x[0][0]);
160 mm->setLocalToWorld(mtx);
161 return mm;
162 }
163 catch (...) {
164 // Do nothing
165 }
166
167 // If we didn't find the non-time-varying matrix data then we attempt
168 // to read time samples
169
170 try {
171 if (!readAttribute(mappingGroup, k_matrixMappingNumSamples, 1, numSamples)) {
172 Msg::print(Msg::SevWarning, "Couldn't read attribute " +
173 k_matrixMappingNumSamples);
174 return FieldMapping::Ptr();
175 }
176 } catch (...) {
177 //do nothing
178 }
179
180 for (int i = 0; i < numSamples; ++i) {
181 float time;
182 string timeAttr = k_matrixMappingTime + boost::lexical_cast<string>(i);
183 string matrixAttr = k_matrixMappingMatrix + boost::lexical_cast<string>(i);
184 if (!readAttribute(mappingGroup, timeAttr, 1, time)) {
185 Msg::print(Msg::SevWarning, "Couldn't read attribute " + timeAttr);
186 return FieldMapping::Ptr();
187 }
188 std::vector<unsigned int> attrSize;
189 attrSize.assign(2,4);
190
191 if (!readAttribute(mappingGroup, matrixAttr, attrSize, mtx.x[0][0])) {
192 Msg::print(Msg::SevWarning, "Couldn't read attribute " + matrixAttr);
193 return FieldMapping::Ptr();
194 }
195 mm->setLocalToWorld(time, mtx);
196 }
197
198 return mm;
199}
200
201//----------------------------------------------------------------------------//
202
204MatrixFieldMappingIO::read(const OgIGroup &mappingGroup)
205{
206 M44d mtx;
207 int numSamples = 0;
208
210
211 try {
212 OgIAttribute<int> numSamplesAttr =
213 mappingGroup.findAttribute<int>(k_matrixMappingNumSamples);
214 if (!numSamplesAttr.isValid()) {
215 Msg::print(Msg::SevWarning, "Couldn't read attribute " +
216 k_matrixMappingNumSamples);
217 return FieldMapping::Ptr();
218 }
219 numSamples = numSamplesAttr.value();
220 } catch (...) {
221 //do nothing
222 }
223
224 for (int i = 0; i < numSamples; ++i) {
225 string timeAttr = k_matrixMappingTime + boost::lexical_cast<string>(i);
226 string matrixAttr = k_matrixMappingMatrix + boost::lexical_cast<string>(i);
227 // Read time
229 mappingGroup.findAttribute<float32_t>(timeAttr);
230 if (!time.isValid()) {
231 Msg::print(Msg::SevWarning, "Couldn't read attribute " + timeAttr);
232 return FieldMapping::Ptr();
233 }
234 // Read matrix
236 mappingGroup.findAttribute<mtx64_t>(matrixAttr);
237 if (!mtx.isValid()) {
238 Msg::print(Msg::SevWarning, "Couldn't read attribute " + matrixAttr);
239 return FieldMapping::Ptr();
240 }
241 mm->setLocalToWorld(time.value(), mtx.value());
242 }
243
244 return mm;
245}
246
247//----------------------------------------------------------------------------//
248
249bool
251{
253
256
257 if (!mm) {
258 Msg::print(Msg::SevWarning, "Couldn't get MatrixFieldMapping from pointer");
259 return false;
260 }
261
262 // First write number of time samples
263
264 const SampleVec &samples = mm->localToWorldSamples();
265 int numSamples = static_cast<int>(samples.size());
266
267 if (!writeAttribute(mappingGroup, k_matrixMappingNumSamples, 1, numSamples)) {
268 Msg::print(Msg::SevWarning, "Couldn't add attribute " +
269 k_matrixMappingNumSamples);
270 return false;
271 }
272
273 // Then write each sample
274
275 for (int i = 0; i < numSamples; ++i) {
276 string timeAttr = k_matrixMappingTime + boost::lexical_cast<string>(i);
277 string matrixAttr = k_matrixMappingMatrix + boost::lexical_cast<string>(i);
278 if (!writeAttribute(mappingGroup, timeAttr, 1, samples[i].first)) {
279 Msg::print(Msg::SevWarning, "Couldn't add attribute " + timeAttr);
280 return false;
281 }
282 std::vector<unsigned int> attrSize;
283 attrSize.assign(2,4);
284 if (!writeAttribute(mappingGroup, matrixAttr, attrSize,
285 samples[i].second.x[0][0])) {
286 Msg::print(Msg::SevWarning, "Couldn't add attribute " + matrixAttr);
287 return false;
288 }
289 }
290
291 return true;
292}
293
294//----------------------------------------------------------------------------//
295
296bool
297MatrixFieldMappingIO::write(OgOGroup &mappingGroup, FieldMapping::Ptr mapping)
298{
300
303
304 if (!mm) {
305 Msg::print(Msg::SevWarning, "Couldn't get MatrixFieldMapping from pointer");
306 return false;
307 }
308
309 // First write number of time samples
310
311 const SampleVec &samples = mm->localToWorldSamples();
312 const int numSamples = static_cast<int>(samples.size());
313
314 OgOAttribute<int> numSamplesAttr(mappingGroup, k_matrixMappingNumSamples,
315 numSamples);
316
317 // Then write each sample
318
319 for (int i = 0; i < numSamples; ++i) {
320 // Attribute names
321 const string timeAttr =
322 k_matrixMappingTime + boost::lexical_cast<string>(i);
323 const string matrixAttr =
324 k_matrixMappingMatrix + boost::lexical_cast<string>(i);
325 OgOAttribute<float32_t> time(mappingGroup, timeAttr, samples[i].first);
326 OgOAttribute<mtx64_t> mtx (mappingGroup, matrixAttr, samples[i].second);
327 }
328
329 return true;
330}
331
332//----------------------------------------------------------------------------//
333
335{
336 return k_matrixMappingName;
337}
338
339//----------------------------------------------------------------------------//
340// FrustumFieldMapping
341//----------------------------------------------------------------------------//
342
345{
346 float time;
347 M44d ssMtx, csMtx;
348 int numSamples=0;
349
351
352 // Read number of time samples
353
354 try {
355 if (!readAttribute(mappingGroup, k_frustumMappingNumSamples, 1, numSamples)) {
356 Msg::print(Msg::SevWarning, "Couldn't read attribute " +
357 k_frustumMappingNumSamples);
358 return FieldMapping::Ptr();
359 }
360 } catch (...) {
361 //do nothing
362 }
363
364 // Read each time sample
365
366 for (int i = 0; i < numSamples; ++i) {
367 string timeAttr = k_frustumMappingTime + boost::lexical_cast<string>(i);
368 string ssAttr = k_frustumMappingScreenMatrix + boost::lexical_cast<string>(i);
369 string csAttr = k_frustumMappingCameraMatrix + boost::lexical_cast<string>(i);
370 if (!readAttribute(mappingGroup, timeAttr, 1, time)) {
371 Msg::print(Msg::SevWarning, "Couldn't read attribute " + timeAttr);
372 return FieldMapping::Ptr();
373 }
374 std::vector<unsigned int> attrSize;
375 attrSize.assign(2,4);
376
377 if (!readAttribute(mappingGroup, ssAttr, attrSize, ssMtx.x[0][0])) {
378 Msg::print(Msg::SevWarning, "Couldn't read attribute " + ssAttr);
379 return FieldMapping::Ptr();
380 }
381 if (!readAttribute(mappingGroup, csAttr, attrSize, csMtx.x[0][0])) {
382 Msg::print(Msg::SevWarning, "Couldn't read attribute " + csAttr);
383 return FieldMapping::Ptr();
384 }
385
386 fm->setTransforms(time, ssMtx, csMtx);
387 }
388
389
390 // Read Z distribution
391
392 int distInt;
394
395 try {
396 if (!readAttribute(mappingGroup, k_frustumMappingZDistribution, 1, distInt)) {
397 Msg::print(Msg::SevWarning, "Couldn't read attribute " +
398 k_frustumMappingZDistribution);
399 return FieldMapping::Ptr();
400 }
401 dist = static_cast<FrustumFieldMapping::ZDistribution>(distInt);
402 } catch (...) {
404 }
405
406 fm->setZDistribution(dist);
407
408 return fm;
409}
410
411//----------------------------------------------------------------------------//
412
414FrustumFieldMappingIO::read(const OgIGroup &mappingGroup)
415{
416 int numSamples = 0;
417
419
420 // Read number of time samples
421
422 try {
423 OgIAttribute<int> numSamplesAttr =
424 mappingGroup.findAttribute<int>(k_frustumMappingNumSamples);
425 if (!numSamplesAttr.isValid()) {
426 Msg::print(Msg::SevWarning, "Couldn't read attribute " +
427 k_frustumMappingNumSamples);
428 return FieldMapping::Ptr();
429 }
430 } catch (...) {
431 //do nothing
432 }
433
434 // Read each time sample
435
436 for (int i = 0; i < numSamples; ++i) {
437 // Attribute names
438 string timeAttr = k_frustumMappingTime + boost::lexical_cast<string>(i);
439 string ssAttr = k_frustumMappingScreenMatrix + boost::lexical_cast<string>(i);
440 string csAttr = k_frustumMappingCameraMatrix + boost::lexical_cast<string>(i);
441 // Read time
442 OgIAttribute<float> time =
443 mappingGroup.findAttribute<float>(timeAttr);
444 if (!time.isValid()) {
445 Msg::print(Msg::SevWarning, "Couldn't read attribute " + timeAttr);
446 return FieldMapping::Ptr();
447 }
448 // Read matrices
449 OgIAttribute<mtx64_t> ssMtx =
450 mappingGroup.findAttribute<mtx64_t>(ssAttr);
451 OgIAttribute<mtx64_t> csMtx =
452 mappingGroup.findAttribute<mtx64_t>(csAttr);
453 if (!ssMtx.isValid()) {
454 Msg::print(Msg::SevWarning, "Couldn't read attribute " + ssAttr);
455 return FieldMapping::Ptr();
456 }
457 if (!csMtx.isValid()) {
458 Msg::print(Msg::SevWarning, "Couldn't read attribute " + csAttr);
459 return FieldMapping::Ptr();
460 }
461
462 fm->setTransforms(time.value(), ssMtx.value(), csMtx.value());
463 }
464
465
466 // Read Z distribution
467
469
470 try {
471 OgIAttribute<int> zDist =
472 mappingGroup.findAttribute<int>(k_frustumMappingZDistribution);
473 if (!zDist.isValid()) {
474 Msg::print(Msg::SevWarning, "Couldn't read attribute " +
475 k_frustumMappingZDistribution);
476 return FieldMapping::Ptr();
477 }
478 dist = static_cast<FrustumFieldMapping::ZDistribution>(zDist.value());
479 } catch (...) {
481 }
482
483 fm->setZDistribution(dist);
484
485 return fm;
486}
487
488//----------------------------------------------------------------------------//
489
490bool
492{
494
497
498 if (!fm) {
499 Msg::print(Msg::SevWarning, "Couldn't get FrustumFieldMapping from pointer");
500 return false;
501 }
502
503 // First write number of time samples
504
505 const SampleVec &ssSamples = fm->screenToWorldSamples();
506 const SampleVec &csSamples = fm->cameraToWorldSamples();
507 int numSamples = static_cast<int>(ssSamples.size());
508
509 if (!writeAttribute(mappingGroup, k_frustumMappingNumSamples, 1, numSamples)) {
510 Msg::print(Msg::SevWarning, "Couldn't add attribute " +
511 k_frustumMappingNumSamples);
512 return false;
513 }
514
515 // Then write each sample
516
517 for (int i = 0; i < numSamples; ++i) {
518 string timeAttr = k_frustumMappingTime + boost::lexical_cast<string>(i);
519 string ssAttr = k_frustumMappingScreenMatrix + boost::lexical_cast<string>(i);
520 string csAttr = k_frustumMappingCameraMatrix + boost::lexical_cast<string>(i);
521 if (!writeAttribute(mappingGroup, timeAttr, 1, ssSamples[i].first)) {
522 Msg::print(Msg::SevWarning, "Couldn't add attribute " + timeAttr);
523 return false;
524 }
525
526 std::vector<unsigned int> attrSize;
527 attrSize.assign(2,4);
528
529 if (!writeAttribute(mappingGroup, ssAttr,attrSize,
530 ssSamples[i].second.x[0][0])) {
531 Msg::print(Msg::SevWarning, "Couldn't add attribute " + ssAttr);
532 return false;
533 }
534 if (!writeAttribute(mappingGroup, csAttr, attrSize,
535 csSamples[i].second.x[0][0])) {
536 Msg::print(Msg::SevWarning, "Couldn't add attribute " + csAttr);
537 return false;
538 }
539 }
540
541 // Write distribution type
542
543 int dist = static_cast<int>(fm->zDistribution());
544
545 if (!writeAttribute(mappingGroup, k_frustumMappingZDistribution, 1, dist)) {
546 Msg::print(Msg::SevWarning, "Couldn't add attribute " +
547 k_frustumMappingNumSamples);
548 return false;
549 }
550
551 return true;
552}
553
554//----------------------------------------------------------------------------//
555
556bool
557FrustumFieldMappingIO::write(OgOGroup &mappingGroup, FieldMapping::Ptr mapping)
558{
560
563
564 if (!fm) {
566 "Couldn't get FrustumFieldMapping from pointer");
567 return false;
568 }
569
570 // First write number of time samples ---
571
572 const SampleVec &ssSamples = fm->screenToWorldSamples();
573 const SampleVec &csSamples = fm->cameraToWorldSamples();
574 const int numSamples = static_cast<int>(ssSamples.size());
575
576 OgOAttribute<int> numSamplesAttr(mappingGroup, k_frustumMappingNumSamples,
577 numSamples);
578
579 // Then write each sample ---
580
581 for (int i = 0; i < numSamples; ++i) {
582 const string timeAttr = k_frustumMappingTime +
583 boost::lexical_cast<string>(i);
584 const string ssAttr = k_frustumMappingScreenMatrix +
585 boost::lexical_cast<string>(i);
586 const string csAttr = k_frustumMappingCameraMatrix +
587 boost::lexical_cast<string>(i);
588
589 OgOAttribute<float> time(mappingGroup, timeAttr, ssSamples[i].first);
590 OgOAttribute<mtx64_t> ss(mappingGroup, ssAttr, ssSamples[i].second);
591 OgOAttribute<mtx64_t> cs(mappingGroup, csAttr, csSamples[i].second);
592 }
593
594 // Write distribution type ---
595
596 int dist = static_cast<int>(fm->zDistribution());
597
598 OgOAttribute<int> zDist(mappingGroup, k_frustumMappingZDistribution, dist);
599
600 return true;
601}
602
603//----------------------------------------------------------------------------//
604
606{
607 return k_frustumMappingName;
608}
609
610//----------------------------------------------------------------------------//
611
613
614//----------------------------------------------------------------------------//
Contains the FieldMappingIO base class and the NullFieldMappingIO and MatrixFieldMappingIO subclasses...
Contains various utility functions for Hdf5.
#define FIELD_DYNAMIC_CAST
Definition RefCount.h:271
Imath::M44d M44d
Definition SpiMathLib.h:82
Field3D::M44d mtx64_t
Definition Traits.h:95
float float32_t
Definition Traits.h:87
std::vector< Sample > SampleVec
Definition Curve.h:102
boost::intrusive_ptr< FieldMapping > Ptr
virtual bool write(hid_t mappingGroup, FieldMapping::Ptr mapping)
Writes the given field mapping to disk.
virtual std::string className() const
Returns the class name.
virtual FieldMapping::Ptr read(hid_t mappingGroup)
Reads the field mapping and tries to create a FrustumFieldMapping object from it.
Represents the mapping of a field by a perspective transform.
ZDistribution
Enumerates the Z slice distribution. .f3d files will store values as an int, so be very careful not t...
boost::intrusive_ptr< FrustumFieldMapping > Ptr
Convenience typedef.
virtual bool write(hid_t mappingGroup, FieldMapping::Ptr mapping)
Writes the given field mapping to disk.
virtual std::string className() const
Returns the class name.
virtual FieldMapping::Ptr read(hid_t mappingGroup)
Reads the field mapping and tries to create a MatrixFieldMapping object from it.
Represents the mapping of a field by a matrix transform.
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
virtual bool write(hid_t mappingGroup, FieldMapping::Ptr mapping)
Writes the given field mapping to disk.
virtual std::string className() const
Returns the class name.
virtual FieldMapping::Ptr read(hid_t mappingGroup)
Reads the field mapping and tries to create a NullFieldMapping object from it.
Trivial class, world space is equal to local space, i.e. the field is contained in the unit cube [0....
boost::intrusive_ptr< NullFieldMapping > Ptr
Convenience typedef.
FIELD3D_API bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
Namespace for Exception objects.
Definition Exception.h:57
const string k_nullMappingName("NullFieldMapping")
const string k_matrixMappingName("MatrixFieldMapping")
const string k_frustumMappingName("FrustumFieldMapping")
Contains utility functions and classes for Hdf5 files.
Definition Hdf5Util.h:86
@ SevWarning
Definition Log.h:68
FIELD3D_API void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity.
Definition Log.cpp:70
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition ns.h:60