//-***************************************************************************** void ProcessCurves( ICurves &curves, ProcArgs &args ) { ICurvesSchema &cs = curves.getSchema(); TimeSamplingPtr ts = cs.getTimeSampling(); SampleTimeSet sampleTimes; GetRelevantSampleTimes( args, ts, cs.getNumSamples(), sampleTimes ); bool multiSample = sampleTimes.size() > 1; bool firstSample = true; for ( SampleTimeSet::iterator iter = sampleTimes.begin(); iter != sampleTimes.end(); ++iter ) { ISampleSelector sampleSelector( *iter ); ICurvesSchema::Sample sample = cs.getValue( sampleSelector ); //need to set the basis prior to the MotionBegin block if ( firstSample ) { firstSample = false; BasisType basisType = sample.getBasis(); if ( basisType != kNoBasis ) { RtBasis * basis = NULL; RtInt step = 0; switch ( basisType ) { case kBezierBasis: basis = &RiBezierBasis; step = RI_BEZIERSTEP; break; case kBsplineBasis: basis = &RiBSplineBasis; step = RI_BSPLINESTEP; break; case kCatmullromBasis: basis = &RiCatmullRomBasis; step = RI_CATMULLROMSTEP; break; case kHermiteBasis: basis = &RiHermiteBasis; step = RI_HERMITESTEP; break; case kPowerBasis: basis = &RiPowerBasis; step = RI_POWERSTEP; break; default: break; } if ( basis != NULL ) { RiBasis( *basis, step, *basis, step); } } if ( multiSample ) { WriteMotionBegin( args, sampleTimes ); } } ParamListBuilder paramListBuilder; paramListBuilder.add( "P", (RtPointer)sample.getPositions()->get() ); IFloatGeomParam widthParam = cs.getWidthsParam(); if ( widthParam.valid() ) { ICompoundProperty parent = widthParam.getParent(); //prman requires "width" to be named "constantwidth" when //constant instead of declared as "constant float width". //It's even got an error message specifically for it. std::string widthName; if ( widthParam.getScope() == kConstantScope || widthParam.getScope() == kUnknownScope ) { widthName = "constantwidth"; } else { widthName = "width"; } AddGeomParamToParamListBuilder<IFloatGeomParam>( parent, widthParam.getHeader(), sampleSelector, "float", paramListBuilder, 1, widthName); } IN3fGeomParam nParam = cs.getNormalsParam(); if ( nParam.valid() ) { ICompoundProperty parent = nParam.getParent(); AddGeomParamToParamListBuilder<IN3fGeomParam>( parent, nParam.getHeader(), sampleSelector, "normal", paramListBuilder); } IV2fGeomParam uvParam = cs.getUVsParam(); if ( uvParam.valid() ) { ICompoundProperty parent = uvParam.getParent(); AddGeomParamToParamListBuilder<IV2fGeomParam>( parent, uvParam.getHeader(), sampleSelector, "float", paramListBuilder, 2, "st"); } ICompoundProperty arbGeomParams = cs.getArbGeomParams(); AddArbitraryGeomParams( arbGeomParams, sampleSelector, paramListBuilder ); RtToken curveType; switch ( sample.getType() ) { case kCubic: curveType = const_cast<RtToken>( "cubic" ); break; default: curveType = const_cast<RtToken>( "linear" ); } RtToken wrap; switch ( sample.getWrap() ) { case kPeriodic: wrap = const_cast<RtToken>( "periodic" ); break; default: wrap = const_cast<RtToken>( "nonperiodic" ); } RiCurvesV(curveType, sample.getNumCurves(), (RtInt*) sample.getCurvesNumVertices()->get(), wrap, paramListBuilder.n(), paramListBuilder.nms(), paramListBuilder.vals() ); } if ( multiSample ) { RiMotionEnd(); } }
//-***************************************************************************** void ProcessSubD( ISubD &subd, ProcArgs &args, const std::string & facesetName ) { ISubDSchema &ss = subd.getSchema(); TimeSamplingPtr ts = ss.getTimeSampling(); SampleTimeSet sampleTimes; GetRelevantSampleTimes( args, ts, ss.getNumSamples(), sampleTimes ); bool multiSample = sampleTimes.size() > 1; //include this code path for future expansion bool isHierarchicalSubD = false; bool hasLocalResources = false; std::vector<IFaceSet> faceSets; std::vector<std::string> faceSetResourceNames; if ( facesetName.empty() ) { std::vector <std::string> childFaceSetNames; ss.getFaceSetNames(childFaceSetNames); faceSets.reserve(childFaceSetNames.size()); faceSetResourceNames.reserve(childFaceSetNames.size()); for (size_t i = 0; i < childFaceSetNames.size(); ++i) { faceSets.push_back(ss.getFaceSet(childFaceSetNames[i])); IFaceSet & faceSet = faceSets.back(); std::string resourceName = args.getResource( faceSet.getFullName() ); if ( resourceName.empty() ) { resourceName = args.getResource( faceSet.getName() ); } #ifdef PRMAN_USE_ABCMATERIAL Mat::MaterialFlatten mafla(faceSet); if (!mafla.empty()) { if (!hasLocalResources) { RiResourceBegin(); hasLocalResources = true; } RiAttributeBegin(); if ( !resourceName.empty() ) { //restore existing resource state here RestoreResource( resourceName ); } WriteMaterial( mafla, args ); resourceName = faceSet.getFullName(); SaveResource( resourceName ); RiAttributeEnd(); } #endif faceSetResourceNames.push_back(resourceName); } } #ifdef PRMAN_USE_ABCMATERIAL else { //handle single faceset material directly if ( ss.hasFaceSet( facesetName ) ) { IFaceSet faceSet = ss.getFaceSet( facesetName ); ApplyObjectMaterial(faceSet, args); } } #endif if ( multiSample ) { WriteMotionBegin( args, sampleTimes ); } for ( SampleTimeSet::iterator iter = sampleTimes.begin(); iter != sampleTimes.end(); ++iter ) { ISampleSelector sampleSelector( *iter ); ISubDSchema::Sample sample = ss.getValue( sampleSelector ); RtInt npolys = (RtInt) sample.getFaceCounts()->size(); ParamListBuilder paramListBuilder; paramListBuilder.add( "P", (RtPointer)sample.getPositions()->get() ); IV2fGeomParam uvParam = ss.getUVsParam(); if ( uvParam.valid() ) { ICompoundProperty parent = uvParam.getParent(); if ( !args.flipv ) { AddGeomParamToParamListBuilder<IV2fGeomParam>( parent, uvParam.getHeader(), sampleSelector, "float", paramListBuilder, 2, "st"); } else if ( std::vector<float> * values = AddGeomParamToParamListBuilderAsFloat<IV2fGeomParam, float>( parent, uvParam.getHeader(), sampleSelector, "float", paramListBuilder, "st") ) { for ( size_t i = 1, e = values->size(); i < e; i += 2 ) { (*values)[i] = 1.0 - (*values)[i]; } } } ICompoundProperty arbGeomParams = ss.getArbGeomParams(); AddArbitraryGeomParams( arbGeomParams, sampleSelector, paramListBuilder ); std::string subdScheme = sample.getSubdivisionScheme(); SubDTagBuilder tags; ProcessFacevaryingInterpolateBoundry( tags, sample ); ProcessInterpolateBoundry( tags, sample ); ProcessFacevaryingPropagateCorners( tags, sample ); ProcessHoles( tags, sample ); ProcessCreases( tags, sample ); ProcessCorners( tags, sample ); if ( !facesetName.empty() ) { if ( ss.hasFaceSet( facesetName ) ) { IFaceSet faceSet = ss.getFaceSet( facesetName ); ApplyResources( faceSet, args ); // TODO, move the hold test outside of MotionBegin // as it's not meaningful to change per sample IFaceSetSchema::Sample faceSetSample = faceSet.getSchema().getValue( sampleSelector ); std::set<int> facesToKeep; facesToKeep.insert( faceSetSample.getFaces()->get(), faceSetSample.getFaces()->get() + faceSetSample.getFaces()->size() ); for ( int i = 0; i < npolys; ++i ) { if ( facesToKeep.find( i ) == facesToKeep.end() ) { tags.add( "hole" ); tags.addIntArg( i ); } } } } else { //loop through the facesets and determine whether there are any //resources assigned to each for (size_t i = 0; i < faceSetResourceNames.size(); ++i) { const std::string & resourceName = faceSetResourceNames[i]; //TODO, visibility? if ( !resourceName.empty() ) { IFaceSet & faceSet = faceSets[i]; isHierarchicalSubD = true; tags.add("faceedit"); Int32ArraySamplePtr faces = faceSet.getSchema().getValue( sampleSelector ).getFaces(); for (size_t j = 0, e = faces->size(); j < e; ++j) { tags.addIntArg(1); //yep, every face gets a 1 in front of it too tags.addIntArg( (int) faces->get()[j]); } tags.addStringArg( "attributes" ); tags.addStringArg( resourceName ); tags.addStringArg( "shading" ); } } } if ( isHierarchicalSubD ) { RiHierarchicalSubdivisionMeshV( const_cast<RtToken>( subdScheme.c_str() ), npolys, (RtInt*) sample.getFaceCounts()->get(), (RtInt*) sample.getFaceIndices()->get(), tags.nt(), tags.tags(), tags.nargs( true ), tags.intargs(), tags.floatargs(), tags.stringargs(), paramListBuilder.n(), paramListBuilder.nms(), paramListBuilder.vals() ); } else { RiSubdivisionMeshV( const_cast<RtToken>(subdScheme.c_str() ), npolys, (RtInt*) sample.getFaceCounts()->get(), (RtInt*) sample.getFaceIndices()->get(), tags.nt(), tags.tags(), tags.nargs( false ), tags.intargs(), tags.floatargs(), paramListBuilder.n(), paramListBuilder.nms(), paramListBuilder.vals() ); } } if ( multiSample ) { RiMotionEnd(); } if ( hasLocalResources ) { RiResourceEnd(); } }
//-***************************************************************************** void ProcessPolyMesh( IPolyMesh &polymesh, ProcArgs &args ) { IPolyMeshSchema &ps = polymesh.getSchema(); TimeSamplingPtr ts = ps.getTimeSampling(); SampleTimeSet sampleTimes; GetRelevantSampleTimes( args, ts, ps.getNumSamples(), sampleTimes ); bool multiSample = sampleTimes.size() > 1; if ( multiSample ) { WriteMotionBegin( args, sampleTimes ); } for ( SampleTimeSet::iterator iter = sampleTimes.begin(); iter != sampleTimes.end(); ++ iter ) { ISampleSelector sampleSelector( *iter ); IPolyMeshSchema::Sample sample = ps.getValue( sampleSelector ); RtInt npolys = (RtInt) sample.getFaceCounts()->size(); ParamListBuilder paramListBuilder; paramListBuilder.add( "P", (RtPointer)sample.getPositions()->get() ); IV2fGeomParam uvParam = ps.getUVsParam(); if ( uvParam.valid() ) { ICompoundProperty parent = uvParam.getParent(); if ( !args.flipv ) { AddGeomParamToParamListBuilder<IV2fGeomParam>( parent, uvParam.getHeader(), sampleSelector, "float", paramListBuilder, 2, "st"); } else if ( std::vector<float> * values = AddGeomParamToParamListBuilderAsFloat<IV2fGeomParam, float>( parent, uvParam.getHeader(), sampleSelector, "float", paramListBuilder, "st") ) { for ( size_t i = 1, e = values->size(); i < e; i += 2 ) { (*values)[i] = 1.0 - (*values)[i]; } } } IN3fGeomParam nParam = ps.getNormalsParam(); if ( nParam.valid() ) { ICompoundProperty parent = nParam.getParent(); AddGeomParamToParamListBuilder<IN3fGeomParam>( parent, nParam.getHeader(), sampleSelector, "normal", paramListBuilder); } ICompoundProperty arbGeomParams = ps.getArbGeomParams(); AddArbitraryGeomParams( arbGeomParams, sampleSelector, paramListBuilder ); RiPointsPolygonsV( npolys, (RtInt*) sample.getFaceCounts()->get(), (RtInt*) sample.getFaceIndices()->get(), paramListBuilder.n(), paramListBuilder.nms(), paramListBuilder.vals() ); } if (multiSample) RiMotionEnd(); }
//-***************************************************************************** void Example1_MeshIn() { IArchive archive( Alembic::AbcCoreHDF5::ReadArchive(), "subD1.abc" ); std::cout << "Reading: " << archive.getName() << std::endl; IGeomBaseObject geomBase( IObject( archive, kTop ), "subd" ); TESTING_ASSERT( geomBase.getSchema().getSelfBoundsProperty().valid() ); ISubD meshyObj( IObject( archive, kTop ), "subd", ErrorHandler::kNoisyNoopPolicy ); ISubDSchema &mesh = meshyObj.getSchema(); TESTING_ASSERT( mesh.getErrorHandlerPolicy() == ErrorHandler::kNoisyNoopPolicy ); TESTING_ASSERT( mesh.getUVsParam().getValueProperty().getErrorHandlerPolicy() == ErrorHandler::kNoisyNoopPolicy ); TESTING_ASSERT( mesh.getInterpolateBoundaryProperty().getErrorHandlerPolicy() == ErrorHandler::kNoisyNoopPolicy ); TESTING_ASSERT( 3 == mesh.getNumSamples() ); // UVs IV2fGeomParam uv = mesh.getUVsParam(); TESTING_ASSERT( ! uv.isIndexed() ); // we can fake like the UVs are indexed IV2fGeomParam::Sample uvsamp = uv.getIndexedValue(); TESTING_ASSERT( (*(uvsamp.getIndices()))[1] == 1 ); V2f uv2 = (*(uvsamp.getVals()))[2]; TESTING_ASSERT( uv2 == V2f( 1.0f, 1.0f ) ); std::cout << "2th UV: " << uv2 << std::endl; // get the 1th sample by value ISubDSchema::Sample samp1 = mesh.getValue( 1 ); IGeomBase::Sample baseSamp = geomBase.getSchema().getValue( 1 ); std::cout << "bounds: " << samp1.getSelfBounds().min << ", " << samp1.getSelfBounds().max << std::endl; TESTING_ASSERT( samp1.getSelfBounds().min == V3d( -1.0, -1.0, -1.0 ) ); TESTING_ASSERT( samp1.getSelfBounds().max == V3d( 1.0, 1.0, 1.0 ) ); TESTING_ASSERT( baseSamp.getSelfBounds().min == V3d( -1.0, -1.0, -1.0 ) ); TESTING_ASSERT( baseSamp.getSelfBounds().max == V3d( 1.0, 1.0, 1.0 ) ); for ( size_t i = 0 ; i < samp1.getCreaseSharpnesses()->size() ; ++i ) { std::cout << "crease sharpness[" << i << "]: " << (*(samp1.getCreaseSharpnesses()))[i] << std::endl; TESTING_ASSERT( 0.5 == (*(samp1.getCreaseSharpnesses()))[i] ); } for ( size_t i = 0 ; i < samp1.getCornerSharpnesses()->size() ; ++i ) { std::cout << "corner sharpness[" << i << "]: " << (*(samp1.getCornerSharpnesses()))[i] << std::endl; TESTING_ASSERT( 10.0 == (*(samp1.getCornerSharpnesses()))[i] ); } for ( size_t i = 0 ; i < samp1.getVelocities()->size() ; ++i ) { V3f veloc( g_veloc[i*3], g_veloc[i*3+1], g_veloc[i*3+2] ); std::cout << "velocities[" << i << "]: " << (*(samp1.getVelocities()))[i] << std::endl; TESTING_ASSERT( veloc == (*(samp1.getVelocities()))[i] ); } // test the second sample has '1' as the interpolate boundary value TESTING_ASSERT( 1 == samp1.getInterpolateBoundary() ); std::cout << "Interpolate boundary at 1th sample: " << samp1.getInterpolateBoundary() << std::endl; // get the twoth sample by reference ISubDSchema::Sample samp2; mesh.get( samp2, 2 ); TESTING_ASSERT( samp2.getSelfBounds().min == V3d( -1.0, -1.0, -1.0 ) ); TESTING_ASSERT( samp2.getSelfBounds().max == V3d( 1.0, 1.0, 1.0 ) ); TESTING_ASSERT( 0 == samp2.getInterpolateBoundary() ); std::cout << "Interpolate boundary at 2th sample: " << samp2.getInterpolateBoundary() << std::endl; std::cout << "Mesh num vertices: " << samp2.getPositions()->size() << std::endl; std::cout << "0th vertex from the mesh sample: " << (*(samp2.getPositions()))[0] << std::endl; std::cout << "0th vertex from the mesh sample with get method: " << samp2.getPositions()->get()[0] << std::endl; ICompoundProperty arbattrs = mesh.getArbGeomParams(); // This better exist since we wrote custom attr called color to it TESTING_ASSERT( arbattrs ); for (int i = 0; i < 2; ++ i) { PropertyHeader p = arbattrs.getPropertyHeader(i); TESTING_ASSERT( IC3fGeomParam::matches( p ) ); TESTING_ASSERT( OC3fGeomParam::matches( p ) ); TESTING_ASSERT( ! IC3cGeomParam::matches( p ) ); TESTING_ASSERT( ! OC3cGeomParam::matches( p ) ); TESTING_ASSERT( ! IInt32GeomParam::matches( p ) ); TESTING_ASSERT( ! IFloatGeomParam::matches( p ) ); TESTING_ASSERT( ! IDoubleGeomParam::matches( p ) ); TESTING_ASSERT( ! IV3iGeomParam::matches( p ) ); TESTING_ASSERT( ! IV3fGeomParam::matches( p ) ); if ( p.getName() == "color" ) { IC3fGeomParam color(arbattrs, "color"); TESTING_ASSERT( color.getValueProperty().isScalarLike() ); IC3fGeomParam::Sample cSamp0, cSamp1; color.getExpanded(cSamp0, 0); color.getExpanded(cSamp1, 1); TESTING_ASSERT( (*(cSamp0.getVals()))[0] == C3f( 1.0, 0.0, 0.0 ) ); TESTING_ASSERT( (*(cSamp1.getVals()))[0] == C3f( 1.0, 0.0, 1.0 ) ); } else if ( p.getName() == "colori" ) { IC3fGeomParam color(arbattrs, "colori"); TESTING_ASSERT( !color.getValueProperty().isScalarLike() ); IC3fGeomParam::Sample cSamp; color.getIndexed( cSamp ); TESTING_ASSERT( cSamp.getScope() == kFacevaryingScope ); TESTING_ASSERT( cSamp.getVals()->size() == 3 ); TESTING_ASSERT( (*cSamp.getVals())[0] == C3f( 0.0, 1.0, 1.0 ) ); TESTING_ASSERT( (*cSamp.getVals())[1] == C3f( 1.0, 0.0, 1.0 ) ); TESTING_ASSERT( (*cSamp.getVals())[2] == C3f( 1.0, 1.0, 0.0 ) ); Alembic::Util::uint32_t indices[24] = { 2, 2, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 2, 2, 1, 1}; for (int j = 0; j < 24; ++j) { TESTING_ASSERT( (*cSamp.getIndices())[j] == indices[j] ); } } } }
//-***************************************************************************** // a recursive function that reads all inputs and write to the given oObject // node if there's no gap in the frame range for animated nodes // void visitObjects(std::vector< IObject > & iObjects, OObject & oParentObj) { OObject outObj; const AbcA::ObjectHeader & header = iObjects[0].getHeader(); // there are a number of things that needs to be checked for each node // to make sure they can be properly stitched together // // for xform node: // locator or normal xform node // if an xform node, numOps and type of ops match // static or no, and if not, timesampling type matches // if sampled, timesampling type should match // if sampled, no frame gaps // if (IXform::matches(header)) { OXformSchema oSchema; init< IXform, IXformSchema, OXform, OXformSchema >(iObjects, oParentObj, oSchema); outObj = oSchema.getObject(); ICompoundPropertyVec iCompoundProps; iCompoundProps.reserve(iObjects.size()); ICompoundProperty cp = iObjects[0].getProperties(); iCompoundProps.push_back(cp); bool isLocator = cp.getPropertyHeader("locator")?true:false; for (size_t i = 1; i < iObjects.size(); i++) { ICompoundProperty cp = iObjects[i].getProperties(); iCompoundProps.push_back(cp); } // stitch the operations if this is an xform node for (size_t i = 0; i < iObjects.size(); i++) { IXformSchema iSchema = IXform(iObjects[i], Alembic::Abc::kWrapExisting).getSchema(); index_t numSamples = iSchema.getNumSamples(); index_t reqIdx = getIndexSample(oSchema.getNumSamples(), oSchema.getTimeSampling(), numSamples, iSchema.getTimeSampling()); for (; reqIdx < numSamples; reqIdx++) { XformSample samp = iSchema.getValue(reqIdx); oSchema.set(samp); } } // stitch "locator" if it's a locator OCompoundProperty oCompoundProp = outObj.getProperties(); if (isLocator) { const PropertyHeader * propHeaderPtr = iCompoundProps[0].getPropertyHeader("locator"); stitchScalarProp(*propHeaderPtr, iCompoundProps, oCompoundProp); } } else if (ISubD::matches(header)) { OSubDSchema oSchema; init< ISubD, ISubDSchema, OSubD, OSubDSchema >(iObjects, oParentObj, oSchema); outObj = oSchema.getObject(); // stitch the SubDSchema // for (size_t i = 0; i < iObjects.size(); i++) { ISubDSchema iSchema = ISubD(iObjects[i], Alembic::Abc::kWrapExisting).getSchema(); index_t numSamples = iSchema.getNumSamples(); IV2fGeomParam uvs = iSchema.getUVsParam(); if (i == 0 && uvs) { oSchema.setUVSourceName(GetSourceName(uvs.getMetaData())); } index_t reqIdx = getIndexSample(oSchema.getNumSamples(), oSchema.getTimeSampling(), numSamples, iSchema.getTimeSampling()); for (; reqIdx < numSamples; reqIdx++) { ISubDSchema::Sample iSamp = iSchema.getValue(reqIdx); OSubDSchema::Sample oSamp; Abc::P3fArraySamplePtr posPtr = iSamp.getPositions(); if (posPtr) oSamp.setPositions(*posPtr); Abc::V3fArraySamplePtr velocPtr = iSamp.getVelocities(); if (velocPtr) oSamp.setVelocities(*velocPtr); Abc::Int32ArraySamplePtr faceIndicesPtr = iSamp.getFaceIndices(); if (faceIndicesPtr) oSamp.setFaceIndices(*faceIndicesPtr); Abc::Int32ArraySamplePtr faceCntPtr = iSamp.getFaceCounts(); if (faceCntPtr) oSamp.setFaceCounts(*faceCntPtr); oSamp.setFaceVaryingInterpolateBoundary(iSamp.getFaceVaryingInterpolateBoundary()); oSamp.setFaceVaryingPropagateCorners(iSamp.getFaceVaryingPropagateCorners()); oSamp.setInterpolateBoundary(iSamp.getInterpolateBoundary()); Abc::Int32ArraySamplePtr creaseIndicesPtr = iSamp.getCreaseIndices(); if (creaseIndicesPtr) oSamp.setCreaseIndices(*creaseIndicesPtr); Abc::Int32ArraySamplePtr creaseLenPtr = iSamp.getCreaseLengths(); if (creaseLenPtr) oSamp.setCreaseLengths(*creaseLenPtr); Abc::FloatArraySamplePtr creaseSpPtr = iSamp.getCreaseSharpnesses(); if (creaseSpPtr) oSamp.setCreaseSharpnesses(*creaseSpPtr); Abc::Int32ArraySamplePtr cornerIndicesPtr = iSamp.getCornerIndices(); if (cornerIndicesPtr) oSamp.setCornerIndices(*cornerIndicesPtr); Abc::FloatArraySamplePtr cornerSpPtr = iSamp.getCornerSharpnesses(); if (cornerSpPtr) oSamp.setCreaseSharpnesses(*cornerSpPtr); Abc::Int32ArraySamplePtr holePtr = iSamp.getHoles(); if (holePtr) oSamp.setHoles(*holePtr); oSamp.setSubdivisionScheme(iSamp.getSubdivisionScheme()); // set uvs IV2fGeomParam::Sample iUVSample; OV2fGeomParam::Sample oUVSample; if (uvs) { getOGeomParamSamp <IV2fGeomParam, IV2fGeomParam::Sample, OV2fGeomParam::Sample>(uvs, iUVSample, oUVSample, reqIdx); oSamp.setUVs(oUVSample); } oSchema.set(oSamp); } } } else if (IPolyMesh::matches(header)) { OPolyMeshSchema oSchema; init< IPolyMesh, IPolyMeshSchema, OPolyMesh, OPolyMeshSchema >(iObjects, oParentObj, oSchema); outObj = oSchema.getObject(); // stitch the PolySchema // for (size_t i = 0; i < iObjects.size(); i++) { IPolyMeshSchema iSchema = IPolyMesh(iObjects[i], Alembic::Abc::kWrapExisting).getSchema(); index_t numSamples = iSchema.getNumSamples(); IN3fGeomParam normals = iSchema.getNormalsParam(); IV2fGeomParam uvs = iSchema.getUVsParam(); if (i == 0 && uvs) { oSchema.setUVSourceName(GetSourceName(uvs.getMetaData())); } index_t reqIdx = getIndexSample(oSchema.getNumSamples(), oSchema.getTimeSampling(), numSamples, iSchema.getTimeSampling()); for (; reqIdx < numSamples; reqIdx++) { IPolyMeshSchema::Sample iSamp = iSchema.getValue(reqIdx); OPolyMeshSchema::Sample oSamp; Abc::P3fArraySamplePtr posPtr = iSamp.getPositions(); if (posPtr) oSamp.setPositions(*posPtr); Abc::V3fArraySamplePtr velocPtr = iSamp.getVelocities(); if (velocPtr) oSamp.setVelocities(*velocPtr); Abc::Int32ArraySamplePtr faceIndicesPtr = iSamp.getFaceIndices(); if (faceIndicesPtr) oSamp.setFaceIndices(*faceIndicesPtr); Abc::Int32ArraySamplePtr faceCntPtr = iSamp.getFaceCounts(); if (faceCntPtr) oSamp.setFaceCounts(*faceCntPtr); // set uvs IV2fGeomParam::Sample iUVSample; OV2fGeomParam::Sample oUVSample; if (uvs) { getOGeomParamSamp <IV2fGeomParam, IV2fGeomParam::Sample, OV2fGeomParam::Sample>(uvs, iUVSample, oUVSample, reqIdx); oSamp.setUVs(oUVSample); } // set normals IN3fGeomParam::Sample iNormalsSample; ON3fGeomParam::Sample oNormalsSample; if (normals) { getOGeomParamSamp <IN3fGeomParam, IN3fGeomParam::Sample, ON3fGeomParam::Sample>(normals, iNormalsSample, oNormalsSample, reqIdx); oSamp.setNormals(oNormalsSample); } oSchema.set(oSamp); } } } else if (ICamera::matches(header)) { OCameraSchema oSchema; init< ICamera, ICameraSchema, OCamera, OCameraSchema >(iObjects, oParentObj, oSchema); outObj = oSchema.getObject(); // stitch the CameraSchemas // for (size_t i = 0; i < iObjects.size(); i++) { ICameraSchema iSchema = ICamera(iObjects[i], Alembic::Abc::kWrapExisting).getSchema(); index_t numSamples = iSchema.getNumSamples(); index_t reqIdx = getIndexSample(oSchema.getNumSamples(), oSchema.getTimeSampling(), numSamples, iSchema.getTimeSampling()); for (; reqIdx < numSamples; reqIdx++) { oSchema.set(iSchema.getValue(reqIdx)); } } } else if (ICurves::matches(header)) { OCurvesSchema oSchema; init< ICurves, ICurvesSchema, OCurves, OCurvesSchema >(iObjects, oParentObj, oSchema); outObj = oSchema.getObject(); // stitch the CurvesSchemas // for (size_t i = 0; i < iObjects.size(); i++) { ICurvesSchema iSchema = ICurves(iObjects[i], Alembic::Abc::kWrapExisting).getSchema(); IV2fGeomParam iUVs = iSchema.getUVsParam(); IN3fGeomParam iNormals = iSchema.getNormalsParam(); IFloatGeomParam iWidths = iSchema.getWidthsParam(); IFloatArrayProperty iKnots = iSchema.getKnotsProperty(); IUcharArrayProperty iOrders = iSchema.getOrdersProperty(); index_t numSamples = iSchema.getNumSamples(); index_t reqIdx = getIndexSample(oSchema.getNumSamples(), oSchema.getTimeSampling(), numSamples, iSchema.getTimeSampling()); for (; reqIdx < numSamples; reqIdx++) { ICurvesSchema::Sample iSamp = iSchema.getValue(reqIdx); OCurvesSchema::Sample oSamp; Abc::P3fArraySamplePtr posPtr = iSamp.getPositions(); if (posPtr) oSamp.setPositions(*posPtr); Abc::V3fArraySamplePtr velocPtr = iSamp.getVelocities(); if (velocPtr) oSamp.setVelocities(*velocPtr); oSamp.setType(iSamp.getType()); Abc::Int32ArraySamplePtr curvsNumPtr = iSamp.getCurvesNumVertices(); if (curvsNumPtr) oSamp.setCurvesNumVertices(*curvsNumPtr); oSamp.setWrap(iSamp.getWrap()); oSamp.setBasis(iSamp.getBasis()); Abc::FloatArraySamplePtr knotsPtr = iSamp.getKnots(); if (knotsPtr) { oSamp.setKnots(*knotsPtr); } Abc::UcharArraySamplePtr ordersPtr = iSamp.getOrders(); if (ordersPtr) { oSamp.setOrders(*ordersPtr); } IFloatGeomParam::Sample iWidthSample; OFloatGeomParam::Sample oWidthSample; if (iWidths) { getOGeomParamSamp <IFloatGeomParam, IFloatGeomParam::Sample, OFloatGeomParam::Sample>(iWidths, iWidthSample, oWidthSample, reqIdx); oSamp.setWidths(oWidthSample); } IV2fGeomParam::Sample iUVSample; OV2fGeomParam::Sample oUVSample; if (iUVs) { getOGeomParamSamp <IV2fGeomParam, IV2fGeomParam::Sample, OV2fGeomParam::Sample>(iUVs, iUVSample, oUVSample, reqIdx); oSamp.setUVs(oUVSample); } IN3fGeomParam::Sample iNormalsSample; ON3fGeomParam::Sample oNormalsSample; if (iNormals) { getOGeomParamSamp <IN3fGeomParam, IN3fGeomParam::Sample, ON3fGeomParam::Sample>(iNormals, iNormalsSample, oNormalsSample, reqIdx); oSamp.setNormals(oNormalsSample); } oSchema.set(oSamp); } } } else if (IPoints::matches(header)) { OPointsSchema oSchema; init< IPoints, IPointsSchema, OPoints, OPointsSchema >(iObjects, oParentObj, oSchema); outObj = oSchema.getObject(); // stitch the PointsSchemas // for (size_t i = 0; i < iObjects.size(); i++) { IPointsSchema iSchema = IPoints(iObjects[i], Alembic::Abc::kWrapExisting).getSchema(); IFloatGeomParam iWidths = iSchema.getWidthsParam(); index_t numSamples = iSchema.getNumSamples(); index_t reqIdx = getIndexSample(oSchema.getNumSamples(), oSchema.getTimeSampling(), numSamples, iSchema.getTimeSampling()); for (; reqIdx < numSamples; reqIdx++) { IPointsSchema::Sample iSamp = iSchema.getValue(reqIdx); OPointsSchema::Sample oSamp; Abc::P3fArraySamplePtr posPtr = iSamp.getPositions(); if (posPtr) oSamp.setPositions(*posPtr); Abc::UInt64ArraySamplePtr idPtr = iSamp.getIds(); if (idPtr) oSamp.setIds(*idPtr); Abc::V3fArraySamplePtr velocPtr = iSamp.getVelocities(); if (velocPtr) oSamp.setVelocities(*velocPtr); IFloatGeomParam::Sample iWidthSample; OFloatGeomParam::Sample oWidthSample; if (iWidths) { getOGeomParamSamp <IFloatGeomParam, IFloatGeomParam::Sample, OFloatGeomParam::Sample>(iWidths, iWidthSample, oWidthSample, reqIdx); oSamp.setWidths(oWidthSample); } oSchema.set(oSamp); } } } else if (INuPatch::matches(header)) { ONuPatchSchema oSchema; init< INuPatch, INuPatchSchema, ONuPatch, ONuPatchSchema >(iObjects, oParentObj, oSchema); outObj = oSchema.getObject(); // stitch the NuPatchSchemas // for (size_t i = 0; i < iObjects.size(); i++) { INuPatchSchema iSchema = INuPatch(iObjects[i], Alembic::Abc::kWrapExisting).getSchema(); index_t numSamples = iSchema.getNumSamples(); IN3fGeomParam normals = iSchema.getNormalsParam(); IV2fGeomParam uvs = iSchema.getUVsParam(); index_t reqIdx = getIndexSample(oSchema.getNumSamples(), oSchema.getTimeSampling(), numSamples, iSchema.getTimeSampling()); for (; reqIdx < numSamples; reqIdx++) { INuPatchSchema::Sample iSamp = iSchema.getValue(reqIdx); ONuPatchSchema::Sample oSamp; Abc::P3fArraySamplePtr posPtr = iSamp.getPositions(); if (posPtr) oSamp.setPositions(*posPtr); Abc::V3fArraySamplePtr velocPtr = iSamp.getVelocities(); if (velocPtr) oSamp.setVelocities(*velocPtr); oSamp.setNu(iSamp.getNumU()); oSamp.setNv(iSamp.getNumV()); oSamp.setUOrder(iSamp.getUOrder()); oSamp.setVOrder(iSamp.getVOrder()); Abc::FloatArraySamplePtr uKnotsPtr = iSamp.getUKnot(); if (uKnotsPtr) oSamp.setUKnot(*uKnotsPtr); Abc::FloatArraySamplePtr vKnotsPtr = iSamp.getVKnot(); if (vKnotsPtr) oSamp.setVKnot(*vKnotsPtr); IV2fGeomParam::Sample iUVSample; OV2fGeomParam::Sample oUVSample; if (uvs) { getOGeomParamSamp <IV2fGeomParam, IV2fGeomParam::Sample, OV2fGeomParam::Sample>(uvs, iUVSample, oUVSample, reqIdx); oSamp.setUVs(oUVSample); } IN3fGeomParam::Sample iNormalsSample; ON3fGeomParam::Sample oNormalsSample; if (normals) { getOGeomParamSamp <IN3fGeomParam, IN3fGeomParam::Sample, ON3fGeomParam::Sample>(normals, iNormalsSample, oNormalsSample, reqIdx); oSamp.setNormals(oNormalsSample); } if (iSchema.hasTrimCurve()) { oSamp.setTrimCurve(iSamp.getTrimNumLoops(), *(iSamp.getTrimNumCurves()), *(iSamp.getTrimNumVertices()), *(iSamp.getTrimOrders()), *(iSamp.getTrimKnots()), *(iSamp.getTrimMins()), *(iSamp.getTrimMaxes()), *(iSamp.getTrimU()), *(iSamp.getTrimV()), *(iSamp.getTrimW())); } oSchema.set(oSamp); } } } else { outObj = OObject(oParentObj, header.getName(), header.getMetaData()); // collect the top level compound property ICompoundPropertyVec iCompoundProps(iObjects.size()); for (size_t i = 0; i < iObjects.size(); i++) { iCompoundProps[i] = iObjects[i].getProperties(); } OCompoundProperty oCompoundProperty = outObj.getProperties(); stitchCompoundProp(iCompoundProps, oCompoundProperty); } // After done writing THIS OObject node, if input nodes have children, // go deeper. // Otherwise we are done here size_t numChildren = iObjects[0].getNumChildren(); // check to make sure all of our iObjects have the same number of children for (size_t j = 1; j < iObjects.size(); j++) { if (numChildren != iObjects[j].getNumChildren()) { std::cerr << "ERROR: " << iObjects[j].getFullName() << " in " << iObjects[j].getArchive().getName() << " has a different number of children than " << iObjects[0].getFullName() << " in " << iObjects[0].getArchive().getName() << std::endl; exit(1); } } for (size_t i = 0 ; i < numChildren; i++ ) { std::vector< IObject > iChildObjects; for (size_t f = 0; f < iObjects.size(); f++) { iChildObjects.push_back(iObjects[f].getChild(i)); } visitObjects(iChildObjects, outObj); } }
//-***************************************************************************** void Example1_MeshIn() { IArchive archive( Alembic::AbcCoreHDF5::ReadArchive(), "polyMesh1.abc" ); std::cout << "Reading: " << archive.getName() << std::endl; IGeomBaseObject geomBase( IObject( archive, kTop ), "meshy" ); TESTING_ASSERT( geomBase.getSchema().getSelfBoundsProperty().valid() ); IPolyMesh meshyObj( IObject( archive, kTop ), "meshy" ); IPolyMeshSchema &mesh = meshyObj.getSchema(); IN3fGeomParam N = mesh.getNormalsParam(); IV2fGeomParam uv = mesh.getUVsParam(); TESTING_ASSERT( ! N.isIndexed() ); TESTING_ASSERT( ! uv.isIndexed() ); IPolyMeshSchema::Sample mesh_samp; mesh.get( mesh_samp ); IGeomBase::Sample baseSamp; geomBase.getSchema().get( baseSamp ); TESTING_ASSERT( mesh_samp.getSelfBounds().min == V3d( -1.0, -1.0, -1.0 ) ); TESTING_ASSERT( mesh_samp.getSelfBounds().max == V3d( 1.0, 1.0, 1.0 ) ); TESTING_ASSERT( baseSamp.getSelfBounds().min == V3d( -1.0, -1.0, -1.0 ) ); TESTING_ASSERT( baseSamp.getSelfBounds().max == V3d( 1.0, 1.0, 1.0 ) ); ICompoundProperty arbattrs = mesh.getArbGeomParams(); // we didn't set any on write, so on read, it should be an invalid container TESTING_ASSERT( ! arbattrs ); // getExpandedValue() takes an optional ISampleSelector; // getVals() returns a TypedArraySamplePtr N3fArraySamplePtr nsp = N.getExpandedValue().getVals(); TESTING_ASSERT( N.isConstant() ); TESTING_ASSERT( uv.isConstant() ); TESTING_ASSERT( IsGeomParam( N.getMetaData() ) ); N3f n0 = (*nsp)[0]; for ( size_t i = 0 ; i < nsp->size() ; ++i ) { std::cout << i << "th normal: " << (*nsp)[i] << std::endl; } TESTING_ASSERT( n0 == N3f( -1.0f, 0.0f, 0.0f ) ); std::cout << "0th normal: " << n0 << std::endl; IV2fGeomParam::Sample uvsamp = uv.getIndexedValue(); TESTING_ASSERT( (*(uvsamp.getIndices()))[1] == 1 ); V2f uv2 = (*(uvsamp.getVals()))[2]; TESTING_ASSERT( uv2 == V2f( 1.0f, 1.0f ) ); std::cout << "2th UV: " << uv2 << std::endl; std::cout << "Mesh num vertices: " << mesh_samp.getPositions()->size() << std::endl; std::cout << "0th vertex from the mesh sample: " << (*(mesh_samp.getPositions()))[0] << std::endl; std::cout << "0th vertex from the mesh sample with get method: " << mesh_samp.getPositions()->get()[0] << std::endl; }