Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/*
-----------------------------------------

	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;

}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
    
}
Esempio n. 6
0
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()
            );
    }
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
//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;
}
Esempio n. 14
0
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 );
			}
		}
	}
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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;
		}
Esempio n. 20
0
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;

}