1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2014,
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/All.h>
38 #include <Alembic/AbcCoreFactory/All.h>
39
40 #include <ImathBoxAlgo.h>
41
42 #include <iostream>
43
44 //-*****************************************************************************
45 using namespace ::Alembic::AbcGeom;
46
47 static Box3d g_bounds;
48
49 //-*****************************************************************************
accumXform(M44d & xf,IObject obj,chrono_t seconds)50 void accumXform( M44d &xf, IObject obj, chrono_t seconds )
51 {
52 if ( IXform::matches( obj.getHeader() ) )
53 {
54 IXform x( obj, kWrapExisting );
55 XformSample xs;
56 ISampleSelector sel( seconds );
57 x.getSchema().get( xs, sel );
58 xf *= xs.getMatrix();
59 }
60 }
61
62 //-*****************************************************************************
getFinalMatrix(IObject & iObj,chrono_t seconds)63 M44d getFinalMatrix( IObject &iObj, chrono_t seconds )
64 {
65 M44d xf;
66 xf.makeIdentity();
67
68 IObject parent = iObj.getParent();
69
70 while ( parent )
71 {
72 accumXform( xf, parent, seconds );
73 parent = parent.getParent();
74 }
75
76 return xf;
77 }
78
79 //-*****************************************************************************
getBounds(IObject iObj,chrono_t seconds)80 Box3d getBounds( IObject iObj, chrono_t seconds )
81 {
82 Box3d bnds;
83 bnds.makeEmpty();
84
85 M44d xf = getFinalMatrix( iObj, seconds );
86 IBox3dProperty boxProp;
87
88 if ( ICurves::matches( iObj.getMetaData() ) )
89 {
90 ICurves curves( iObj, kWrapExisting );
91 ICurvesSchema cs = curves.getSchema();
92 boxProp = cs.getSelfBoundsProperty();
93 }
94 else if ( INuPatch::matches( iObj.getMetaData() ) )
95 {
96 INuPatch patch( iObj, kWrapExisting );
97 INuPatchSchema ps = patch.getSchema();
98 boxProp = ps.getSelfBoundsProperty();
99 }
100 else if ( IPolyMesh::matches( iObj.getMetaData() ) )
101 {
102 IPolyMesh mesh( iObj, kWrapExisting );
103 IPolyMeshSchema ms = mesh.getSchema();
104 boxProp = ms.getSelfBoundsProperty();
105 }
106 else if ( IPoints::matches( iObj.getMetaData() ) )
107 {
108 IPoints pts( iObj, kWrapExisting );
109 IPointsSchema ps = pts.getSchema();
110 boxProp = ps.getSelfBoundsProperty();
111 }
112 else if ( ISubD::matches( iObj.getMetaData() ) )
113 {
114 ISubD mesh( iObj, kWrapExisting );
115 ISubDSchema ms = mesh.getSchema();
116 boxProp = ms.getSelfBoundsProperty();
117 }
118
119 if ( boxProp.valid() )
120 {
121 ISampleSelector sel( seconds );
122 bnds = boxProp.getValue( sel );
123 bnds = Imath::transform( bnds, xf );
124 g_bounds.extendBy( bnds );
125 }
126
127 g_bounds.extendBy( bnds );
128
129 return bnds;
130 }
131
132 //-*****************************************************************************
visitObject(IObject iObj,chrono_t seconds)133 void visitObject( IObject iObj, chrono_t seconds )
134 {
135 std::string path = iObj.getFullName();
136
137 const MetaData &md = iObj.getMetaData();
138
139 if ( ICurves::matches( md ) ||
140 INuPatch::matches( md ) ||
141 IPoints::matches( md ) ||
142 IPolyMesh::matches( md ) ||
143 ISubDSchema::matches( md ) )
144 {
145 Box3d bnds = getBounds( iObj, seconds );
146 std::cout << path << " " << bnds.min << " " << bnds.max << std::endl;
147 }
148
149 // now the child objects
150 for ( size_t i = 0 ; i < iObj.getNumChildren() ; i++ )
151 {
152 visitObject( IObject( iObj, iObj.getChildHeader( i ).getName() ),
153 seconds );
154 }
155 }
156
157 //-*****************************************************************************
158 //-*****************************************************************************
159 // DO IT.
160 //-*****************************************************************************
161 //-*****************************************************************************
main(int argc,char * argv[])162 int main( int argc, char *argv[] )
163 {
164 if ( argc != 2 && argc != 3 )
165 {
166 std::cerr << "USAGE: " << argv[0] << " <AlembicArchive.abc> <seconds>"
167 << std::endl;
168 exit( -1 );
169 }
170
171 chrono_t seconds = 0.0;
172 if ( argc == 3 )
173 {
174 seconds = atof(argv[2]);
175 }
176
177 // Scoped.
178 g_bounds.makeEmpty();
179 {
180 Alembic::AbcCoreFactory::IFactory factory;
181 factory.setPolicy(ErrorHandler::kQuietNoopPolicy);
182 IArchive archive = factory.getArchive( argv[1] );
183 visitObject( archive.getTop(), seconds );
184 }
185
186 std::cout << "/" << " " << g_bounds.min << " " << g_bounds.max << std::endl;
187
188 return 0;
189 }
190