int main() { std::ostringstream output; // Test setting of options. const char* outputType = "Ascii"; RiOption((char*)"RI2RIB_Output", "Type", &outputType, "OStream", &output, RI_NULL); int indentSize = 2; const char* indentType = "Space"; RiOption((char*)"RI2RIB_Indentation", "Size", &indentSize, "Type", &indentType, RI_NULL); RtPointer badHandle = RtPointer(0xDEADBEEF); // Create RIB RiBegin(0); RiFrameBegin(0); RiBasis(RiCatmullRomBasis, 2, RiHermiteBasis, 3); RiFrameEnd(); RiArchiveRecord((char*)"comment", (char*)" Note that we expect a bad handle error " "regarding %p somewhere here!", badHandle); RiFrameBegin(1); RiDisplay((char*)"blah.tif", (char*)"framebuffer", (char*)"rgb", RI_NULL); RiBasis(RiBezierBasis, 3, RiCatmullRomBasis, 1); RiPixelFilter(RiGaussianFilter, 2, 2); RiProjection((char*)"perspective", RI_NULL); RiTranslate(0,0,5); RiWorldBegin(); RtLightHandle h = RiLightSource((char*)"pointlight", RI_NULL); RiIlluminate(h, RI_FALSE); RiIlluminate(badHandle, RI_TRUE); // Invalid handle! float Cs[] = {1,0,0, 0,1,0, 0,0,1, 2,2,2}; RiSphere(1, -1, 1, 360, "Cs", Cs, RI_NULL); float blah[] = {42}; RiSphere(2, -2, 2, 360, "float blah", blah, RI_NULL); int nvertices[] = {5}; float P[] = {-1,-1,0, 1,-1,0, 1,1,0, -1,1,0, -1,-1,2}; float width[] = {1, 2, 3}; RiCurves((char*)"cubic", 1, nvertices, (char*)"nonperiodic", "P", P, "width", width, RI_NULL); RiWorldEnd(); RiFrameEnd(); RiEnd(); // Stream the output buffer to stdout std::cout << output.str(); 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(); } }
MStatus ribGenCmd::doIt( const MArgList& args) { /*=========================================* * the parameters of command * =========================================*/ MString ribPath, shaderPath; unsigned index; index = args.flagIndex("p", "ribPath"); if(MArgList::kInvalidArgIndex != index) args.get(index+1, ribPath); index = args.flagIndex("sp", "shaderPath"); if(MArgList::kInvalidArgIndex != index) args.get(index+1, shaderPath); /*=========================================* * shaderPath & ribPath *=========================================*/ RtToken shader= new char[50] , path=new char[50]; strcpy(shader, shaderPath.asChar()); strcpy(path, ribPath.asChar()); char *curve[] = {"curves"}; RtMatrix identityMatrix = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }}; RtInt ustep, vstep; ustep = vstep =1; /*=====================================* * Begenning of writting out the .rib file. *=====================================*/ RiBegin(path); RiAttributeBegin(); RiTransformBegin(); //RiSurface(shader); RiTransformEnd(); //RiAttribute("identifier", "name", curve); RiConcatTransform(identityMatrix); RiShadingInterpolation(RI_SMOOTH); RiBasis(RiBezierBasis, ustep, RiBezierBasis, vstep); int nodeId = 0, knotNum = 0; float baseWidth = 0.0f, tipWidth = 0.0f; MObject surface, node; /*=========================================* * get the informations of selected Objects in scene. *=========================================*/ MSelectionList selection; MGlobal::getActiveSelectionList(selection); MItSelectionList iter(selection, MFn::kNurbsSurface ); for(; !iter.isDone(); iter.next()) { RtInt numCurves = 0; RtInt numVertexs = 0; /*======================================* * get the drawHairNode from selected NurbsSurface. *======================================*/ iter.getDependNode(surface); MFnDependencyNode surfaceFn(surface); MStatus state; MPlug plug = surfaceFn.findPlug("worldSpace",false, &state); plug = plug.elementByLogicalIndex(0); MPlugArray desPlugs; plug.connectedTo(desPlugs,false,true); plug = desPlugs[0]; node = plug.node(); //drawHairNode has found here!! /*=====================================* * get the attributes of drawHairNode. *=====================================*/ MFnDependencyNode hairNodeFn(node); plug = hairNodeFn.findPlug("nodeId"); plug.getValue(nodeId); MGlobal::displayInfo(MString(" nodeId: ")+nodeId); plug = hairNodeFn.findPlug("number"); plug.getValue(numCurves); plug= hairNodeFn.findPlug("smooth"); plug.getValue(knotNum); plug = hairNodeFn.findPlug("baseWidth"); plug.getValue(baseWidth); plug = hairNodeFn.findPlug("tipWidth"); plug.getValue(tipWidth); /*=====================================* * caculate the linear interpolate of the width of the curve. *=====================================*/ numVertexs = numCurves * knotNum; int widthNum = numCurves * (knotNum -2 ); float *curveWidth = new float[widthNum]; float widthStep = 0.0f; for(int c=0; c<widthNum; ++c){ widthStep = ((c%(knotNum-2)) / (float)(knotNum-3)) *(tipWidth - baseWidth); if(widthStep < epslion) widthStep = 0.0f; curveWidth[c] = baseWidth + widthStep; } RtInt *nvertices = new RtInt[numCurves]; //the numbers of vertices on each curve. RtPoint *vertexs = new RtPoint[numVertexs]; //the total vertexs. /*=====================================* * nvertices[] assignment. *=====================================*/ for(int j=0; j<numCurves ; ++j){ nvertices[j] = knotNum; } /*=====================================* * get the hair's datas from the static member * named "nodeManager" of the drawHairNode class. *=====================================*/ nodeMap::iterator iter = drawHairNode::nodeManager.find(nodeId); vector<MPointArray> helixVec = iter->second; /*=====================================* * vertexs[] assignment. *=====================================*/ float x=0, y=0, z=0; int countVT=0; for(vector<MPointArray>::iterator it=helixVec.begin(); it != helixVec.end(); ++it){ MPointArray helixCurve = (MPointArray)(*it); for(int k=0; k < helixCurve.length() ; ++k){ x = helixCurve[k].x; if(fabs(x) < epslion) vertexs[countVT][0] = 0; else vertexs[countVT][0] = helixCurve[k].x; y = helixCurve[k].y; if(fabs(y) < epslion) vertexs[countVT][1] = 0; else vertexs[countVT][1] = helixCurve[k].y; z = helixCurve[k].z; if(fabs(z) < epslion) vertexs[countVT++][2] = 0; else vertexs[countVT++][2] = helixCurve[k].z; } } RiCurves( RI_CUBIC, numCurves, nvertices, RI_NONPERIODIC, RI_P, vertexs, RI_WIDTH, curveWidth, RI_NULL); } RiAttributeEnd(); RiEnd(); return redoIt(); }
void liqWriteArchive::writeObjectToRib(const MDagPath &objDagPath, bool writeTransform) { if (!isObjectVisible(objDagPath)) { return; } if (debug) { cout << "liquidWriteArchive: writing object: " << objDagPath.fullPathName().asChar() << endl; } if (objDagPath.node().hasFn(MFn::kShape) || MFnDagNode( objDagPath ).typeName() == "liquidCoorSys") { // we're looking at a shape node, so write out the geometry to the RIB outputObjectName(objDagPath); liqRibNode ribNode; ribNode.set(objDagPath, 0, MRT_Unknown); // don't write out clipping planes if ( ribNode.object(0)->type == MRT_ClipPlane ) return; if ( ribNode.rib.box != "" && ribNode.rib.box != "-" ) { RiArchiveRecord( RI_COMMENT, "Additional RIB:\n%s", ribNode.rib.box.asChar() ); } if ( ribNode.rib.readArchive != "" && ribNode.rib.readArchive != "-" ) { // the following test prevents a really nasty infinite loop !! if ( ribNode.rib.readArchive != outputFilename ) RiArchiveRecord( RI_COMMENT, "Read Archive Data: \nReadArchive \"%s\"", ribNode.rib.readArchive.asChar() ); } if ( ribNode.rib.delayedReadArchive != "" && ribNode.rib.delayedReadArchive != "-" ) { // the following test prevents a really nasty infinite loop !! if ( ribNode.rib.delayedReadArchive != outputFilename ) RiArchiveRecord( RI_COMMENT, "Delayed Read Archive Data: \nProcedural \"DelayedReadArchive\" [ \"%s\" ] [ %f %f %f %f %f %f ]", ribNode.rib.delayedReadArchive.asChar(), ribNode.bound[0], ribNode.bound[3], ribNode.bound[1], ribNode.bound[4], ribNode.bound[2], ribNode.bound[5]); } // If it's a curve we should write the basis function if ( ribNode.object(0)->type == MRT_NuCurve ) { RiBasis( RiBSplineBasis, 1, RiBSplineBasis, 1 ); } if ( !ribNode.object(0)->ignore ) { ribNode.object(0)->writeObject(); } } else { // we're looking at a transform node bool wroteTransform = false; if (writeTransform && (objDagPath.apiType() == MFn::kTransform)) { if (debug) { cout << "liquidWriteArchive: writing transform: " << objDagPath.fullPathName().asChar() << endl; } // push the transform onto the RIB stack outputObjectName(objDagPath); MFnDagNode mfnDag(objDagPath); MMatrix tm = mfnDag.transformationMatrix(); if (true) { // (!tm.isEquivalent(MMatrix::identity)) { RtMatrix riTM; tm.get(riTM); wroteTransform = true; outputIndentation(); RiAttributeBegin(); indentLevel++; outputIndentation(); RiConcatTransform(riTM); } } // go through all the children of this node and deal with each of them int nChildren = objDagPath.childCount(); if (debug) { cout << "liquidWriteArchive: object " << objDagPath.fullPathName().asChar() << "has " << nChildren << " children" << endl; } for(int i=0; i<nChildren; ++i) { if (debug) { cout << "liquidWriteArchive: writing child number " << i << endl; } MDagPath childDagNode; MStatus stat = MDagPath::getAPathTo(objDagPath.child(i), childDagNode); if (stat) { writeObjectToRib(childDagNode, outputChildTransforms); } else { MGlobal::displayWarning("error getting a dag path to child node of object " + objDagPath.fullPathName()); } } if (wroteTransform) { indentLevel--; outputIndentation(); RiAttributeEnd(); } } if (debug) { cout << "liquidWriteArchive: finished writing object: " << objDagPath.fullPathName().asChar() << endl; } }