bool HesperisCurveCreator::CreateACurve(Vector3F * pos, unsigned nv, MObject &target) { MPointArray vertexArray; unsigned i=0; for(; i<nv; i++) vertexArray.append( MPoint( pos[i].x, pos[i].y, pos[i].z ) ); const int degree = 2; const int spans = nv - degree; const int nknots = spans + 2 * degree - 1; MDoubleArray knotSequences; knotSequences.append(0.0); for(i = 0; i < nknots-2; i++) knotSequences.append( (double)i ); knotSequences.append(nknots-3); MFnNurbsCurve curveFn; MStatus stat; curveFn.create(vertexArray, knotSequences, degree, MFnNurbsCurve::kOpen, false, false, target, &stat ); return stat == MS::kSuccess; }
MStatus makeSurf() { cout << ">>>> Start creation of test surface <<<<" << endl; // Set up knots // MDoubleArray knotArray; int i; // Add extra starting knots so that the first CV matches the curve start point // knotArray.append( 0.0 ); knotArray.append( 0.0 ); for ( i = 0; i <= NUM_SPANS; i++ ) { knotArray.append( (double)i ); } // Add extra ending knots so that the last CV matches the curve end point // knotArray.append( (double)i ); knotArray.append( (double)i ); // Now, Set up CVs // MPointArray cvArray; // We need a 2D array of CVs with NUM_SPANS + 3 CVs on a side // int last = NUM_SPANS + 3; for ( i = 0; i < last; i++ ) { for ( int j = 0; j < last; j++ ) { MPoint cv; cv.x = (((double)(j))/((double)(NUM_SPANS + 3)) * WIDTH) - (WIDTH/2.0); cv.z = (((double)(i))/((double)(NUM_SPANS + 3)) * WIDTH) - (WIDTH/2.0); double dist = sqrt( cv.x*cv.x + cv.z*cv.z ); cv.y = cos( dist ) * VERTICAL_SCALING; cvArray.append( cv ); } } // Create the surface // MFnNurbsSurface mfnNurbsSurf; MStatus stat; mfnNurbsSurf.create( cvArray, knotArray, knotArray, 3, 3, MFnNurbsSurface::kOpen, MFnNurbsSurface::kOpen, true, MObject::kNullObj, &stat ); if ( stat ) { cout << ">>>> Test Surface Creation Successfull <<<<\n"; } else { stat.perror("MFnNurbsSurface::create"); cout << ">>>> Test Surface Creation Failed <<<<\n"; } return stat; }
/* ----------------------------------------- Make a degree 1 curve from the given CVs. ----------------------------------------- */ static void jMakeCurve( MPointArray cvs ) { MStatus stat; unsigned int deg = 1; MDoubleArray knots; unsigned int i; for ( i = 0; i < cvs.length(); i++ ) knots.append( (double) i ); // Now create the curve // MFnNurbsCurve curveFn; curveFn.create( cvs, knots, deg, MFnNurbsCurve::kOpen, false, false, MObject::kNullObj, &stat ); if ( MS::kSuccess != stat ) cout<<"Error creating curve."<<endl; }
MStatus helix::doIt( const MArgList& args ) { MStatus stat; const unsigned deg = 3; // Curve Degree const unsigned ncvs = 20; // Number of CVs const unsigned spans = ncvs - deg; // Number of spans const unsigned nknots = spans+2*deg-1;// Number of knots double radius = 4.0; // Helix radius double pitch = 0.5; // Helix pitch unsigned i; // Parse the arguments. for ( i = 0; i < args.length(); i++ ) if ( MString( "-p" ) == args.asString( i, &stat ) && MS::kSuccess == stat) { double tmp = args.asDouble( ++i, &stat ); if ( MS::kSuccess == stat ) pitch = tmp; } else if ( MString( "-r" ) == args.asString( i, &stat ) && MS::kSuccess == stat) { double tmp = args.asDouble( ++i, &stat ); if ( MS::kSuccess == stat ) radius = tmp; } MPointArray controlVertices; MDoubleArray knotSequences; // Set up cvs and knots for the helix // for (i = 0; i < ncvs; i++) controlVertices.append( MPoint( radius * cos( (double)i ), pitch * (double)i, radius * sin( (double)i ) ) ); for (i = 0; i < nknots; i++) knotSequences.append( (double)i ); // Now create the curve // MFnNurbsCurve curveFn; curveFn.create( controlVertices, knotSequences, deg, MFnNurbsCurve::kOpen, false, false, MObject::kNullObj, &stat ); if ( MS::kSuccess != stat ) cout<<"Error creating curve."<<endl; return stat; }
MDoubleArray boingRbCmd::getBulletVectorAttribute(MString &name, MString &attr) { MVector vec; MDoubleArray result; shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node(); MStringArray nodes; if (name == "*") { nodes = b_solv->get_all_keys(); } else { nodes.append(name); } //std::cout<<"nodes : "<<nodes<<std::endl; //std::cout<<"nodes.length() : "<<nodes.length()<<std::endl; for (int i=0; i<nodes.length(); i++) { std::cout<<"trying to get rb...."<<std::endl; rigid_body_t::pointer rb = b_solv->getdata(nodes[i])->m_rigid_body; std::cout<<"got rb : "<<b_solv->getdata(nodes[i])->name<<std::endl; //rigid_body_t::pointer rb = getPointerFromName(name); if (rb != 0) { float mass = rb->get_mass(); bool active = (mass>0.f); if(active) { if (attr=="velocity") { vec3f vel; rb->get_linear_velocity(vel); vec = MVector((double)vel[0], (double)vel[1], (double)vel[2]); } else if (attr=="position") { vec3f pos; quatf rot; rb->get_transform(pos, rot); vec = MVector((double)pos[0], (double)pos[1], (double)pos[2]); } else if (attr=="angularVelocity") { vec3f av; rb->get_angular_velocity(av); vec = MVector((double)av[0], (double)av[1], (double)av[2]); } /*else { boing *b = static_cast<boing*>( rb->impl()->body()->getUserPointer() ); MString vecStr = b->get_data(attr); MStringArray vecArray = parseArguments(vecStr, ","); vec = MVector(vecArray[0].asDouble(), vecArray[1].asDouble(), vecArray[2].asDouble()); }*/ } } for (int j=0; j<3; j++) { //std::cout<<"vec["<<j<<"] : "<<vec[j]<<std::endl; result.append(vec[j]); } } return result; }
void HelixButton::createHelix() { MStatus st; const unsigned deg = 3; // Curve Degree const unsigned ncvs = 20; // Number of CVs const unsigned spans = ncvs - deg; // Number of spans const unsigned nknots = spans + 2 * deg - 1; // Number of knots double radius = 4.0; // Helix radius double pitch = 0.5; // Helix pitch unsigned i; MPointArray controlVertices; MDoubleArray knotSequences; // Set up cvs and knots for the helix for (i = 0; i < ncvs; i++) { controlVertices.append( MPoint( radius * cos((double)i), pitch * (double)i, radius * sin((double)i) ) ); } for (i = 0; i < nknots; i++) knotSequences.append((double)i); // Now create the curve MFnNurbsCurve curveFn; MObject curve = curveFn.create( controlVertices, knotSequences, deg, MFnNurbsCurve::kOpen, false, false, MObject::kNullObj, &st ); MGlobal::displayInfo("Helix curve created!"); if (!st) { MGlobal::displayError( HelixQtCmd::commandName + " - could not create helix: " + st.errorString() ); } }
MStatus boingRbCmd::redoIt() { //MGlobal::getActiveSelectionList(m_undoSelectionList) /* if (argData->isFlagSet("help")) { MGlobal::displayInfo(MString("Tässä olisi helppi-teksti")); return MS::kSuccess; }*/ isSetAttr = argParser->isFlagSet("-setAttr"); isGetAttr = argParser->isFlagSet("-getAttr"); isCreate = argParser->isFlagSet("-create"); isDelete = argParser->isFlagSet("-delete"); isValue = argParser->isFlagSet("-value"); if (isSetAttr && isValue) { MString sAttr; //MArgList argList; argParser->getFlagArgument("setAttr", 0, sAttr); //cout<<sAttr<<endl; MStringArray jobArgsArray = parseArguments(sAttr, "."); /* MString stringBuffer; for (unsigned int charIdx = 0; charIdx < sAttr.numChars(); charIdx++) { MString ch = sAttr.substringW(charIdx, charIdx); //cout<<"ch = "<<ch<<endl; if (ch == ".") { if (stringBuffer.length() > 0) { jobArgsArray.append(stringBuffer); //cout<<"jobArgsArray = "<<jobArgsArray<<endl; stringBuffer.clear(); } } else { stringBuffer += ch; //cout<<"stringBuffer = "<<stringBuffer<<endl; } } jobArgsArray.append(stringBuffer); */ MVector value; argParser->getFlagArgument("-value", 0, value.x); argParser->getFlagArgument("-value", 1, value.y); argParser->getFlagArgument("-value", 2, value.z); //cout<<"jobArgsArray[1] : "<<jobArgsArray[1]<<endl; MString attr = checkAttribute(jobArgsArray[1]); setBulletVectorAttribute(nameToNode(jobArgsArray[0]), attr, value); //cout<<value<<endl; setResult(MS::kSuccess); } else if ( isGetAttr) { MString gAttr; argParser->getFlagArgument("getAttr", 0, gAttr); //cout<<gAttr<<endl; MStringArray jobArgsArray = parseArguments(gAttr, "."); MString attr = checkAttribute(jobArgsArray[1]); //cout<<"attr = "<<attr<<endl; if (attr!="name") { MVector result = getBulletVectorAttribute(nameToNode(jobArgsArray[0]), attr); MDoubleArray dResult; dResult.append(result.x); dResult.append(result.y); dResult.append(result.z); setResult(dResult); } else { MStringArray result; std::set<boingRBNode*> nodes; //bSolverNode::getRigidBodies(result, nodes); //solver_t *solver_t; //shared_ptr<solver_impl_t> m_impl_t = solver_t->get_solver(); //bt_solver_t *solv = bt_solver_t; //shared_ptr<solver_impl_t> solver = solver_t->get_solver(); //cout<<"size(m_rigid_bodies)"<<m_rigid_bodies->length()<<endl; //btDefaultSerializer* serializer = new MySerializer(solver_t->get_solver()); //btHashMap<btHashPtr,const char*> m_nameMap; //for(size_t i = 0; i < m_rigid_bodies.size(); ++i) { //solver_t::remove_rigid_body(m_rigid_bodies[i]); //cout<<"m_rigid_bodies["<<i<<"] : "<<m_rigid_bodies[i]<<endl; //} //cout << "rigid bodies" << endl; //std::set<rigid_body_t::pointer>m_rigid_bodies = solver_t->get_rigid_bodies(); //btDefaultSerializer* serializer = new MySerializer(solv); //btHashMap<btHashPtr,const char*> m_nameMap = bt_solver_t::get_m_nameMap(); //std::set<rigid_body_t::pointer>::iterator it; //unsigned int i=0; //for (it = m_rigid_bodies.begin(); it != m_rigid_bodies.end(); ++it) { //rigid_body_t::pointer body = static_cast<rigid_body_t::pointer>bt_rigid_body_t::body(); //rigid_body_t::pointer body = it->get(); //bt_rigid_body_t::body(); //collision_shape_t::pointer collshape_pointer = (collision_shape_t::pointer)body->collision_shape(); //const char *namePtr = solv->m_nameMap.find(it); // rigid_body_t::pointer m_rigid_body = it->get(); // const rigid_body_impl_t* rb = m_rigid_body->impl(); //const char*const * namePtr = solv->m_nameMap.find(rb); // const char* namePtr = serializer->findNameForPointer(rb); // cout<<++i<<endl; //if (namePtr && *namePtr) { //cout<<namePtr<<endl; // result.append((MString) namePtr); //} else { // continue; //} //cout<<collshape_pointer<<endl; //cout<<"pointer : " << (*)it << endl; //const char* rbname = MySerializer::findNameForPointer(it); //cout<<"rbname = "<<rbname<<endl; //} cout<<"result : "<<result<<endl; setResult(result); } } else if ( isCreate ) { MString aArgument; argParser->getFlagArgument("-create", 0, aArgument); MStringArray createArgs = parseArguments(aArgument,";"); int size = createArgs.length(); MString inputShape; MString rbname = "dummyRb"; MVector vel; MVector pos; MVector rot; for (int i=0; i<size; ++i) { //cout<<"createArgs[i] = "<<createArgs[i]<<endl; MStringArray singleArg = parseArguments(createArgs[i],"="); cout<<"singleArg[0] : "<<singleArg[0]<<endl; cout<<"singleArg[1] : "<<singleArg[1]<<endl; if (singleArg[0] == "name") { //name rbname = singleArg[1]; cout<<"name"<<endl; cout<<"singleArg[0] : "<<singleArg[0]<<endl; cout<<"singleArg[1] : "<<singleArg[1]<<endl; } else if (singleArg[0] == "geo") { //geo inputShape = singleArg[1]; } else if (singleArg[0] == "vel") { //initialvelocity MStringArray velArray = parseArguments(singleArg[1], ","); vel = MVector(velArray[0].asDouble(), velArray[1].asDouble(), velArray[2].asDouble() ); //cout<<"velocity = "<<vel<<endl; } else if (singleArg[0] == "pos") { //initialposition MStringArray posArray = parseArguments(singleArg[1], ","); pos = MVector(posArray[0].asDouble(), posArray[1].asDouble(), posArray[2].asDouble() ); //cout<<"position = "<<pos<<endl; } else if (singleArg[0] == "rot") { //initialrotation MStringArray rotArray = parseArguments(singleArg[1], ","); rot = MVector(rotArray[0].asDouble(), rotArray[1].asDouble(), rotArray[2].asDouble() ); //cout<<"rotation = "<<rot<<endl; } else { cout<<"Unrecognized parameter : "<<singleArg[0]<<endl; } } // create the collisionShape-node MObject node = nameToNode(inputShape); collision_shape_t::pointer collShape = createCollisionShape(node); createRigidBody(collShape, node, rbname, vel, pos, rot); } else if ( isDelete ) { } return MS::kSuccess; }
MObject createSubD(double iFrame, SubDAndColors & iNode, MObject & iParent) { Alembic::AbcGeom::ISubDSchema schema = iNode.mMesh.getSchema(); Alembic::AbcCoreAbstract::index_t index, ceilIndex; getWeightAndIndex(iFrame, schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex); Alembic::AbcGeom::ISubDSchema::Sample samp; schema.get(samp, Alembic::Abc::ISampleSelector(index)); MString name(iNode.mMesh.getName().c_str()); MFnMesh fnMesh; MFloatPointArray pointArray; Alembic::Abc::P3fArraySamplePtr emptyPtr; fillPoints(pointArray, samp.getPositions(), emptyPtr, 0.0); fillTopology(fnMesh, iParent, pointArray, samp.getFaceIndices(), samp.getFaceCounts()); fnMesh.setName(iNode.mMesh.getName().c_str()); setInitialShadingGroup(fnMesh.partialPathName()); MObject obj = fnMesh.object(); setUVs(iFrame, fnMesh, schema.getUVsParam()); setColors(iFrame, fnMesh, iNode.mC3s, iNode.mC4s, true); // add the mFn-specific attributes to fnMesh node MFnNumericAttribute numAttr; MString attrName("SubDivisionMesh"); MObject attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, 1); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); if (samp.getInterpolateBoundary() > 0) { attrName = MString("interpolateBoundary"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getInterpolateBoundary()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } if (samp.getFaceVaryingInterpolateBoundary() > 0) { attrName = MString("faceVaryingInterpolateBoundary"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getFaceVaryingInterpolateBoundary()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } if (samp.getFaceVaryingPropagateCorners() > 0) { attrName = MString("faceVaryingPropagateCorners"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getFaceVaryingPropagateCorners()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } #if MAYA_API_VERSION >= 201100 Alembic::Abc::Int32ArraySamplePtr holes = samp.getHoles(); if (holes && !holes->size() == 0) { unsigned int numHoles = (unsigned int)holes->size(); MUintArray holeData(numHoles); for (unsigned int i = 0; i < numHoles; ++i) { holeData[i] = (*holes)[i]; } if (fnMesh.setInvisibleFaces(holeData) != MS::kSuccess) { MString warn = "Failed to set holes on: "; warn += iNode.mMesh.getName().c_str(); printWarning(warn); } } #endif Alembic::Abc::FloatArraySamplePtr creases = samp.getCreaseSharpnesses(); if (creases && !creases->size() == 0) { Alembic::Abc::Int32ArraySamplePtr indices = samp.getCreaseIndices(); Alembic::Abc::Int32ArraySamplePtr lengths = samp.getCreaseLengths(); std::size_t numLengths = lengths->size(); MUintArray edgeIds; MDoubleArray creaseData; std::size_t curIndex = 0; // curIndex incremented here to move on to the next crease length for (std::size_t i = 0; i < numLengths; ++i, ++curIndex) { std::size_t len = (*lengths)[i] - 1; float creaseSharpness = (*creases)[i]; // curIndex incremented here to go between all the edges that make // up a given length for (std::size_t j = 0; j < len; ++j, ++curIndex) { Alembic::Util::int32_t vertA = (*indices)[curIndex]; Alembic::Util::int32_t vertB = (*indices)[curIndex+1]; MItMeshVertex itv(obj); int prev; itv.setIndex(vertA, prev); MIntArray edges; itv.getConnectedEdges(edges); std::size_t numEdges = edges.length(); for (unsigned int k = 0; k < numEdges; ++k) { int oppVert = -1; itv.getOppositeVertex(oppVert, edges[k]); if (oppVert == vertB) { creaseData.append(creaseSharpness); edgeIds.append(edges[k]); break; } } } } if (fnMesh.setCreaseEdges(edgeIds, creaseData) != MS::kSuccess) { MString warn = "Failed to set creases on: "; warn += iNode.mMesh.getName().c_str(); printWarning(warn); } } Alembic::Abc::FloatArraySamplePtr corners = samp.getCornerSharpnesses(); if (corners && !corners->size() == 0) { Alembic::Abc::Int32ArraySamplePtr cornerVerts = samp.getCornerIndices(); unsigned int numCorners = static_cast<unsigned int>(corners->size()); MUintArray vertIds(numCorners); MDoubleArray cornerData(numCorners); for (unsigned int i = 0; i < numCorners; ++i) { cornerData[i] = (*corners)[i]; vertIds[i] = (*cornerVerts)[i]; } if (fnMesh.setCreaseVertices(vertIds, cornerData) != MS::kSuccess) { MString warn = "Failed to set corners on: "; warn += iNode.mMesh.getName().c_str(); printWarning(warn); } } return obj; }
MStatus mshUtil::doIt( const MArgList& args ) { MString objname, mcfname; MArgDatabase argData(syntax(), args); MSelectionList selList; MGlobal::getActiveSelectionList ( selList ); if ( selList.length() < 2 ) { MGlobal:: displayError ( "Not sufficient selection!" ); return MS::kSuccess; } MItSelectionList iter( selList ); iter.reset(); MDagPath meshPath; iter.getDagPath( meshPath ); meshPath.extendToShape(); MObject meshObj = meshPath.node(); MString surface = meshPath.partialPathName(); MStatus status; MFnMesh meshFn(meshPath, &status ); if(!status) { MGlobal:: displayError ( "Not sufficient selection!" ); return MS::kSuccess; } MPointArray vxa; meshFn.getPoints (vxa, MSpace::kWorld); MPoint cenfrom(0.f, 0.f, 0.f); for(unsigned i=0; i<vxa.length(); i++) cenfrom += vxa[i]; cenfrom = cenfrom/(float)vxa.length(); iter.next(); iter.getDagPath( meshPath ); meshPath.extendToShape(); MFnMesh mesh1Fn(meshPath, &status ); if(!status) { MGlobal:: displayError ( "Not sufficient selection!" ); return MS::kSuccess; } vxa.clear(); mesh1Fn.getPoints (vxa, MSpace::kWorld); MPoint cento(0.f, 0.f, 0.f); for(unsigned i=0; i<vxa.length(); i++) cento += vxa[i]; cento = cento/(float)vxa.length(); MVector diff = cento - cenfrom; MDoubleArray res; res.append(diff.x); res.append(diff.y); res.append(diff.z); setResult ( res ); /* if ( !argData.isFlagSet("-i") || !argData.isFlagSet("-o") ) { //MGlobal::displayError( "No .obj or .mcf file specified to translate! Example: mshUtil -i filename.obj -o filename.mcf" ); return MS::kSuccess; } else { argData.getFlagArgument("-i", 0, objname); argData.getFlagArgument("-o", 0, mcfname); return MS::kSuccess; } */ return MS::kSuccess; }
bool ToMayaCurveConverter::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const { MStatus s; IECore::ConstCurvesPrimitivePtr curves = IECore::runTimeCast<const IECore::CurvesPrimitive>( from ); assert( curves ); if ( !curves->arePrimitiveVariablesValid() || !curves->numCurves() ) { return false; } int curveIndex = indexParameter()->getNumericValue(); if( curveIndex < 0 || curveIndex >= (int)curves->numCurves() ) { IECore::msg( IECore::Msg::Warning,"ToMayaCurveConverter::doConversion", boost::format( "Invalid curve index \"%d\"") % curveIndex ); return false; } IECore::ConstV3fVectorDataPtr p = curves->variableData< IECore::V3fVectorData >( "P", IECore::PrimitiveVariable::Vertex ); if( !p ) { IECore::msg( IECore::Msg::Warning,"ToMayaCurveConverter::doConversion", "Curve has no \"P\" data" ); return false; } const std::vector<int>& verticesPerCurve = curves->verticesPerCurve()->readable(); int curveBase = 0; for( int i=0; i<curveIndex; ++i ) { curveBase += verticesPerCurve[i]; } MPointArray vertexArray; int numVertices = verticesPerCurve[curveIndex]; int cvOffset = 0; if( curves->basis() != IECore::CubicBasisf::linear() && !curves->periodic() ) { // Maya implicitly duplicates end points, so they're explicitly duplicated in the CurvePrimitives. // We need to remove those duplicates when converting back to Maya. Remove 2 cvs at start, 2 at end. if( numVertices < 8 ) { IECore::msg( IECore::Msg::Warning,"ToMayaCurveConverter::doConversion", "The Curve Primitive does not have enough CVs to be converted into a Maya Curve. Needs at least 8." ); return false; } cvOffset = 2; } const std::vector<Imath::V3f>& pts = p->readable(); // triple up the start points for cubic periodic curves: if( curves->periodic() && curves->basis() != IECore::CubicBasisf::linear() ) { vertexArray.append( IECore::convert<MPoint, Imath::V3f>( pts[curveBase] ) ); vertexArray.append( vertexArray[0] ); } for( int i = cvOffset; i < numVertices-cvOffset; ++i ) { vertexArray.append( IECore::convert<MPoint, Imath::V3f>( pts[i + curveBase] ) ); } // if the curve is periodic, the first N cvs must be identical to the last N cvs, where N is the degree // of the curve: if( curves->periodic() ) { if( curves->basis() == IECore::CubicBasisf::linear() ) { // linear: N = 1 vertexArray.append( vertexArray[0] ); } else { // cubic: N = 3 vertexArray.append( vertexArray[0] ); vertexArray.append( vertexArray[1] ); vertexArray.append( vertexArray[2] ); } } unsigned vertexArrayLength = vertexArray.length(); MDoubleArray knotSequences; if( curves->basis() == IECore::CubicBasisf::linear() ) { for( unsigned i=0; i < vertexArrayLength; ++i ) { knotSequences.append( i ); } } else { if( curves->periodic() ) { // Periodic curve, knots must be spaced out. knotSequences.append( -1 ); for( unsigned i=0; i < vertexArrayLength+1; ++i ) { knotSequences.append( i ); } } else { // For a cubic curve, the first three and last three knots must be duplicated for the curve start/end to start at the first/last CV. knotSequences.append( 0 ); knotSequences.append( 0 ); for( unsigned i=0; i < vertexArrayLength-2; ++i ) { knotSequences.append( i ); } knotSequences.append( vertexArrayLength-3 ); knotSequences.append( vertexArrayLength-3 ); } } MFnNurbsCurve fnCurve; fnCurve.create( vertexArray, knotSequences, curves->basis() == IECore::CubicBasisf::linear() ? 1 : 3, curves->periodic() ? MFnNurbsCurve::kPeriodic : MFnNurbsCurve::kOpen, false, false, to, &s ); if (!s) { IECore::msg( IECore::Msg::Warning,"ToMayaCurveConverter::doConversion", s.errorString().asChar() ); return false; } return true; }
MStatus clusterWeightFunctionCmd::performWeighting(MFnWeightGeometryFilter &cluster, MDagPath &dagPath, MObject &component) { MStatus status; MItGeometry geomIter(dagPath, component, &status); MObject comp; MObjectArray compArray; MDoubleArray weightArray; double weight = 0.0; if (MS::kSuccess == status) { for (; !geomIter.isDone(); geomIter.next()) { comp = geomIter.component(); MPoint pnt = geomIter.position(MSpace::kWorld, &status); if (MS::kSuccess != status) { return MS::kFailure; } if (kSine == fEffectType) { weight = sin(pnt.x)*sin(pnt.z); } else if (kSineDistance == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = sin(distance); } else if (kSineDistance2 == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = sin(distance*distance); } else if (kDistanceSineDistance == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance*sin(distance); } else if (kInverseDistanceSineDistance == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = sin(distance)/(distance+1); } else if (kDistance == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance; } else if (kDistance2 == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance*distance; } else if (kDistance3 == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance*distance*distance; } else if (kDistance4 == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance*distance*distance*distance; } else if (kInverseDistance == fEffectType) { double dist = pnt.distanceTo(MPoint::origin) + 1; weight = 1/(dist); } else if (kInverseDistance2 == fEffectType) { double dist = pnt.distanceTo(MPoint::origin) + 1; weight = 1/(dist*dist); } else if (kInverseDistance3 == fEffectType) { double dist = pnt.distanceTo(MPoint::origin) + 1; weight = 1/(dist*dist*dist); } else if (kInverseDistance4 == fEffectType) { double dist = pnt.distanceTo(MPoint::origin) + 1; weight = 1/(dist*dist*dist*dist); } compArray.append(comp); weightArray.append(weight); } unsigned length = compArray.length(); for (unsigned i = 0; i < length; i++) { cluster.setWeight(dagPath, compArray[i], (float) weightArray[i]); } return MS::kSuccess; } else return MS::kFailure; }
//apply fields in the scene from the rigid body void dSolverNode::applyFields(MPlugArray &rbConnections, float dt) { MVectorArray position; MVectorArray velocity; MDoubleArray mass; std::vector<rigid_body_t*> rigid_bodies; //gather active rigid bodies for(size_t i = 0; i < rbConnections.length(); ++i) { MObject node = rbConnections[i].node(); MFnDagNode fnDagNode(node); if(fnDagNode.typeId() == rigidBodyNode::typeId) { rigidBodyNode *rbNode = static_cast<rigidBodyNode*>(fnDagNode.userNode()); rigid_body_t::pointer rb = rbNode->rigid_body(); MPlug plgMass(node, rigidBodyNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(active) { rigid_bodies.push_back(rb.get()); } } else if(fnDagNode.typeId() == rigidBodyArrayNode::typeId) { rigidBodyArrayNode *rbNode = static_cast<rigidBodyArrayNode*>(fnDagNode.userNode()); std::vector<rigid_body_t::pointer>& rbs = rbNode->rigid_bodies(); MPlug plgMass(node, rigidBodyArrayNode::ia_mass); float mass = 0.f; plgMass.getValue(mass); bool active = (mass>0.f); if(active) { for(size_t j = 0; j < rbs.size(); ++j) { rigid_bodies.push_back(rbs[j].get()); } } } } //clear forces and get the properties needed for field computation for(size_t i = 0; i < rigid_bodies.size(); ++i) { rigid_bodies[i]->clear_forces(); vec3f pos, vel; quatf rot; rigid_bodies[i]->get_transform(pos, rot); rigid_bodies[i]->get_linear_velocity(vel); position.append(MVector(pos[0], pos[1], pos[2])); velocity.append(MVector(vel[0], vel[1], vel[2])); //TODO mass.append(1.0); // } //apply the fields to the rigid bodies MVectorArray force; for(MItDag it(MItDag::kDepthFirst, MFn::kField); !it.isDone(); it.next()) { MFnField fnField(it.item()); fnField.getForceAtPoint(position, velocity, mass, force, dt); for(size_t i = 0; i < rigid_bodies.size(); ++i) { rigid_bodies[i]->apply_central_force(vec3f(force[i].x, force[i].y, force[i].z)); } } }
MStatus AlembicExportCommand::doIt(const MArgList &args) { ESS_PROFILE_SCOPE("AlembicExportCommand::doIt"); MStatus status = MS::kFailure; MTime currentAnimStartTime = MAnimControl::animationStartTime(), currentAnimEndTime = MAnimControl::animationEndTime(), oldCurTime = MAnimControl::currentTime(), curMinTime = MAnimControl::minTime(), curMaxTime = MAnimControl::maxTime(); MArgParser argData(syntax(), args, &status); if (argData.isFlagSet("help")) { // TODO: implement help for this command // MGlobal::displayInfo(util::getHelpText()); return MS::kSuccess; } unsigned int jobCount = argData.numberOfFlagUses("jobArg"); MStringArray jobStrings; if (jobCount == 0) { // TODO: display dialog MGlobal::displayError("[ExocortexAlembic] No jobs specified."); MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no job specified"); return status; } else { // get all of the jobstrings for (unsigned int i = 0; i < jobCount; i++) { MArgList jobArgList; argData.getFlagArgumentList("jobArg", i, jobArgList); jobStrings.append(jobArgList.asString(0)); } } // create a vector to store the jobs std::vector<AlembicWriteJob *> jobPtrs; double minFrame = 1000000.0; double maxFrame = -1000000.0; double maxSteps = 1; double maxSubsteps = 1; // init the curve accumulators AlembicCurveAccumulator::Initialize(); try { // for each job, check the arguments bool failure = false; for (unsigned int i = 0; i < jobStrings.length(); ++i) { double frameIn = 1.0; double frameOut = 1.0; double frameSteps = 1.0; double frameSubSteps = 1.0; MString filename; bool purepointcache = false; bool normals = true; bool uvs = true; bool facesets = true; bool bindpose = true; bool dynamictopology = false; bool globalspace = false; bool withouthierarchy = false; bool transformcache = false; bool useInitShadGrp = false; bool useOgawa = false; // Later, will need to be changed! MStringArray objectStrings; std::vector<std::string> prefixFilters; std::set<std::string> attributes; std::vector<std::string> userPrefixFilters; std::set<std::string> userAttributes; MObjectArray objects; std::string search_str, replace_str; // process all tokens of the job MStringArray tokens; jobStrings[i].split(';', tokens); for (unsigned int j = 0; j < tokens.length(); j++) { MStringArray valuePair; tokens[j].split('=', valuePair); if (valuePair.length() != 2) { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } const MString &lowerValue = valuePair[0].toLowerCase(); if (lowerValue == "in") { frameIn = valuePair[1].asDouble(); } else if (lowerValue == "out") { frameOut = valuePair[1].asDouble(); } else if (lowerValue == "step") { frameSteps = valuePair[1].asDouble(); } else if (lowerValue == "substep") { frameSubSteps = valuePair[1].asDouble(); } else if (lowerValue == "normals") { normals = valuePair[1].asInt() != 0; } else if (lowerValue == "uvs") { uvs = valuePair[1].asInt() != 0; } else if (lowerValue == "facesets") { facesets = valuePair[1].asInt() != 0; } else if (lowerValue == "bindpose") { bindpose = valuePair[1].asInt() != 0; } else if (lowerValue == "purepointcache") { purepointcache = valuePair[1].asInt() != 0; } else if (lowerValue == "dynamictopology") { dynamictopology = valuePair[1].asInt() != 0; } else if (lowerValue == "globalspace") { globalspace = valuePair[1].asInt() != 0; } else if (lowerValue == "withouthierarchy") { withouthierarchy = valuePair[1].asInt() != 0; } else if (lowerValue == "transformcache") { transformcache = valuePair[1].asInt() != 0; } else if (lowerValue == "filename") { filename = valuePair[1]; } else if (lowerValue == "objects") { // try to find each object valuePair[1].split(',', objectStrings); } else if (lowerValue == "useinitshadgrp") { useInitShadGrp = valuePair[1].asInt() != 0; } // search/replace else if (lowerValue == "search") { search_str = valuePair[1].asChar(); } else if (lowerValue == "replace") { replace_str = valuePair[1].asChar(); } else if (lowerValue == "ogawa") { useOgawa = valuePair[1].asInt() != 0; } else if (lowerValue == "attrprefixes") { splitListArg(valuePair[1], prefixFilters); } else if (lowerValue == "attrs") { splitListArg(valuePair[1], attributes); } else if (lowerValue == "userattrprefixes") { splitListArg(valuePair[1], userPrefixFilters); } else if (lowerValue == "userattrs") { splitListArg(valuePair[1], userAttributes); } else { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } } // now check the object strings for (unsigned int k = 0; k < objectStrings.length(); k++) { MSelectionList sl; MString objectString = objectStrings[k]; sl.add(objectString); MDagPath dag; for (unsigned int l = 0; l < sl.length(); l++) { sl.getDagPath(l, dag); MObject objRef = dag.node(); if (objRef.isNull()) { MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" + objectStrings[k] + "', not found."); break; } // get all parents MObjectArray parents; // check if this is a camera bool isCamera = false; for (unsigned int m = 0; m < dag.childCount(); ++m) { MFnDagNode child(dag.child(m)); MFn::Type ctype = child.object().apiType(); if (ctype == MFn::kCamera) { isCamera = true; break; } } if (dag.node().apiType() == MFn::kTransform && !isCamera && !globalspace && !withouthierarchy) { MDagPath ppath = dag; while (!ppath.node().isNull() && ppath.length() > 0 && ppath.isValid()) { parents.append(ppath.node()); if (ppath.pop() != MStatus::kSuccess) { break; } } } else { parents.append(dag.node()); } // push all parents in while (parents.length() > 0) { bool found = false; for (unsigned int m = 0; m < objects.length(); m++) { if (objects[m] == parents[parents.length() - 1]) { found = true; break; } } if (!found) { objects.append(parents[parents.length() - 1]); } parents.remove(parents.length() - 1); } // check all of the shapes below if (!transformcache) { sl.getDagPath(l, dag); for (unsigned int m = 0; m < dag.childCount(); m++) { MFnDagNode child(dag.child(m)); if (child.isIntermediateObject()) { continue; } objects.append(child.object()); } } } } // check if we have incompatible subframes if (maxSubsteps > 1.0 && frameSubSteps > 1.0) { const double part = (frameSubSteps > maxSubsteps) ? (frameSubSteps / maxSubsteps) : (maxSubsteps / frameSubSteps); if (abs(part - floor(part)) > 0.001) { MString frameSubStepsStr, maxSubstepsStr; frameSubStepsStr.set(frameSubSteps); maxSubstepsStr.set(maxSubsteps); MGlobal::displayError( "[ExocortexAlembic] You cannot combine substeps " + frameSubStepsStr + " and " + maxSubstepsStr + " in one export. Aborting."); return MStatus::kInvalidParameter; } } // remember the min and max values for the frames if (frameIn < minFrame) { minFrame = frameIn; } if (frameOut > maxFrame) { maxFrame = frameOut; } if (frameSteps > maxSteps) { maxSteps = frameSteps; } if (frameSteps > 1.0) { frameSubSteps = 1.0; } if (frameSubSteps > maxSubsteps) { maxSubsteps = frameSubSteps; } // check if we have a filename if (filename.length() == 0) { MGlobal::displayError("[ExocortexAlembic] No filename specified."); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no filename " "specified"); return MStatus::kFailure; } // construct the frames MDoubleArray frames; { const double frameIncr = frameSteps / frameSubSteps; for (double frame = frameIn; frame <= frameOut; frame += frameIncr) { frames.append(frame); } } AlembicWriteJob *job = new AlembicWriteJob(filename, objects, frames, useOgawa, prefixFilters, attributes, userPrefixFilters, userAttributes); job->SetOption("exportNormals", normals ? "1" : "0"); job->SetOption("exportUVs", uvs ? "1" : "0"); job->SetOption("exportFaceSets", facesets ? "1" : "0"); job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0"); job->SetOption("exportBindPose", bindpose ? "1" : "0"); job->SetOption("exportPurePointCache", purepointcache ? "1" : "0"); job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0"); job->SetOption("indexedNormals", "1"); job->SetOption("indexedUVs", "1"); job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0"); job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0"); job->SetOption("transformCache", transformcache ? "1" : "0"); // check if the search/replace strings are valid! if (search_str.length() ? !replace_str.length() : replace_str.length()) // either search or // replace string is // missing or empty! { ESS_LOG_WARNING( "Missing search or replace parameter. No strings will be " "replaced."); job->replacer = SearchReplace::createReplacer(); } else { job->replacer = SearchReplace::createReplacer(search_str, replace_str); } // check if the job is satifsied if (job->PreProcess() != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied."); delete (job); failure = true; break; } // push the job to our registry MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" + jobStrings[i]); jobPtrs.push_back(job); } if (failure) { for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } return MS::kFailure; } // compute the job count unsigned int jobFrameCount = 0; for (size_t i = 0; i < jobPtrs.size(); i++) jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() * (unsigned int)jobPtrs[i]->GetFrames().size(); // now, let's run through all frames, and process the jobs const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit()); const double incrSteps = maxSteps / maxSubsteps; double nextFrame = minFrame + incrSteps; for (double frame = minFrame; frame <= maxFrame; frame += incrSteps, nextFrame += incrSteps) { MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds)); MAnimControl::setAnimationEndTime( MTime(nextFrame / frameRate, MTime::kSeconds)); MAnimControl::playForward(); // this way, it forces Maya to play exactly // one frame! and particles are updated! AlembicCurveAccumulator::StartRecordingFrame(); for (size_t i = 0; i < jobPtrs.size(); i++) { MStatus status = jobPtrs[i]->Process(frame); if (status != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job aborted :" + jobPtrs[i]->GetFileName()); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); return status; } } AlembicCurveAccumulator::StopRecordingFrame(); } } catch (...) { MGlobal::displayError( "[ExocortexAlembic] Jobs aborted, force closing all archives!"); for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin(); beg != jobPtrs.end(); ++beg) { (*beg)->forceCloseArchive(); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); MPxCommand::setResult("Error caught in AlembicExportCommand::doIt"); status = MS::kFailure; } MAnimControl::stop(); AlembicCurveAccumulator::Destroy(); // restore the animation start/end time and the current time! restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); // delete all jobs for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } // remove all known archives deleteAllArchives(); return status; }
MStatus AlembicCurvesNode::compute(const MPlug &plug, MDataBlock &dataBlock) { ESS_PROFILE_SCOPE("AlembicCurvesNode::compute"); MStatus status; // update the frame number to be imported const double inputTime = dataBlock.inputValue(mTimeAttr).asTime().as(MTime::kSeconds); MString &fileName = dataBlock.inputValue(mFileNameAttr).asString(); MString &identifier = dataBlock.inputValue(mIdentifierAttr).asString(); // check if we have the file if (fileName != mFileName || identifier != mIdentifier) { mSchema.reset(); if (fileName != mFileName) { delRefArchive(mFileName); mFileName = fileName; addRefArchive(mFileName); } mIdentifier = identifier; // get the object from the archive Abc::IObject iObj = getObjectFromArchive(mFileName, identifier); if (!iObj.valid()) { MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier + "' not found in archive '" + mFileName + "'."); return MStatus::kFailure; } AbcG::ICurves obj(iObj, Abc::kWrapExisting); if (!obj.valid()) { MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier + "' in archive '" + mFileName + "' is not a Curves."); return MStatus::kFailure; } mObj = obj; mSchema = obj.getSchema(); mCurvesData = MObject::kNullObj; } if (!mSchema.valid()) { return MStatus::kFailure; } { ESS_PROFILE_SCOPE("AlembicCurvesNode::compute readProps"); Alembic::Abc::ICompoundProperty arbProp = mSchema.getArbGeomParams(); Alembic::Abc::ICompoundProperty userProp = mSchema.getUserProperties(); readProps(inputTime, arbProp, dataBlock, thisMObject()); readProps(inputTime, userProp, dataBlock, thisMObject()); // Set all plugs as clean // Even if one of them failed to get set, // trying again in this frame isn't going to help for (unsigned int i = 0; i < mGeomParamPlugs.length(); i++) { dataBlock.outputValue(mGeomParamPlugs[i]).setClean(); } for (unsigned int i = 0; i < mUserAttrPlugs.length(); i++) { dataBlock.outputValue(mUserAttrPlugs[i]).setClean(); } } // get the sample SampleInfo sampleInfo = getSampleInfo(inputTime, mSchema.getTimeSampling(), mSchema.getNumSamples()); // check if we have to do this at all if (!mCurvesData.isNull() && mLastSampleInfo.floorIndex == sampleInfo.floorIndex && mLastSampleInfo.ceilIndex == sampleInfo.ceilIndex) { return MStatus::kSuccess; } mLastSampleInfo = sampleInfo; const float blend = (float)sampleInfo.alpha; // access the camera values AbcG::ICurvesSchema::Sample sample; AbcG::ICurvesSchema::Sample sample2; mSchema.get(sample, sampleInfo.floorIndex); if (blend != 0.0f) { mSchema.get(sample2, sampleInfo.ceilIndex); } Abc::P3fArraySamplePtr samplePos = sample.getPositions(); Abc::P3fArraySamplePtr samplePos2 = sample2.getPositions(); Abc::Int32ArraySamplePtr nbVertices = sample.getCurvesNumVertices(); const bool applyBlending = (blend == 0.0f) ? false : (samplePos->size() == samplePos2->size()); Abc::FloatArraySamplePtr pKnotVec = getKnotVector(mObj); Abc::UInt16ArraySamplePtr pOrders = getCurveOrders(mObj); MArrayDataHandle arrh = dataBlock.outputArrayValue(mOutGeometryAttr); MArrayDataBuilder builder = arrh.builder(); // reference: // http://download.autodesk.com/us/maya/2010help/API/multi_curve_node_8cpp-example.html const int degree = (sample.getType() == AbcG::kCubic) ? 3 : 1; const bool closed = (sample.getWrap() == AbcG::kPeriodic); unsigned int pointOffset = 0; unsigned int knotOffset = 0; for (int ii = 0; ii < nbVertices->size(); ++ii) { const unsigned int nbCVs = (unsigned int)nbVertices->get()[ii]; const int ldegree = (pOrders) ? pOrders->get()[ii] : degree; const int nbSpans = (int)nbCVs - ldegree; MDoubleArray knots; if (pKnotVec) { const unsigned int nb_knot = nbCVs + ldegree - 1; for (unsigned int i = 0; i < nb_knot; ++i) { knots.append(pKnotVec->get()[knotOffset + i]); } knotOffset += nb_knot; } else { for (int span = 0; span <= nbSpans; ++span) { knots.append(double(span)); if (span == 0 || span == nbSpans) { for (int m = 1; m < degree; ++m) { knots.append(double(span)); } } } } MPointArray points; if (samplePos->size() > 0) { points.setLength((unsigned int)nbCVs); if (applyBlending) { for (unsigned int i = 0; i < nbCVs; ++i) { const Abc::P3fArraySample::value_type &vals1 = samplePos->get()[pointOffset + i]; const Abc::P3fArraySample::value_type &vals2 = samplePos2->get()[pointOffset + i]; MPoint &pt = points[i]; pt.x = vals1.x + (vals2.x - vals1.x) * blend; pt.y = vals1.y + (vals2.y - vals1.y) * blend; pt.z = vals1.z + (vals2.z - vals1.z) * blend; } } else { for (unsigned int i = 0; i < nbCVs; ++i) { const Abc::P3fArraySample::value_type &vals = samplePos->get()[pointOffset + i]; MPoint &pt = points[i]; pt.x = vals.x; pt.y = vals.y; pt.z = vals.z; } } pointOffset += nbCVs; } // create a subd either with or without uvs MObject mmCurvesData = MFnNurbsCurveData().create(); if (ldegree == 1 || ldegree == 3) mCurves.create(points, knots, ldegree, closed ? MFnNurbsCurve::kClosed : MFnNurbsCurve::kOpen, false, false, mmCurvesData); builder.addElement(ii).set(mmCurvesData); } arrh.set(builder); arrh.setAllClean(); return MStatus::kSuccess; }
MStatus closestPointOnCurveCommand::redoIt() { // DOUBLE-CHECK TO MAKE SURE THERE'S A SPECIFIED OBJECT TO EVALUATE ON: if (sList.length() == 0) { MStatus stat; MString msg = MStringResource::getString(kNoValidObject, stat); displayError(msg); return MStatus::kFailure; } // RETRIEVE THE SPECIFIED OBJECT AS A DAGPATH: MDagPath curveDagPath; sList.getDagPath(0, curveDagPath); // CHECK FOR INVALID NODE-TYPE INPUT WHEN SPECIFIED/SELECTED NODE IS *NOT* A "CURVE" NOR "CURVE TRANSFORM": if (!curveDagPath.node().hasFn(MFn::kNurbsCurve) && !(curveDagPath.node().hasFn(MFn::kTransform) && curveDagPath.hasFn(MFn::kNurbsCurve))) { MStatus stat; MString msg; // Use format to place variable string into message MString msgFmt = MStringResource::getString(kInvalidType, stat); MStringArray selectionStrings; sList.getSelectionStrings(0, selectionStrings); msg.format(msgFmt, selectionStrings[0]); displayError(msg); return MStatus::kFailure; } // WHEN COMMAND *NOT* IN "QUERY MODE" (I.E. "CREATION MODE"), CREATE AND CONNECT A "closestPointOnCurve" NODE AND RETURN ITS NODE NAME: if (!queryFlagSet) { // CREATE THE NODE: MFnDependencyNode depNodeFn; if (closestPointOnCurveNodeName == "") depNodeFn.create("closestPointOnCurve"); else depNodeFn.create("closestPointOnCurve", closestPointOnCurveNodeName); closestPointOnCurveNodeName = depNodeFn.name(); // SET THE ".inPosition" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (inPositionFlagSet) { MPlug inPositionXPlug = depNodeFn.findPlug("inPositionX"); inPositionXPlug.setValue(inPosition.x); MPlug inPositionYPlug = depNodeFn.findPlug("inPositionY"); inPositionYPlug.setValue(inPosition.y); MPlug inPositionZPlug = depNodeFn.findPlug("inPositionZ"); inPositionZPlug.setValue(inPosition.z); } // MAKE SOME ADJUSTMENTS WHEN THE SPECIFIED NODE IS A "TRANSFORM" OF A CURVE SHAPE: unsigned instanceNumber=0; if (curveDagPath.node().hasFn(MFn::kTransform)) { // EXTEND THE DAGPATH TO ITS CURVE "SHAPE" NODE: curveDagPath.extendToShape(); // TRANSFORMS ARE *NOT* NECESSARILY THE "FIRST" INSTANCE TRANSFORM OF A CURVE SHAPE: instanceNumber = curveDagPath.instanceNumber(); } // CONNECT THE NODES: MPlug worldCurvePlug, inCurvePlug; inCurvePlug = depNodeFn.findPlug("inCurve"); depNodeFn.setObject(curveDagPath.node()); worldCurvePlug = depNodeFn.findPlug("worldSpace"); worldCurvePlug = worldCurvePlug.elementByLogicalIndex(instanceNumber); MDGModifier dgModifier; dgModifier.connect(worldCurvePlug, inCurvePlug); dgModifier.doIt(); // SET COMMAND RESULT TO BE NEW NODE'S NAME, AND RETURN: setResult(closestPointOnCurveNodeName); return MStatus::kSuccess; } // OTHERWISE, WE'RE IN THE COMMAND'S "QUERY MODE": else { // COMPUTE THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE, USING THE *FIRST* INSTANCE TRANSFORM WHEN CURVE IS SPECIFIED AS A "SHAPE": MPoint position; MVector normal, tangent; double paramU, distance; closestTangentUAndDistance(curveDagPath, inPosition, position, normal, tangent, paramU, distance); // WHEN NO QUERYABLE FLAG IS SPECIFIED, INDICATE AN ERROR: if (!positionFlagSet && !normalFlagSet && !tangentFlagSet && !paramUFlagSet && !distanceFlagSet) { MStatus stat; MString msg = MStringResource::getString(kNoQueryFlag, stat); displayError(msg); return MStatus::kFailure; } // WHEN JUST THE "DISTANCE" IS QUERIED, RETURN A SINGLE "FLOAT" INSTEAD OF AN ENTIRE FLOAT ARRAY FROM THE COMMAND: else if (distanceFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || paramUFlagSet)) setResult(distance); // WHEN JUST THE "PARAMETER-U" IS QUERIED, RETURN A SINGLE "FLOAT" INSTEAD OF AN ENTIRE FLOAT ARRAY FROM THE COMMAND: else if (paramUFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || distanceFlagSet)) setResult(paramU); // OTHERWISE, SET THE RETURN VALUE OF THE COMMAND'S RESULT TO A "COMPOSITE ARRAY OF FLOATS": else { // HOLDS FLOAT ARRAY RESULT: MDoubleArray floatArrayResult; // APPEND THE RESULTS OF THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE VALUES TO THE FLOAT ARRAY RESULT: if (positionFlagSet) { floatArrayResult.append(position.x); floatArrayResult.append(position.y); floatArrayResult.append(position.z); } if (normalFlagSet) { floatArrayResult.append(normal.x); floatArrayResult.append(normal.y); floatArrayResult.append(normal.z); } if (tangentFlagSet) { floatArrayResult.append(tangent.x); floatArrayResult.append(tangent.y); floatArrayResult.append(tangent.z); } if (paramUFlagSet) floatArrayResult.append(paramU); if (distanceFlagSet) floatArrayResult.append(distance); // FINALLY, SET THE COMMAND'S RESULT: setResult(floatArrayResult); } return MStatus::kSuccess; } }
void NifAnimationImporter::ImportControllers( NiAVObjectRef niAVObj, MDagPath & path ) { list<NiTimeControllerRef> controllers = niAVObj->GetControllers(); //Iterate over the controllers, reacting properly to each type for ( list<NiTimeControllerRef>::iterator it = controllers.begin(); it != controllers.end(); ++it ) { if ( (*it)->IsDerivedType( NiKeyframeController::TYPE ) ) { //--NiKeyframeController--// NiKeyframeControllerRef niKeyCont = DynamicCast<NiKeyframeController>(*it); NiKeyframeDataRef niKeyData = niKeyCont->GetData(); MFnTransform transFn( path.node() ); MFnAnimCurve traXFn; MFnAnimCurve traYFn; MFnAnimCurve traZFn; MObject traXcurve = traXFn.create( transFn.findPlug("translateX") ); MObject traYcurve = traYFn.create( transFn.findPlug("translateY") ); MObject traZcurve = traZFn.create( transFn.findPlug("translateZ") ); MTimeArray traTimes; MDoubleArray traXValues; MDoubleArray traYValues; MDoubleArray traZValues; vector<Key<Vector3> > tra_keys = niKeyData->GetTranslateKeys(); for ( size_t i = 0; i < tra_keys.size(); ++i) { traTimes.append( MTime( tra_keys[i].time, MTime::kSeconds ) ); traXValues.append( tra_keys[i].data.x ); traYValues.append( tra_keys[i].data.y ); traZValues.append( tra_keys[i].data.z ); //traXFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.x ); //traYFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.y ); //traZFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.z ); } traXFn.addKeys( &traTimes, &traXValues ); traYFn.addKeys( &traTimes, &traYValues ); traZFn.addKeys( &traTimes, &traZValues ); KeyType kt = niKeyData->GetRotateType(); if ( kt != XYZ_ROTATION_KEY ) { vector<Key<Quaternion> > rot_keys = niKeyData->GetQuatRotateKeys(); MFnAnimCurve rotXFn; MFnAnimCurve rotYFn; MFnAnimCurve rotZFn; MObject rotXcurve = rotXFn.create( transFn.findPlug("rotateX") ); //rotXFn.findPlug("rotationInterpolation").setValue(3); MObject rotYcurve = rotYFn.create( transFn.findPlug("rotateY") ); //rotYFn.findPlug("rotationInterpolation").setValue(3); MObject rotZcurve = rotZFn.create( transFn.findPlug("rotateZ") ); //rotZFn.findPlug("rotationInterpolation").setValue(3); MTimeArray rotTimes; MDoubleArray rotXValues; MDoubleArray rotYValues; MDoubleArray rotZValues; MEulerRotation mPrevRot; for( size_t i = 0; i < rot_keys.size(); ++i ) { Quaternion niQuat = rot_keys[i].data; MQuaternion mQuat( niQuat.x, niQuat.y, niQuat.z, niQuat.w ); MEulerRotation mRot = mQuat.asEulerRotation(); MEulerRotation mAlt; mAlt[0] = PI + mRot[0]; mAlt[1] = PI - mRot[1]; mAlt[2] = PI + mRot[2]; for ( size_t j = 0; j < 3; ++j ) { double prev_diff = abs(mRot[j] - mPrevRot[j]); //Try adding and subtracting multiples of 2 pi radians to get //closer to the previous angle while (true) { double new_angle = mRot[j] - (PI * 2); double diff = abs( new_angle - mPrevRot[j] ); if ( diff < prev_diff ) { mRot[j] = new_angle; prev_diff = diff; } else { break; } } while (true) { double new_angle = mRot[j] + (PI * 2); double diff = abs( new_angle - mPrevRot[j] ); if ( diff < prev_diff ) { mRot[j] = new_angle; prev_diff = diff; } else { break; } } } for ( size_t j = 0; j < 3; ++j ) { double prev_diff = abs(mAlt[j] - mPrevRot[j]); //Try adding and subtracting multiples of 2 pi radians to get //closer to the previous angle while (true) { double new_angle = mAlt[j] - (PI * 2); double diff = abs( new_angle - mPrevRot[j] ); if ( diff < prev_diff ) { mAlt[j] = new_angle; prev_diff = diff; } else { break; } } while (true) { double new_angle = mAlt[j] + (PI * 2); double diff = abs( new_angle - mPrevRot[j] ); if ( diff < prev_diff ) { mAlt[j] = new_angle; prev_diff = diff; } else { break; } } } //Try taking advantage of the fact that: //Rotate(x,y,z) = Rotate(pi + x, pi - y, pi +z) double rot_diff = ( (abs(mRot[0] - mPrevRot[0]) + abs(mRot[1] - mPrevRot[1]) + abs(mRot[2] - mPrevRot[2]) ) / 3.0 ); double alt_diff = ( (abs(mAlt[0] - mPrevRot[0]) + abs(mAlt[1] - mPrevRot[1]) + abs(mAlt[2] - mPrevRot[2]) ) / 3.0 ); if ( alt_diff < rot_diff ) { mRot = mAlt; } mPrevRot = mRot; rotTimes.append( MTime(rot_keys[i].time, MTime::kSeconds) ); rotXValues.append( mRot[0] ); rotYValues.append( mRot[1] ); rotZValues.append( mRot[2] ); } rotXFn.addKeys( &rotTimes, &rotXValues ); rotYFn.addKeys( &rotTimes, &rotYValues ); rotZFn.addKeys( &rotTimes, &rotZValues ); } } } }
MStatus boingRbCmd::redoIt() { if (argParser->isFlagSet("help") || argParser->isFlagSet("h")) { MString helpMsg = "boingRB - command : Boing - bullet plugin by Risto Puukko\n"; helpMsg += "---------------------------------------------------------\n"; helpMsg += "boingRB [flag] [args] \n"; helpMsg += "\n"; helpMsg += "flags :\n"; helpMsg += " -getAttr [name.attr]\n"; helpMsg += " example : boingRb -getAttr (\"boingRb1.velocity\");\n" ; helpMsg += "\n"; helpMsg += " -getAttr [*.attr]\n"; helpMsg += " example : boingRb -getAttr (\"*.name\");\n" ; helpMsg += "\n"; helpMsg += " -setAttr [name.attr] -value [float float float ]\n"; helpMsg += " example : boingRb -setAttr (\"boingRb1.velocity\") -value 0 4 3 ;\n" ; helpMsg += "\n"; helpMsg += " -addAttr [name.attr] -type [int/double/string/vector]\n"; helpMsg += " example : boingRb -addAttr \"sampleRb.IntAttribute\" -type \"int\";\n" ; helpMsg += " example : boingRb -addAttr \"sampleRb.VectorAttribute\" -type \"vector\";\n" ; helpMsg += "\n"; helpMsg += " -create [ ( \"name=string;geo=string;velocity/vel=float,float,float;position/pos=float,float,float\" )]\n"; helpMsg += " example : boingRb -create (\"name=sampleRb;geo=pCubeShape1;pos=0,4,0\");\n"; helpMsg += "\n"; helpMsg += " -exists [name]\n"; helpMsg += " example : boingRb -exists \"sampleRb\";\n" ; helpMsg += "\n"; helpMsg += " -delete [name]\n"; helpMsg += " example : boingRb -delete \"sampleRb\";\n"; helpMsg += "\n"; helpMsg += "---------------------------------------------------------\n"; MGlobal::displayInfo(helpMsg); return MS::kSuccess; } isSetAttr = argParser->isFlagSet("-setAttr"); isGetAttr = argParser->isFlagSet("-getAttr"); isAddAttr = argParser->isFlagSet("-addAttr"); isType = argParser->isFlagSet("-type"); isExists = argParser->isFlagSet("-exists"); isAttributeExist = argParser->isFlagSet("-attributeExist"); isCreate = argParser->isFlagSet("-create"); isDelete = argParser->isFlagSet("-delete"); isValue = argParser->isFlagSet("-value"); //std::cout<<"argsList : "<<*argsList<<std::endl; //unsigned i; //MStatus stat; //MVector res; // Parse the arguments. /* for (i = 0; i <argsList->length (); i++) { //MString arg = argsList->asString(i, &stat); //if (MS::kSuccess == stat) std::cout<<"arg["<<i<<"] : "<<arg<<std::endl; if ( MString ("-setAttr") == argsList->asString(i, &stat) && MString ("-value") == argsList->asString(i+2, &stat) && MS::kSuccess == stat ) { for (unsigned j=3; j!=6; ++j) res[j-3 ] = argsList->asDouble (j, &stat); } } std::cout<<"res : "<<res<<std::endl; */ if (isSetAttr && isValue) { MString sAttr; argParser->getFlagArgument("setAttr", 0, sAttr); //std::cout<<sAttr<<std::endl; MStringArray jobArgsArray = parseArguments(sAttr, "."); MString rbName = jobArgsArray[0]; MString attr = checkAttribute(jobArgsArray[1]); //std::cout<<"attr : "<<attr<<std::endl; if ( attr == "custom" ) { MString customAttr = jobArgsArray[1]; //char * custAttr = (char*)customAttr.asChar(); //std::cout<<"customAttr : "<<customAttr<<std::endl; shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node(); bSolverNode::m_custom_data *data = b_solv->getdata(rbName); //std::cout<<"data : "<<data<<std::endl; if (!data) return MS::kFailure; //std::cout<<"data->m_int_data : "<<data->m_int_data<<std::endl; MString type = b_solv->getAttrType(data, customAttr); //std::cout<<"attrype : "<<type<<std::endl; if (type == "string") { //std::cout<<"saving custom string : "<<customAttr<<std::endl; MString value; value = argsList->asString(3); data->m_string_data.append(value); b_solv->set_custom_data_string(data, customAttr, value); //data->m_attr_type.append(customAttr); //char * chars = (char *)value.asChar(); //void * char_ptr = (void *)chars; //b_solv->set_custom_data(customAttr, char_ptr); } else if (type == "double") { //std::cout<<"saving custom double : "<<customAttr<<std::endl; double value; value = argsList->asDouble(3); data->m_double_data.append(value); b_solv->set_custom_data_double(data, customAttr, value); //data->m_attr_type.append(customAttr); //void *val = &value; //b_solv->set_custom_data(customAttr, val); } else if (type == "int") { //std::cout<<"saving custom int : "<<customAttr<<std::endl; int value; value = argsList->asInt(3); //std::cout<<"argsList->get(3, value) -> value : "<<value<<std::endl; data->m_int_data.append(value); b_solv->set_custom_data_int(data, customAttr, value); //data->m_attr_type.append(customAttr); //std::cout<<"data->m_int_data : "<<data->m_int_data<<std::endl; //void *val = &value; //b_solv->set_custom_data(customAttr, val); //std::cout<<"b_solv->set_custom_data,static_cast<void*>(&value)) DONE!!!"<<std::endl; } else if (type == "vector") { //std::cout<<"saving custom vector : "<<customAttr<<std::endl; MVector value = MVector(); value.x = argsList->asDouble(3); value.y = argsList->asDouble(4); value.z = argsList->asDouble(5); data->m_vector_data.append(value); b_solv->set_custom_data_vector(data, customAttr, value); //data->m_attr_type.append(customAttr); //MVector *MVecPtr = &value; //void * vec_ptr = static_cast<void*const>(MVecPtr); //b_solv->set_custom_data(customAttr, vec_ptr); } } else { if (attr == "velocity" || attr == "position" || attr == "angularVelocity") { MVector value; value.x = argsList->asDouble(3); value.y = argsList->asDouble(4); value.z = argsList->asDouble(5); //std::cout<<"vector argument : "<<value<<std::endl; setBulletVectorAttribute(rbName, attr, value); } } //cout<<value<<endl; setResult(MS::kSuccess); } else if ( isAttributeExist ) { MString exAttr; bool result = false; argParser->getFlagArgument("attributeExist", 0, exAttr); //std::cout<<"exAttr : "<<exAttr<<std::endl; MStringArray jobArgsArray = parseArguments(exAttr, "."); MString rbname = jobArgsArray[0]; //std::cout<<"rbname : "<<rbname<<std::endl; MString attrToQuery = jobArgsArray[1]; //std::cout<<"attrToQuery : "<<attrToQuery<<std::endl; MString attr = checkAttribute(attrToQuery); //std::cout<<"attr : "<<attr<<std::endl; if ( attr == "custom" ){ // here we check if user attribute by the name attrToQuery exists shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node(); //char * queryAttr = (char*)attrToQuery.asChar(); MString attrResult = b_solv->getAttrType(b_solv->getdata(rbname), attrToQuery); if (attrResult != "") //if (b_solv->attribute_exists(attrToQuery)) result = true; //std::cout<<result<<std::endl;; setResult(result); } } else if ( isAddAttr && isType ) { MString aAttr; argParser->getFlagArgument("addAttr", 0, aAttr); //std::cout<<"aAttr : "<<aAttr<<std::endl; MStringArray jobArgsArray = parseArguments(aAttr, "."); //std::cout<<"jobArgsArray : "<<jobArgsArray<<std::endl; MString rbname = jobArgsArray[0]; MString attrAdded = jobArgsArray[1]; //char *added = (char *)attrAdded.asChar(); MString attrType; argParser->getFlagArgument("-type", 0, attrType); //char *type = (char *)attrType.asChar(); //std::cout<<"attrType : "<<attrType<<std::endl; shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node(); bSolverNode::m_custom_data *data = b_solv->getdata(rbname); data->m_attr_name.append(attrAdded); data->m_attr_type.append(attrType); b_solv->saveAttrType(data, attrAdded, attrType); //std::cout<<"attr "<<aAttr<<" added"<<std::endl; //std::cout<<"data->m_attr_type : "<<data->m_attr_type<<std::endl; //std::cout<<"data->m_attr_name : "<<data->m_attr_name<<std::endl; } else if ( isGetAttr) { MString gAttr; shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node(); argParser->getFlagArgument("getAttr", 0, gAttr); //std::cout<<gAttr<<std::endl; MStringArray jobArgsArray = parseArguments(gAttr, "."); MString rbname = jobArgsArray[0]; //std::cout<<"name : "<<rbname<<std::endl; if ( rbname == "" ) { MString errorMsg = "ERROR ! boing -getAttr must provide a rigid body name!"; displayWarning(errorMsg, true); return MS::kFailure; } MString attr = checkAttribute(jobArgsArray[1]); //std::cout<<"attr = "<<attr<<std::endl; if ( attr=="velocity" || attr=="position" || attr=="angularVelocity" ) { //MVector result = MDoubleArray dResult = getBulletVectorAttribute(rbname, attr); setResult(dResult); } else if (attr == "contactPositions") { bSolverNode::m_custom_data *data = b_solv->getdata(rbname); MDoubleArray d_points = MDoubleArray(); if ( data->m_contact_count > 0 ) { MPointArray points = data->m_contact_positions; for (int i=0; i<points.length();i++) { d_points.append(points[i].x); d_points.append(points[i].y); d_points.append(points[i].z); } } setResult(d_points); } else if (attr == "contactGeos") { MStringArray contact_objects = MStringArray(); bSolverNode::m_custom_data *data = b_solv->getdata(rbname); if ( data->m_contact_count > 0 ) { MStringArray contact_objects = data->m_contact_objects; } setResult(contact_objects); } else if (attr == "contactCount") { bSolverNode::m_custom_data *data = b_solv->getdata(rbname); int contact_count = data->m_contact_count; setResult(contact_count); } else if (attr == "name") { MStringArray result; MStringArray names = b_solv->get_all_keys(); //std::cout<<"names : "<<names<<std::endl; //std::cout<<"b_solv->getdatalength() : "<<b_solv->getdatalength()<<std::endl; for(int i=0; i < names.length(); i++) { bSolverNode::m_custom_data *data = b_solv->getdata(names[i]); if ( NULL != data) { //std::cout<<"data->name : "<<data->name<<std::endl; //std::cout<<"data->m_initial_position: "<<data->m_initial_position<<std::endl; result.append(data->name); } } setResult(result); } else if ( attr == "" ) { MString errorMsg = "ERROR ! boing -getAttr must provide an attribute name to query!"; displayWarning(errorMsg, true); return MS::kFailure; } else if ( attr == "custom" ){ // here we handle user attributes MString customAttr = jobArgsArray[1]; //char * custAttr = (char*)customAttr.asChar(); //std::cout<<"customAttr : "<<customAttr<<std::endl; MString type = b_solv->getAttrType(b_solv->getdata(rbname), customAttr); //bSolverNode::m_custom_data *data = b_solv->getdata(rbname); std::cout<<" type : "<<type<<std::endl; if (type == "string") { //char * result = static_cast<char*>(b_solv->get_custom_data(customAttr)); MString result = b_solv->get_custom_data_string(b_solv->getdata(rbname), customAttr); if (result != NULL) { //std::cout<<"result : "<<result<<std::endl; MString value(result); setResult(value); } else { displayError(MString("Error getting b_solv->get_custom_data_string(\"" + customAttr + "\")")); } } else if (type == "double") { //double *value = static_cast<double*>(b_solv->get_custom_data(customAttr)); double value = b_solv->get_custom_data_double(b_solv->getdata(rbname), customAttr); setResult(value); } else if (type == "int") { //int *value = static_cast<int*>(b_solv->get_custom_data(customAttr)); int value = b_solv->get_custom_data_int(b_solv->getdata(rbname), customAttr); setResult(value); } else if (type == "vector") { //void * result = b_solv->get_custom_data(customAttr); //MVector *vec_res = (MVector*)result; MVector result = b_solv->get_custom_data_vector(b_solv->getdata(rbname), customAttr); MDoubleArray value; value.append(result.x); value.append(result.y); value.append(result.z); setResult(value); } } } else if ( isCreate ) { MString aArgument; argParser->getFlagArgument("-create", 0, aArgument); MStringArray createArgs = parseArguments(aArgument,";"); int size = createArgs.length(); MString inputShape; MString rbname = "dummyRb"; MVector av; MVector vel; MVector pos; MVector rot; for (int i=0; i!=size; ++i) { MStringArray singleArg = parseArguments(createArgs[i],"="); //std::cout<<"singleArg : "<<singleArg<<std::endl; if (singleArg[0] == "name") { rbname = singleArg[1]; } else if (singleArg[0] == "geo") { //geo inputShape = singleArg[1]; //std::cout<<"geo = "<<inputShape<<std::endl; } else if (singleArg[0] == "vel") { //initialvelocity MStringArray velArray = parseArguments(singleArg[1], ","); vel = MVector(velArray[0].asDouble(), velArray[1].asDouble(), velArray[2].asDouble() ); //std::cout<<"velocity = "<<vel<<std::endl; } else if (singleArg[0] == "pos") { //initialposition MStringArray posArray = parseArguments(singleArg[1], ","); pos = MVector(posArray[0].asDouble(), posArray[1].asDouble(), posArray[2].asDouble() ); //std::cout<<"position = "<<pos<<std::endl; } else if (singleArg[0] == "rot") { //initialrotation MStringArray rotArray = parseArguments(singleArg[1], ","); rot = MVector(rotArray[0].asDouble(), rotArray[1].asDouble(), rotArray[2].asDouble() ); //std::cout<<"rotation = "<<rot<<std::endl; } else if (singleArg[0] == "av") { //initialAngularVelocity MStringArray avArray = parseArguments(singleArg[1], ","); av = MVector(avArray[0].asDouble(), avArray[1].asDouble(), avArray[2].asDouble() ); //std::cout<<"initialAngularVelocity = "<<av<<std::endl; } else { std::cout<<"Unrecognized parameter : "<<singleArg[0]<<std::endl; } } // create boing node shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node(); MObject node = nameToNode(inputShape); float mass = 1.0f; MString tname = "boing"; MStatus stat = b_solv->createNode(node, rbname, tname, pos, vel, rot, av, mass); if (MS::kSuccess == stat) { setResult(rbname); } else { MGlobal::displayError(MString("Something went wrong when trying to create rigidbody : " + rbname + " .")); } } else if ( isDelete ) { MString aArgument; argParser->getFlagArgument("-delete", 0, aArgument); //std::cout<<"delete aArgument "<<aArgument<<std::endl; if (aArgument != "") { shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node(); b_solv->deletedata(aArgument); MStatus stat = b_solv->delete_key(aArgument, -1); if (stat != MS::kSuccess) { std::cerr<<"error occurred deleting "<<aArgument<<" ."<<std::endl; setResult(1); } } } else if ( isExists ) { MString exArg; argParser->getFlagArgument("-exists", 0, exArg); //std::cout<<"exArg : "<<exArg<<std::endl; if (exArg != "") { shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node(); bSolverNode::m_custom_data *data = b_solv->getdata(exArg); int result = false; if ( NULL != data ) { //setResult ( data->name ); result = true; } setResult(result); } } return MS::kSuccess; }
MStatus particlePathsCmd::doIt( const MArgList& args ) { MStatus stat = parseArgs( args ); if( stat != MS::kSuccess ) { return stat; } MFnParticleSystem cloud( particleNode ); if( ! cloud.isValid() ) { MGlobal::displayError( "The function set is invalid!" ); return MS::kFailure; } // // Create curves from the particle system in two stages. First, sample // all particle positions from the start time to the end time. Then, // use the data that was collected to create curves. // // Create the particle hash table at a fixed size. This should work fine // for small particle systems, but may become inefficient for larger ones. // If the plugin is running very slow, increase the size. The value should // be roughly the number of particles that are expected to be emitted // within the time period. // ParticleIdHash hash(1024); MIntArray idList; // // Stage 1 // MVectorArray positions; MIntArray ids; int i = 0; for (double time = start; time <= finish + TOLERANCE; time += increment) { MTime timeSeconds(time,MTime::kSeconds); // It is necessary to query the worldPosition attribute to force the // particle positions to update. // cloud.evaluateDynamics(timeSeconds,false); // MGlobal::executeCommand(MString("getAttr ") + cloud.name() + // MString(".worldPosition")); if (!cloud.isValid()) { MGlobal::displayError( "Particle system has become invalid." ); return MS::kFailure; } MGlobal::displayInfo( MString("Received ") + (int)(cloud.count()) + " particles, at time " + time); // Request position and ID data for particles // cloud.position( positions ); cloud.particleIds( ids ); if (ids.length() != cloud.count() || positions.length() != cloud.count()) { MGlobal::displayError( "Invalid array sizes." ); return MS::kFailure; } for (int j = 0; j < (int)cloud.count(); j++) { // Uncomment to show particle positions as the plugin accumulates // samples. /* MGlobal::displayInfo(MString("(") + (positions[j])[0] + MString(",") + (positions[j])[1] + MString(",") + (positions[j])[2] + MString(")")); */ MPoint pt(positions[j]); if (hash.getPoints(ids[j]).length() == 0) { idList.append(ids[j]); } hash.insert(ids[j],pt); } i++; } // // Stage 2 // for (i = 0; i < (int)(idList.length()); i++) { MPointArray points = hash.getPoints(idList[i]); // Don't bother with single samples if (points.length() <= 1) { continue; } // Add two additional points, so that the curve covers all sampled // values. // MPoint p1 = points[0]*2 - points[1]; MPoint p2 = points[points.length()-1]*2 - points[points.length()-2]; points.insert(p1,0); points.append(p2); // Uncomment to show information about the generated curves /* MGlobal::displayInfo( MString("ID ") + (int)(idList[i]) + " has " + (int)(points.length()) + " curve points."); for (int j = 0; j < (int)(points.length()); j++) { MGlobal::displayInfo(MString("(") + points[j][0] + MString(",") + points[j][1] + MString(",") + points[j][2] + MString(")")); } */ MDoubleArray knots; knots.insert(0.0,0); for (int j = 0; j < (int)(points.length()); j++) { knots.append((double)j); } knots.append(points.length()-1); MStatus status; MObject dummy; MFnNurbsCurve curve; curve.create(points,knots,3,MFnNurbsCurve::kOpen,false,false,dummy,&status); if (!status) { MGlobal::displayError("Failed to create nurbs curve."); return MS::kFailure; } } return MS::kSuccess; }
MStatus CreateCurves::createCurve(Model::Strand & strand) { MStatus status; std::cerr << "Working with strand defined by base: " << strand.getDefiningBase().getDagPath(status).fullPathName().asChar() << std::endl; /* * Make sure this base is an end base (5') */ Model::Strand::BackwardIterator base_it = std::find_if(strand.reverse_begin(), strand.reverse_end(), Model::Strand::BaseTypeFunc(Model::Base::FIVE_PRIME_END)); /* * If we found an end base, use it, if not, it's a loop and it wont matter but we have to close the curve */ bool isLoop = base_it == strand.reverse_end(); Model::Strand strand_(isLoop ? strand.getDefiningBase() : *base_it); std::cerr << "5' end or loop base: " << strand_.getDefiningBase().getDagPath(status).fullPathName().asChar() << std::endl; MPointArray pointArray; MDoubleArray knotSequences; /* * Notice that the first point is different, it is as if it was inserted 4 times * Also notice that radius is probably normally never changed, but is taken into account * radius is only measured on the X,Y plane */ MVector translation; for(Model::Strand::ForwardIterator it = strand_.forward_begin(); it != strand_.forward_end(); ++it) { /* * Extract our coordinates, then interpolate between the last coordinates and these m_degree times */ if (!(status = it->getTranslation(translation, MSpace::kWorld))) { status.perror("Base::getTranslation"); return status; } pointArray.append(translation); } /* * Now create the CV curve */ knotSequences.setSizeIncrement(pointArray.length() + 2 * (unsigned int) m_degree - 1); for(int i = 0; i < m_degree - 1; ++i) knotSequences.append(0); for(unsigned int i = 0; i < pointArray.length() - 2; ++i) knotSequences.append(i); for(int i = 0; i < m_degree - 1; ++i) knotSequences.append(pointArray.length() - 3); m_curve_data.push_back(Curve(pointArray, knotSequences, isLoop)); if (!(status = m_curve_data.back().create(*this))) { status.perror("Curve::create"); return status; } return MStatus::kSuccess; }
MStatus pointOnMeshCommand::redoIt() { // WHEN NO MESH IS SPECIFIED IN THE COMMAND, GET THE FIRST SELECTED MESH FROM THE SELECTION LIST: MSelectionList sList; if (meshNodeName=="") { MGlobal::getActiveSelectionList(sList); if (sList.length()==0) { displayError("No mesh or mesh transform specified!"); return MS::kFailure; } } // OTHERWISE, USE THE NODE NAME SPECIFIED IN THE LAST ARGUMENT OF THE COMMAND: else if (sList.add(meshNodeName) == MS::kInvalidParameter) { displayError("Specified mesh does not exist!"); return MS::kFailure; } // RETRIEVE THE FIRST ITEM FROM THE SELECTION LIST: MDagPath meshDagPath; sList.getDagPath(0, meshDagPath); // CREATE AND CONNECT A "pointOnMeshInfo" NODE, OR GET THE POINT AND NORMAL ACCORDING TO // WHETHER THE "-position/-p" AND/OR "-normal/-nr" FLAGS WERE SPECIFIED, AND WHETHER THE MESH // "SHAPE" OR ITS "TRANSFORM" WAS SPECIFIED/SELECTED: MPoint point; MVector normal; // WHEN THE SPECIFIED NODE IS THE MESH "SHAPE": if (meshDagPath.node().hasFn(MFn::kMesh)) { // WHEN NEITHER "-position/-p" NOR "-normal/-nr" ARE SPECIFIED, CREATE AND CONNECT A "pointOnMeshInfo" NODE AND RETURN ITS NODE NAME: if (!positionSpecified && !normalSpecified) { // CREATE THE NODE: nodeCreated = true; MFnDependencyNode depNodeFn; if (pointOnMeshInfoName == "") depNodeFn.create("pointOnMeshInfo"); else depNodeFn.create("pointOnMeshInfo", pointOnMeshInfoName); pointOnMeshInfoName = depNodeFn.name(); // SET THE ".faceIndex" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (faceIndexSpecified) { MPlug faceIndexPlug = depNodeFn.findPlug("faceIndex"); faceIndexPlug.setValue(faceIndex); } // SET THE ".relative" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (relativeSpecified) { MPlug relativePlug = depNodeFn.findPlug("relative"); relativePlug.setValue(relative); } // SET THE ".parameterU" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (parameterUSpecified) { MPlug parameterUPlug = depNodeFn.findPlug("parameterU"); parameterUPlug.setValue(parameterU); } // SET THE ".parameterV" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (parameterVSpecified) { MPlug parameterVPlug = depNodeFn.findPlug("parameterV"); parameterVPlug.setValue(parameterV); } // CONNECT THE NODES: MPlug worldMeshPlug, inMeshPlug; inMeshPlug = depNodeFn.findPlug("inMesh"); depNodeFn.setObject(meshDagPath.node()); worldMeshPlug = depNodeFn.findPlug("worldMesh"); worldMeshPlug = worldMeshPlug.elementByLogicalIndex(0); // ASSUME THE *FIRST* INSTANCE OF THE MESH IS REQUESTED FOR MESH SHAPES. MDGModifier dgModifier; dgModifier.connect(worldMeshPlug, inMeshPlug); dgModifier.doIt(); // SET COMMAND RESULT AND RETURN: setResult(pointOnMeshInfoName); return MStatus::kSuccess; } // OTHERWISE, COMPUTE THE POINT-POSITION AND NORMAL, USING THE *FIRST* INSTANCE'S TRANSFORM: else getPointAndNormal(meshDagPath, faceIndex, relative, parameterU, parameterV, point, normal); } // WHEN THE SPECIFIED NODE IS A "TRANSFORM" OF A MESH SHAPE: else if (meshDagPath.node().hasFn(MFn::kTransform) && meshDagPath.hasFn(MFn::kMesh)) { // WHEN NEITHER "-position/-p" NOR "-normal/-nr" ARE SPECIFIED, CREATE AND CONNECT A "pointOnMeshInfo" NODE AND RETURN ITS NODE NAME: if (!positionSpecified && !normalSpecified) { // CREATE THE NODE: nodeCreated = true; meshDagPath.extendToShape(); MFnDependencyNode depNodeFn; if (pointOnMeshInfoName == "") depNodeFn.create("pointOnMeshInfo"); else depNodeFn.create("pointOnMeshInfo", pointOnMeshInfoName); pointOnMeshInfoName = depNodeFn.name(); // SET THE ".faceIndex" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (faceIndexSpecified) { MPlug faceIndexPlug = depNodeFn.findPlug("faceIndex"); faceIndexPlug.setValue(faceIndex); } // SET THE ".relative" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (relativeSpecified) { MPlug relativePlug = depNodeFn.findPlug("relative"); relativePlug.setValue(relative); } // SET THE ".parameterU" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (parameterUSpecified) { MPlug parameterUPlug = depNodeFn.findPlug("parameterU"); parameterUPlug.setValue(parameterU); } // SET THE ".parameterV" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (parameterVSpecified) { MPlug parameterVPlug = depNodeFn.findPlug("parameterV"); parameterVPlug.setValue(parameterV); } // CONNECT THE NODES: MPlug worldMeshPlug, inMeshPlug; inMeshPlug = depNodeFn.findPlug("inMesh"); depNodeFn.setObject(meshDagPath.node()); worldMeshPlug = depNodeFn.findPlug("worldMesh"); worldMeshPlug = worldMeshPlug.elementByLogicalIndex(meshDagPath.instanceNumber()); MDGModifier dgModifier; dgModifier.connect(worldMeshPlug, inMeshPlug); dgModifier.doIt(); // SET COMMAND RESULT AND RETURN: setResult(pointOnMeshInfoName); return MStatus::kSuccess; } // OTHERWISE, COMPUTE THE POINT-POSITION AND NORMAL: else getPointAndNormal(meshDagPath, faceIndex, relative, parameterU, parameterV, point, normal); } // INVALID INPUT WHEN SPECIFIED/SELECTED NODE IS NOT A MESH NOR TRANSFORM: else { displayError("Invalid type! Only a mesh or its transform can be specified!"); return MStatus::kFailure; } // SET THE RETURN VALUES OF THE COMMAND'S RESULT TO BE AN ARRAY OF FLOATS OUTPUTTING THE POSITION AND/OR NORMAL: MDoubleArray result; if (positionSpecified) { result.append(point.x); result.append(point.y); result.append(point.z); } if (normalSpecified) { result.append(normal.x); result.append(normal.y); result.append(normal.z); } setResult(result); return MStatus::kSuccess; }