//-***************************************************************************** void ProcessPoints( IPoints &points, ProcArgs &args ) { IPointsSchema &ps = points.getSchema(); TimeSamplingPtr ts = ps.getTimeSampling(); SampleTimeSet sampleTimes; //for now, punt on the changing point count case -- even for frame ranges //for which the point count isn't changing if ( ps.getIdsProperty().isConstant() ) { //grab only the current time sampleTimes.insert( args.frame / args.fps ); } else { 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 ); IPointsSchema::Sample sample = ps.getValue( sampleSelector ); ParamListBuilder paramListBuilder; paramListBuilder.add( "P", (RtPointer)sample.getPositions()->get() ); ICompoundProperty arbGeomParams = ps.getArbGeomParams(); AddArbitraryGeomParams( arbGeomParams, sampleSelector, paramListBuilder ); RiPointsV(sample.getPositions()->size(), paramListBuilder.n(), paramListBuilder.nms(), paramListBuilder.vals() ); } if ( multiSample ) { RiMotionEnd(); } }
int main(int argc, const char *argv[]) { RtPoint points[] = { { 0, 0, 0}, {-.5, .5, 0}, {.5, .5, 0} }; RtPoint points2[] = { { 0, 0, 0}, { 0, 1.0F, 0}, {1.33333F, -1.0F, 0}, {-1.33333F, -1.0F, 0} }; RtFloat color[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; RtFloat Cs1[] = {1, 1, 1}; RtFloat Cs2[] = {1, 1, 0}; RtFloat Cs3[] = {1, 0, 0}; RtBound bound = { -.5F, 0, 0, .5F, .5F, 0 }; RtInt renderer = 0; RtString myVal[2] = {"MyVal0", "MyVal1"}; RiOption("MyOption", "string MyVar", &myVal[0], RI_NULL); RiCPPControl("MyControl", "string MyVar2", &myVal[1], RI_NULL); switch(renderer) { case 1: RiBegin("|aqsis -progress"); break; case 2: RiBegin("|rndr -p"); break; default: RiBegin(RI_NULL); } /* RiMakeTexture("mytexture.tiff", "mytexture.tx", RI_PERIODIC, RI_PERIODIC, RiSincFilter, (RtFloat)3.0, (RtFloat)3.0, RI_NULL); */ /* Using gcc-4.0.1 I got a warning for Ri-functions that float is used instead of double due to prototype, * even if I pass explictely float. Due to a message in fr.comp.lang.c "Complexe avex fonction réelle" Jan 23, 2008 * this warning (gcc-4.2.3) is not issued in gcc-4.3.0 anymore, so I disabled the "Prototype conversion" option temporarily. */ RiPixelFilter(RiGaussianFilter, 3.0f, 3.0f), RiShutter(0.0F, 1.0F); RiClipping(0.5F, 20.0F); RiProjection(RI_PERSPECTIVE, RI_NULL); RiFrameBegin(1); RiDisplay("Polygon", RI_FRAMEBUFFER, RI_RGB, RI_NULL); RiTranslate(0.0F, 0.0F, 4.5F); RiLightSource("pointlight", RI_NULL); RiTranslate(0.0F, 0.0F, .5F); RiWorldBegin(); RiOrientation(RI_LH); RiSides(1); RiSurface("matte", RI_NULL); RiMotionBegin(3, 0.0F, 0.5F, 1.0F); RiColor(Cs1); RiColor(Cs2); RiColor(Cs3); RiMotionEnd(); RiMotionBegin(3, 0.0F, 0.5F, 1.0F); RiRotate(10.0F, 0.0F, 0.0F, 1.0F); RiRotate(20.0F, 0.0F, 0.0F, 1.0F); RiRotate(30.0F, 0.0F, 0.0F, 1.0F); RiMotionEnd(); RiDetail(bound); RiDetailRange(0.0F, 0.0F, 100.0F, 150.0F); RiPolygon(3, RI_P, points, RI_NULL); RiDetailRange(100.0F, 150.0F, RI_INFINITY, RI_INFINITY); RiPolygon(3, RI_P, points, RI_CS, color, RI_NULL); RiTransformPoints(RI_SCREEN, RI_RASTER, sizeof(points2)/sizeof(RtPoint), points2); RiWorldEnd(); RiFrameEnd(); RiEnd(); exit(0); return 0; }
//-***************************************************************************** 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 ProcessNuPatch( INuPatch &patch, ProcArgs &args ) { INuPatchSchema &ps = patch.getSchema(); TimeSamplingPtr ts = ps.getTimeSampling(); SampleTimeSet sampleTimes; GetRelevantSampleTimes( args, ts, ps.getNumSamples(), sampleTimes ); //trim curves are described outside the motion blocks if ( ps.hasTrimCurve() ) { //get the current time sample independent of any shutter values INuPatchSchema::Sample sample = ps.getValue( ISampleSelector( args.frame / args.fps ) ); RiTrimCurve( sample.getTrimNumCurves()->size(), //numloops (RtInt*) sample.getTrimNumCurves()->get(), (RtInt*) sample.getTrimOrders()->get(), (RtFloat*) sample.getTrimKnots()->get(), (RtFloat*) sample.getTrimMins()->get(), (RtFloat*) sample.getTrimMaxes()->get(), (RtInt*) sample.getTrimNumVertices()->get(), (RtFloat*) sample.getTrimU()->get(), (RtFloat*) sample.getTrimV()->get(), (RtFloat*) sample.getTrimW()->get() ); } bool multiSample = sampleTimes.size() > 1; if ( multiSample ) { WriteMotionBegin( args, sampleTimes ); } for ( SampleTimeSet::iterator iter = sampleTimes.begin(); iter != sampleTimes.end(); ++iter ) { ISampleSelector sampleSelector( *iter ); INuPatchSchema::Sample sample = ps.getValue( sampleSelector ); ParamListBuilder paramListBuilder; //build this here so that it's still in scope when RiNuPatchV is //called. std::vector<RtFloat> pwValues; if ( sample.getPositionWeights() ) { if ( sample.getPositionWeights()->size() == sample.getPositions()->size() ) { //need to combine P with weight form Pw pwValues.reserve( sample.getPositions()->size() * 4 ); const float32_t * pStart = reinterpret_cast<const float32_t * >( sample.getPositions()->get() ); const float32_t * wStart = reinterpret_cast<const float32_t * >( sample.getPositionWeights()->get() ); for ( size_t i = 0, e = sample.getPositionWeights()->size(); i < e; ++i ) { pwValues.push_back( pStart[i*3] ); pwValues.push_back( pStart[i*3+1] ); pwValues.push_back( pStart[i*3+2] ); pwValues.push_back( wStart[i] ); } paramListBuilder.add( "Pw", (RtPointer) &pwValues[0] ); } } if ( pwValues.empty() ) { //no Pw so go straight with P paramListBuilder.add( "P", (RtPointer)sample.getPositions()->get() ); } ICompoundProperty arbGeomParams = ps.getArbGeomParams(); AddArbitraryGeomParams( arbGeomParams, sampleSelector, paramListBuilder ); //For now, use the last knot value for umin and umax as it's //not described in the alembic data RiNuPatchV( sample.getNumU(), sample.getUOrder(), (RtFloat *) sample.getUKnot()->get(), 0.0, //umin sample.getUKnot()->get()[sample.getUKnot()->size()-1],//umax sample.getNumV(), sample.getVOrder(), (RtFloat *) sample.getVKnot()->get(), 0.0, //vmin sample.getVKnot()->get()[sample.getVKnot()->size()-1], //vmax 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 ProcessXform( IXform &xform, ProcArgs &args ) { IXformSchema &xs = xform.getSchema(); TimeSamplingPtr ts = xs.getTimeSampling(); size_t xformSamps = xs.getNumSamples(); SampleTimeSet sampleTimes; GetRelevantSampleTimes( args, ts, xformSamps, sampleTimes ); bool multiSample = sampleTimes.size() > 1; std::vector<XformSample> sampleVectors; sampleVectors.resize( sampleTimes.size() ); //fetch all operators at each sample time first size_t sampleTimeIndex = 0; for ( SampleTimeSet::iterator I = sampleTimes.begin(); I != sampleTimes.end(); ++I, ++sampleTimeIndex ) { ISampleSelector sampleSelector( *I ); xs.get( sampleVectors[sampleTimeIndex], sampleSelector ); } if (xs.getInheritsXforms () == false) { RiIdentity (); } //loop through the operators individually since a MotionBegin block //can enclose only homogenous statements for ( size_t i = 0, e = xs.getNumOps(); i < e; ++i ) { if ( multiSample ) { WriteMotionBegin(args, sampleTimes); } for ( size_t j = 0; j < sampleVectors.size(); ++j ) { XformOp &op = sampleVectors[j][i]; switch ( op.getType() ) { case kScaleOperation: { V3d value = op.getScale(); RiScale( value.x, value.y, value.z ); break; } case kTranslateOperation: { V3d value = op.getTranslate(); RiTranslate( value.x, value.y, value.z ); break; } case kRotateOperation: case kRotateXOperation: case kRotateYOperation: case kRotateZOperation: { V3d axis = op.getAxis(); float degrees = op.getAngle(); RiRotate( degrees, axis.x, axis.y, axis.z ); break; } case kMatrixOperation: { WriteConcatTransform( op.getMatrix() ); break; } } } if ( multiSample ) { RiMotionEnd(); } } }
void RFeather::generateRIB(RtFloat detail) { if(m_is_shd!=1) RiSides(2); else RiSides(1); RtToken paramname[MAX_NUMPARAM]; RtPointer paramvalue[MAX_NUMPARAM]; MATRIX44F hair_space; XYZ wind, pw, side; float length, curl, root_s, root_t, noil; int n_curve; FBend* fb = new FBend(); int num_hair = feather->getNumHair(); n_curve = num_hair; float delta = (m_shutter_close-m_shutter_open)*m_fps; if(m_is_shd!=1) { XYZ* parray = new XYZ[2*(NUMBENDSEG+1)]; XYZ* parray_close = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col0 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col1 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col2 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col3 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col4 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col5 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col6 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col7 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col8 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col9 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col10 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col11 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col12 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col13 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col14 = new XYZ[2*(NUMBENDSEG+1)]; XYZ* col15 = new XYZ[2*(NUMBENDSEG+1)]; int g_seed = 13; CoeRec root_rt; for(int i=0; i<num_hair; i++) { feather->getAParam(i, hair_space, length, wind, side, curl, root_s, root_t, root_rt); float noil = 1.f+(randfint( g_seed )-0.5)*0.13; g_seed++; length *= noil; fb->create(length, wind.x, wind.y+length*(curl*noil-0.5)*2); for(int j=0; j<NUMBENDSEG+1; j++) { fb->getPoint(j, pw); hair_space.transform(pw); parray[j*2] = pw - side*length*m_f_wh*0.5; parray[j*2+1] = pw + side * length*m_f_wh*0.5; } for(int j=0; j<4*NUMBENDSEG; j++) { roots[j]=root_s; roott[j] = 1.f-root_t; } paramname[0] = "P"; paramvalue[0] = (RtPoint*)parray; paramname[1] = "facevarying float s"; paramvalue[1] = (RtFloat*)scoord; paramname[2] = "facevarying float t"; paramvalue[2] = (RtFloat*)tcoord; paramname[3] = "facevarying float root_s"; paramvalue[3] = (RtFloat*)roots; paramname[4] = "facevarying float root_t"; paramvalue[4] = (RtFloat*)roott; for(int j=0; j<2*(NUMBENDSEG+1);j++) { col0[j] = root_rt.data[0]; col1[j] = root_rt.data[1]; col2[j] = root_rt.data[2]; col3[j] = root_rt.data[3]; col4[j] = root_rt.data[4]; col5[j] = root_rt.data[5]; col6[j] = root_rt.data[6]; col7[j] = root_rt.data[7]; col8[j] = root_rt.data[8]; col9[j] = root_rt.data[9]; col10[j] = root_rt.data[10]; col11[j] = root_rt.data[11]; col12[j] = root_rt.data[12]; col13[j] = root_rt.data[13]; col14[j] = root_rt.data[14]; col15[j] = root_rt.data[15]; } paramname[5] = "vertex color coeff0"; paramvalue[5] = (RtFloat*)col0; paramname[6] = "vertex color coeff1"; paramvalue[6] = (RtFloat*)col1; paramname[7] = "vertex color coeff2"; paramvalue[7] = (RtFloat*)col2; paramname[8] = "vertex color coeff3"; paramvalue[8] = (RtFloat*)col3; paramname[9] = "vertex color coeff4"; paramvalue[9] = (RtFloat*)col4; paramname[10] = "vertex color coeff5"; paramvalue[10] = (RtFloat*)col5; paramname[11] = "vertex color coeff6"; paramvalue[11] = (RtFloat*)col6; paramname[12] = "vertex color coeff7"; paramvalue[12] = (RtFloat*)col7; paramname[13] = "vertex color coeff8"; paramvalue[13] = (RtFloat*)col8; paramname[14] = "vertex color coeff9"; paramvalue[14] = (RtFloat*)col9; paramname[15] = "vertex color coeff10"; paramvalue[15] = (RtFloat*)col10; paramname[16] = "vertex color coeff11"; paramvalue[16] = (RtFloat*)col11; paramname[17] = "vertex color coeff12"; paramvalue[17] = (RtFloat*)col12; paramname[18] = "vertex color coeff13"; paramvalue[18] = (RtFloat*)col13; paramname[19] = "vertex color coeff14"; paramvalue[19] = (RtFloat*)col14; paramname[20] = "vertex color coeff15"; paramvalue[20] = (RtFloat*)col15; if(m_is_blur ==1 && feather_close) { RiMotionBegin(2, m_shutter_open, m_shutter_close); RiHierarchicalSubdivisionMeshV("catmull-clark", (RtInt)3, (RtInt*)nvertices, (RtInt*)vertices, (RtInt)2, tags, nargs, intargs, floatargs, stringargs, (RtInt)21, paramname, paramvalue ); feather_close->getAParam(i, hair_space, length, wind, side, curl, root_s, root_t); fb->create(length, wind.x, wind.y+length*(curl*noil-0.5)*2); for(int j=0; j<NUMBENDSEG+1; j++) { fb->getPoint(j, pw); hair_space.transform(pw); parray_close[j*2] = pw - side*length*m_f_wh*0.5; parray_close[j*2+1] = pw + side * length*m_f_wh*0.5; parray[j*2] += (parray_close[j*2] - parray[j*2])*delta; parray[j*2+1] += (parray_close[j*2+1] - parray[j*2+1])*delta; } paramvalue[0] = (RtPoint*)parray; RiHierarchicalSubdivisionMeshV("catmull-clark", (RtInt)3, (RtInt*)nvertices, (RtInt*)vertices, (RtInt)2, tags, nargs, intargs, floatargs, stringargs, (RtInt)21, paramname, paramvalue ); RiMotionEnd(); } else RiHierarchicalSubdivisionMeshV("catmull-clark", (RtInt)3, (RtInt*)nvertices, (RtInt*)vertices, (RtInt)2, tags, nargs, intargs, floatargs, stringargs, (RtInt)21, paramname, paramvalue ); } delete[] parray; delete[] parray_close; delete[] col0; delete[] col1; delete[] col2; delete[] col3; delete[] col4; delete[] col5; delete[] col6; delete[] col7; delete[] col8; delete[] col9; delete[] col10; delete[] col11; delete[] col12; delete[] col13; delete[] col14; delete[] col15; } else { XYZ* parray = new XYZ[2*(NUMBENDSEG+1)]; int g_seed = 13; for(int i=0; i<num_hair; i++) { feather->getAParam(i, hair_space, length, wind, side, curl, root_s, root_t); float noil = 1.f+(randfint( g_seed )-0.5)*0.13; g_seed++; length *= noil; fb->create(length, wind.x, wind.y+length*(curl*noil-0.5)*2); for(int j=0; j<NUMBENDSEG+1; j++) { fb->getPoint(j, pw); hair_space.transform(pw); parray[j*2] = pw - side*length*m_f_wh*0.5; parray[j*2+1] = pw + side * length*m_f_wh*0.5; } for(int j=0; j<4*NUMBENDSEG; j++) { roots[j]=root_s; roott[j] = 1.f-root_t; } paramname[0] = "P"; paramvalue[0] = (RtPoint*)parray; paramname[1] = "facevarying float s"; paramvalue[1] = (RtFloat*)scoord; paramname[2] = "facevarying float t"; paramvalue[2] = (RtFloat*)tcoord; paramname[3] = "facevarying float root_s"; paramvalue[3] = (RtFloat*)roots; paramname[4] = "facevarying float root_t"; paramvalue[4] = (RtFloat*)roott; RiHierarchicalSubdivisionMeshV("catmull-clark", (RtInt)3, (RtInt*)nvertices, (RtInt*)vertices, (RtInt)2, tags, nargs, intargs, floatargs, stringargs, (RtInt)5, paramname, paramvalue ); } delete[] parray; } return; }