Ejemplo n.º 1
0
// Reference: OSD shape_utils.h:: applyTags() "corner"
static float
getCreaseVertices( MFnMesh const & inMeshFn, Descriptor & outDesc) {

    MUintArray tVertexIds;
    MDoubleArray tCreaseData;
    float maxCreaseValue = 0.0f;

    if ( inMeshFn.getCreaseVertices(tVertexIds, tCreaseData) ) {

        assert( tVertexIds.length() == tCreaseData.length() );

        int    ncorners = tVertexIds.length();
        int *     verts = new int[ncorners*2];
        float * weights = new float[ncorners];

        // Has crease vertices
        for (unsigned int j=0; j < tVertexIds.length(); j++) {

            assert( tCreaseData[j] >= 0.0 );

            verts[j] = tVertexIds[j];
            weights[j] = float(tCreaseData[j]);

            maxCreaseValue = std::max(float(tCreaseData[j]), maxCreaseValue);
        }

        outDesc.numCorners = ncorners;
        outDesc.cornerVertexIndices = verts;
        outDesc.cornerWeights = weights;
    }
    return maxCreaseValue;
}
Ejemplo n.º 2
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;

}
Ejemplo n.º 3
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;
}
bool ToMayaMatrixVectorDataConverter<F>::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const
{
	MStatus s;

	typename F::ConstPtr data = IECore::runTimeCast<const F>( from );
	if( !data )
	{
		return false;
	}

	MFnDoubleArrayData fnData;
	
	const typename F::ValueType &v = data->readable();
	
	MDoubleArray array;
	array.setLength( v.size() * 16 );

	for ( unsigned i=0; i < v.size(); i++ )
	{
		for ( unsigned j=0; j < 4; j++ )
		{
			for ( unsigned k=0; k < 4; k++ )
			{
				array[ i*16 + j*4 + k ] = (double)v[i][j][k];
			}
		}
	}

	to = fnData.create( array, &s );
	
	return s;
}
Ejemplo n.º 5
0
bool
PxrUsdMayaWriteUtil::ReadMayaAttribute(
        const MFnDependencyNode& depNode,
        const MString& name,
        VtFloatArray* val)
{
    MStatus status;
    depNode.attribute(name, &status);

    if (status == MS::kSuccess) {
        MPlug plug = depNode.findPlug(name);
        MObject dataObj;

        if ( (plug.getValue(dataObj) == MS::kSuccess) &&
             (dataObj.hasFn(MFn::kDoubleArrayData)) ) {

            MFnDoubleArrayData dData(dataObj, &status);
            if (status == MS::kSuccess) {
                MDoubleArray arrayValues = dData.array();
                size_t numValues = arrayValues.length();
                val->resize(numValues);
                for (size_t i = 0; i < numValues; ++i) {
                    (*val)[i] = arrayValues[i];
                }
                return true;
            }
        }
    }

    return false;
}
Ejemplo n.º 6
0
// Reference: OSD shape_utils.h:: applyTags() "crease"
static float
getCreaseEdges(MFnMesh const & inMeshFn, Descriptor & outDesc) {

    MUintArray tEdgeIds;
    MDoubleArray tCreaseData;
    float maxCreaseValue = 0.0f;

    if (inMeshFn.getCreaseEdges(tEdgeIds, tCreaseData)) {

        assert( tEdgeIds.length() == tCreaseData.length() );

        int    ncreases = tEdgeIds.length();
        int * vertPairs = new int[ncreases*2];
        float * weights = new float[ncreases];

        int2 edgeVerts;
        for (unsigned int j=0; j < tEdgeIds.length(); j++) {

            assert( tCreaseData[j] >= 0.0 );
            inMeshFn.getEdgeVertices(tEdgeIds[j], edgeVerts);

            vertPairs[j*2  ] = edgeVerts[0];
            vertPairs[j*2+1] = edgeVerts[1];
            weights[j] = float(tCreaseData[j]);
            maxCreaseValue = std::max(float(tCreaseData[j]), maxCreaseValue);
        }

        outDesc.numCreases = ncreases;
        outDesc.creaseVertexIndexPairs = vertPairs;
        outDesc.creaseWeights = weights;
    }
    return maxCreaseValue;
}
Ejemplo n.º 7
0
// Reference: OSD shape_utils.h:: applyTags() "corner"
float
applyCreaseVertices( MFnMesh const & inMeshFn, HMesh * hbrMesh ) {

    MUintArray tVertexIds;
    MDoubleArray tCreaseData;
    float maxCreaseValue = 0.0f;

    if ( inMeshFn.getCreaseVertices(tVertexIds, tCreaseData) ) {

        assert( tVertexIds.length() == tCreaseData.length() );

        // Has crease vertices
        for (unsigned int j=0; j < tVertexIds.length(); j++) {

            // Assumption: The OSD vert ids are identical to those of the Maya mesh

            HVertex * v = hbrMesh->GetVertex( tVertexIds[j] );
            if(v) {

                assert( tCreaseData[j] >= 0.0 );

                v->SetSharpness( (float)tCreaseData[j] );

                maxCreaseValue = std::max(float(tCreaseData[j]), maxCreaseValue);
            } else {
                fprintf(stderr,
                    "warning: cannot find vertex for corner tag (%d)\n",
                        tVertexIds[j] );
           }
        }
    }
    return maxCreaseValue;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
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;
    
}
void
VertexPolyColourCommand::WriteColoursToNode(MDagPath& dagPath, MColorArray& colors, bool isSource)
{
	MStatus status;

	// Try to find the colour node attached to the mesh
	// If it's not found, create it
	MObject ourNode;
	if (!FindNodeOnMesh(dagPath,ourNode))
	{
		CreateNodeOnMesh(dagPath, ourNode);
	}

	// Send the selection to the node
	{
		// Pass the component list down to the node.
		// To do so, we create/retrieve the current plug
		// from the uvList attribute on the node and simply
		// set the value to our component list.
		//

		MDoubleArray dcols;
		dcols.setLength(colors.length()*4);
		int idx = 0;
		for (unsigned int i=0; i<colors.length(); i++)
		{
			dcols[idx] = (double)colors[i].r; idx++;
			dcols[idx] = (double)colors[i].g; idx++;
			dcols[idx] = (double)colors[i].b; idx++;
			dcols[idx] = (double)colors[i].a; idx++;
		}
		MFnDoubleArrayData wrapper;
		wrapper.create(dcols,&status);

		MPlug* colourPlug = NULL;
		if (isSource)
		{
			colourPlug = new MPlug(ourNode, PolyColourNode::m_colors);
		}
		else
		{
			colourPlug = new MPlug(ourNode, PolyColourNode::m_colorsDest);
		}

		// Warning, we have to do this as GCC doesn't like to pass by temporary reference
		MObject wrapperObjRef = wrapper.object();
		status = colourPlug->setValue(wrapperObjRef);
		delete colourPlug;
	}
}
Ejemplo n.º 12
0
void dynExprField::apply(
MDataBlock         &block,
int                 receptorSize,
const MDoubleArray &magnitudeArray,
const MDoubleArray &magnitudeOwnerArray,
const MVectorArray &directionArray,
const MVectorArray &directionOwnerArray,
MVectorArray       &outputForce
)
//
//      Compute output force for each particle.  If there exists the 
//      corresponding per particle attribute, use the data passed from
//      particle shape (stored in magnitudeArray and directionArray).  
//      Otherwise, use the attribute value from the field.
//
{
        // get the default values
	MVector defaultDir = direction(block);
	double  defaultMag = magnitude(block);
	int magArraySize = magnitudeArray.length();
	int dirArraySize = directionArray.length();
	int magOwnerArraySize = magnitudeOwnerArray.length();
	int dirOwnerArraySize = directionOwnerArray.length();
	int numOfOwner = magOwnerArraySize;
	if( dirOwnerArraySize > numOfOwner )
	    numOfOwner = dirOwnerArraySize;

	double  magnitude = defaultMag;
	MVector direction = defaultDir;

	for (int ptIndex = 0; ptIndex < receptorSize; ptIndex ++ ) {
	    if(receptorSize == magArraySize)
	        magnitude = magnitudeArray[ptIndex];
	    if(receptorSize == dirArraySize)
	        direction = directionArray[ptIndex];
	    if( numOfOwner > 0) {
	        for( int nthOwner = 0; nthOwner < numOfOwner; nthOwner++ ) {
		    if(magOwnerArraySize == numOfOwner)
		        magnitude = magnitudeOwnerArray[nthOwner];
		    if(dirOwnerArraySize == numOfOwner)
		        direction = directionOwnerArray[nthOwner];
		    outputForce.append( direction * magnitude );
		}
	    } else {
	        outputForce.append( direction * magnitude );
	    }
	}
}
Ejemplo n.º 13
0
AlembicWriteJob::AlembicWriteJob(const MString &in_FileName,
                                 const MObjectArray &in_Selection,
                                 const MDoubleArray &in_Frames, bool use_ogawa,
                                 const std::vector<std::string> &in_prefixFilters,
                                 const std::set<std::string> &in_attributes,
                                 const std::vector<std::string> &in_userPrefixFilters,
                                 const std::set<std::string> &in_userAttributes)
    : useOgawa(use_ogawa),
    mPrefixFilters(in_prefixFilters),
    mAttributes(in_attributes),
    mUserPrefixFilters(in_userPrefixFilters),
    mUserAttributes(in_userAttributes)
{
  // ensure to clear the isRefAnimated cache
  clearIsRefAnimatedCache();

  mFileName = in_FileName;
  for (unsigned int i = 0; i < in_Selection.length(); i++) {
    mSelection.append(in_Selection[i]);
  }

  for (unsigned int i = 0; i < in_Frames.length(); i++) {
    mFrames.push_back(in_Frames[i]);
  }
}
Ejemplo n.º 14
0
// Reference: OSD shape_utils.h:: applyTags() "crease"
float
applyCreaseEdges(MFnMesh const & inMeshFn, HMesh * hbrMesh) {

    MStatus returnStatus;
    MUintArray tEdgeIds;
    MDoubleArray tCreaseData;
    float maxCreaseValue = 0.0f;

    if (inMeshFn.getCreaseEdges(tEdgeIds, tCreaseData)) {

        assert( tEdgeIds.length() == tCreaseData.length() );

        // Has crease edges
        int2 edgeVerts;
        for (unsigned int j=0; j < tEdgeIds.length(); j++) {

            // Get vert ids from maya edge
            int edgeId = tEdgeIds[j];
            returnStatus = inMeshFn.getEdgeVertices(edgeId, edgeVerts);

            // Assumption: The OSD vert ids are identical to those of the Maya mesh
            HVertex const * v = hbrMesh->GetVertex( edgeVerts[0] ),
                          * w = hbrMesh->GetVertex( edgeVerts[1] );

            HHalfedge * e = 0;
            if( v and w ) {

                if( (e = v->GetEdge(w)) == 0) {
                    e = w->GetEdge(v);
                }

                if(e) {
                    assert( tCreaseData[j] >= 0.0 );
                    e->SetSharpness( (float)tCreaseData[j] );

                    maxCreaseValue = std::max(float(tCreaseData[j]), maxCreaseValue);
                } else {
                    fprintf(stderr,
                        "warning: cannot find edge for crease tag (%d,%d)\n",
                            edgeVerts[0], edgeVerts[1] );
                }
            }
        }
    }
    return maxCreaseValue;
}
Ejemplo n.º 15
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()
            );
    }
}
Ejemplo n.º 16
0
void skinClusterWeights::doItQuery()
{
    MStatus status;
    unsigned int i, j;

    MDoubleArray weights;
    // To allow "skinClusterWeights -q" to return empty double array
    setResult(weights);
    MSelectionList selList;
    for (i = 0; i < geometryArray.length(); i++) {
	MDagPath dagPath;
	MObject  component;
	  
	selList.clear();
	selList.add(geometryArray[i]);
	MStatus status = selList.getDagPath(0, dagPath, component);
	if (status != MS::kSuccess) {
	    continue;
	}
	if (component.isNull()) dagPath.extendToShape();
	  
	MObject skinCluster = findSkinCluster(dagPath);
	if (!isSkinClusterIncluded(skinCluster)) {
	    continue;
	}  

	MFnSkinCluster skinClusterFn(skinCluster, &status);
	if (status != MS::kSuccess) {
	    continue; 
	}

	MIntArray influenceIndexArray;
	populateInfluenceIndexArray(skinClusterFn, influenceIndexArray);
	  
	weights.clear();
	skinClusterFn.getWeights(dagPath, component, influenceIndexArray, weights);

	if (weights.length() > 0) {
	    for (j = 0; j < weights.length(); j++) {
		appendToResult(weights[j]);
	    }
	}
    }
}
Ejemplo n.º 17
0
MStatus mDbl1dNoise::doIt( const MArgList& args )
{
	// get the arguments
    MDoubleArray dblA;
    unsigned int count;
	MStatus stat = getArgDbl(args, dblA, count);
	ERROR_FAIL(stat);
    
	// do the actual job
	Noise noiseGen;
    
	for (unsigned int i=0;i<dblA.length();i++)
	{
        dblA[i] = noiseGen.improvedPerlin1dS(float(dblA[i]));
	}

	setResult(dblA);
	return MS::kSuccess;
}
Ejemplo n.º 18
0
MStatus mDblSignedToUnsigned::doIt( const MArgList& args )
{
	// get the arguments
    MDoubleArray dblA;
    unsigned int count;
	MStatus stat = getArgDbl(args, dblA, count);
	ERROR_FAIL(stat);
    
    
	// do the actual job

	for (unsigned int i=0;i<dblA.length();i++)
	{
        dblA[i] = (0.5 * dblA[i] + 0.5);
	}

	setResult(dblA);
	return MS::kSuccess;
}
Ejemplo n.º 19
0
MStatus ReduceArrayNode::compute(const MPlug& plug, MDataBlock& data)
{
    if (plug != aOutput)
        return MS::kUnknownParameter;

    MStatus status;

    MDataHandle inputHandle = data.inputValue(aInput, &status);
    CHECK_MSTATUS_AND_RETURN_IT(status);

    MFnDoubleArrayData inputArrayData(inputHandle.data());
    MDoubleArray inputArray = inputArrayData.array();
    int numInputs = inputArray.length();

    short operation = data.inputValue(aOperation).asShort();

    double output = numInputs > 0 ? inputArray[0] : 0.0;

    if (operation == kLENGTH)
    {
        output = double(numInputs);
    } else {
        for (int i = 1; i < numInputs; i++)
        {
            output = computeOutput(output, inputArray[i], operation, status);

            if (!status)
            {
                reportComputeError(this, operation);
                break;
            }
        }
    }

    MDataHandle outputHandle = data.outputValue(this->aOutput);
    outputHandle.setDouble(output);
    outputHandle.setClean();

    return MS::kSuccess;
}
Ejemplo n.º 20
0
MStatus getMDoubleArray(MObject &node, MString attrString, MDoubleArray &arr)
{
    MStatus stat; 
    MFnDependencyNode nodeFn(node);
    
    MObject attr = nodeFn.attribute( attrString, &stat );  MCheckStatus(stat,"ERROR node.attribute()"); 
    MPlug plug( node, attr );
    MDataHandle handle; plug.getValue( handle );
    arr.copy(MFnDoubleArrayData(handle.data()).array());
    plug.destructHandle(handle);
    
    return MS::kSuccess;
}
Ejemplo n.º 21
0
void CalculateSampleWeights(const std::map<int, double>& distances, double radius,
                            MIntArray& vertexIds, MDoubleArray& weights) {
  
  std::map<int, double>::const_iterator itDistance;
  std::vector<std::pair<int, double> > samples;
  for (itDistance = distances.begin();
        itDistance != distances.end();
        itDistance++) {
    double x = itDistance->second;
    double w = 1.0 - (x/radius);
    samples.push_back(std::pair<int, double>(itDistance->first, w));
  }

  // Make the samples a multiple of 4 so we can use fast intrinsics!
  int remainder = 4 - ((samples.size()-1) % 4);
  if (remainder != 4) {
    for (int i = 0; i < remainder; ++i) {
      samples.push_back(std::pair<int, double>(0, 0.0));
    }
  }

  unsigned int length = (unsigned int)samples.size();
  weights.setLength(length);
  vertexIds.setLength(length);
  std::sort(samples.begin(), samples.end(), SampleSort);
  std::vector<std::pair<int, double> >::iterator iter;
  int ii = 0;
  double sum = 0.0;
  for (iter = samples.begin(); iter != samples.end(); ++iter, ++ii) {
    vertexIds[ii] = (*iter).first;
    weights[ii] = (*iter).second;
    sum += (*iter).second;
  }
  assert(sum > 0.0);
  // Normalize the weights
  for (unsigned int i = 0; i < weights.length(); ++i) {
    weights[i] /= sum;
  }
}
Ejemplo n.º 22
0
MStatus
XmlCacheFormat::readDoubleArray( MDoubleArray& array, unsigned arraySize )
{
	MStringArray value;
	readXmlTagValue(doubleArrayTag, value);

	assert( value.length() == arraySize );
	array.setLength( arraySize );
	for ( unsigned int i = 0; i < value.length(); i++ )
	{
		array[i] = strtod( value[i].asChar(), NULL );
	}
	
	return MS::kSuccess;
}
Ejemplo n.º 23
0
MStatus
XmlCacheFormat::writeDoubleArray( const MDoubleArray& array )
{
	int size = array.length();
	assert(size != 0);

	writeXmlTagValue(sizeTag,size);

	startXmlBlock( doubleArrayTag );
	for(int i = 0; i < size; i++)
	{
	    writeXmlValue(array[i]);
	}
	endXmlBlock();
	return MS::kSuccess;
}
Ejemplo n.º 24
0
void GetValidUp(const MDoubleArray& weights, const MPointArray& points,
                const MIntArray& sampleIds, const MPoint& origin, const MVector& normal,
                MVector& up) {
  MVector unitUp = up.normal();
  // Adjust up if it's parallel to normal or if it's zero length
  if (std::abs((unitUp * normal) - 1.0) < 0.001 || up.length() < 0.0001) {
    for (unsigned int j = 0; j < weights.length()-1; ++j) {
      up -= (points[sampleIds[j]] - origin) * weights[j];
      unitUp = up.normal();
      if (std::abs((unitUp * normal) - 1.0) > 0.001 && up.length() > 0.0001) {
        // If the up and normal vectors are no longer parallel and the up vector has a length,
        // then we are good to go.
        break;
      }
    }
    up.normalize();
  } else {
    up = unitUp;
  }
}
Ejemplo n.º 25
0
void CalculateBasisComponents(const MDoubleArray& weights, const BaryCoords& coords,
                              const MIntArray& triangleVertices, const MPointArray& points,
                              const MFloatVectorArray& normals, const MIntArray& sampleIds,
                              double* alignedStorage,
                              MPoint& origin, MVector& up, MVector& normal) {
  // Start with the recreated point and normal using the barycentric coordinates of the hit point.
  unsigned int hitIndex = weights.length()-1;
#ifdef __AVX__
  __m256d originV = Dot4<MPoint>(coords[0], coords[1], coords[2], 0.0,
                                points[triangleVertices[0]], points[triangleVertices[1]],
                                points[triangleVertices[2]], MPoint::origin);
  __m256d hitNormalV = Dot4<MVector>(coords[0], coords[1], coords[2], 0.0,
                                normals[triangleVertices[0]], normals[triangleVertices[1]],
                                normals[triangleVertices[2]], MVector::zero);
  __m256d hitWeightV = _mm256_set1_pd(weights[hitIndex]);
  // Create the barycentric point and normal.
  __m256d normalV = _mm256_mul_pd(hitNormalV, hitWeightV);
  // Then use the weighted adjacent data.
  for (unsigned int j = 0; j < hitIndex; j += 4) {
    __m256d tempNormal = Dot4<MVector>(weights[j], weights[j+1], weights[j+2], weights[j+3],
                                       normals[sampleIds[j]], normals[sampleIds[j+1]],
                                       normals[sampleIds[j+2]], normals[sampleIds[j+3]]);
    normalV = _mm256_add_pd(tempNormal, normalV);
  }

  _mm256_store_pd(alignedStorage, originV);
  origin.x = alignedStorage[0];
  origin.y = alignedStorage[1];
  origin.z = alignedStorage[2];
  _mm256_store_pd(alignedStorage, normalV);
  normal.x = alignedStorage[0];
  normal.y = alignedStorage[1];
  normal.z = alignedStorage[2];

  // Calculate the up vector
  const MPoint& pt1 = points[triangleVertices[0]];
  const MPoint& pt2 = points[triangleVertices[1]];
  __m256d p1 = _mm256_set_pd(pt1.w, pt1.z, pt1.y, pt1.x);
  __m256d p2 = _mm256_set_pd(pt2.w, pt2.z, pt2.y, pt2.x);
  p1 = _mm256_add_pd(p1, p2);
  __m256d half = _mm256_set_pd(0.5, 0.5, 0.5, 0.5);
  p1 = _mm256_mul_pd(p1, half);
  __m256d upV = _mm256_sub_pd(p1, originV);
  _mm256_store_pd(alignedStorage, upV);
  up.x = alignedStorage[0];
  up.y = alignedStorage[1];
  up.z = alignedStorage[2];
#else
  MVector hitNormal;
  // Create the barycentric point and normal.
  for (int i = 0; i < 3; ++i) {
    origin += points[triangleVertices[i]] * coords[i];
    hitNormal += MVector(normals[triangleVertices[i]]) * coords[i];
  }
  // Use crawl data to calculate normal
  normal = hitNormal * weights[hitIndex];
  for (unsigned int j = 0; j < hitIndex; j++) {
    normal += MVector(normals[sampleIds[j]]) * weights[j];
  }

  // Calculate the up vector
  // The triangle vertices are sorted by decreasing barycentric coordinates so the first two are
  // the two closest vertices in the triangle.
  up = ((points[triangleVertices[0]] + points[triangleVertices[1]]) * 0.5) - origin;
#endif
  normal.normalize();
  GetValidUp(weights, points, sampleIds, origin, normal, up);
}
Ejemplo n.º 26
0
		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;
		}
Ejemplo n.º 27
0
void MayaNurbsCurveWriter::write()
{
    Alembic::AbcGeom::OCurvesSchema::Sample samp;
    samp.setBasis(Alembic::AbcGeom::kBsplineBasis);

    MStatus stat;
    mCVCount = 0;

    // if inheritTransform is on and the curve group is animated,
    // bake the cv positions in the world space
    MMatrix exclusiveMatrixInv = mRootDagPath.exclusiveMatrixInverse(&stat);

    std::size_t numCurves = 1;

    if (mIsCurveGrp)
        numCurves = mNurbsCurves.length();

    std::vector<Alembic::Util::int32_t> nVertices(numCurves);
    std::vector<float> points;
    std::vector<float> width;
    std::vector<float> knots;
    std::vector<Alembic::Util::uint8_t> orders(numCurves);

    MMatrix transformMatrix;
    bool useConstWidth = false;

    MFnDependencyNode dep(mRootDagPath.transform());
    MPlug constWidthPlug = dep.findPlug("width");

    if (!constWidthPlug.isNull())
    {
        useConstWidth = true;
        width.push_back(constWidthPlug.asFloat());
    }

    for (unsigned int i = 0; i < numCurves; i++)
    {
        MFnNurbsCurve curve;
        if (mIsCurveGrp)
        {
            curve.setObject(mNurbsCurves[i]);
            MMatrix inclusiveMatrix = mNurbsCurves[i].inclusiveMatrix(&stat);
            transformMatrix = inclusiveMatrix*exclusiveMatrixInv;
        }
        else
        {
            curve.setObject(mRootDagPath.node());
        }

        if (i == 0)
        {
            if (curve.form() == MFnNurbsCurve::kOpen)
            {
                samp.setWrap(Alembic::AbcGeom::kNonPeriodic);
            }
            else
            {
                samp.setWrap(Alembic::AbcGeom::kPeriodic);
            }

            if (curve.degree() == 3)
            {
                samp.setType(Alembic::AbcGeom::kCubic);
            }
            else if (curve.degree() == 1)
            {
                samp.setType(Alembic::AbcGeom::kLinear);
            }
            else
            {
                samp.setType(Alembic::AbcGeom::kVariableOrder);
            }
        }
        else
        {
            if (curve.form() == MFnNurbsCurve::kOpen)
            {
                samp.setWrap(Alembic::AbcGeom::kNonPeriodic);
            }

            if ((samp.getType() == Alembic::AbcGeom::kCubic &&
                curve.degree() != 3) ||
                (samp.getType() == Alembic::AbcGeom::kLinear &&
                curve.degree() != 1))
            {
                samp.setType(Alembic::AbcGeom::kVariableOrder);
            }
        }

        orders[i] = static_cast<Alembic::Util::uint8_t>(curve.degree() + 1);

        Alembic::Util::int32_t numCVs = curve.numCVs(&stat);

        MPointArray cvArray;
        stat = curve.getCVs(cvArray, MSpace::kObject);

        mCVCount += numCVs;
        nVertices[i] = numCVs;

        for (Alembic::Util::int32_t j = 0; j < numCVs; j++)
        {
            MPoint transformdPt;
            if (mIsCurveGrp)
            {
                transformdPt = cvArray[j]*transformMatrix;
            }
            else
            {
                transformdPt = cvArray[j];
            }

            points.push_back(static_cast<float>(transformdPt.x));
            points.push_back(static_cast<float>(transformdPt.y));
            points.push_back(static_cast<float>(transformdPt.z));
        }

        MDoubleArray knotsArray;
        curve.getKnots(knotsArray);
        knots.reserve(knotsArray.length() + 2);

        // need to add a knot to the start and end (M + 2N + 1)
        if (knotsArray.length() > 1)
        {
            unsigned int knotsLength = knotsArray.length();
            if (knotsArray[0] == knotsArray[knotsLength - 1] ||
                knotsArray[0] == knotsArray[1])
            {
                knots.push_back(knotsArray[0]);
            }
            else
            {
                knots.push_back(2 * knotsArray[0] - knotsArray[1]);
            }

            for (unsigned int j = 0; j < knotsLength; ++j)
            {
                knots.push_back(knotsArray[j]);
            }

            if (knotsArray[0] == knotsArray[knotsLength - 1] ||
                knotsArray[knotsLength - 1] == knotsArray[knotsLength - 2])
            {
                knots.push_back(knotsArray[knotsLength - 1]);
            }
            else
            {
                knots.push_back(2 * knotsArray[knotsLength - 1] -
                                knotsArray[knotsLength - 2]);
            }
        }

        // width
        MPlug widthPlug = curve.findPlug("width");

        if (!useConstWidth && !widthPlug.isNull())
        {
            MObject widthObj;
            MStatus status = widthPlug.getValue(widthObj);
            MFnDoubleArrayData fnDoubleArrayData(widthObj, &status);
            MDoubleArray doubleArrayData = fnDoubleArrayData.array();
            Alembic::Util::int32_t arraySum = doubleArrayData.length();
            if (arraySum == numCVs)
            {
                for (Alembic::Util::int32_t i = 0; i < arraySum; i++)
                {
                    width.push_back(static_cast<float>(doubleArrayData[i]));
                }
            }
            else if (status == MS::kSuccess)
            {
                MString msg = "Curve ";
                msg += curve.partialPathName();
                msg += " has incorrect size for the width vector.";
                msg += "\nUsing default constant width of 0.1.";
                MGlobal::displayWarning(msg);

                width.clear();
                width.push_back(0.1f);
                useConstWidth = true;
            }
            else
            {
                width.push_back(widthPlug.asFloat());
                useConstWidth = true;
            }
        }
        else if (!useConstWidth)
        {
            // pick a default value
            width.clear();
            width.push_back(0.1f);
            useConstWidth = true;
        }
    }

    Alembic::AbcGeom::GeometryScope scope = Alembic::AbcGeom::kVertexScope;
    if (useConstWidth)
        scope = Alembic::AbcGeom::kConstantScope;

    samp.setCurvesNumVertices(Alembic::Abc::Int32ArraySample(nVertices));
    samp.setPositions(Alembic::Abc::V3fArraySample(
        (const Imath::V3f *)&points.front(), points.size() / 3 ));
    samp.setWidths(Alembic::AbcGeom::OFloatGeomParam::Sample(
        Alembic::Abc::FloatArraySample(width), scope) );

    if (samp.getType() == Alembic::AbcGeom::kVariableOrder)
    {
        samp.setOrders(Alembic::Abc::UcharArraySample(orders));
    }

    if (!knots.empty())
    {
        samp.setKnots(Alembic::Abc::FloatArraySample(knots));
    }

    mSchema.set(samp);
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
0
IECore::DataPtr convert( const MCommandResult &result )
{
	MStatus s;
	switch (result.resultType())
	{
		case MCommandResult::kInvalid:
		{
			// No result
			return 0;
		}
		case MCommandResult::kInt:
		{
			int i;
			s = result.getResult(i);
			assert(s);

			IECore::IntDataPtr data = new IECore::IntData();
			data->writable() = i;

			return data;
		}
		case MCommandResult::kIntArray:
		{
			MIntArray v;
			s = result.getResult(v);
			assert(s);
			unsigned sz = v.length();
			IECore::IntVectorDataPtr data = new IECore::IntVectorData();
			data->writable().resize(sz);
			for (unsigned i = 0; i < sz; i++)
			{
				(data->writable())[i] = v[i];
			}

			return data;
		}
		case MCommandResult::kDouble:
		{
			double d;
			s = result.getResult(d);
			assert(s);

			IECore::FloatDataPtr data = new IECore::FloatData();
			data->writable() = static_cast<float>(d);

			return data;
		}
		case MCommandResult::kDoubleArray:
		{
			MDoubleArray v;
			s = result.getResult(v);
			assert(s);
			unsigned sz = v.length();
			IECore::DoubleVectorDataPtr data = new IECore::DoubleVectorData();
			data->writable().resize(sz);
			for (unsigned i = 0; i < sz; i++)
			{
				data->writable()[i] = v[i];
			}

			return data;
		}
		case MCommandResult::kString:
		{
			MString str;
			s = result.getResult(str);
			assert(s);

			IECore::StringDataPtr data = new IECore::StringData();
			data->writable() = std::string(str.asChar());

			return data;
		}
		case MCommandResult::kStringArray:
		{
			MStringArray v;
			s = result.getResult(v);
			assert(s);
			unsigned sz = v.length();
			IECore::StringVectorDataPtr data = new IECore::StringVectorData();
			data->writable().resize(sz);
			for (unsigned i = 0; i < sz; i++)
			{
				data->writable()[i] = std::string(v[i].asChar());
			}

			return data;
		}
		case MCommandResult::kVector:
		{
			MVector v;
			s = result.getResult(v);
			assert(s);

			IECore::V3fDataPtr data = new IECore::V3fData();
			data->writable() = Imath::V3f(v.x, v.y, v.z);

			return data;
		}
		case MCommandResult::kVectorArray:
		{
			MVectorArray v;
			s = result.getResult(v);
			assert(s);
			unsigned sz = v.length();
			IECore::V3fVectorDataPtr data = new IECore::V3fVectorData();
			data->writable().resize(sz);
			for (unsigned i = 0; i < sz; i++)
			{
				data->writable()[i] = Imath::V3f(v[i].x, v[i].y, v[i].z);
			}

			return data;
		}
		case MCommandResult::kMatrix:
		{
			MDoubleArray v;
			int numRows, numColumns;

			s = result.getResult(v, numRows, numColumns);
			assert(s);

			if (numRows > 4 || numColumns > 4)
			{
				throw IECoreMaya::StatusException( MS::kFailure );
			}

			IECore::M44fDataPtr data = new IECore::M44fData();

			for (int i = 0; i < numColumns; i++)
			{
				for (int j = 0; j < numRows; j++)
				{
					(data->writable())[i][j] = v[i*numRows+j];
				}
			}

			return data;
		}
		case MCommandResult::kMatrixArray:
		{
			return 0;
		}
		default:

			assert( false );
			return 0;
	}
}
Ejemplo n.º 30
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;
}