void SpatialGrid::getClosestVoxelCoords( const MPoint& point, gridPoint3<int>& coords) const // // Description: // // Given a point, compute the x,y,z indices of the voxel grid // that it is closest to. // { MPoint c1 = fBounds.min() + MVector(fBounds.width()/4, fBounds.height()/4, fBounds.depth()/4); MPoint c2 = fBounds.max() - MVector(fBounds.width()/4, fBounds.height()/4, fBounds.depth()/4); MBoundingBox bounds(c1,c2); MPoint relPoint; if(bounds.contains(point)){ relPoint = point - fBounds.min(); } else { //snap to bbox MPoint closestPoint = point; GPUCache::gpuCacheIsectUtil::getClosestPointOnBox(point, bounds, closestPoint); relPoint = closestPoint - fBounds.min(); } for( int axis = 0; axis < 3; axis++ ) { // figure out which cell point resides in // float voxSpace = relPoint[axis] / fVoxelSizes[axis]; coords[axis] = (int)floor( voxSpace ); } }
sgBLocator_fromGeo::sgBLocator_fromGeo() { m_pointArr.setLength(6); m_pointArr[0] = MFloatPoint( 1, 0, 0 ); m_pointArr[1] = MFloatPoint( -1, 0, 0 ); m_pointArr[2] = MFloatPoint( 0, -1, 0 ); m_pointArr[3] = MFloatPoint( 0, 1, 0 ); m_pointArr[4] = MFloatPoint( 0, 0, 1 ); m_pointArr[5] = MFloatPoint( 0, 0, -1 ); m_boundingBox.clear(); m_boundingBox.expand( MVector( 1.0, 1.0, 1.0 ) ); m_boundingBox.expand( MVector( -1.0, -1.0, -1.0 ) ); m_colorActive = MColor( 1.0f, 1.0f, 1.0f ); m_colorLead = MColor( .26f, 1.0f, .64f ); m_colorDefault = MColor( 1.0f, 1.0f, 0.0f ); m_lineWidth = 1; MFnDependencyNode fnNode( thisMObject() ); MPlug plugOutput = fnNode.findPlug( aOutputValue ); MPlug plugVis =fnNode.findPlug( "v" ); MDGModifier dgModifier; dgModifier.connect( plugOutput, plugVis ); }
/*! * Deforms a point in the STU space into another point in the STU space using a lattice. */ MPoint ffdPlanar::getDeformedPoint( MPoint& point, MVector (& lattice)[FFD_LATTICE_POINTS_S][FFD_LATTICE_POINTS_T][FFD_LATTICE_POINTS_U] ) { MPoint ffd1 = MPoint(); MVector ffd2 = MVector(); MVector ffd3 = MVector(); for ( int i = 0; i < FFD_LATTICE_POINTS_S; i++ ) { for ( int j = 0; j < FFD_LATTICE_POINTS_T; j++ ) { for ( int k = 0; k < FFD_LATTICE_POINTS_U; k++ ) { double bernstein_u = bernsteinPoly( k, FFD_DIMENSIONS_U, point.z); ffd3 += lattice[i][j][k] * bernstein_u; } double bernstein_t = bernsteinPoly( j, FFD_DIMENSIONS_T, point.y ); ffd2 += ffd3 * bernstein_t; ffd3.x = 0; ffd3.y = 0; ffd3.z = 0; } double bernstein_s = bernsteinPoly( i, FFD_DIMENSIONS_S, point.x ); ffd1 += ffd2 * bernstein_s; ffd2.x = 0; ffd2.y = 0; ffd2.z = 0; } return ffd1; }
void CylinderMesh::initCylinderMesh(double r1, double r2) { int numslices = 10; double angle = M_PI*2/numslices; // Add points and normals gPoints.clear(); gNormals.clear(); gFaceCounts.clear(); gFaceConnects.clear(); for (int i = 0; i < numslices; i++) { gPoints.append(MPoint(0,r1*cos(angle*i), r1*sin(angle*i))); gNormals.append(MVector(0,r1*cos(angle*i), r1*sin(angle*i))); } for (int i = 0; i < numslices; i++) { gPoints.append(MPoint(1,r2*cos(angle*i), r2*sin(angle*i))); gNormals.append(MVector(0,r2*cos(angle*i), r2*sin(angle*i))); } // endcap 1 /*gPoints.append(MPoint(0,0,0)); gNormals.append(MVector(-1,0,0)); // endcap 2 gPoints.append(MPoint(1,0,0)); gNormals.append(MVector(1,0,0)); // Set indices for endcap 1 for (int i = 0; i < numslices; i++) { gFaceCounts.append(3); // append triangle gFaceConnects.append(2*numslices); gFaceConnects.append((i+1)%numslices); gFaceConnects.append(i); } // Set indices for endcap 2 for (int i = numslices; i < 2*numslices; i++) { gFaceCounts.append(3); // append triangle gFaceConnects.append(2*numslices+1); gFaceConnects.append(i); int next = i+1; if (next >= 2*numslices) next = numslices; gFaceConnects.append(next); } */ // Set indices for middle for (int i = 0; i < numslices; i++) { gFaceCounts.append(4); // append quad gFaceConnects.append(i); gFaceConnects.append((i+1)%numslices); gFaceConnects.append((i+1)%numslices+numslices); gFaceConnects.append(i+numslices); } }
// COMPUTE ====================================== MStatus gear_uToPercentage::compute(const MPlug& plug, MDataBlock& data) { MStatus returnStatus; // Error check if (plug != percentage) return MS::kUnknownParameter; // Curve MFnNurbsCurve crv( data.inputValue( curve ).asNurbsCurve() ); // Sliders bool in_normU = data.inputValue( normalizedU ).asBool(); double in_u = (double)data.inputValue( u ).asFloat(); unsigned in_steps = data.inputValue( steps ).asShort(); // Process if (in_normU) in_u = normalizedUToU(in_u, crv.numCVs()); // Get length MVectorArray u_subpos(in_steps); MVectorArray t_subpos(in_steps); MPoint pt; double step; for (unsigned i = 0; i < in_steps ; i++){ step = i * in_u / (in_steps - 1.0); crv.getPointAtParam(step, pt, MSpace::kWorld); u_subpos[i] = MVector(pt); step = i/(in_steps - 1.0); crv.getPointAtParam(step, pt, MSpace::kWorld); t_subpos[i] = MVector(pt); } double u_length = 0; double t_length = 0; MVector v; for (unsigned i = 0; i < in_steps ; i++){ if (i>0){ v = u_subpos[i] - u_subpos[i-1]; u_length += v.length(); v = t_subpos[i] - t_subpos[i-1]; t_length += v.length(); } } double out_perc = (u_length / t_length) * 100; // Output MDataHandle h = data.outputValue( percentage ); h.setDouble( out_perc ); data.setClean( plug ); return MS::kSuccess; }
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; }
retargetLocator::retargetLocator() { discAxis = 0; discDivision = 32; discSize = MVector( 1,1,1 ); discOffset = MVector( 0,0,0 ); float discFillAlpha = 0.1f; float discLineAlpha = 1.0f; int arrowNum = 0; }
char BCIViz::checkFirstFour(const MPointArray & p) const { const MVector e01 = p[1] - p[0]; const MVector e02 = p[2] - p[0]; MVector nor = e01^e02; nor.normalize(); const float d = -(MVector(p[0])*nor); // P.N + d = 0 , P = P0 + Vt, (P0 + Vt).N + d = 0, t = -(P0.N + d)/(V.N) const float t = MVector(p[3])*nor + d; // where V = -N if(t > -10e-5 && t < 10e-5) return 0; return 1; }
// Convert from cartesian to spherical coordinates void sphericalBlendShape::cartesianToSpherical(const MPoint& point, short poleAxis, short seamAxis, MPoint& warpPoint, MPoint& outPoint) { double radius, zenith, azimuth; radius = MVector(point).length(); azimuth = getAzimuth(point, poleAxis, seamAxis); zenith = 0.0; if (!isNearZero(radius)) { zenith = acos(getAxis(MVector(point), poleAxis) / radius); } outPoint.x = radius; outPoint.y = zenith; outPoint.z = azimuth; }
MStatus OParticleCmd::redoIt() { MStatus status; MObject tr = dgMod.createNode("transform"); MObject op = dgMod.createNode(OParticleNode::typeId,tr,&status); static int count=0; if(status==MS::kSuccess)count++; MString name = "transformOfOParticles"; name += count; dgMod.renameNode(tr,name); MString command = "select -add "; command += name; dgMod.commandToExecute( command); MFnTransform fn(tr); fn.setTranslation(MVector(x,y,z),MSpace::kTransform); MPlug radius(op,OParticleNode::radius); radius.setValue(r); bool update; MPlug(op,OParticleNode::Param).getValue(update); MPlug(op,OParticleNode::Pattribute).getValue(update); return dgMod.doIt(); }
MStatus HairToolContext::doDrag( MEvent& event ) { if(intersectionFound){ //Our Viewer m_View = M3dView::active3dView(); //Get Screen click position event.getPosition( m_storage[0], m_storage[1] ); screenPoints.push_back(vec2(m_storage[0], m_storage[1])); //Camera stuff MPoint origin = MPoint(); MVector direction = MVector(); m_View.viewToWorld(m_storage[0], m_storage[1], origin, direction); float tValue = ((point - origin)*normal) / (direction * normal); MPoint newPoint = tValue*direction + origin; splinePoints.push_back(newPoint); //Draw GL curve m_View.beginXorDrawing(true, true, 1.0f, M3dView::kStippleDashed); glBegin(GL_LINE_STRIP ); for ( unsigned i = 0; i < screenPoints.size() ; i++ ){ glVertex2i( screenPoints[i][0], screenPoints[i][1] ); } glEnd(); m_View.endXorDrawing(); } return MPxContext::doDrag(event); }
double sphericalBlendShape::getAzimuth(MPoint point, short aPoleAxis, short aSeamAxis) { double azimuth = atan2(getAxis(MVector(point), axisCross(aPoleAxis, aSeamAxis)), getAxis(MVector(point), aSeamAxis)); // atan2 returns the range [-pi, pi]. remap to [0, 2pi). if (azimuth < 0 && isNearZero(azimuth)) { azimuth += 2 * M_PI; } return azimuth; }
MVector boingRbCmd::getBulletVectorAttribute(MObject node, MString attr) { MVector vec; MFnDagNode fnDagNode(node); if(fnDagNode.typeId() == boingRBNode::typeId) { boingRBNode *rbNode = static_cast<boingRBNode*>(fnDagNode.userNode()); rigid_body_t::pointer rb = rbNode->rigid_body(); if (rb) { if(fnDagNode.parentCount() == 0) { std::cout << "No transform found!" << std::endl; return vec; } MPlug plgMass(node, boingRBNode::ia_mass); float mass = 0.f; plgMass.getValue(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]); } } } } return vec; }
MStatus MVC::computeMVCPosition(MVCWeights &weights, MPoint &p) { if (cageVertices.length() != weights.length()) return MStatus::kInvalidParameter; MPoint weightedPoint(0.0, 0.0, 0.0); for (int i = 0; i < weights.length(); i++) weightedPoint += weights[i] * MVector(cageVertices[i]); p = weightedPoint; return MStatus::kSuccess; }
void n_tentacle::removeMatrixScale(MMatrix &matrix) { MVector axisX = MVector(matrix(0, 0), matrix(0, 1), matrix(0, 2)); MVector axisY = MVector(matrix(1, 0), matrix(1, 1), matrix(1, 2)); MVector axisZ = MVector(matrix(2, 0), matrix(2, 1), matrix(2, 2)); axisX.normalize(); axisY.normalize(); axisZ.normalize(); matrix[0][0] = axisX.x; matrix[0][1] = axisX.y; matrix[0][2] = axisX.z; matrix[1][0] = axisY.x; matrix[1][1] = axisY.y; matrix[1][2] = axisY.z; matrix[2][0] = axisZ.x; matrix[2][1] = axisZ.y; matrix[2][2] = axisZ.z; }
double gpuCacheIsectUtil::getClosestPointOnBox(const MPoint& point, const MBoundingBox& bbox, MPoint& closestPoint){ MVector diff = point - bbox.center(); MVector axis[3] = { MVector(1.0,0.0,0.0), MVector(0.0,1.0,0.0), MVector(0.0,0.0,1.0)}; double dimensions[3] = {0.5*bbox.width(),0.5*bbox.height(),0.5*bbox.depth()}; double sqrDistance = 0.0; double delta; MPoint closest; for (int i = 0; i < 3; ++i) { closest[i] = diff * axis[i]; if (closest[i] < -dimensions[i]) { delta = closest[i] + dimensions[i]; sqrDistance += delta*delta; closest[i] = -dimensions[i]; } else if (closest[i] > dimensions[i]) { delta = closest[i] - dimensions[i]; sqrDistance += delta*delta; closest[i] = dimensions[i]; } } closestPoint = bbox.center(); for (int i = 0; i < 3; ++i) { closestPoint += closest[i]*axis[i]; } return sqrt(sqrDistance); }
MStatus sgBLocator_fromGeo::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; m_boundingBox.clear(); m_boundingBox.expand( MVector( 1.0, 1.0, 1.0 ) ); m_boundingBox.expand( MVector( -1.0, -1.0, -1.0 ) ); m_pointArr.setLength(6); m_pointArr[0] = MFloatPoint( 1, 0, 0 ); m_pointArr[1] = MFloatPoint( -1, 0, 0 ); m_pointArr[2] = MFloatPoint( 0, -1, 0 ); m_pointArr[3] = MFloatPoint( 0, 1, 0 ); m_pointArr[4] = MFloatPoint( 0, 0, 1 ); m_pointArr[5] = MFloatPoint( 0, 0, -1 ); m_lineWidth = data.inputValue( aLineWidth ).asInt(); data.setClean( plug ); return MS::kSuccess; }
void CylinderMesh::transform(MPointArray& points, MVectorArray& normals) { MVector forward = mEnd - mStart; double s = forward.length(); forward.normalize(); MVector left = MVector(0,0,1)^forward; MVector up; if (left.length() < 0.0001) { up = forward^MVector(0,1,0); left = up^forward; } else { up = forward^left; } MMatrix mat; mat[0][0] = forward[0]; mat[0][1] = left[0]; mat[0][2] = up[0]; mat[0][3] = 0; mat[1][0] = forward[1]; mat[1][1] = left[1]; mat[1][2] = up[1]; mat[1][3] = 0; mat[2][0] = forward[2]; mat[2][1] = left[2]; mat[2][2] = up[2]; mat[2][3] = 0; mat[3][0] = 0; mat[3][1] = 0; mat[3][2] = 0; mat[3][3] = 1; mat = mat.transpose(); for (int i = 0; i < gPoints.length(); i++) { MPoint p = gPoints[i]; p.x = p.x * s; // scale p = p * mat + mStart; // transform points.append(p); MVector n = gNormals[i] * mat; normals.append(n); } }
//--------------------------------------------------- bool DagHelper::getPlugValue ( const MPlug& plug, MVector& value ) { MObject obj; plug.getValue ( obj ); MStatus status = plug.getValue ( obj ); COLLADABU_ASSERT ( status ); MFnNumericData data ( obj ); double x, y, z; status = data.getData ( x, y, z ); COLLADABU_ASSERT ( status ); value = MVector ( x,y,z ); return true; }
void SGNormalManipIntersector::build() { MMatrix camMatrix = SGMatrix::getCamMatrix(); MFnMesh fnMesh = SGMesh::pMesh->dagPath; MIntArray selIndices = SGSelection::sels.getSelVtxIndices(); MMatrix worldToView = SGMatrix::getWorldToViewMatrix(camMatrix); int targetIndex = selIndices[0]; MPoint mousePoint(SGMouse::x, SGMouse::y); double closeDist = 100000.0; for (unsigned int i = 0; i < selIndices.length(); i++) { MPoint point, viewPoint; fnMesh.getPoint(selIndices[i], point, MSpace::kWorld); viewPoint = SGMatrix::getViewPointFromWorld(point, camMatrix, &worldToView); double dist = mousePoint.distanceTo(viewPoint); if (dist < closeDist) { closeDist = dist; targetIndex = selIndices[i]; } } if (closeDist > catchDist) { exists = false; return; } fnMesh.getPoint(targetIndex, center, MSpace::kWorld); fnMesh.getVertexNormal(targetIndex, normal, MSpace::kWorld); normal.normalize(); double manipSize = SGMatrix::getManipSizeFromWorldPoint(center, camMatrix); double normalSize = axisSize / manipSize; double coneMatrixSize = coneSize / manipSize; normal *= normalSize; normalLine.setLength(2); normalLine[0] = center; normalLine[1] = center + normal; MMatrix rotMatrix = SGMatrix::getRotateMatrix(MVector(0, 1, 0), normal); rotMatrix *= coneMatrixSize; rotMatrix(3, 0) = normalLine[1].x; rotMatrix(3, 1) = normalLine[1].y; rotMatrix(3, 2) = normalLine[1].z; rotMatrix(3, 3) = 1; coneMatrix = rotMatrix; exists = true; }
geometryCacheBlockFVAData::geometryCacheBlockFVAData( const MString& tag, const float* value, const uint& size ) /////////////////////////////////////////////////////////////////////////////// // // Description : ( public method ) // Constructor // /////////////////////////////////////////////////////////////////////////////// { blockTag = tag; group = false; for( uint i = 0; i < size * 3; i+=3 ) { vectorArrayData.append( MVector( value[i], value[i+1], value[i+2] ) ); } }
void VMesh::init() { m_p_buf.clear(); m_v_buf.clear(); MStatus status; MItMeshVertex vertIter(pgrow, &status); for( int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { m_p_buf.append( vertIter.position(MSpace::kWorld) ); } m_v_buf.setLength(m_p_buf.length()); for( int i=0; i<m_v_buf.length(); i++ ) { m_v_buf[i] = MVector(0,0,0); } }
MMatrix sgHair_controlJoint::getAngleWeightedMatrix( const MMatrix& targetMtx, double weight ) { MMatrix mtx; if( m_bStaticRotation ) { mtx = MMatrix() * ( weight-1 ) + targetMtx * weight; cleanMatrix( mtx ); } else { MVector vUpDefault( 0, 1, 0 ); MVector vCrossDefault( 0,0,1 ); MVector vUpInput( targetMtx(1,0), targetMtx(1,1), targetMtx(1,2) ); double angleUp = vUpInput.angle( vUpDefault ) * weight; if( vUpInput.x == 0 && vUpInput.z == 0 ) vUpInput.x = 1; MVector direction( vUpInput.x, 0, vUpInput.z ); direction.normalize(); MVector vUp( sin( angleUp ) * direction.x, cos( angleUp ), sin( angleUp ) * direction.z ); double dot = vUp * MVector( 0.0, 0.0, 1.0 ); MVector vCross( 0.0, -dot, (dot+1) ); MVector vAim = vUp ^ vCross; vAim.normalize(); vUp.normalize(); vCross = vAim ^ vUp; mtx( 0, 0 ) = vAim.x; mtx( 0, 1 ) = vAim.y; mtx( 0, 2 ) = vAim.z; mtx( 1, 0 ) = vUp.x; mtx( 1, 1 ) = vUp.y; mtx( 1, 2 ) = vUp.z; mtx( 2, 0 ) = vCross.x; mtx( 2, 1 ) = vCross.y; mtx( 2, 2 ) = vCross.z; } return mtx; }
MThreadRetVal slidingDeformer2::compute_getDist( void* voidPThread ) { slidingDeformer2GetDistThread* pThread = ( slidingDeformer2GetDistThread* )voidPThread; slidingDeformer2GetDistTask* pTask = pThread->pTask; MPointOnMesh pointOnMesh; MVectorArray& vectorArr = *pTask->pVectors; MPointArray& pointsOrig = *pTask->pPointsOrig; MVector vPoint; MVector getPoint; MVector normal; double dot; for( int i = pThread->start; i < pThread->end; i++ ) { pTask->pMeshIntersector->getClosestPoint( pointsOrig[i], pointOnMesh ); getPoint = pointOnMesh.getPoint(); vectorArr[i] = MVector( pointsOrig[i] ) - getPoint; } return MThreadRetVal( 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 ) ); } } }
void ropeGenerator::createRopesUvs( int ropesCount, int pointsCount, float ropeStrength, float uvCapSize,MFloatArray &uArray, MFloatArray &vArray, float direction ) { 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() ); ropV = ropV * 0.5 * uvCapSize; uArray.append( (( ropV.x * direction) + 0.5 ) ); vArray.append( ropV.z + 0.5 ); } } }
MThreadRetVal PushDeformer::threadEvaluate( void *pParam ) { MStatus status; ThreadData* pThreadData = (ThreadData*)(pParam); TaskData* pData = pThreadData->pData; unsigned int start = pThreadData->start; unsigned int end = pThreadData->end; MPointArray& points = pData->points; MFloatVectorArray& normals = pData->normals; //MDataBlock& dataBlock = pData->dataBlock; MDoubleArray& stressV = pData->stressV; double bulgeAmount = pData->bulgeAmount; bool useStressV = pData->useStressV; float envelope = pData->envelope; int geomIndex = pData->geomIndex; for ( unsigned int i = start; i < end; ++i ) { //float w = weightValue(dataBlock, geomIndex, i); float w = 1.0; if (useStressV == true && (stressV.length() > 0)) { //deform points[i] += (MVector(normals[i]) * bulgeAmount * envelope * w * stressV[i]); } else { //deform points[i] += normals[i] * bulgeAmount * envelope * w; } } return 0; }
MVector convert( const Imath::Color3f &from ) { return MVector( from[0], from[1], from[2] ); }
MVector convert( const Imath::V3d &from ) { return MVector( from[0], from[1], from[2] ); }
PXR_NAMESPACE_OPEN_SCOPE /* static */ bool PxrUsdMayaTranslatorMesh::Create( const UsdGeomMesh& mesh, MObject parentNode, const PxrUsdMayaPrimReaderArgs& args, PxrUsdMayaPrimReaderContext* context) { if (!mesh) { return false; } const UsdPrim& prim = mesh.GetPrim(); MStatus status; // Create node (transform) MObject mayaNodeTransformObj; if (!PxrUsdMayaTranslatorUtil::CreateTransformNode(prim, parentNode, args, context, &status, &mayaNodeTransformObj)) { return false; } VtArray<GfVec3f> points; VtArray<GfVec3f> normals; VtArray<int> faceVertexCounts; VtArray<int> faceVertexIndices; UsdAttribute fvc = mesh.GetFaceVertexCountsAttr(); if (fvc.ValueMightBeTimeVarying()){ // at some point, it would be great, instead of failing, to create a usd/hydra proxy node // for the mesh, perhaps? For now, better to give a more specific error MGlobal::displayError( TfStringPrintf("<%s> is a topologically varying Mesh (animated faceVertexCounts). Skipping...", prim.GetPath().GetText()).c_str()); return false; } else { // for any non-topo-varying mesh, sampling at zero will get us the right answer fvc.Get(&faceVertexCounts, 0); } UsdAttribute fvi = mesh.GetFaceVertexIndicesAttr(); if (fvi.ValueMightBeTimeVarying()){ // at some point, it would be great, instead of failing, to create a usd/hydra proxy node // for the mesh, perhaps? For now, better to give a more specific error MGlobal::displayError( TfStringPrintf("<%s> is a topologically varying Mesh (animated faceVertexIndices). Skipping...", prim.GetPath().GetText()).c_str()); return false; } else { // for any non-topo-varying mesh, sampling at zero will get us the right answer fvi.Get(&faceVertexIndices, 0); } // Sanity Checks. If the vertex arrays are empty, skip this mesh if (faceVertexCounts.size() == 0 || faceVertexIndices.size() == 0) { MGlobal::displayError( TfStringPrintf("FaceVertex arrays are empty [Count:%zu Indices:%zu] on Mesh <%s>. Skipping...", faceVertexCounts.size(), faceVertexIndices.size(), prim.GetPath().GetText()).c_str()); return false; // invalid mesh, so exit } // Gather points and normals // If args.GetReadAnimData() is TRUE, // pick the first avaiable sample or default UsdTimeCode pointsTimeSample=UsdTimeCode::EarliestTime(); UsdTimeCode normalsTimeSample=UsdTimeCode::EarliestTime(); std::vector<double> pointsTimeSamples; size_t pointsNumTimeSamples = 0; if (args.GetReadAnimData()) { PxrUsdMayaTranslatorUtil::GetTimeSamples(mesh.GetPointsAttr(), args, &pointsTimeSamples); pointsNumTimeSamples = pointsTimeSamples.size(); if (pointsNumTimeSamples>0) { pointsTimeSample = pointsTimeSamples[0]; } std::vector<double> normalsTimeSamples; PxrUsdMayaTranslatorUtil::GetTimeSamples(mesh.GetNormalsAttr(), args, &normalsTimeSamples); if (normalsTimeSamples.size()) { normalsTimeSample = normalsTimeSamples[0]; } } mesh.GetPointsAttr().Get(&points, pointsTimeSample); mesh.GetNormalsAttr().Get(&normals, normalsTimeSample); if (points.size() == 0) { MGlobal::displayError( TfStringPrintf("Points arrays is empty on Mesh <%s>. Skipping...", prim.GetPath().GetText()).c_str()); return false; // invalid mesh, so exit } // == Convert data size_t mayaNumVertices = points.size(); MPointArray mayaPoints(mayaNumVertices); for (size_t i=0; i < mayaNumVertices; i++) { mayaPoints.set( i, points[i][0], points[i][1], points[i][2] ); } MIntArray polygonCounts( faceVertexCounts.cdata(), faceVertexCounts.size() ); MIntArray polygonConnects( faceVertexIndices.cdata(), faceVertexIndices.size() ); // == Create Mesh Shape Node MFnMesh meshFn; MObject meshObj = meshFn.create(mayaPoints.length(), polygonCounts.length(), mayaPoints, polygonCounts, polygonConnects, mayaNodeTransformObj, &status ); if (status != MS::kSuccess) { return false; } // Since we are "decollapsing", we will create a xform and a shape node for each USD prim std::string usdPrimName(prim.GetName().GetText()); std::string shapeName(usdPrimName); shapeName += "Shape"; // Set mesh name and register meshFn.setName(MString(shapeName.c_str()), false, &status); if (context) { std::string usdPrimPath(prim.GetPath().GetText()); std::string shapePath(usdPrimPath); shapePath += "/"; shapePath += shapeName; context->RegisterNewMayaNode( shapePath, meshObj ); // used for undo/redo } // If a material is bound, create (or reuse if already present) and assign it // If no binding is present, assign the mesh to the default shader const TfToken& shadingMode = args.GetShadingMode(); PxrUsdMayaTranslatorMaterial::AssignMaterial(shadingMode, mesh, meshObj, context); // Mesh is a shape, so read Gprim properties PxrUsdMayaTranslatorGprim::Read(mesh, meshObj, context); // Set normals if supplied MIntArray normalsFaceIds; if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices())) { for (size_t i=0; i < polygonCounts.length(); i++) { for (int j=0; j < polygonCounts[i]; j++) { normalsFaceIds.append(i); } } if (normalsFaceIds.length() == static_cast<size_t>(meshFn.numFaceVertices())) { MVectorArray mayaNormals(normals.size()); for (size_t i=0; i < normals.size(); i++) { mayaNormals.set( MVector(normals[i][0], normals[i][1], normals[i][2]), i); } if (meshFn.setFaceVertexNormals(mayaNormals, normalsFaceIds, polygonConnects) != MS::kSuccess) { } } } // Determine if PolyMesh or SubdivMesh TfToken subdScheme = PxrUsdMayaMeshUtil::setSubdivScheme(mesh, meshFn, args.GetDefaultMeshScheme()); // If we are dealing with polys, check if there are normals // If we are dealing with SubdivMesh, read additional attributes and SubdivMesh properties if (subdScheme == UsdGeomTokens->none) { if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices())) { PxrUsdMayaMeshUtil::setEmitNormals(mesh, meshFn, UsdGeomTokens->none); } } else { PxrUsdMayaMeshUtil::setSubdivInterpBoundary(mesh, meshFn, UsdGeomTokens->edgeAndCorner); PxrUsdMayaMeshUtil::setSubdivFVLinearInterpolation(mesh, meshFn); _AssignSubDivTagsToMesh(mesh, meshObj, meshFn); } // Set Holes VtArray<int> holeIndices; mesh.GetHoleIndicesAttr().Get(&holeIndices); // not animatable if ( holeIndices.size() != 0 ) { MUintArray mayaHoleIndices; mayaHoleIndices.setLength( holeIndices.size() ); for (size_t i=0; i < holeIndices.size(); i++) { mayaHoleIndices[i] = holeIndices[i]; } if (meshFn.setInvisibleFaces(mayaHoleIndices) == MS::kFailure) { MGlobal::displayError(TfStringPrintf("Unable to set Invisible Faces on <%s>", meshFn.fullPathName().asChar()).c_str()); } } // GETTING PRIMVARS std::vector<UsdGeomPrimvar> primvars = mesh.GetPrimvars(); TF_FOR_ALL(iter, primvars) { const UsdGeomPrimvar& primvar = *iter; const TfToken& name = primvar.GetBaseName(); const SdfValueTypeName& typeName = primvar.GetTypeName(); // If the primvar is called either displayColor or displayOpacity check // if it was really authored from the user. It may not have been // authored by the user, for example if it was generated by shader // values and not an authored colorset/entity. // If it was not really authored, we skip the primvar. if (name == PxrUsdMayaMeshColorSetTokens->DisplayColorColorSetName || name == PxrUsdMayaMeshColorSetTokens->DisplayOpacityColorSetName) { if (!PxrUsdMayaRoundTripUtil::IsAttributeUserAuthored(primvar)) { continue; } } // XXX: Maya stores UVs in MFloatArrays and color set data in MColors // which store floats, so we currently only import primvars holding // float-typed arrays. Should we still consider other precisions // (double, half, ...) and/or numeric types (int)? if (typeName == SdfValueTypeNames->Float2Array) { // We assume that Float2Array primvars are UV sets. if (!_AssignUVSetPrimvarToMesh(primvar, meshFn)) { MGlobal::displayWarning( TfStringPrintf("Unable to retrieve and assign data for UV set <%s> on mesh <%s>", name.GetText(), mesh.GetPrim().GetPath().GetText()).c_str()); } } else if (typeName == SdfValueTypeNames->FloatArray || typeName == SdfValueTypeNames->Float3Array || typeName == SdfValueTypeNames->Color3fArray || typeName == SdfValueTypeNames->Float4Array || typeName == SdfValueTypeNames->Color4fArray) { if (!_AssignColorSetPrimvarToMesh(mesh, primvar, meshFn)) { MGlobal::displayWarning( TfStringPrintf("Unable to retrieve and assign data for color set <%s> on mesh <%s>", name.GetText(), mesh.GetPrim().GetPath().GetText()).c_str()); } } } // We only vizualize the colorset by default if it is "displayColor". MStringArray colorSetNames; if (meshFn.getColorSetNames(colorSetNames)==MS::kSuccess) { for (unsigned int i=0; i < colorSetNames.length(); i++) { const MString colorSetName = colorSetNames[i]; if (std::string(colorSetName.asChar()) == PxrUsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetString()) { MFnMesh::MColorRepresentation csRep= meshFn.getColorRepresentation(colorSetName); if (csRep==MFnMesh::kRGB || csRep==MFnMesh::kRGBA) { // both of these are needed to show the colorset. MPlug plg=meshFn.findPlug("displayColors"); if ( !plg.isNull() ) { plg.setBool(true); } meshFn.setCurrentColorSetName(colorSetName); } break; } } } // == Animate points == // Use blendShapeDeformer so that all the points for a frame are contained in a single node // if (pointsNumTimeSamples > 0) { MPointArray mayaPoints(mayaNumVertices); MObject meshAnimObj; MFnBlendShapeDeformer blendFn; MObject blendObj = blendFn.create(meshObj); if (context) { context->RegisterNewMayaNode( blendFn.name().asChar(), blendObj ); // used for undo/redo } for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) { mesh.GetPointsAttr().Get(&points, pointsTimeSamples[ti]); for (unsigned int i=0; i < mayaNumVertices; i++) { mayaPoints.set( i, points[i][0], points[i][1], points[i][2] ); } // == Create Mesh Shape Node MFnMesh meshFn; if ( meshAnimObj.isNull() ) { meshAnimObj = meshFn.create(mayaPoints.length(), polygonCounts.length(), mayaPoints, polygonCounts, polygonConnects, mayaNodeTransformObj, &status ); if (status != MS::kSuccess) { continue; } } else { // Reuse the already created mesh by copying it and then setting the points meshAnimObj = meshFn.copy(meshAnimObj, mayaNodeTransformObj, &status); meshFn.setPoints(mayaPoints); } // Set normals if supplied // // NOTE: This normal information is not propagated through the blendShapes, only the controlPoints. // mesh.GetNormalsAttr().Get(&normals, pointsTimeSamples[ti]); if (normals.size() == static_cast<size_t>(meshFn.numFaceVertices()) && normalsFaceIds.length() == static_cast<size_t>(meshFn.numFaceVertices())) { MVectorArray mayaNormals(normals.size()); for (size_t i=0; i < normals.size(); i++) { mayaNormals.set( MVector(normals[i][0], normals[i][1], normals[i][2]), i); } if (meshFn.setFaceVertexNormals(mayaNormals, normalsFaceIds, polygonConnects) != MS::kSuccess) { } } // Add as target and set as an intermediate object blendFn.addTarget(meshObj, ti, meshAnimObj, 1.0); meshFn.setIntermediateObject(true); if (context) { context->RegisterNewMayaNode( meshFn.fullPathName().asChar(), meshAnimObj ); // used for undo/redo } } // Animate the weights so that mesh0 has a weight of 1 at frame 0, etc. MFnAnimCurve animFn; // Construct the time array to be used for all the keys MTimeArray timeArray; timeArray.setLength(pointsNumTimeSamples); for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) { timeArray.set( MTime(pointsTimeSamples[ti]), ti); } // Key/Animate the weights MPlug plgAry = blendFn.findPlug( "weight" ); if ( !plgAry.isNull() && plgAry.isArray() ) { for (unsigned int ti=0; ti < pointsNumTimeSamples; ++ti) { MPlug plg = plgAry.elementByLogicalIndex(ti, &status); MDoubleArray valueArray(pointsNumTimeSamples, 0.0); valueArray[ti] = 1.0; // Set the time value where this mesh's weight should be 1.0 MObject animObj = animFn.create(plg, NULL, &status); animFn.addKeys(&timeArray, &valueArray); if (context) { context->RegisterNewMayaNode(animFn.name().asChar(), animObj ); // used for undo/redo } } } } return true; }