//-***************************************************************************** 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 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 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(); }