//-***************************************************************************** void meshUnderXformOut( const std::string &iName ) { OArchive archive( Alembic::AbcCoreHDF5::WriteArchive(), iName ); TimeSamplingPtr ts( new TimeSampling( 1.0 / 24.0, 0.0 ) ); OXform xfobj( archive.getTop(), "xf", ts ); OPolyMesh meshobj( xfobj, "mesh", ts ); OPolyMeshSchema::Sample mesh_samp( V3fArraySample( ( const V3f * )g_verts, g_numVerts ), Int32ArraySample( g_indices, g_numIndices ), Int32ArraySample( g_counts, g_numCounts ) ); XformSample xf_samp; XformOp rotOp( kRotateYOperation ); Box3d childBounds; childBounds.makeEmpty(); childBounds.extendBy( V3d( 1.0, 1.0, 1.0 ) ); childBounds.extendBy( V3d( -1.0, -1.0, -1.0 ) ); xf_samp.setChildBounds( childBounds ); double rotation = 0.0; for ( std::size_t i = 0 ; i < 100 ; ++i ) { xf_samp.addOp( rotOp, rotation ); xfobj.getSchema().set( xf_samp ); meshobj.getSchema().set( mesh_samp ); rotation += 30.0; } }
Imath::Box3d AlembicInput::boundAtTime( double time ) const { if( hasStoredBound() ) { size_t index0, index1; double lerpFactor = sampleIntervalAtTime( time, index0, index1 ); if( index0 == index1 ) { return boundAtSample( index0 ); } else { Box3d bound0 = boundAtSample( index0 ); Box3d bound1 = boundAtSample( index1 ); Box3d result; result.min = lerp( bound0.min, bound1.min, lerpFactor ); result.max = lerp( bound0.max, bound1.max, lerpFactor ); return result; } } else { Box3d result; for( size_t i=0, n=numChildren(); i<n; i++ ) { AlembicInputPtr c = child( i ); Box3d childBound = c->boundAtTime( time ); childBound = Imath::transform( childBound, c->transformAtTime( time ) ); result.extendBy( childBound ); } return result; } }
//-***************************************************************************** //-***************************************************************************** // WRITING OUT AN ANIMATED MESH // // Here we'll create an "Archive", which is Alembic's term for the actual // file on disk containing all of the scene geometry. The Archive will contain // a single animated Transform with a single static PolyMesh as its child. //-***************************************************************************** //-***************************************************************************** void Example1_MeshOut() { // Create an OArchive. // Like std::iostreams, we have a completely separate-but-parallel class // hierarchy for output and for input (OArchive, IArchive, and so on). This // maintains the important abstraction that Alembic is for storage, // representation, and archival. (as opposed to being a dynamic scene // manipulation framework). OArchive archive( // The hard link to the implementation. Alembic::AbcCoreHDF5::WriteArchive(), // The file name. // Because we're an OArchive, this is creating (or clobbering) // the archive with this filename. "polyMesh1.abc" ); // Create a PolyMesh class. OPolyMesh meshyObj( OObject( archive, kTop ), "meshy" ); OPolyMeshSchema &mesh = meshyObj.getSchema(); // UVs and Normals use GeomParams, which can be written or read // as indexed or not, as you'd like. OV2fGeomParam::Sample uvsamp( V2fArraySample( (const V2f *)g_uvs, g_numUVs ), kFacevaryingScope ); // indexed normals ON3fGeomParam::Sample nsamp( N3fArraySample( (const N3f *)g_normals, g_numNormals ), kFacevaryingScope ); // Set a mesh sample. // We're creating the sample inline here, // but we could create a static sample and leave it around, // only modifying the parts that have changed. OPolyMeshSchema::Sample mesh_samp( V3fArraySample( ( const V3f * )g_verts, g_numVerts ), Int32ArraySample( g_indices, g_numIndices ), Int32ArraySample( g_counts, g_numCounts ), uvsamp, nsamp ); // not actually the right data; just making it up Box3d cbox; cbox.extendBy( V3d( 1.0, -1.0, 0.0 ) ); cbox.extendBy( V3d( -1.0, 1.0, 3.0 ) ); mesh_samp.setChildBounds( cbox ); // Set the sample twice mesh.set( mesh_samp ); mesh.set( mesh_samp ); // Alembic objects close themselves automatically when they go out // of scope. So - we don't have to do anything to finish // them off! std::cout << "Writing: " << archive.getName() << std::endl; }
//-***************************************************************************** Box3d getBounds( IObject iObj ) { Box3d bnds; bnds.makeEmpty(); M44d xf = getFinalMatrix( iObj ); if ( IPolyMesh::matches( iObj.getMetaData() ) ) { IPolyMesh mesh( iObj, kWrapExisting ); IPolyMeshSchema ms = mesh.getSchema(); V3fArraySamplePtr positions = ms.getValue().getPositions(); size_t numPoints = positions->size(); for ( size_t i = 0 ; i < numPoints ; ++i ) { bnds.extendBy( (*positions)[i] ); } } else if ( ISubD::matches( iObj.getMetaData() ) ) { ISubD mesh( iObj, kWrapExisting ); ISubDSchema ms = mesh.getSchema(); V3fArraySamplePtr positions = ms.getValue().getPositions(); size_t numPoints = positions->size(); for ( size_t i = 0 ; i < numPoints ; ++i ) { bnds.extendBy( (*positions)[i] ); } } bnds.extendBy( Imath::transform( bnds, xf ) ); g_bounds.extendBy( bnds ); return bnds; }
void worldToVoxel(const Field3D::FieldMapping* mapping, const Box3d &wsBounds, Box3d &vsBounds) { V3d test1, test2; mapping->worldToVoxel(test1, test2); //! \todo Make this integrate over time V3d wsVerts[] = { V3d(wsBounds.min.x, wsBounds.min.y, wsBounds.min.z), V3d(wsBounds.max.x, wsBounds.min.y, wsBounds.min.z), V3d(wsBounds.min.x, wsBounds.max.y, wsBounds.min.z), V3d(wsBounds.max.x, wsBounds.max.y, wsBounds.min.z), V3d(wsBounds.min.x, wsBounds.min.y, wsBounds.max.z), V3d(wsBounds.max.x, wsBounds.min.y, wsBounds.max.z), V3d(wsBounds.min.x, wsBounds.max.y, wsBounds.max.z), V3d(wsBounds.max.x, wsBounds.max.y, wsBounds.max.z) }; vsBounds.makeEmpty(); V3d vsP; for (int i = 0; i < 8; i++) { mapping->worldToVoxel(wsVerts[i], vsP); vsBounds.extendBy(vsP); } }