/src/alembic/lib/Alembic/AbcGeom/IXform.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //-***************************************************************************** |
2 | | // |
3 | | // Copyright (c) 2009-2012, |
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/AbcGeom/IXform.h> |
38 | | #include <Alembic/AbcGeom/XformOp.h> |
39 | | |
40 | | namespace Alembic { |
41 | | namespace AbcGeom { |
42 | | namespace ALEMBIC_VERSION_NS { |
43 | | |
44 | | //-***************************************************************************** |
45 | | void IXformSchema::init( const Abc::Argument &iArg0, |
46 | | const Abc::Argument &iArg1 ) |
47 | 1 | { |
48 | 2 | ALEMBIC_ABC_SAFE_CALL_BEGIN( "IXformSchema::init()" ); |
49 | | |
50 | 2 | Abc::Arguments args; |
51 | 2 | iArg0.setInto( args ); |
52 | 2 | iArg1.setInto( args ); |
53 | | |
54 | 2 | AbcA::CompoundPropertyReaderPtr ptr = this->getPtr(); |
55 | | |
56 | 2 | if ( ptr->getPropertyHeader( ".childBnds" ) ) |
57 | 0 | { |
58 | 0 | m_childBoundsProperty = Abc::IBox3dProperty( ptr, ".childBnds", |
59 | 0 | iArg0, iArg1 ); |
60 | 0 | } |
61 | | |
62 | 2 | if ( ptr->getPropertyHeader( ".inherits" ) ) |
63 | 0 | { |
64 | 0 | m_inheritsProperty = Abc::IBoolProperty( ptr, ".inherits", |
65 | 0 | iArg0, iArg1 ); |
66 | 0 | } |
67 | | |
68 | 2 | m_useArrayProp = false; |
69 | | |
70 | 2 | const AbcA::PropertyHeader *valsPH = ptr->getPropertyHeader( ".vals" ); |
71 | 2 | if ( valsPH != NULL ) |
72 | 0 | { |
73 | 0 | if ( valsPH->isScalar() ) |
74 | 0 | { |
75 | 0 | m_valsProperty = ptr->getScalarProperty( valsPH->getName() ); |
76 | 0 | } |
77 | 0 | else |
78 | 0 | { |
79 | 0 | m_useArrayProp = true; |
80 | 0 | m_valsProperty = ptr->getArrayProperty( valsPH->getName() ); |
81 | 0 | } |
82 | 0 | } |
83 | | |
84 | 2 | m_isConstantIdentity = true; |
85 | | |
86 | 2 | if ( ptr->getPropertyHeader( "isNotConstantIdentity" ) ) |
87 | 0 | { |
88 | | // that it's here at all means we're not constant identity. |
89 | 0 | m_isConstantIdentity = false; |
90 | 0 | } |
91 | | |
92 | 2 | m_isConstant = true; |
93 | | |
94 | 2 | if ( m_valsProperty ) |
95 | 0 | { |
96 | |
|
97 | 0 | if ( m_useArrayProp ) |
98 | 0 | { m_isConstant = m_valsProperty->asArrayPtr()->isConstant(); } |
99 | 0 | else |
100 | 0 | { m_isConstant = m_valsProperty->asScalarPtr()->isConstant(); } |
101 | 0 | } |
102 | | |
103 | 2 | m_isConstant = m_isConstant && ( !m_inheritsProperty || |
104 | 1 | m_inheritsProperty.isConstant() ); |
105 | | |
106 | 2 | std::set < Alembic::Util::uint32_t > animChannels; |
107 | | |
108 | 2 | if ( ptr->getPropertyHeader( ".animChans" ) ) |
109 | 0 | { |
110 | 0 | Abc::IUInt32ArrayProperty p( ptr, ".animChans" ); |
111 | 0 | if ( p.getNumSamples() > 0 ) |
112 | 0 | { |
113 | 0 | Abc::UInt32ArraySamplePtr animSamp; |
114 | 0 | p.get( animSamp, p.getNumSamples() - 1 ); |
115 | 0 | for ( std::size_t i = 0; i < animSamp->size(); ++i ) |
116 | 0 | { |
117 | 0 | animChannels.insert( (*animSamp)[i] ); |
118 | 0 | } |
119 | 0 | } |
120 | 0 | } |
121 | | |
122 | 2 | AbcA::ScalarPropertyReaderPtr ops; |
123 | 2 | if ( ptr->getPropertyHeader( ".ops" ) != NULL ) |
124 | 0 | { |
125 | 0 | ops = ptr->getScalarProperty( ".ops" ); |
126 | 0 | } |
127 | | |
128 | 2 | if ( ops && ops->getNumSamples() > 0 ) |
129 | 0 | { |
130 | |
|
131 | 0 | std::size_t numOps = ops->getHeader().getDataType().getExtent(); |
132 | 0 | std::vector<Alembic::Util::uint8_t> opVec( numOps ); |
133 | 0 | ops->getSample( 0, &(opVec.front()) ); |
134 | |
|
135 | 0 | for ( std::size_t i = 0; i < numOps; ++i ) |
136 | 0 | { |
137 | 0 | XformOp op( opVec[i] ); |
138 | 0 | m_sample.addOp( op ); |
139 | 0 | } |
140 | |
|
141 | 0 | std::set < Alembic::Util::uint32_t >::iterator it, itEnd; |
142 | 0 | std::vector< XformOp >::iterator op = m_sample.m_ops.begin(); |
143 | 0 | std::vector< XformOp >::iterator opEnd = m_sample.m_ops.end(); |
144 | 0 | std::size_t curChan = 0; |
145 | 0 | std::size_t chanPos = 0; |
146 | |
|
147 | 0 | for ( it = animChannels.begin(), itEnd = animChannels.end(); |
148 | 0 | it != itEnd; ++it ) |
149 | 0 | { |
150 | 0 | Alembic::Util::uint32_t animChan = *it; |
151 | 0 | while ( op != opEnd ) |
152 | 0 | { |
153 | 0 | std::size_t numChans = op->getNumChannels(); |
154 | 0 | bool foundChan = false; |
155 | 0 | while ( curChan < numChans ) |
156 | 0 | { |
157 | 0 | if ( animChan == chanPos ) |
158 | 0 | { |
159 | 0 | op->m_animChannels.insert( curChan ); |
160 | 0 | foundChan = true; |
161 | 0 | break; |
162 | 0 | } |
163 | | |
164 | 0 | ++curChan; |
165 | 0 | ++chanPos; |
166 | 0 | } |
167 | | |
168 | | // move on to the next animChan, because we found the current one |
169 | 0 | if ( foundChan == true ) |
170 | 0 | { |
171 | 0 | ++curChan; |
172 | 0 | ++chanPos; |
173 | 0 | break; |
174 | 0 | } |
175 | | |
176 | 0 | ++op; |
177 | 0 | curChan = 0; |
178 | 0 | } |
179 | 0 | } |
180 | 0 | } |
181 | | |
182 | 2 | if ( ptr->getPropertyHeader( ".arbGeomParams" ) != NULL ) |
183 | 0 | { |
184 | 0 | m_arbGeomParams = Abc::ICompoundProperty( ptr, ".arbGeomParams", |
185 | 0 | args.getErrorHandlerPolicy() |
186 | 0 | ); |
187 | 0 | } |
188 | | |
189 | 2 | if ( ptr->getPropertyHeader( ".userProperties" ) != NULL ) |
190 | 0 | { |
191 | 0 | m_userProperties = Abc::ICompoundProperty( ptr, ".userProperties", |
192 | 0 | args.getErrorHandlerPolicy() |
193 | 0 | ); |
194 | 0 | } |
195 | 2 | ALEMBIC_ABC_SAFE_CALL_END_RESET(); |
196 | 1 | } |
197 | | |
198 | | //-***************************************************************************** |
199 | | AbcA::TimeSamplingPtr IXformSchema::getTimeSampling() const |
200 | 0 | { |
201 | 0 | ALEMBIC_ABC_SAFE_CALL_BEGIN( "IXformSchema::getTimeSampling()" ); |
202 | |
|
203 | 0 | if ( m_inheritsProperty ) |
204 | 0 | { |
205 | 0 | return m_inheritsProperty.getTimeSampling(); |
206 | 0 | } |
207 | 0 | else |
208 | 0 | { |
209 | 0 | return AbcA::TimeSamplingPtr( new AbcA::TimeSampling() ); |
210 | 0 | } |
211 | |
|
212 | 0 | ALEMBIC_ABC_SAFE_CALL_END(); |
213 | | |
214 | 0 | AbcA::TimeSamplingPtr ret; |
215 | 0 | return ret; |
216 | 0 | } |
217 | | |
218 | | //-***************************************************************************** |
219 | | std::size_t IXformSchema::getNumSamples() const |
220 | 1 | { |
221 | 2 | ALEMBIC_ABC_SAFE_CALL_BEGIN( "IXformSchema::getNumSamples()" ); |
222 | | |
223 | 2 | if ( m_inheritsProperty ) |
224 | 0 | { |
225 | 0 | return m_inheritsProperty.getNumSamples(); |
226 | 0 | } |
227 | 1 | else { return 0; } |
228 | | |
229 | 2 | ALEMBIC_ABC_SAFE_CALL_END(); |
230 | | |
231 | 0 | return 0; |
232 | 1 | } |
233 | | |
234 | | //-***************************************************************************** |
235 | | void IXformSchema::getChannelValues( const AbcA::index_t iSampleIndex, |
236 | | XformSample & oSamp ) const |
237 | 0 | { |
238 | 0 | std::vector<Alembic::Util::float64_t> dataVec; |
239 | |
|
240 | 0 | if ( m_useArrayProp ) |
241 | 0 | { |
242 | 0 | AbcA::ArraySamplePtr sptr; |
243 | 0 | m_valsProperty->asArrayPtr()->getSample( iSampleIndex, sptr ); |
244 | |
|
245 | 0 | dataVec.assign( |
246 | 0 | static_cast<const Alembic::Util::float64_t*>( sptr->getData() ), |
247 | 0 | static_cast<const Alembic::Util::float64_t*>( sptr->getData() ) + |
248 | 0 | sptr->size() ); |
249 | 0 | } |
250 | 0 | else |
251 | 0 | { |
252 | 0 | dataVec.resize( m_valsProperty->asScalarPtr()->getDataType().getExtent() ); |
253 | 0 | m_valsProperty->asScalarPtr()->getSample( iSampleIndex, &(dataVec.front()) ); |
254 | 0 | } |
255 | |
|
256 | 0 | std::vector< XformOp >::iterator op = oSamp.m_ops.begin(); |
257 | 0 | std::vector< XformOp >::iterator opEnd = oSamp.m_ops.end(); |
258 | 0 | std::size_t chanPos = 0; |
259 | 0 | while ( op != opEnd ) |
260 | 0 | { |
261 | 0 | for ( std::size_t j = 0; j < op->getNumChannels(); |
262 | 0 | ++j, ++chanPos ) |
263 | 0 | { |
264 | 0 | op->setChannelValue( j, dataVec[chanPos] ); |
265 | 0 | } |
266 | 0 | ++op; |
267 | 0 | } |
268 | 0 | } |
269 | | |
270 | | //-***************************************************************************** |
271 | | void IXformSchema::get( XformSample &oSamp, const Abc::ISampleSelector &iSS ) const |
272 | 0 | { |
273 | 0 | ALEMBIC_ABC_SAFE_CALL_BEGIN( "IXformSchema::get()" ); |
274 | |
|
275 | 0 | oSamp.reset(); |
276 | |
|
277 | 0 | if ( ! valid() ) { return; } |
278 | | |
279 | 0 | oSamp = m_sample; |
280 | |
|
281 | 0 | if ( m_inheritsProperty && m_inheritsProperty.getNumSamples() > 0 ) |
282 | 0 | { |
283 | 0 | oSamp.setInheritsXforms( m_inheritsProperty.getValue( iSS ) ); |
284 | 0 | } |
285 | |
|
286 | 0 | if ( ! m_valsProperty ) { return; } |
287 | | |
288 | 0 | AbcA::index_t numSamples = 0; |
289 | 0 | if ( m_useArrayProp ) |
290 | 0 | { |
291 | 0 | numSamples = m_valsProperty->asArrayPtr()->getNumSamples(); |
292 | 0 | } |
293 | 0 | else |
294 | 0 | { |
295 | 0 | numSamples = m_valsProperty->asScalarPtr()->getNumSamples(); |
296 | 0 | } |
297 | |
|
298 | 0 | if ( numSamples == 0 ) { return; } |
299 | | |
300 | 0 | AbcA::index_t sampIdx = iSS.getIndex( m_valsProperty->getTimeSampling(), |
301 | 0 | numSamples ); |
302 | |
|
303 | 0 | if ( sampIdx < 0 ) { return; } |
304 | | |
305 | 0 | this->getChannelValues( sampIdx, oSamp ); |
306 | |
|
307 | 0 | ALEMBIC_ABC_SAFE_CALL_END(); |
308 | 0 | } |
309 | | |
310 | | //-***************************************************************************** |
311 | | XformSample IXformSchema::getValue( const Abc::ISampleSelector &iSS ) const |
312 | 0 | { |
313 | 0 | XformSample ret; |
314 | 0 | this->get( ret, iSS ); |
315 | 0 | return ret; |
316 | 0 | } |
317 | | |
318 | | //-***************************************************************************** |
319 | | bool IXformSchema::getInheritsXforms( const Abc::ISampleSelector &iSS ) const |
320 | 0 | { |
321 | 0 | ALEMBIC_ABC_SAFE_CALL_BEGIN( "IXformSchema::getInheritsXforms()" ); |
322 | |
|
323 | 0 | if ( ! m_inheritsProperty || m_inheritsProperty.getNumSamples() == 0 ) |
324 | 0 | { |
325 | 0 | return true; |
326 | 0 | } |
327 | | |
328 | 0 | AbcA::index_t sampIdx = iSS.getIndex( m_inheritsProperty.getTimeSampling(), |
329 | 0 | m_inheritsProperty.getNumSamples() ); |
330 | |
|
331 | 0 | if ( sampIdx < 0 ) { return true; } |
332 | | |
333 | 0 | return m_inheritsProperty.getValue( sampIdx ); |
334 | |
|
335 | 0 | ALEMBIC_ABC_SAFE_CALL_END(); |
336 | | |
337 | 0 | return true; |
338 | 0 | } |
339 | | |
340 | | } // End namespace ALEMBIC_VERSION_NS |
341 | | } // End namespace AbcGeom |
342 | | } // End namespace Alembic |