//-***************************************************************************** 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 MeshDrwHelper::update( V3fArraySamplePtr iP, V3fArraySamplePtr iN ) { // Check validity. if ( !m_valid || !iP || !m_meshP || ( iP->size() != m_meshP->size() ) ) { makeInvalid(); return; } // Set meshP m_meshP = iP; computeBounds(); updateNormals( iN ); }
void readV3fArrayProperty(const std::string &archiveName) { // Open an existing archive for reading. Indicate that we want // Alembic to throw exceptions on errors. std::cout << "Reading " << archiveName << std::endl; IArchive archive( Alembic::AbcCoreHDF5::ReadArchive(), archiveName, ErrorHandler::kThrowPolicy ); IObject archiveTop = archive.getTop(); // Determine the number of (top level) children the archive has const unsigned int numChildren = archiveTop.getNumChildren(); ABCA_ASSERT( numChildren == 1, "Wrong number of children (expected 1)"); std::cout << "The archive has " << numChildren << " children:" << std::endl; // Iterate through them, print out their names IObject child( archiveTop, archiveTop.getChildHeader(0).getName() ); std::cout << " named '" << child.getName() << "'"; // Properties ICompoundProperty props = child.getProperties(); size_t numProperties = props.getNumProperties(); // only top-level props ABCA_ASSERT( numProperties == 1, "Expected 1 property, found " << numProperties); std::cout << " with one property"; std::vector<std::string> propNames(1); propNames[0] = props.getPropertyHeader(0).getName(); std::cout << " named '" << propNames[0] << "'" << std::endl; PropertyType pType = props.getPropertyHeader(0).getPropertyType(); ABCA_ASSERT( pType == kArrayProperty, "Expected an array property, but didn't find one" ); std::cout << " which is an array property"; DataType dType = props.getPropertyHeader(0).getDataType(); ABCA_ASSERT( dType.getPod() == kFloat32POD, "Expected an v3f property, but didn't find one" ); // We know this is an array property (I'm eliding the if/else // statements required to recognize and handle this properly) IV3fArrayProperty positions( props, propNames[0] ); size_t numSamples = positions.getNumSamples(); std::cout << ".. it has " << numSamples << " samples" << std::endl; ABCA_ASSERT( numSamples == 5, "Expected 5 samples, found " << numSamples ); const TimeSampling ts = positions.getTimeSampling(); std::cout << "..with time/value pairs: " << std::endl;; for (int ss=0; ss<numSamples; ss++) { std::cout << " "; ISampleSelector iss( (index_t) ss); std::cout << ts.getSampleTime( (index_t) ss ) << " / "; V3fArraySamplePtr samplePtr; positions.get( samplePtr, iss ); std::cout << "[ "; size_t numPoints = samplePtr->size(); for ( size_t jj=0 ; jj<numPoints ; jj++ ) std::cout << (*samplePtr)[jj] << " "; std::cout << "]" << std::endl; if (ss == 2) // no entries in sample #2 { ABCA_ASSERT( numPoints == 0, "Expected an empty sample, but found " << numPoints << " entries." ); } else { for ( size_t jj=0 ; jj<numPoints ; jj++ ) ABCA_ASSERT( (*samplePtr)[jj] == g_vectors[jj], "Incorrect value read from archive." ); } } std::cout << std::endl; // Done - the archive closes itself }
//-***************************************************************************** void MeshDrwHelper::update( V3fArraySamplePtr iP, V3fArraySamplePtr iN, Int32ArraySamplePtr iIndices, Int32ArraySamplePtr iCounts ) { // Before doing a ton, just have a quick look. if ( m_meshP && iP && ( m_meshP->size() == iP->size() ) && m_meshIndices && ( m_meshIndices == iIndices ) && m_meshCounts && ( m_meshCounts == iCounts ) ) { if ( m_meshP == iP ) { updateNormals( iN ); } else { update( iP, iN ); } return; } // Okay, if we're here, the indices are not equal or the counts // are not equal or the P-array size changed. // So we can clobber those three, but leave N alone for now. m_meshP = iP; m_meshIndices = iIndices; m_meshCounts = iCounts; // Check stuff. if ( !m_meshP || !m_meshIndices || !m_meshCounts ) { std::cerr << "Mesh update quitting because no input data" << std::endl; makeInvalid(); return; } // Get the number of each thing. size_t numFaces = m_meshCounts->size(); size_t numIndices = m_meshIndices->size(); size_t numPoints = m_meshP->size(); if ( numFaces < 1 || numIndices < 1 || numPoints < 1 ) { // Invalid. std::cerr << "Mesh update quitting because bad arrays" << ", numFaces = " << numFaces << ", numIndices = " << numIndices << ", numPoints = " << numPoints << std::endl; makeInvalid(); return; } // Make triangles. size_t faceIndexBegin = 0; size_t faceIndexEnd = 0; for ( size_t face = 0; face < numFaces; ++face ) { faceIndexBegin = faceIndexEnd; size_t count = (*m_meshCounts)[face]; faceIndexEnd = faceIndexBegin + count; // Check this face is valid if ( faceIndexEnd > numIndices || faceIndexEnd < faceIndexBegin ) { std::cerr << "Mesh update quitting on face: " << face << " because of wonky numbers" << ", faceIndexBegin = " << faceIndexBegin << ", faceIndexEnd = " << faceIndexEnd << ", numIndices = " << numIndices << ", count = " << count << std::endl; // Just get out, make no more triangles. break; } // Checking indices are valid. bool goodFace = true; for ( size_t fidx = faceIndexBegin; fidx < faceIndexEnd; ++fidx ) { if ( (*m_meshIndices)[fidx] >= numPoints ) { std::cout << "Mesh update quitting on face: " << face << " because of bad indices" << ", indexIndex = " << fidx << ", vertexIndex = " << (*m_meshIndices)[fidx] << ", numPoints = " << numPoints << std::endl; goodFace = false; break; } } // Make triangles to fill this face. if ( goodFace && count > 2 ) { m_triangles.push_back( Tri( ( unsigned int )(*m_meshIndices)[faceIndexBegin+0], ( unsigned int )(*m_meshIndices)[faceIndexBegin+1], ( unsigned int )(*m_meshIndices)[faceIndexBegin+2] ) ); for ( size_t c = 3; c < count; ++c ) { m_triangles.push_back( Tri( ( unsigned int )(*m_meshIndices)[faceIndexBegin+0], ( unsigned int )(*m_meshIndices)[faceIndexBegin+c-1], ( unsigned int )(*m_meshIndices)[faceIndexBegin+c] ) ); } } } // Cool, we made triangles. // Pretend the mesh is made... m_valid = true; // And now update just the P and N, which will update bounds // and calculate new normals if necessary. computeBounds(); updateNormals( iN ); // And that's it. }