Beispiel #1
0
MFloatPointArray ropeGenerator::createHalfRope( int pointsCount, float radius )
{
	MFloatPointArray points;
	MPoint baseVector( 1,0,0 );
	baseVector =  baseVector * radius;
	points.append( MFloatPoint( baseVector.x, baseVector.y, baseVector.z, 1.0 ) );
	float fbaseAngle = 180.0 / float( pointsCount );
	for (int d = 1; d < pointsCount; d++)
	{
		if (d == 1)
		{
			MAngle baseAngle((fbaseAngle * 0.25), MAngle::kDegrees  );
			MVector vVector( baseVector );
			vVector = vVector.rotateBy( MVector::kYaxis, baseAngle.asRadians() );
			points.append( MFloatPoint( vVector.x, vVector.y, vVector.z, 1.0 ) );
		}
		MAngle baseAngle((fbaseAngle * float( d ) ), MAngle::kDegrees  );
		MVector vVector( baseVector );
		vVector = vVector.rotateBy( MVector::kYaxis, baseAngle.asRadians() );
		points.append( MFloatPoint( vVector.x, vVector.y, vVector.z, 1.0 ) );
		if ( d == pointsCount - 1 )
		{
			MAngle baseAngle((fbaseAngle * ( d + 0.75 )), MAngle::kDegrees  );
			MVector vVector( baseVector );
			vVector = vVector.rotateBy( MVector::kYaxis, baseAngle.asRadians() );
			points.append( MFloatPoint( vVector.x, vVector.y, vVector.z, 1.0 ) );
		}

	}
	return points;
}
Beispiel #2
0
void SoftBodyNode::createHelperMesh(MFnMesh &mayaMesh, std::vector<int> &triIndices, std::vector<float> &triVertices, MSpace::Space space)
{
	MFloatPointArray ptArray;
	mayaMesh.getPoints(ptArray, space);	

	// append vertex locations (x, y, z) into "flattened array"
	for(int i = 0; i < ptArray.length(); i++)
	{
		MFloatPoint pt;		
		pt = ptArray[i];
		pt.cartesianize();		
		triVertices.push_back(pt.x);
		triVertices.push_back(pt.y);
		triVertices.push_back(pt.z);

	}
	std::cout << std::endl;

	// create vector of triangle indices
	MIntArray tCounts;
	MIntArray tVerts;
	mayaMesh.getTriangles(tCounts, tVerts);
	triIndices.resize(tVerts.length());
	for(int i = 0; i < tVerts.length(); i ++)
	{
		triIndices[i] = tVerts[i];	
	} 	
}
Beispiel #3
0
MObject animCube::createMesh(const MTime& time,
							  MObject& outData,
							  MStatus& stat)

{
	int				numVertices, frame;
	float			cubeSize;
	MFloatPointArray		points;
	MFnMesh			meshFS;

	// Scale the cube on the frame number, wrap every 10 frames.
	frame = (int)time.as( MTime::kFilm );
	if (frame == 0)
	  frame = 1;
	cubeSize		    		= 0.5f * (float)( frame % 10);

	const int numFaces			= 6;
	numVertices					= 8;
	const int numFaceConnects	= 24;

	MFloatPoint vtx_1( -cubeSize, -cubeSize, -cubeSize );
	MFloatPoint vtx_2(  cubeSize, -cubeSize, -cubeSize );
	MFloatPoint vtx_3(  cubeSize, -cubeSize,  cubeSize );
	MFloatPoint vtx_4( -cubeSize, -cubeSize,  cubeSize );
	MFloatPoint vtx_5( -cubeSize,  cubeSize, -cubeSize );
	MFloatPoint vtx_6( -cubeSize,  cubeSize,  cubeSize );
	MFloatPoint vtx_7(  cubeSize,  cubeSize,  cubeSize );
	MFloatPoint vtx_8(  cubeSize,  cubeSize, -cubeSize );
	points.append( vtx_1 );
	points.append( vtx_2 );
	points.append( vtx_3 );
	points.append( vtx_4 );
	points.append( vtx_5 );
	points.append( vtx_6 );
	points.append( vtx_7 );
	points.append( vtx_8 );

	// Set up an array containing the number of vertices
	// for each of the 6 cube faces (4 verticies per face)
	//
	int face_counts[numFaces] = { 4, 4, 4, 4, 4, 4 };
	MIntArray faceCounts( face_counts, numFaces );

	// Set up and array to assign vertices from points to each face 
	//
	int face_connects[ numFaceConnects ] = {	0, 1, 2, 3,
												4, 5, 6, 7,
												3, 2, 6, 5,
												0, 3, 5, 4,
												0, 4, 7, 1,
												1, 7, 6, 2	};
	MIntArray faceConnects( face_connects, numFaceConnects );

	MObject newMesh = meshFS.create(numVertices, numFaces,
									points, faceCounts, faceConnects,
									outData, &stat);

	return newMesh;
}
MStatus metro_model_translator::create_shape( const m2033::mesh_ptr m )
{
	MFloatPointArray v;
	MVectorArray norm;
	MIntArray p;
	MIntArray idx;

	MFnTransform transform_fn;
	MObject transform_obj = transform_fn.create( MObject::kNullObj );
	transform_fn.setName( m->get_name().c_str() );

	m2033::mesh::vertices mv = m->get_vertices();
	m2033::mesh::indices mi = m->get_indices();
	m2033::mesh::texcoords mt = m->get_tex_coords();
	m2033::mesh::normals mn = m->get_normals();

	for( unsigned i = 0; i < mv.size(); i++ ) {
		v.append( -mv[i].x, mv[i].y, mv[i].z );
		norm.append( MVector( -mn[i].x, mn[i].y, mn[i].z ) );
	}

	for( unsigned i = 0; i < mi.size() / 3; i++ ) {
		idx.append( mi[i*3+2] );
		idx.append( mi[i*3+1] );
		idx.append( mi[i*3] );
		p.append( 3 );
	}

	MFloatArray u_values, v_values;
	for( unsigned i = 0; i < mt.size(); i++ ) {
		u_values.append( mt[i].x );
		v_values.append( -mt[i].y );
	}

	MFnMesh meshFn;
	MObject mesh = meshFn.create( v.length(), p.length(), v, p, idx, u_values, v_values, transform_obj );
	MString name = m->get_name().c_str();
	meshFn.setName( name + MString("_shape") );

	MStatus s = meshFn.assignUVs( p, idx, 0 );
	if( !s ) {
		return s;
	}

	s = meshFn.unlockVertexNormals( idx );
	if( !s ) {
		return s;
	}
	meshFn.setVertexNormals( norm, idx );

	MObject mat = create_material( m->get_texture_name(), &s );
	if( !s ) {
		return s;
	}
	MFnSet mat_fn(mat);
	mat_fn.addMember(mesh);

	return MS::kSuccess;
}
Beispiel #5
0
static void makeCubes(std::vector<cube> &cubes, MString &name, MStatus *stat)
{
    MFnMesh fnMesh;
    MObject result;

    MFloatPointArray points;
    MIntArray faceCounts;
    MIntArray faceConnects;

    int index_offset = 0;
    for (std::vector<cube>::iterator cit = cubes.begin(); cit != cubes.end(); ++cit)
    {
        point3 diag = cit->diagonal();
        float scale = diag.x;
        point3 pos = cit->start + (diag * .5f);

        MFloatVector mpos(pos.x, pos.y, pos.z);

        addCube(scale, mpos, index_offset * (8), points, faceCounts, faceConnects);
        index_offset += 1;
    }

    unsigned int vtx_cnt = points.length();
    unsigned int face_cnt = faceCounts.length();

    MObject newMesh =
        fnMesh.create(
            /* numVertices */ vtx_cnt,
            /* numFaces */ face_cnt,
            points,
            faceCounts,
            faceConnects,
            MObject::kNullObj,
            stat);

    /* Harden all edges. */
    int n_edges = fnMesh.numEdges(stat);
    for (int i = 0; i < n_edges; ++i)
    {
        fnMesh.setEdgeSmoothing(i, false);
    }
    fnMesh.cleanupEdgeSmoothing(); /* Must be called after editing edges. */

    fnMesh.updateSurface();

    /* Assign Shader. */
    MSelectionList sel_list;
    if (!MFAIL(sel_list.add("initialShadingGroup")))
    {
        MObject set_obj;
        sel_list.getDependNode(0, set_obj);
        MFnSet set(set_obj);
        set.addMember(newMesh);
    }

    /* Give it a swanky name. */
    MFnDagNode parent(fnMesh.parent(0));
    name = parent.setName("polyMengerSponge", false, stat);
}
Beispiel #6
0
MStatus testNucleusNode::compute(const MPlug &plug, MDataBlock &data)
{
	MStatus stat;

	if ( plug == nextState )
	{
        
        //get the value of the currentTime 
        MTime currTime = data.inputValue(currentTime).asTime();        
        MObject inputData;
        //pull on start state or current state depending on the current time.
        if(currTime.value() <= 0.0) {
            MArrayDataHandle multiDataHandle = data.inputArrayValue(startState);
            multiDataHandle.jumpToElement(0);
            inputData =multiDataHandle.inputValue().data();
        }
        else {
            MArrayDataHandle multiDataHandle = data.inputArrayValue(currentState);
            multiDataHandle.jumpToElement(0);
            inputData =multiDataHandle.inputValue().data();
        }                
                
        MFnNObjectData inputNData(inputData);                
        MnCloth * nObj = NULL;
        inputNData.getObjectPtr(nObj);        
        
        MFloatPointArray points;
        nObj->getPositions(points);
        unsigned int ii;
        for(ii=0;ii<points.length();ii++) {            
            points[ii].y = (float) sin(points[ii].x + currTime.value()*4.0f*(3.1415f/180.0f));
        }
        nObj->setPositions(points);

        delete nObj;        
        data.setClean(plug);
	}
	else if ( plug == currentState )
	{        
	    data.setClean(plug);

	}
    else if (plug == startState) {        
	    data.setClean(plug);
    }
    else {
		stat = MS::kUnknownParameter;
	}
	return stat;
}
MObject AniMesh::readFrame(const MTime& time,MObject& outData,MStatus& stat)

{
	MFloatPointArray points;
	MFnMesh         meshFS;
	int frame = (int)time.as( MTime::kFilm );
	if (frame == 0)
		frame = 1; 
	vector<size_t> face_v;
	vector<double> points_v;
	char cfilename[256];
	sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),frame);
	//sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),0);
	string filename = string(cfilename);
	fstream fp;
	fp.open(filename,ios::in);
	if (fp)
	{
		ImportVrml2 (filename, face_v, points_v);
	}else{
		sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),0);
		string filename = string(cfilename); 
		ImportVrml2(filename,face_v,points_v);
	}
	
	size_t numVertices = points_v.size()/3;
	size_t numFaces = face_v.size()/3;
	for(vector<double>::const_iterator it = points_v.begin();it != points_v.end();it+=3) {
		MFloatPoint vtx(*it,*(it+1),*(it+2));
		points.append(vtx);
	}

	vector<int> face_count;
	for(int i=0;i<numFaces;i++) {
		face_count.push_back(3);
	}
	MIntArray faceCounts(&face_count[0],numFaces);

	vector<int> face_connects;
	face_connects.resize(face_v.size());
	for(int i=0;i<face_v.size();++i)
	{
		face_connects[i] = face_v[i];
	}

	MIntArray faceConnects( &face_connects[0], face_connects.size() );
	MObject newMesh=meshFS.create(numVertices, numFaces,points, faceCounts, faceConnects,outData,&stat);
	return newMesh;

}
Beispiel #8
0
bool kgLocator::getPoints( MFloatPointArray &pts ) 
{
	
	MFloatPoint pt;
	
	pt.x = -0.5f; pt.y = 0.0f; pt.z = 0.0f;
	pts.append( pt );
	pt.x = 0.5f; pt.y = 0.0f; pt.z = 0.0f;
	pts.append( pt );
	pt.x = 0.0f; pt.y = 0.0f; pt.z = -0.5f;
	pts.append( pt );
	pt.x = 0.0f; pt.y = 0.0f; pt.z = 0.5f;
	pts.append( pt );
	assert( pts.length() == 4 );
	return true;
}
Beispiel #9
0
void ropeGenerator::createCriclePoints( int pointsCount, MMatrix bMatrix, MFloatPointArray &points, float radius )
{
	MPoint baseVector2( radius,0,0 );
	baseVector2 = baseVector2 * bMatrix;
	points.append( MFloatPoint( baseVector2.x, baseVector2.y, baseVector2.z, 1.0 ) );
	float baseAngle = 360.0f / float( pointsCount );
	for (int d = 1; d < pointsCount; d++ )
	{
		MVector vVector( radius,0,0 );
		vVector = vVector.rotateBy( MVector::kYaxis, 
							MAngle( baseAngle * float( d ),MAngle::kDegrees).asRadians() );
		MPoint point( vVector.x, vVector.y, vVector.z );
		point = point * bMatrix;
		points.append( MFloatPoint( point.x, point.y, point.z, 1.0 ));
	}

}
void MayaGeoAttribute::transferValueFromMaya(MPlug &plug, MDataBlock &data){
	MDataHandle dataHandle = data.inputValue(plug);
	MFnMesh meshFn(dataHandle.asMesh());
	
	MFloatPointArray mayaPoints;
	meshFn.getPoints(mayaPoints);
	
	// collect points
	std::vector<Imath::V3f> coralPoints;
	for(int i = 0; i < mayaPoints.length(); ++i){
		MFloatPoint* mayaPoint = &mayaPoints[i];
		coralPoints.push_back(Imath::V3f(mayaPoint->x, mayaPoint->y, mayaPoint->z));
	}
	
	// collect faces
	int numPolys =  meshFn.numPolygons();
	std::vector<std::vector<int> > coralFaces(numPolys);
	for(int polyId = 0; polyId < numPolys; ++polyId){
		MIntArray mayaVertexList;
		meshFn.getPolygonVertices(polyId, mayaVertexList);
		
		int polyPoints = mayaVertexList.length();
		std::vector<int> coralFace(polyPoints);
		for(int i = 0; i < polyPoints; ++i){
			int pointId = mayaVertexList[i];
			coralFace[i] = pointId;
		}
		
		coralFaces[polyId] = coralFace;
	}
	
	// create coral geo
	coral::Geo *coralGeo = outValue();
	
	if(coralGeo->hasSameTopology(coralFaces)){
		coralGeo->setPoints(coralPoints);
	}
	else{
		coralGeo->build(coralPoints, coralFaces);
	}
	
	valueChanged();
}
void MayaGeoAttribute::transferValueToMaya(MPlug &plug, MDataBlock &data){
	coral::Geo *coralGeo = value();
	const std::vector<Imath::V3f> &coralPoints = coralGeo->points();
	
	// transfer points
	MFloatPointArray mayaPoints;
	for(int i = 0; i < coralPoints.size(); ++i){
		const Imath::V3f *coralPoint = &coralPoints[i];
		mayaPoints.append(MFloatPoint(coralPoint->x, coralPoint->y, coralPoint->z));
	}
	
	// transfer faces
	MIntArray mayaFaceCount;
	MIntArray mayaFaceVertices;
	
	const std::vector<std::vector<int> > coralFaces = coralGeo->rawFaces();
	for(int polyId = 0; polyId < coralFaces.size(); ++polyId){
		const std::vector<int> *coralFace = &coralFaces[polyId];
		int faceVertexCount = coralFace->size();
		mayaFaceCount.append(faceVertexCount);
		
		for(int i = 0; i < faceVertexCount; ++i){
			mayaFaceVertices.append(coralFace->at(i));
		}
	}
	
	// create maya mesh
	MDataHandle dataHandle = data.outputValue(plug);
	
	MFnMeshData dataCreator;
	MObject newOutputData = dataCreator.create();
	
	MFnMesh newMesh;
	newMesh.create(mayaPoints.length(), coralFaces.size(), mayaPoints, mayaFaceCount, mayaFaceVertices, newOutputData);
	dataHandle.set(newOutputData);
}
Beispiel #12
0
void store_in_hds(HDS &hds, MFloatPointArray &points, MIntArray &nFV, MIntArray &F)
{
    size_t nV = points.length();
    hds.V.setDims(3, nV);
    for (size_t k=0; k<nV; k++) 
    {
        hds.V[3*k+0] = points[k](0);
        hds.V[3*k+1] = points[k](1);
        hds.V[3*k+2] = points[k](2);
    }
    
    hds.nFV.setDims(1,nFV.length());
    for (size_t k=0; k<nFV.length(); k++) hds.nFV[k] = nFV[k];
    
    hds.tip.setDims(1,F.length());
    for (size_t k=0; k<F.length(); k++) hds.tip[k] = F[k];
}                      
Beispiel #13
0
MBoundingBox BasicLocator::boundingBox() const
{
	MBoundingBox bbox;
	MFloatPointArray points;
	points.clear();
	points.setSizeIncrement(4);
	points.append(-1.0, 0.0, 0.0);
	points.append(1.0, 0.0, 0.0);
	points.append(0.0, 0.0, 1.0);
	points.append(0.0, 0.0, -1.0);

	for (unsigned int i = 0; i < points.length(); i++)
		bbox.expand(points[i]);

	return bbox;
}
Beispiel #14
0
void load_from_hds(HDS &hds, MFloatPointArray &points, MIntArray &nFV, MIntArray &F)
{
    size_t nV   = hds.nV();
    size_t nF   = hds.nF();
    size_t nIHE = hds.nIHE();
    
    points.setLength(nV);
    for (size_t k=0; k<nV; k++) 
    {
        points[k](0) = hds.V[3*k+0];
        points[k](1) = hds.V[3*k+1];
        points[k](2) = hds.V[3*k+2];
    }
    
    nFV.setLength(nF);
    for (size_t k=0; k<nF; k++) nFV[k] = hds.nFV[k];
    
    F.setLength(nIHE);
    for (size_t k=0; k<nIHE; k++) F[k] = hds.tip[k];
}
void
OsdMeshData::updateGeometry(const MHWRender::MVertexBuffer *points, const MHWRender::MVertexBuffer *normals)
{
    // Update coarse vertex
    if (!_positionBuffer) return;
    if (!_normalBuffer) return;

    int nCoarsePoints = _pointArray.length();

    OpenSubdiv::OsdCpuVertexBuffer *cpuPos = dynamic_cast<OpenSubdiv::OsdCpuVertexBuffer*>(_positionBuffer);
    OpenSubdiv::OsdCpuVertexBuffer *cpuNormal = dynamic_cast<OpenSubdiv::OsdCpuVertexBuffer*>(_normalBuffer);

    if (cpuPos) {
        // I know, this is very inefficient...
        float *d_pos = cpuPos->GetCpuBuffer();
        float *d_normal = cpuNormal->GetCpuBuffer();

        glBindBuffer(GL_ARRAY_BUFFER, *(GLuint*)points->resourceHandle());
        glGetBufferSubData(GL_ARRAY_BUFFER, 0, nCoarsePoints*3*sizeof(float), d_pos);
        glBindBuffer(GL_ARRAY_BUFFER, *(GLuint*)normals->resourceHandle());
        glGetBufferSubData(GL_ARRAY_BUFFER, 0, nCoarsePoints*3*sizeof(float), d_normal);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
    } else {
        glBindBuffer(GL_COPY_READ_BUFFER, *(GLuint*)points->resourceHandle());
        glBindBuffer(GL_COPY_WRITE_BUFFER, _positionBuffer->GetGpuBuffer());
        glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, nCoarsePoints*3*sizeof(float));
        
        glBindBuffer(GL_COPY_READ_BUFFER, *(GLuint*)normals->resourceHandle());
        glBindBuffer(GL_COPY_WRITE_BUFFER, _normalBuffer->GetGpuBuffer());
        glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, nCoarsePoints*3*sizeof(float));
        
        glBindBuffer(GL_COPY_READ_BUFFER, 0);
        glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
    }

    _osdmesh->Subdivide(_positionBuffer, NULL);
    _osdmesh->Subdivide(_normalBuffer, NULL);

    _needsUpdate = false;
}
Beispiel #16
0
void ropeGenerator::createRopesRings( int ropesCount, MMatrix bMatrix, MFloatPointArray &points, int pointsCount, float ropeStrength, float radius )
{
	MAngle angle( (180.0/ ropesCount ), MAngle::kDegrees );
	float distanceToMoveRope = cos( angle.asRadians() );
	float singleRopeRadius = sin( angle.asRadians() );
	float baseAngle = 360.0f / float( ropesCount ); 
	for ( int d = 1; d < ropesCount + 1; d++)
	{
		MFloatPointArray ropePoints( createHalfRope( pointsCount, singleRopeRadius ) );
		for ( int ropP = 0; ropP < ropePoints.length(); ropP++)
		{
			MFloatPoint ropPoint( ropePoints[ropP] );
			MVector ropV( ropPoint.x, ropPoint.y, ropPoint.z * ropeStrength );
			ropV = ropV + MVector( 0,0,-distanceToMoveRope );
			ropV = ropV.rotateBy( MVector::kYaxis, MAngle( baseAngle * float( d ), MAngle::kDegrees).asRadians() );
			MPoint ropFinalPoint( ropV * radius );
			ropFinalPoint = ropFinalPoint * bMatrix;
			points.append( MFloatPoint( ropFinalPoint.x, ropFinalPoint.y, ropFinalPoint.z ) );
		}
	}
}
Beispiel #17
0
void write_to_TCCNodeData(TCCData &tcc, MFloatPointArray &V, TCCNodeData &nd)
{
    size_t nV = V.length();
    nd.V.setDims(3, nV);
    for (size_t k=0; k<nV; k++) 
    {
        nd.V[3*k+0] = V[k](0);
        nd.V[3*k+1] = V[k](1);
        nd.V[3*k+2] = V[k](2);
    }
    
    // vertex data 
    nd.pole.setDims(1,tcc.pole.length());
    for (size_t k=0; k<tcc.pole.length(); k++) nd.pole[k] = tcc.pole[k]==1;

    nd.corner.setDims(1,tcc.corner.length());
    for (size_t k=0; k<tcc.corner.length(); k++) nd.corner[k] = tcc.corner[k];
    
    // halfedge data
    nd.T.setDims(1,tcc.T.length());
    for (size_t k=0; k<tcc.T.length(); k++) nd.T[k] = tcc.T[k];
    
    nd.itv.setDims(1,tcc.itv.length());
    for (size_t k=0; k<tcc.itv.length(); k++) nd.itv[k] = tcc.itv[k];
    
    nd.eqc.setDims(1,tcc.eqc.length());
    for (size_t k=0; k<tcc.eqc.length(); k++) nd.eqc[k] = tcc.eqc[k];

    // err is not needed!
    
    nd.nFV.setDims(1,tcc.nFV.length());
    for (size_t k=0; k<tcc.nFV.length(); k++) nd.nFV[k] = tcc.nFV[k];
    
    nd.tip.setDims(1,tcc.F.length());
    for (size_t k=0; k<tcc.F.length(); k++) nd.tip[k] = tcc.F[k];

    nd.selHE.setDims(1,tcc.selHE.length());
    for (size_t k=0; k<tcc.selHE.length(); k++) nd.selHE[k] = tcc.selHE[k];
}
bool ToMayaMeshConverter::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const
{
	MStatus s;

	IECore::ConstMeshPrimitivePtr mesh = IECore::runTimeCast<const IECore::MeshPrimitive>( from );
	assert( mesh );

	if ( !mesh->arePrimitiveVariablesValid() )
	{
		return false;
	}

	MFloatPointArray vertexArray;
	MIntArray polygonCounts;
	MIntArray polygonConnects;

	MFnMesh fnMesh;

	int numVertices = 0;
	IECore::PrimitiveVariableMap::const_iterator it = mesh->variables.find("P");
	if ( it != mesh->variables.end() )
	{
		/// \todo Employ some M*Array converters to simplify this
		IECore::ConstV3fVectorDataPtr p = IECore::runTimeCast<const IECore::V3fVectorData>(it->second.data);
		if (p)
		{
			numVertices = p->readable().size();

			vertexArray.setLength( numVertices );
			for (int i = 0; i < numVertices; i++)
			{
				vertexArray[i] = IECore::convert<MFloatPoint, Imath::V3f>( p->readable()[i] );
			}
		}
		else
		{
			IECore::ConstV3dVectorDataPtr p = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data);
			if (p)
			{
				numVertices = p->readable().size();

				vertexArray.setLength( numVertices );
				for (int i = 0; i < numVertices; i++)
				{
					vertexArray[i] = IECore::convert<MFloatPoint, Imath::V3d>( p->readable()[i] );
				}
			}
			else
			{
				// "P" is not convertible to an array of "points"
				return false;
			}
		}
	}


	IECore::ConstIntVectorDataPtr verticesPerFace = mesh->verticesPerFace();
	assert( verticesPerFace );
	int numPolygons = verticesPerFace->readable().size();

	polygonCounts.setLength( numPolygons );
	for (int i = 0; i < numPolygons; i++)
	{
		polygonCounts[i] = verticesPerFace->readable()[i];
	}

	IECore::ConstIntVectorDataPtr vertexIds = mesh->vertexIds();
	assert( vertexIds );
	int numPolygonConnects = vertexIds->readable().size();
	polygonConnects.setLength( numPolygonConnects );
	for (int i = 0; i < numPolygonConnects; i++)
	{
		polygonConnects[i] = vertexIds->readable()[i];
	}

	MObject mObj = fnMesh.create( numVertices, numPolygons, vertexArray, polygonCounts, polygonConnects, to, &s );

	if (!s)
	{
		return false;
	}

	it = mesh->variables.find("N");
	if ( it != mesh->variables.end() )
	{
		if (it->second.interpolation == IECore::PrimitiveVariable::FaceVarying )
		{
			/// \todo Employ some M*Array converters to simplify this
			MVectorArray vertexNormalsArray;
			IECore::ConstV3fVectorDataPtr n = IECore::runTimeCast<const IECore::V3fVectorData>(it->second.data);
			if (n)
			{
				int numVertexNormals = n->readable().size();

				vertexNormalsArray.setLength( numVertexNormals );
				for (int i = 0; i < numVertexNormals; i++)
				{
					vertexNormalsArray[i] = IECore::convert<MVector, Imath::V3f>( n->readable()[i] );
				}
			}
			else
			{
				IECore::ConstV3dVectorDataPtr n = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data);
				if (n)
				{
					int numVertexNormals = n->readable().size();

					vertexNormalsArray.setLength( numVertexNormals );
					for (int i = 0; i < numVertexNormals; i++)
					{
						vertexNormalsArray[i] = IECore::convert<MVector, Imath::V3d>( n->readable()[i] );
					}
				}
				else
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"N\" has unsupported type \"%s\"." ) % it->second.data->typeName() );
				}
			}
			
			if ( vertexNormalsArray.length() )
			{
				MStatus status;
				MItMeshPolygon itPolygon( mObj, &status );
				if( status != MS::kSuccess )
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to create mesh iterator" );
				}

				unsigned v = 0;
				MIntArray vertexIds;
				MIntArray faceIds;
				
				for ( ; !itPolygon.isDone(); itPolygon.next() )
				{
					for ( v=0; v < itPolygon.polygonVertexCount(); ++v )
					{
						faceIds.append( itPolygon.index() );
						vertexIds.append( itPolygon.vertexIndex( v ) );
					}
				}

				if( !fnMesh.setFaceVertexNormals( vertexNormalsArray, faceIds, vertexIds ) )
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Setting normals failed" );
				}
			}
		}
		else
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "PrimitiveVariable \"N\" has unsupported interpolation (expected FaceVarying)." );
		}
	}

	bool haveDefaultUVs = false;
	IECore::PrimitiveVariableMap::const_iterator sIt = mesh->variables.find( "s" );
	IECore::RefCountedPtr sDataRef = ( sIt == mesh->variables.end() ) ? 0 : static_cast<IECore::RefCountedPtr>( sIt->second.data );

	/// Add named UV sets
	std::set< std::string > uvSets;
	for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it )
	{
		const std::string &sName = it->first;

		size_t suffixOffset = sName.rfind( "_s" );

		if ( ( suffixOffset != std::string::npos) && ( suffixOffset == sName.length() - 2 ) )
		{
			std::string uvSetNameStr = sName.substr( 0, suffixOffset );

			if ( uvSetNameStr.size() )
			{
				MString uvSetName = uvSetNameStr.c_str();
				std::string tName = uvSetNameStr + "_t";
				std::string stIdName = uvSetNameStr + "Indices";

				addUVSet( fnMesh, polygonCounts, mesh, sName, tName, stIdName, &uvSetName );

				uvSets.insert( uvSetNameStr );
				
				if ( sDataRef == static_cast<IECore::RefCountedPtr>( it->second.data ) )
				{
					haveDefaultUVs = true;
				}
			}
		}
	}

	/// Add default UV set if it isn't just a reference to a named set
	if ( !haveDefaultUVs )
	{
		addUVSet( fnMesh, polygonCounts, mesh, "s", "t", "stIndices" );
	}

	// We do the search again, but looking for primvars ending "_t", so we can catch cases where either "UVSETNAME_s" or "UVSETNAME_t" is present, but not both, taking care
	// not to attempt adding any duplicate sets
	for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it )
	{
		const std::string &tName = it->first;

		size_t suffixOffset = tName.rfind( "_t" );

		if ( ( suffixOffset != std::string::npos) && ( suffixOffset == tName.length() - 2 ) )
		{
			std::string uvSetNameStr = tName.substr( 0, suffixOffset );

			if ( uvSetNameStr.size() && uvSets.find( uvSetNameStr ) == uvSets.end() )
			{
				MString uvSetName = uvSetNameStr.c_str();
				std::string sName = uvSetNameStr + "_s";
				std::string stIdName = uvSetNameStr + "Indices";
				
				addUVSet( fnMesh, polygonCounts, mesh, sName, tName, stIdName, &uvSetName );
				uvSets.insert( uvSetNameStr );
			}
		}
	}

	/// If we're making a mesh node (rather than a mesh data) then make sure it belongs
	/// to the default shading group and add the ieMeshInterpolation attribute.
	MObject oMesh = fnMesh.object();
	if( oMesh.apiType()==MFn::kMesh )
	{
		assignDefaultShadingGroup( oMesh );
		setMeshInterpolationAttribute( oMesh, mesh->interpolation() );
	}

	/// \todo Other primvars, e.g. vertex color ("Cs")

	return true;
}
Beispiel #19
0
// the arrays being passed in are assumed to be empty
void MayaMeshWriter::fillTopology(
    std::vector<float> & oPoints,
    std::vector<Alembic::Util::int32_t> & oFacePoints,
    std::vector<Alembic::Util::int32_t> & oPointCounts)
{
    MStatus status = MS::kSuccess;
    MFnMesh lMesh( mDagPath, &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
    }

    MFloatPointArray pts;

    lMesh.getPoints(pts);

    if (pts.length() < 3 && pts.length() > 0)
    {
        MString err = lMesh.fullPathName() +
            " is not a valid mesh, because it only has ";
        err += pts.length();
        err += " points.";
        MGlobal::displayError(err);
        return;
    }

    unsigned int numPolys = lMesh.numPolygons();

    if (numPolys == 0)
    {
        MGlobal::displayWarning(lMesh.fullPathName() + " has no polygons.");
        return;
    }

    unsigned int i;
    int j;

    oPoints.resize(pts.length() * 3);

    // repack the float
    for (i = 0; i < pts.length(); i++)
    {
        size_t local = i * 3;
        oPoints[local] = pts[i].x;
        oPoints[local+1] = pts[i].y;
        oPoints[local+2] = pts[i].z;
    }

    /*
        oPoints -
        oFacePoints - vertex list
        oPointCounts - number of points per polygon
    */

    MIntArray faceArray;

    for (i = 0; i < numPolys; i++)
    {
        lMesh.getPolygonVertices(i, faceArray);

        if (faceArray.length() < 3)
        {
            MGlobal::displayWarning("Skipping degenerate polygon");
            continue;
        }

        // write backwards cause polygons in Maya are in a different order
        // from Renderman (clockwise vs counter-clockwise?)
        int faceArrayLength = faceArray.length() - 1;
        for (j = faceArrayLength; j > -1; j--)
        {
            oFacePoints.push_back(faceArray[j]);
        }

        oPointCounts.push_back(faceArray.length());
    }
}
// h�mta all n�dv�ndig data och l�gger det i ett MeshData-objekt, som senare anv�nds vid exportering.
bool Exporter::ExtractMeshData(MFnMesh &mesh, UINT index)
{
	MeshData mesh_data;

	MFloatPointArray points;

	MFloatVectorArray normals;

	MSpace::Space world_space = MSpace::kTransform;

	// DAG-path
	mesh_data.mesh_path = mesh.dagPath();

	// namn och id
	mesh_data.name = mesh.name();
	mesh_data.id = index;

	std::string name = mesh.partialPathName().asChar();
	if (!strcmp(name.substr(0, 5).c_str(), "Blend")){
		return true;
	}

	// triangulera meshen innan man h�mtar punkterna
	MString command = "polyTriangulate -ch 1 " + mesh_data.name;
	if (!MGlobal::executeCommand(command))
	{
		return false;
	}

	// h�mta icke-indexerade vertexpunkter
	if (!mesh.getPoints(points, world_space))
	{
		return false;
	}

	for (int i = 0; i < points.length(); i++){
		point temppoints = { points[i].x, points[i].y, points[i].z };
		vec3 temppurepoints = { points[i].x, points[i].y, points[i].z };
		mesh_data.points.push_back(temppoints);
		mesh_data.purepoints.push_back(temppurepoints);
	}

	// h�mta icke-indexerade normaler
	if (!mesh.getNormals(normals, world_space))
	{
		return false;
	}

	for (int i = 0; i < normals.length(); i++){
		vec3 tempnormals = { normals[i].x, normals[i].y, normals[i].z };
		mesh_data.normals.push_back(tempnormals);
	}

	//variabler f�r att mellanlagra uvdata och tangenter/bitangenter
	MStringArray uvSets;
	mesh.getUVSetNames(uvSets);

	uvSet tempUVSet;
	MFloatArray Us;
	MFloatArray Vs;
	vec2 UVs;

	// iterera �ver uvsets och ta ut koordinater, tangenter och bitangenter
	for (int i = 0; i < uvSets.length(); i++)
	{
		MString currentSet = uvSets[i];
		mesh.getUVs(Us, Vs, &currentSet);
		for (int a = 0; a < Us.length(); a++){
			UVs.u = Us[a];
			UVs.v = Vs[a];
			//1-Vs in order to get correct UV angles
			tempUVSet.UVs.push_back(UVs);
		}
		mesh.getTangents(tempUVSet.tangents, world_space, &currentSet);
		mesh.getBinormals(tempUVSet.binormals, world_space, &currentSet);
		mesh_data.uvSets.push_back(tempUVSet);
	}

	//itererar �ver trianglar och returnerar ID:n f�r associerade vertiser, normaler och uvset
	MItMeshPolygon itFaces(mesh.dagPath());
	while (!itFaces.isDone()) {
		face tempface;

		//		printf("%d", itFaces.vertexIndex(0));
		//		printf(" %d", itFaces.vertexIndex(1));
		//		printf(" %d\n", itFaces.vertexIndex(2));

		int vc = itFaces.polygonVertexCount();
		for (int i = 0; i < vc; ++i) {
			tempface.verts[i].pointID = itFaces.vertexIndex(i);
			tempface.verts[i].normalID = itFaces.normalIndex(i);

			for (int k = 0; k < uvSets.length(); ++k) {
				int temptexCoordsID;
				itFaces.getUVIndex(i, temptexCoordsID, &uvSets[k]);

				tempface.verts[i].texCoordsID.push_back(temptexCoordsID);
			}
		}

		mesh_data.faces.push_back(tempface);
		itFaces.next();
	}

	// l�gg till mesh_data i scen-datan
	scene_.meshes.push_back(mesh_data);

	return true;
}
Beispiel #21
0
MStatus sseDeformer::compute(const MPlug& plug, MDataBlock& data)
{
    MStatus status;
    if (plug.attribute() != outputGeom) {
        printf("Ignoring requested plug\n");
        return status;
    }
    unsigned int index = plug.logicalIndex();
    MObject thisNode = this->thisMObject();

    // get input value
    MPlug inPlug(thisNode,input);
    inPlug.selectAncestorLogicalIndex(index,input);
    MDataHandle hInput = data.inputValue(inPlug, &status);
    MCheckStatus(status, "ERROR getting input mesh\n");

    // get the input geometry
    MDataHandle inputData = hInput.child(inputGeom);
    if (inputData.type() != MFnData::kMesh) {
        printf("Incorrect input geometry type\n");
        return MStatus::kFailure;
    }

    MObject iSurf = inputData.asMesh() ;
    MFnMesh inMesh;
    inMesh.setObject( iSurf ) ;

    MDataHandle outputData = data.outputValue(plug);
    outputData.copy(inputData);
    if (outputData.type() != MFnData::kMesh) {
        printf("Incorrect output mesh type\n");
        return MStatus::kFailure;
    }

    MObject oSurf = outputData.asMesh() ;
    if(oSurf.isNull()) {
        printf("Output surface is NULL\n");
        return MStatus::kFailure;
    }

    MFnMesh outMesh;
    outMesh.setObject( oSurf ) ;
    MCheckStatus(status, "ERROR setting points\n");

    // get all points at once for demo purposes. Really should get points from the current group using iterator
    MFloatPointArray pts;
    outMesh.getPoints(pts);

    int nPoints = pts.length();

    MDataHandle envData = data.inputValue(envelope, &status);
    float env = envData.asFloat();

    MDataHandle sseData = data.inputValue(sseEnabled, &status);
    bool sseEnabled = (bool) sseData.asBool();

    // NOTE: Using MTimer and possibly other classes disables
    // autovectorization with Intel <=10.1 compiler on OSX and Linux!!
    // Must compile this function with -fno-exceptions on OSX and
    // Linux to guarantee autovectorization is done. Use -fvec_report2
    // to check for vectorization status messages with Intel compiler.
    MTimer timer;
    timer.beginTimer();

    if(sseEnabled) {

        // Innter loop will autovectorize. Around 3x faster than the
        // loop below it. It would be faster if first element was
        // guaranteed to be aligned on 16 byte boundary.
        for(int i=0; i<nPoints; i++) {
            float* ptPtr = &pts[i].x;
            for(int j=0; j<4; j++) {
                ptPtr[j] = env * (cosf(ptPtr[j]) * sinf(ptPtr[j]) * tanf(ptPtr[j]));
            }
        }

    } else {

        // This inner loop will not autovectorize.
        for(int i=0; i<nPoints; i++) {
            MFloatPoint& pt = pts[i];
            for(int j=0; j<3; j++) {
                pt[j] = env * (cosf(pt[j]) * sinf(pt[j]) * tanf(pt[j]));
            }

        }
    }

    timer.endTimer();
    if(sseEnabled) {
        printf("SSE enabled, runtime %f\n", timer.elapsedTime());
    } else {
        printf("SSE disabled, runtime %f\n", timer.elapsedTime());
    }

    outMesh.setPoints(pts);

    return status;
}
Beispiel #22
0
MStatus meshOpFty::doLightningSplit(MFnMesh& meshFn)
//
//	Description:
//		Performs the kSplitLightning operation on the selected mesh
//      and components. It may not split all the selected components.
//
{
	unsigned int i, j;

	// These are the input arrays to the split function. The following
	// algorithm fills them in with the arguments for a continuous
	// split that goes through some of the selected faces.
	//
	MIntArray placements;
	MIntArray edgeIDs;
	MFloatArray edgeFactors;
	MFloatPointArray internalPoints;
	
	// The following array is going to be used to determine which faces
	// have been split. Since the split function can only split faces
	// which are adjacent to the earlier face, we may not split
	// all the faces
	//
	bool* faceTouched = new bool[fComponentIDs.length()];
	for (i = 0; i < fComponentIDs.length(); ++i)
		faceTouched[i] = false;
	
	// We need a starting point. For this example, the first face in
	// the component list is picked. Also get a polygon iterator
	// to this face.
	// 
	MItMeshPolygon itPoly(fMesh);
	for (; !itPoly.isDone(); itPoly.next())
	{
		if (fComponentIDs[0] == itPoly.index()) break;
	}
	if (itPoly.isDone())
	{
		// Should never happen.
		//
		delete [] faceTouched;
		return MS::kFailure;
	}
	
	// In this example, edge0 is called the starting edge and
	// edge1 is called the destination edge. This algorithm will split
	// each face from the starting edge to the destination edge
	// while going through two inner points inside each face.
	//
	int edge0, edge1;
	MPoint innerVert0, innerVert1;
	int nextFaceIndex = 0;
	
	// We need a starting edge. For this example, the first edge in the
	// edge list is used.
	//
	MIntArray edgeList;
	itPoly.getEdges(edgeList);
	edge0 = edgeList[0];
	
	bool done = false;
	while (!done)
	{
		// Set this face as touched so that we don't try to split it twice
		//
		faceTouched[nextFaceIndex] = true;
		
		// Get the current face's center. It is used later in the
		// algorithm to calculate inner vertices.
		//
		MPoint faceCenter = itPoly.center();
			
		// Iterate through the connected faces to find an untouched,
		// selected face and get the ID of the shared edge. That face
		// will become the next face to be split.
		//
		MIntArray faceList;
		itPoly.getConnectedFaces(faceList);
		nextFaceIndex = -1;
		for (i = 0; i < fComponentIDs.length(); ++i)
		{
			for (j = 0; j < faceList.length(); ++j)
			{
				if (fComponentIDs[i] == faceList[j] && !faceTouched[i])
				{
					nextFaceIndex = i;
					break;
				}
			}
			if (nextFaceIndex != -1) break;
		}
		
		if (nextFaceIndex == -1)
		{
			// There is no selected and untouched face adjacent to this
			// face, so this algorithm is done. Pick the first edge that
			// is not the starting edge as the destination edge.
			//
			done = true;
			edge1 = -1;
			for (i = 0; i < edgeList.length(); ++i)
			{
				if (edgeList[i] != edge0)
				{
					edge1 = edgeList[i];
					break;
				}
			}
			if (edge1 == -1)
			{
				// This should not happen, since there should be more than
				// one edge for each face
				//
				delete [] faceTouched;
				return MS::kFailure;
			}
		}
		else
		{
			// The next step is to find out which edge is shared between
			// the two faces and use it as the destination edge. To do
			// that, we need to iterate through the faces and get the
			// next face's list of edges.
			//
			itPoly.reset();
			for (; !itPoly.isDone(); itPoly.next())
			{
				if (fComponentIDs[nextFaceIndex] == itPoly.index()) break;
			}
			if (itPoly.isDone()) 
			{
				// Should never happen.
				//
				delete [] faceTouched;
				return MS::kFailure;
			}
			
			// Look for a common edge ID in the two faces edge lists
			//
			MIntArray nextFaceEdgeList;
			itPoly.getEdges(nextFaceEdgeList);
			edge1 = -1;
			for (i = 0; i < edgeList.length(); ++i)
			{
				for (j = 0; j < nextFaceEdgeList.length(); ++j)
				{
					if (edgeList[i] == nextFaceEdgeList[j])
					{
						edge1 = edgeList[i];
						break;
					}
				}
				if (edge1 != -1) break;
			}
			if (edge1 == -1)
			{
				// Should never happen.
				//
				delete [] faceTouched;
				return MS::kFailure;
			}
			
			// Save the edge list for the next iteration
			//
			edgeList = nextFaceEdgeList;
		}
		
		// Calculate the two inner points that the split will go through.
		// For this example, the midpoints between the center and the two
		// farthest vertices of the edges are used.
		//
		// Find the 3D positions of the edges' vertices
		//
		MPoint edge0vert0, edge0vert1, edge1vert0, edge1vert1;
		MItMeshEdge itEdge(fMesh, MObject::kNullObj );
		for (; !itEdge.isDone(); itEdge.next())
		{
			if (itEdge.index() == edge0)
			{
				edge0vert0 = itEdge.point(0);
				edge0vert1 = itEdge.point(1);
			}
			if (itEdge.index() == edge1)
			{
				edge1vert0 = itEdge.point(0);
				edge1vert1 = itEdge.point(1);
			}
		}
		
		// Figure out which are the farthest from each other
		//
		double distMax = edge0vert0.distanceTo(edge1vert0);
		MPoint max0, max1;
		max0 = edge0vert0;
		max1 = edge1vert0;
		double newDist = edge0vert1.distanceTo(edge1vert0);
		if (newDist > distMax)
		{
			max0 = edge0vert1;
			max1 = edge1vert0;
			distMax = newDist;
		}
		newDist = edge0vert0.distanceTo(edge1vert1);
		if (newDist > distMax)
		{
			max0 = edge0vert0;
			max1 = edge1vert1;
			distMax = newDist;
		}
		newDist = edge0vert1.distanceTo(edge1vert1);
		if (newDist > distMax)
		{
			max0 = edge0vert1;
			max1 = edge1vert1;
		}
		
		// Calculate the two inner points
		//
		innerVert0 = (faceCenter + max0) / 2.0;
		innerVert1 = (faceCenter + max1) / 2.0;
		
		// Add this split's information to the input arrays. If this is
		// the last split, also add the destination edge's split information.
		//
		placements.append((int) MFnMesh::kOnEdge);
		placements.append((int) MFnMesh::kInternalPoint);
		placements.append((int) MFnMesh::kInternalPoint);
		if (done) placements.append((int) MFnMesh::kOnEdge);
		
		edgeIDs.append(edge0);
		if (done) edgeIDs.append(edge1);
		
		edgeFactors.append(0.5f);
		if (done) edgeFactors.append(0.5f);
		
		MFloatPoint point1((float)innerVert0[0], (float)innerVert0[1],
			(float)innerVert0[2], (float)innerVert0[3]);
		MFloatPoint point2((float)innerVert1[0], (float)innerVert1[1],
			(float)innerVert1[2], (float)innerVert1[3]);
		internalPoints.append(point1);
		internalPoints.append(point2);
		
		// For the next iteration, the current destination
		// edge becomes the start edge.
		//
		edge0 = edge1;
	}

	// Release the dynamically-allocated memory and do the actual split
	//
	delete [] faceTouched;
	return meshFn.split(placements, edgeIDs, edgeFactors, internalPoints);
}
bool		preFrame(
				const MObject		hairSystem,
				const double		curTime,
				void				**privateData )
{
	MStatus status;

	// If you need want to perform any preprocessing on your collision
	// objects pre-frame, do it here. One option for storing the pre-
	// processed data is on a typed attribute on the hairSystem node.
	// That data could be fetched and updated here.
	//
	// In our example, we'll just compute a bounding box here and NOT use
	// attribute storage. That is an exercise for the reader.
	//
	MFnDependencyNode fnHairSystem( hairSystem, &status );
	CHECK_MSTATUS_AND_RETURN( status, false );
	fprintf( stderr,
			"preFrame: calling hairSystem node=`%s', time=%g\n",
			fnHairSystem.name().asChar(), curTime );
	MObjectArray	cols;
	MIntArray		logIdxs;
	CHECK_MSTATUS_AND_RETURN( MHairSystem::getCollisionObject( hairSystem,
			cols, logIdxs ), false );
	int nobj = cols.length();

	// Allocate private data.
	// This allows us to pre-process data on a pre-frame basis to avoid
	// calculating it per hair inside the collide() call. As noted earlier
	// we could allocate this in preFrame() and hang it off the hairSystem
	// node via a dynamic attribute.
	// Instead we'll allocate it here.
	//
	COLLISION_INFO *collisionInfo = (COLLISION_INFO *) malloc(
			sizeof( COLLISION_INFO ) );
	collisionInfo->objs = (COLLISION_OBJ *) malloc(
			nobj * sizeof( COLLISION_OBJ ) );
	collisionInfo->numObjs = nobj;

	// Create the private data that we'll make available to the collide
	// method. The data should actually be stored in a way that it can
	// be cleaned up (such as storing the pointer on the hairSystem node
	// using a dynamic attribute). As it stands right now, there is a
	// memory leak with this plug-in because the memory we're allocating
	// for the private data is never cleaned up.
	//
	// Note that when using the dynamic attribute approach, it is still
	// wise to set *privateData because this avoids the need to look up
	// the plug inside the collide() routine which is a high-traffic
	// method.
	//
	*privateData = (void *) collisionInfo;

	// Loop through the collision objects and pre-process, storing the
	// results in the collisionInfo structure.
	//
	int	   obj;
	for ( obj = 0; obj < nobj; ++obj ) {
		// Get the ith collision geometry we are connected to.
		//
		MObject colObj = cols[obj];

		// Get the DAG path for the collision object so we can transform
		// the vertices to world space.
		//
		MFnDagNode fnDagNode( colObj, &status );
		CHECK_MSTATUS_AND_RETURN( status, false );
		MDagPath path;
		status = fnDagNode.getPath( path );
		CHECK_MSTATUS_AND_RETURN( status, false );
		MFnMesh fnMesh( path, &status );
		if ( MS::kSuccess != status ) {
			fprintf( stderr,
					"%s:%d: collide was not passed a valid mesh shape\n",
					__FILE__, __LINE__ );
			return( false );
		}

		// Get the vertices of the object transformed to world space.
		//
		MFloatPointArray	verts;
		status = fnMesh.getPoints( verts, MSpace::kWorld );
		CHECK_MSTATUS_AND_RETURN( status, false );

		// Compute the bounding box for the collision object.
		// As this is a quick and dirty demo, we'll just support collisions
		// between hair and the bbox.
		//
		double minx, miny, minz, maxx, maxy, maxz, x, y, z;
		minx = maxx = verts[0].x;
		miny = maxy = verts[0].y;
		minz = maxz = verts[0].z;
		int nv = verts.length();
		int i;
		for ( i = 1; i < nv; ++i ) {
			x = verts[i].x;
			y = verts[i].y;
			z = verts[i].z;

			if ( x < minx ) {
				minx = x;
			}
			if ( y < miny ) {
				miny = y;
			}
			if ( z < minz ) {
				minz = z;
			}

			if ( x > maxx ) {
				maxx = x;
			}
			if ( y > maxy ) {
				maxy = y;
			}
			if ( z > maxz ) {
				maxz = z;
			}
		}

		// Store this precomputed informantion into our private data
		// structure.
		//
		collisionInfo->objs[obj].numVerts = nv;
		collisionInfo->objs[obj].minx = minx;
		collisionInfo->objs[obj].miny = miny;
		collisionInfo->objs[obj].minz = minz;
		collisionInfo->objs[obj].maxx = maxx;
		collisionInfo->objs[obj].maxy = maxy;
		collisionInfo->objs[obj].maxz = maxz;
		fprintf( stderr, "Inside preFrameInit, bbox=%g %g %g %g %g %g\n",
				minx,miny,minz,maxx,maxy,maxz);
	}

	return( true );
}
//----------------------------------------------------------------------------------------------------------------------
void OceanNode::createGrid(int _resolution, double _time, double _choppiness, MObject& _outputData, MStatus &_status){
    int numTris = (_resolution-1)*(_resolution-1)*2;

    MFloatPointArray vertices;
    MIntArray numFaceVertices;
    MIntArray faceVertices;
    int tris[numTris*3];

    int width = 500;
    int depth = 500;

    // calculate the deltas for the x,z values of our point
    float wStep=(float)width/(float)_resolution;
    float dStep=(float)depth/(float)_resolution;
    // now we assume that the grid is centered at 0,0,0 so we make
    // it flow from -w/2 -d/2
    float xPos=-((float)width/2.0);
    float zPos=-((float)depth/2.0);

    // now loop from top left to bottom right and generate points

    m_ocean->update(_time);

    float2* heights = m_ocean->getHeights();
    float2* chopXArray = m_ocean->getChopX();
    float2* chopZArray = m_ocean->getChopZ();

    // Sourced form Jon Macey's NGL library
    for(int z=0; z<_resolution; z++){
        for(int x=0; x<_resolution; x++){
            // Divide the values we get out of the FFT by 50000 to get them in a suitable range
            float height = heights[z * _resolution + x].x/50000.0;
            float chopX = _choppiness * chopXArray[z * _resolution + x].x/50000.0;
            float chopZ= _choppiness * chopZArray[z * _resolution + x].x/50000.0;
            int sign = 1.0;
            if ((x+z) % 2 != 0){
                sign = -1.0;
            }
            vertices.append((xPos + (chopX * sign)), height * sign, (zPos + (chopZ * sign)));
            // calculate the new position
            zPos+=dStep;
        }
        // now increment to next z row
        xPos+=wStep;
        // we need to re-set the xpos for new row
        zPos=-((float)depth/2.0);
    }

    // Array for num vertices in each face
    for (int i=0; i<numTris; i++){
        numFaceVertices.append(3);
    }

    // Assign vertices to each face
    int fidx = 0;
    for (int i=0; i<(_resolution-1); i++){
        for (int j=0; j<(_resolution-1); j++){
            tris[fidx*3+0] = (i+1)*_resolution+j;
            tris[fidx*3+1] = i*_resolution+j+1;
            tris[fidx*3+2] = i*_resolution+j;
            fidx++;
            tris[fidx*3+0] = (i+1)*_resolution+j;
            tris[fidx*3+1] = (i+1)*_resolution+j+1;
            tris[fidx*3+2] = i*_resolution+j+1;
            fidx++;
        }
    }

    for (uint i=0; i<sizeof(tris)/sizeof(int); i++){
        faceVertices.append(tris[i]);
    }

   MFnMesh grid;
   grid.create(vertices.length(), numTris, vertices, numFaceVertices, faceVertices, _outputData, &_status);
}
Beispiel #25
0
collision_shape_t::pointer collisionShapeNode::createCollisionShape(const MObject& node)
{

	collision_shape_t::pointer collision_shape = 0;

	MObject thisObject(thisMObject());
	MPlug plgType(thisObject, ia_type);
	int type;
	plgType.getValue(type);

	switch(type) {
	case 0:  
		{
			//convex hull
			{
				if(node.hasFn(MFn::kMesh)) {
					MDagPath dagPath;
					MDagPath::getAPathTo(node, dagPath);
					MFnMesh fnMesh(dagPath);
					MFloatPointArray mpoints;
					MFloatVectorArray mnormals;
					MIntArray mtrianglecounts;
					MIntArray mtrianglevertices;
					fnMesh.getPoints(mpoints, MSpace::kObject);
					fnMesh.getNormals(mnormals, MSpace::kObject);
					fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

					std::vector<vec3f> vertices(mpoints.length());
					std::vector<vec3f> normals(mpoints.length());
					std::vector<unsigned int> indices(mtrianglevertices.length());

					btAlignedObjectArray<btVector3> btVerts; //mb

					for(size_t i = 0; i < vertices.size(); ++i) {
						vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
						normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);

#if UPDATE_SHAPE //future collision margin adjust
						btVerts.push_back(btVector3(mpoints[i].x, mpoints[i].y, mpoints[i].z)); //mb
#endif
					}
					for(size_t i = 0; i < indices.size(); ++i) {
						indices[i] = mtrianglevertices[i];
					}

#if UPDATE_SHAPE //future collision margin adjust
					btAlignedObjectArray<btVector3> planeEquations;
					btGeometryUtil::getPlaneEquationsFromVertices(btVerts, planeEquations);

					btAlignedObjectArray<btVector3> shiftedPlaneEquations;
					for (int p=0;p<planeEquations.size();p++)
					{
						btVector3 plane = planeEquations[p];
						plane[3] += collisionShapeNode::collisionMarginOffset;
						shiftedPlaneEquations.push_back(plane);
					}

					btAlignedObjectArray<btVector3> shiftedVertices;
					btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations, shiftedVertices);

					std::vector<vec3f> shiftedVerticesVec3f(shiftedVertices.size());
					for(size_t i = 0; i < shiftedVertices.size(); ++i) 
					{
						shiftedVerticesVec3f[i] = vec3f(shiftedVertices[i].getX(), shiftedVertices[i].getY(), shiftedVertices[i].getZ());
						//std::cout << "orig verts: " << vertices[i][0] << " " << vertices[i][1] << " " << vertices[i][2] << std::endl;
						//std::cout << "shft verts: " << shiftedVertices[i].getX() << " " << shiftedVertices[i].getY() << " " << shiftedVertices[i].getZ() << std::endl;
						//std::cout << std::endl;
					}

					collision_shape = solver_t::create_convex_hull_shape(&(shiftedVerticesVec3f[0]), shiftedVerticesVec3f.size(), &(normals[0]), &(indices[0]), indices.size());

#endif

#if UPDATE_SHAPE == 0
					collision_shape = solver_t::create_convex_hull_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size()); //original
#endif
				}
			}
		}

		break;
	case 1:
		{
			//mesh
			{
				if(node.hasFn(MFn::kMesh)) {
					MDagPath dagPath;
					MDagPath::getAPathTo(node, dagPath);
					MFnMesh fnMesh(dagPath);
					MFloatPointArray mpoints;
					MFloatVectorArray mnormals;
					MIntArray mtrianglecounts;
					MIntArray mtrianglevertices;
					fnMesh.getPoints(mpoints, MSpace::kObject);
					fnMesh.getNormals(mnormals, MSpace::kObject);
					fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

					std::vector<vec3f> vertices(mpoints.length());
					std::vector<vec3f> normals(mpoints.length());
					std::vector<unsigned int> indices(mtrianglevertices.length());

					for(size_t i = 0; i < vertices.size(); ++i) {
						vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
						normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
					}
					for(size_t i = 0; i < indices.size(); ++i) {
						indices[i] = mtrianglevertices[i];
					}
					bool dynamicMesh = true;
					collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]),
						&(indices[0]), indices.size(),dynamicMesh);
				}
			}
		}
		break;
	case 2:
		//cylinder
		break;
	case 3:
		//capsule
		break;

	case 7:
		//btBvhTriangleMeshShape
		{

				if(node.hasFn(MFn::kMesh)) {
					MDagPath dagPath;
					MDagPath::getAPathTo(node, dagPath);
					MFnMesh fnMesh(dagPath);
					MFloatPointArray mpoints;
					MFloatVectorArray mnormals;
					MIntArray mtrianglecounts;
					MIntArray mtrianglevertices;
					fnMesh.getPoints(mpoints, MSpace::kObject);
					fnMesh.getNormals(mnormals, MSpace::kObject);
					fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

					std::vector<vec3f> vertices(mpoints.length());
					std::vector<vec3f> normals(mpoints.length());
					std::vector<unsigned int> indices(mtrianglevertices.length());

					for(size_t i = 0; i < vertices.size(); ++i) {
						vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
						normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
					}
					for(size_t i = 0; i < indices.size(); ++i) {
						indices[i] = mtrianglevertices[i];
					}
					bool dynamicMesh = false;
					collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]),
						&(indices[0]), indices.size(),dynamicMesh);
			}
		}
		break;
	case 8:
		//hacd convex decomposition
		{

			{
				if(node.hasFn(MFn::kMesh)) {
					MDagPath dagPath;
					MDagPath::getAPathTo(node, dagPath);
					MFnMesh fnMesh(dagPath);
					MFloatPointArray mpoints;
					MFloatVectorArray mnormals;
					MIntArray mtrianglecounts;
					MIntArray mtrianglevertices;
					fnMesh.getPoints(mpoints, MSpace::kObject);
					fnMesh.getNormals(mnormals, MSpace::kObject);
					fnMesh.getTriangles(mtrianglecounts, mtrianglevertices);

					std::vector<vec3f> vertices(mpoints.length());
					std::vector<vec3f> normals(mpoints.length());
					std::vector<unsigned int> indices(mtrianglevertices.length());

					for(size_t i = 0; i < vertices.size(); ++i) {
						vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z);
						normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z);
					}
					for(size_t i = 0; i < indices.size(); ++i) {
						indices[i] = mtrianglevertices[i];
					}
					bool dynamicMesh = false;
					collision_shape = solver_t::create_hacd_shape(&(vertices[0]), vertices.size(), &(normals[0]),
						&(indices[0]), indices.size(),dynamicMesh);
				}
			}
		}
		break;
	default:
		{
		}
	}

	return collision_shape;
}
Beispiel #26
0
//
//  Recursively traverse a mesh by processing each face, and the neighbouring faces along it's edges.
//  The initial invocation of this routine provides the basis for the new first vertex/edge
//  and faces.  
//
//  The result of this routine is an array of values that map the old CV indices to the new ones. Along
//  the a new list of reindexed CVs is built, along with a list of poly counts and connetions. These
//  can be used to build a new mesh with the reordering specfied by the seed face and vertices.
//
//
//  Inputs: 
//		path				: Path to the object being traversed
//		faceIdx				: Current face being traversed
//		v0, v1				: Veretices that define the direction of travel along the face
//		faceTraversal		: An array booleans to track which faces have been 
//							: traversed, controls the recursion  
//		origVertices		: The vertices from the original mesh. The could be obtained
//							: from the path, but are passed in for efficiency
//
// 	Outputs:
//		cvMapping			: Mapping of the existing vertices to their new indices
//							: the fist values in the final array will be the intial v0, v1
//		cvMappingInverse	: The inverse of the cvMapping
//							: the value of items v0 and v1 will be 0 and 1 respectively
//		newPolygonCounts	: Vertex counts for each of the new faces
//		newPolygonConnects  : Connections, specified in terms of new CV indices
//		newVertices			: The orginal vertices resorted based on the reindexing
//
//
MStatus meshMapUtils::traverseFace( 
	MDagPath&	path,
	int faceIdx, 
	int v0, 
	int v1, 
	MIntArray& faceTraversal,
	MIntArray& cvMapping,
	MIntArray& cvMappingInverse,
	MIntArray& newPolygonCounts,
	MIntArray& newPolygonConnects,
	MFloatPointArray& origVertices,
	MFloatPointArray& newVertices
)
{
	int vtxCnt = -1;
	int dir = 0;
	int dummy;		// For setIndex calls

	MStatus stat = MStatus::kSuccess;

	MFnMesh theMesh( path, &stat );
	MItMeshPolygon polyIt( path );
	MItMeshEdge edgeIt( path );

	if( stat != MStatus::kSuccess )
	{
		MGlobal::displayError( " theMesh.getPoint failed");
		return stat;
	}


	//
	// Skip over any faces already processed, this is not a failure
	// 
	if( faceTraversal[faceIdx] )
	{
		return MStatus::kSuccess;
	}

	//
	// get the vertex/edge information and sort it based on the user seed
	//
	MIntArray vtxOrig;
	MIntArray edgeOrig;

	polyIt.setIndex( faceIdx, dummy );
	polyIt.getEdges( edgeOrig );	   
	polyIt.getVertices( vtxOrig );	   

	vtxCnt = vtxOrig.length();

	// 
	// the sorted V/E info
	// 
	MIntArray vtxSorted( vtxCnt );
	MIntArray edgeSorted( vtxCnt );

	//
	// Build a new array ordered with v0, then v1, first figure out the 
	// starting point, and direction 
	//
	int v0Idx =	-1;
	int i;
	for( i = 0; i < vtxCnt; i++ )
	{
		if( vtxOrig[i] == v0 )
		{
			// We've found v0, now find in what direction we need to travel to find v1
					
			v0Idx =	i;
			
			if( vtxOrig[IDX(i+1, vtxCnt)] == v1 )
			{
				dir = 1;
			}
			else if( vtxOrig[IDX(i-1, vtxCnt)] == v1 )
			{
				dir = -1;
			}
			break;
		}
	}

	if (dir == 0)
	{
		MGlobal::displayError("Selected vertices are not adjacent");
		return MS::kFailure;
	}

	// Now sort the vertex/edge arrays
	for( i = 0; i < vtxCnt; i++ )
	{
		vtxSorted[i] = vtxOrig[IDX( v0Idx + i * dir, vtxCnt )];
		if( dir == 1 )
		{
			edgeSorted[i] = edgeOrig[IDX( v0Idx + i * dir, vtxCnt )];
		}
		else
		{
			edgeSorted[i] = edgeOrig[IDX( v0Idx - 1 + i * dir, vtxCnt )];
		}
	}


	// Add any new CVs to the vertex array being constructed
	for ( i = 0; i < vtxCnt; i++ )
	{
		MPoint pos;
		int index = vtxSorted[i];

		if( cvMapping[index] == -1  )
		{
			if( stat != MStatus::kSuccess )
			{
				MGlobal::displayError( " theMesh.getPoint failed");
				return stat;
			}

			// Added the new CV, and mark it as transferred
			newVertices.append( origVertices[index] );

			// Store the mapping from the old CV indices to the new ones
			cvMapping[index] = newVertices.length()-1;
			cvMappingInverse[newVertices.length()-1] = index;
		}

	}

	//
	//  Add the new face count 
	//
	newPolygonCounts.append( vtxCnt );

	//
	//  Add the new polyConnects
	
	for ( i = 0; i < vtxCnt; i++ )
	{
		newPolygonConnects.append( cvMapping[vtxSorted[i]] );
	}

	// Mark this face as complete 
	faceTraversal[faceIdx] = true;

	//
	//  Now recurse over the edges of this face
	// 
	for( i = 0; i < (int)edgeSorted.length(); i++ )
	{
		int nextEdge = edgeSorted[i];

		int2 nextEdgeVtx;
		stat = theMesh.getEdgeVertices(nextEdge, nextEdgeVtx );

		//
		// Find the vertex, in the sorted array, that starts the next edge
		int baseIdx = -1;
		bool swap = false;
		int j;
		for( j = 0; j < (int)vtxSorted.length(); j++ )
		{
			if( vtxSorted[j] == nextEdgeVtx[0] )
			{
				baseIdx = j;
				break;
			}
		}

		assert( baseIdx != -1 );
	
		// 
		// Now look forward and backward in the vertex array to find the
		// edge's other point, this indicates the edges direction. This
		// is needed to guide the next recursion level, and keep the
		// normals pointed consistenly
		//
		if( vtxSorted[IDX(baseIdx+1, vtxCnt)] == nextEdgeVtx[1] )
		{
			// Nothing
		}
		else if ( vtxSorted[IDX(baseIdx-1, vtxCnt)] == nextEdgeVtx[1] )
		{
			swap = true;
		}


		MIntArray connectedFaces;
		edgeIt.setIndex( nextEdge, dummy );
		edgeIt.getConnectedFaces( connectedFaces );

		// A single face is simply the current one. Recurse over the others
		if( connectedFaces.length() > 1 )
		{
			int nextFace;
			if( connectedFaces[0] == faceIdx )
			{
			   	nextFace = connectedFaces[1];
			}
			else
			{
			   	nextFace = connectedFaces[0];
			}

			int nextVtx0 = -1;
			int nextVtx1 = -1;
			if ( !swap )
			{
				nextVtx0 = nextEdgeVtx[1];
				nextVtx1 = nextEdgeVtx[0];
			}
			else
			{
				nextVtx0 = nextEdgeVtx[0];
				nextVtx1 = nextEdgeVtx[1];
			}

			stat = traverseFace( path, nextFace, nextVtx0, nextVtx1, faceTraversal,
					cvMapping, cvMappingInverse, 
					newPolygonCounts, newPolygonConnects, 
					origVertices, newVertices );

			// Break out of edge loop on error
			if( stat != MStatus::kSuccess )
			{
				break;
			}	
		}
	}

	return stat;
}
Beispiel #27
0
MObject ClothSimMayaPlugin::createMesh(const MTime& time,
	MObject& outData,
	MStatus& stat)

{
	double t = time.as(MTime::kSeconds);
	if (t <= 1.0 / 24 && m_prevTime > 1.0/24)
	{
		m_simMesh.reset(0);
	}

	int nx = 60;
	int ny = 60;

	if (!m_simMesh.get())
	{

		Eigen::VectorXf v((nx+1) * (ny+1) * 3);
		Eigen::VectorXf x((nx + 1) * (ny + 1) * 3);
		Eigen::VectorXf uv((nx + 1) * (ny + 1) * 2);

		for (int i = 0; i <= nx; ++i)
		{
			for (int j = 0; j <= ny; ++j)
			{
				int base = i + (nx+1) * j;
				uv[2 * base + 0] = (float)i / nx - 0.5f;
				uv[2 * base + 1] = (float)j / ny - 0.5f;

				x[3 * base + 0] = uv[2 * base + 0];
				x[3 * base + 1] = 0;
				x[3 * base + 2] = uv[2 * base + 1];

				v[3 * base + 0] = v[3 * base + 1] = v[3 * base + 2] = 0;
			}
		}

		std::vector<int> triangleInds;
		for (int i = 0; i < nx; ++i)
		{
			for (int j = 0; j < ny; ++j)
			{
				int base = i + (nx + 1) * j;

				triangleInds.push_back(base + 0);
				triangleInds.push_back(base + 1);
				triangleInds.push_back(base + (nx + 1));

				triangleInds.push_back(base + 1);
				triangleInds.push_back(base + (nx + 2));
				triangleInds.push_back(base + (nx + 1));

			}
		}

		m_simMesh.reset(
			new ClothMesh<float>(
				x, v, uv, triangleInds,
				0.01f, 1000000.0f, 1000000.0f,
				0.01f, 1000.0f, 1000.0f,
				1.0f
			)
		);
	}

	std::vector<int> constraintIndices;
	std::vector< Eigen::Matrix3f > constraintMatrices;

	
	Eigen::VectorXf constraintVelocityDeltas(m_simMesh->x().size());
	constraintVelocityDeltas.setConstant(0);

	for (int i = 0; i <= nx; ++i)
	{
		for (int j = 0; j <= ny; ++j)
		{
			int idx = i + (nx + 1) * j;
			float x = (float)i / nx - 0.5f;
			float y = (float)j / ny - 0.5f;

			if (x * x + y * y < 0.3 * 0.3)
			{
				constraintIndices.push_back(idx);
				constraintMatrices.push_back(Eigen::Matrix3f::Zero());
			}
		}
	}

	if (t > m_prevTime)
	{
		ConstrainedCGSolver<float> solver(
			constraintIndices,
			constraintMatrices,
			constraintVelocityDeltas,
			0.01f,
			400
		);

		GravityField<float> g( m_simMesh->m(), Eigen::Vector3f( 0,-9.8f, 0 ) );
		std::vector< ForceField<float>* > forceFields;
		forceFields.push_back( &g );

		try
		{
			std::cerr << "advance" << std::endl;
			m_simMesh->advance(forceFields, float(t - m_prevTime)*0.5f, solver);
			m_simMesh->advance(forceFields, float(t - m_prevTime)*0.5f, solver);
			std::cerr << "done" << std::endl;
		}
		catch (const std::exception &e)
		{
			std::cerr << e.what() << std::endl;
			stat = MStatus::kFailure;
			return MObject();
		}
		catch (...)
		{
			std::cerr << "unknown exception" << std::endl;
			stat = MStatus::kFailure;
			return MObject();
		}
	}

	m_prevTime = t;

	MFloatPointArray points;
	for (int i = 0; i < m_simMesh->x().size(); i += 3)
	{
		MFloatPoint p(m_simMesh->x()[i], m_simMesh->x()[i + 1], m_simMesh->x()[i + 2]);
		points.append(p);
	}

	MFnMesh meshFS;
	MIntArray faceCounts((int)m_simMesh->triangleIndices().size()/3, 3);
	MIntArray faceConnects;
	for (unsigned i = 0; i < m_simMesh->triangleIndices().size(); ++i)
	{
		faceConnects.append(m_simMesh->triangleIndices()[i]);
	}

	MObject newMesh = meshFS.create((int)m_simMesh->x().size() / 3, (int)m_simMesh->triangleIndices().size() / 3, points, faceCounts, faceConnects, outData, &stat);

	return newMesh;
}
Beispiel #28
0
void readPoly(double iFrame, MFnMesh & ioMesh, MObject & iParent,
              PolyMeshAndFriends & iNode, bool iInitialized)
{
    Alembic::AbcGeom::IPolyMeshSchema schema = iNode.mMesh.getSchema();
    Alembic::AbcGeom::MeshTopologyVariance ttype = schema.getTopologyVariance();

    Alembic::AbcCoreAbstract::index_t index, ceilIndex;
    double alpha = getWeightAndIndex(iFrame,
                                     schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex);

    MFloatPointArray pointArray;
    Alembic::Abc::P3fArraySamplePtr ceilPoints;

    // we can just read the points
    if (ttype != Alembic::AbcGeom::kHeterogenousTopology && iInitialized)
    {

        Alembic::Abc::P3fArraySamplePtr points = schema.getPositionsProperty(
                ).getValue(Alembic::Abc::ISampleSelector(index));

        if (alpha != 0.0)
        {
            ceilPoints = schema.getPositionsProperty().getValue(
                             Alembic::Abc::ISampleSelector(ceilIndex) );
        }

        fillPoints(pointArray, points, ceilPoints, alpha);
        if(pointArray.length() > 0)
        {
            ioMesh.setPoints(pointArray, MSpace::kObject);
        }

        setColorsAndUVs(iFrame, ioMesh, schema.getUVsParam(),
                        iNode.mV2s, iNode.mC3s, iNode.mC4s, !iInitialized);

        if (schema.getNormalsParam().getNumSamples() > 1)
        {
            setPolyNormals(iFrame, ioMesh, schema.getNormalsParam());
        }

        return;
    }

    // we need to read the topology
    Alembic::AbcGeom::IPolyMeshSchema::Sample samp;
    schema.get(samp, Alembic::Abc::ISampleSelector(index));

    if (alpha != 0.0 && ttype != Alembic::AbcGeom::kHeterogenousTopology)
    {
        ceilPoints = schema.getPositionsProperty().getValue(
                         Alembic::Abc::ISampleSelector(ceilIndex) );
    }

    fillPoints(pointArray, samp.getPositions(), ceilPoints, alpha);

    fillTopology(ioMesh, iParent, pointArray, samp.getFaceIndices(),
                 samp.getFaceCounts());

    setPolyNormals(iFrame, ioMesh, schema.getNormalsParam());
    setColorsAndUVs(iFrame, ioMesh, schema.getUVsParam(),
                    iNode.mV2s, iNode.mC3s, iNode.mC4s, !iInitialized);
}
Beispiel #29
0
MStatus intersectCmd::doIt(const MArgList& args)

// Description:
// 		Determine if the ray from the spotlight intersects the mesh.
//		If it does, display the intersection points.

{
	MStatus stat = MStatus::kSuccess;

	if (args.length() != 2) 
	{
		MGlobal::displayError("Need 2 items!");
		return MStatus::kFailure;
	}

	MSelectionList activeList;
	int i;
	
	for ( i = 0; i < 2; i++)
	{
		MString strCurrSelection;
		stat = args.get(i, strCurrSelection);
		if (MStatus::kSuccess == stat) activeList.add(strCurrSelection);
	}

	MItSelectionList iter(activeList);
	MFnSpotLight fnLight;  
	MFnMesh fnMesh;
	MFnDagNode dagNod;
	MFnDependencyNode fnDN;

	float fX = 0;
	float fY = 0;
	float fZ = 0;

	for ( ; !iter.isDone(); iter.next() )
	{
		MObject tempObjectParent, tempObjectChild;
		iter.getDependNode(tempObjectParent);

		if (tempObjectParent.apiType() == MFn::kTransform)
		{
			dagNod.setObject(tempObjectParent);
			tempObjectChild = dagNod.child(0, &stat);
		}

		// check what type of object is selected
		if (tempObjectChild.apiType() == MFn::kSpotLight)
		{
			MDagPath pathToLight;
			MERR_CHK(MDagPath::getAPathTo(tempObjectParent, pathToLight), "Couldn't get a path to the spotlight");
			MERR_CHK(fnLight.setObject(pathToLight), "Failure on assigning light");
			
			stat = fnDN.setObject(tempObjectParent);

			MPlug pTempPlug = fnDN.findPlug("translateX", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fX);
			}

			pTempPlug = fnDN.findPlug("translateY", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fY);
			}

			pTempPlug = fnDN.findPlug("translateZ", &stat);
			if (MStatus::kSuccess == stat)
			{
				pTempPlug.getValue(fZ);
			}	
		}
		else if (tempObjectChild.apiType() == MFn::kMesh)
		{
			MDagPath pathToMesh;
			MERR_CHK(MDagPath::getAPathTo(tempObjectChild, pathToMesh), "Couldn't get a path to the spotlight");
			MERR_CHK(fnMesh.setObject(pathToMesh), "Failure on assigning light");	
		}
		else
		{
			MGlobal::displayError("Need a spotlight and a mesh");
			return MStatus::kFailure;
		}
	}

	MFloatPoint fpSource(fX, fY, fZ);
	MFloatVector fvRayDir = fnLight.lightDirection(0, MSpace::kWorld, &stat);
	MFloatPoint hitPoint;
	
	MMeshIsectAccelParams mmAccelParams = fnMesh.autoUniformGridParams();
	
	float fHitRayParam, fHitBary1, fHitBary2;
	int nHitFace, nHitTriangle;

	// a large positive number is used here for the maxParam parameter
	bool bAnyIntersection = fnMesh.anyIntersection(fpSource, fvRayDir, NULL, NULL, false,				MSpace::kWorld, (float)9999, false, &mmAccelParams, hitPoint, &fHitRayParam, &nHitFace, &nHitTriangle, 		&fHitBary1, &fHitBary2, (float)1e-6, &stat);
	
	if (! bAnyIntersection) 
	{
		MGlobal::displayInfo("There were no intersection points detected");
		return stat;
	}

	MFloatPointArray hitPoints;
	MFloatArray faHitRayParams;
	MIntArray iaHitFaces;
	MIntArray iaHitTriangles;
	MFloatArray faHitBary1;
	MFloatArray faHitBary2;

	bool bAllIntersections = fnMesh.allIntersections(fpSource, fvRayDir, NULL, NULL, false, MSpace::kWorld, 9999, false, NULL, false, hitPoints, &faHitRayParams, &iaHitFaces, &iaHitTriangles, &faHitBary1, &faHitBary2, 0.000001f, &stat);
	
	if (! bAllIntersections)
	{
		MGlobal::displayInfo("Error getting all intersections");
		return stat;
	}
	
	// check how many intersections are found
	unsigned int nNumberHitPoints = hitPoints.length();

	if (! nNumberHitPoints)
	{
		MGlobal::displayInfo("No hit points detected");
		return MStatus::kSuccess;
	}

	// Intersection exists; display intersections as spheres
	MString strCommandString = "string $strBall[] = `polySphere -r 0.5`;";
	strCommandString += "$strBallName = $strBall[0];";

	float x = 0;
	float y = 0;
	float z = 0;

	for (i = 0; i < (int)nNumberHitPoints; i++)
	{
		// get the points
		x = hitPoints[i][0];
		y = hitPoints[i][1];
		z = hitPoints[i][2];

		// execute some MEL to create a small sphere
		strCommandString += "setAttr ($strBallName + \".tx\") ";
		strCommandString += x;
		strCommandString += ";";

		strCommandString += "setAttr ($strBallName + \".ty\") ";
		strCommandString += y;
		strCommandString += ";";

		strCommandString += "setAttr ($strBallName + \".tz\") ";
		strCommandString += z;
		strCommandString += ";";

		MGlobal::executeCommand(strCommandString);
	}

	return stat;
}
Beispiel #30
0
MObject blindDataMesh::createMesh(long seed, MObject& outData, MStatus& stat)
{
	MFloatPointArray vertices;
	MIntArray faceDegrees;
	MIntArray faceVertices;
	int i, j;

	srand(seed);

	float planeSize = 20.0f;
	float planeOffset = planeSize / 2.0f;
	float planeDim = 0.5f;

	int numDivisions = (int) (planeSize / planeDim);
	// int numVertices = (numDivisions + 1) * (numDivisions + 1);
	// int numEdge = (2 * numDivisions) * (numDivisions + 1);
	int numFaces = numDivisions * numDivisions;

	// Set up an array containing the vertex positions for the plane. The
	// vertices are placed equi-distant on the X-Z plane to form a square
	// grid that has a side length of "planeSize".
	//
	// The Y-coordinate of each vertex is the average of the neighbors already
	// calculated, if there are any, with a small random offset added. Because
	// of the way the vertices are calculated, the whole plane will look like
	// it is streaked in a diagonal direction with mountains and depressions.
	//
	for (i = 0; i < (numDivisions + 1); ++i)
	{
		for (j = 0; j < (numDivisions + 1); ++j)
		{
			float height;

			if (i == 0 && j == 0)
			{
				height = ((rand() % 101) / 100.0f - 0.5f);
			}
			else if (i == 0)
			{
				float previousHeight = vertices[j - 1][1];
				height = previousHeight + ((rand() % 101) / 100.0f - 0.5f);
			}
			else if (j == 0)
			{
				float previousHeight = vertices[(i-1)*(numDivisions + 1)][1];
				height = previousHeight + ((rand() % 101) / 100.0f - 0.5f);
			}
			else
			{
				float previousHeight
					= vertices[(i-1)*(numDivisions + 1) + j][1];
				float previousHeight2
					= vertices[i*(numDivisions + 1) + j - 1][1];
				height = (previousHeight + previousHeight2)
					/ 2.0f + ((rand() % 101) / 100.0f - 0.5f);
			}

			MFloatPoint vtx( i * planeDim - planeOffset, height,
				j * planeDim - planeOffset );
			vertices.append(vtx);
		}
	}

	// Set up an array containing the number of vertices
	// for each of the plane's faces
	//
	for (i = 0; i < numFaces; ++i)
	{
		faceDegrees.append(4);
	}

	// Set up an array to assign the vertices for each face
	//
	for (i = 0; i < numDivisions; ++i)
	{
		for (j = 0; j < numDivisions; ++j)
		{
			faceVertices.append(i*(numDivisions+1) + j);
			faceVertices.append(i*(numDivisions+1) + j + 1);
			faceVertices.append((i+1)*(numDivisions+1) + j + 1);
			faceVertices.append((i+1)*(numDivisions+1) + j);
		}
	}

	MFnMesh	meshFn;
	MObject newMesh = meshFn.create(vertices.length(), numFaces, vertices,
		faceDegrees, faceVertices, outData, &stat);

	return newMesh;
}