Field3D
IGroup.cpp
Go to the documentation of this file.
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 Industrial Light & Magic nor the names of
19 // its contributors may be used to endorse or promote products derived
20 // from this software without specific prior written 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 FOR
25 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 //
34 //-*****************************************************************************
35 
36 #include "IGroup.h"
37 #include "IArchive.h"
38 #include "IStreams.h"
39 
40 namespace Alembic {
41 namespace Ogawa {
42 namespace ALEMBIC_VERSION_NS {
43 
44 class IGroup::PrivateData
45 {
46 public:
47  PrivateData(IStreamsPtr iStreams)
48  {
49  numChildren = 0;
50  pos = 0;
51  streams = iStreams;
52  }
53 
54  ~PrivateData() {}
55 
56  IStreamsPtr streams;
57 
58  std::vector<Alembic::Util::uint64_t> childVec;
59 
60  Alembic::Util::uint64_t numChildren;
61  Alembic::Util::uint64_t pos;
62 };
63 
64 IGroup::IGroup(IStreamsPtr iStreams,
65  Alembic::Util::uint64_t iPos,
66  bool iLight,
67  std::size_t iThreadIndex) :
68  mData(new IGroup::PrivateData(iStreams))
69 {
70  // all done, we have no children, or our streams aren't good
71  if (iPos == EMPTY_GROUP || !mData->streams || !mData->streams->isValid())
72  {
73  return;
74  }
75 
76  mData->pos = iPos;
77  mData->streams->read(iThreadIndex, iPos, 8, &mData->numChildren);
78 
79  // 0 should NOT have been written, this groups should have been the
80  // special EMPTY_GROUP instead
81 
82  // read all our child indices, unless we are light and have more than 8
83  // children
84  if (!iLight || mData->numChildren < 9)
85  {
86  mData->childVec.resize(mData->numChildren);
87  mData->streams->read(iThreadIndex, iPos + 8, mData->numChildren * 8,
88  &(mData->childVec.front()));
89  }
90 }
91 
92 IGroup::~IGroup()
93 {
94 
95 }
96 
97 IGroupPtr IGroup::getGroup(Alembic::Util::uint64_t iIndex, bool iLight,
98  std::size_t iThreadIndex)
99 {
100  IGroupPtr child;
101  if (isLight())
102  {
103  if (iIndex < mData->numChildren)
104  {
105  Alembic::Util::uint64_t childPos = 0;
106  mData->streams->read(iThreadIndex, mData->pos + 8 * iIndex + 8, 8,
107  &childPos);
108 
109  // top bit should not be set for groups
110  if ((childPos & EMPTY_DATA) == 0)
111  {
112  child.reset(new IGroup(mData->streams, childPos, iLight,
113  iThreadIndex));
114  }
115  }
116  }
117  else if (isChildGroup(iIndex))
118  {
119  child.reset(new IGroup(mData->streams, mData->childVec[iIndex], iLight,
120  iThreadIndex));
121  }
122  return child;
123 }
124 
125 IDataPtr IGroup::getData(Alembic::Util::uint64_t iIndex,
126  std::size_t iThreadIndex)
127 {
128  IDataPtr child;
129  if (isLight())
130  {
131  if (iIndex < mData->numChildren)
132  {
133  Alembic::Util::uint64_t childPos = 0;
134  mData->streams->read(iThreadIndex, mData->pos + 8 * iIndex + 8, 8,
135  &childPos);
136 
137  // top bit should be set for data
138  if ((childPos & EMPTY_DATA) != 0)
139  {
140  child.reset(new IData(mData->streams, childPos, iThreadIndex));
141  }
142  }
143  }
144  else if (isChildData(iIndex))
145  {
146  child.reset(new IData(mData->streams, mData->childVec[iIndex],
147  iThreadIndex));
148  }
149  return child;
150 }
151 
152 Alembic::Util::uint64_t IGroup::getNumChildren() const
153 {
154  return mData->numChildren;
155 }
156 
157 bool IGroup::isChildGroup(Alembic::Util::uint64_t iIndex) const
158 {
159  return (iIndex < mData->childVec.size() &&
160  (mData->childVec[iIndex] & EMPTY_DATA) == 0);
161 }
162 
163 bool IGroup::isChildData(Alembic::Util::uint64_t iIndex) const
164 {
165  return (iIndex < mData->childVec.size() &&
166  (mData->childVec[iIndex] & EMPTY_DATA) != 0);
167 }
168 
169 bool IGroup::isEmptyChildGroup(Alembic::Util::uint64_t iIndex) const
170 {
171  return (iIndex < mData->childVec.size() &&
172  mData->childVec[iIndex] == EMPTY_GROUP);
173 }
174 
175 bool IGroup::isEmptyChildData(Alembic::Util::uint64_t iIndex) const
176 {
177  return (iIndex < mData->childVec.size() &&
178  mData->childVec[iIndex] == EMPTY_DATA);
179 }
180 
181 bool IGroup::isLight() const
182 {
183  return mData->numChildren != 0 && mData->childVec.empty();
184 }
185 
186 } // End namespace ALEMBIC_VERSION_NS
187 } // End namespace Ogawa
188 } // End namespace Alembic
Alembic
Definition: OgawaFwd.h:77