void GetBarycentricCoordinates(const MPoint& P, const MPoint& A, const MPoint& B, const MPoint& C, BaryCoords& coords) { // Compute the normal of the triangle MVector N = (B - A) ^ (C - A); MVector unitN = N.normal(); // Compute twice area of triangle ABC double areaABC = unitN * N; if (areaABC == 0.0) { // If the triangle is degenerate, just use one of the points. coords[0] = 1.0f; coords[1] = 0.0f; coords[2] = 0.0f; return; } // Compute a double areaPBC = unitN * ((B - P) ^ (C - P)); coords[0] = (float)(areaPBC / areaABC); // Compute b double areaPCA = unitN * ((C - P) ^ (A - P)); coords[1] = (float)(areaPCA / areaABC); // Compute c coords[2] = 1.0f - coords[0] - coords[1]; }
void GetValidUp(const MDoubleArray& weights, const MPointArray& points, const MIntArray& sampleIds, const MPoint& origin, const MVector& normal, MVector& up) { MVector unitUp = up.normal(); // Adjust up if it's parallel to normal or if it's zero length if (std::abs((unitUp * normal) - 1.0) < 0.001 || up.length() < 0.0001) { for (unsigned int j = 0; j < weights.length()-1; ++j) { up -= (points[sampleIds[j]] - origin) * weights[j]; unitUp = up.normal(); if (std::abs((unitUp * normal) - 1.0) > 0.001 && up.length() > 0.0001) { // If the up and normal vectors are no longer parallel and the up vector has a length, // then we are good to go. break; } } up.normalize(); } else { up = unitUp; } }
MStatus HairToolContext::doPress( MEvent& event ) { // if we have a left mouse click if(event.mouseButton() == MEvent::kLeftMouse) { //Our Viewer m_View = M3dView::active3dView(); //Get Screen click position event.getPosition( m_storage[0], m_storage[1] ); screenPoints = vector<vec2>(); screenPoints.push_back(vec2(m_storage[0], m_storage[1])); //char buffer[200]; //sprintf(buffer, "print \"%i, %i\\n\"", m_storage[0], m_storage[1]); //MGlobal::executeCommand(buffer); //Camera stuff MPoint origin = MPoint(); MVector direction = MVector(); m_View.viewToWorld(m_storage[0], m_storage[1], origin, direction); //Iterate through meshes in scene bool intersection = false; MPointArray points = MPointArray(); MIntArray polygonIds = MIntArray(); MItDag dagIter = MItDag(MItDag::kBreadthFirst, MFn::kInvalid); for( ; !dagIter.isDone(); dagIter.next() ){ MDagPath dagPath; dagIter.getPath(dagPath); MFnDagNode dagNode( dagPath); //Object cannot be intermediate, it must be a mesh if( dagNode.isIntermediateObject() ) continue; if( !dagPath.hasFn(MFn::kMesh) ) continue; if( dagPath.hasFn(MFn::kTransform) ) continue; MGlobal::executeCommand(MString("print \"node is a mesh \\n\"")); //MFnMesh mesh = MFnMesh(dagPath); MFnMesh mesh(dagPath); points = MPointArray(); polygonIds = MIntArray(); intersection = mesh.intersect(origin, direction, points, 1e-010, MSpace::kWorld, &polygonIds); if(intersection){ break; } } if(intersection){ intersectionFound = true; MDagPath dagPath; dagIter.getPath(dagPath); // MFnMesh mesh = MFnMesh(dagPath); MFnMesh mesh(dagPath); //Polygon Normal MVector polygonNormal; mesh.getPolygonNormal(polygonIds[0], polygonNormal, MSpace::kWorld); if(polygonNormal.normal().angle(direction.normal()) < 20.0f){ //polygonNormal = mesh.get } //Camera Right m_View.getCamera(dagPath); MFnCamera camera(dagPath); MVector cameraRight = camera.rightDirection(MSpace::kWorld); //Resulting Plane //Point point = points[0]; //Normal normal = cameraRight^polygonNormal; //pushback point splinePoints = vector<MPoint>(); splinePoints.push_back(MPoint(points[0].x, points[0].y, points[0].z, points[0].w)); /*//Calculate Tvalue tValue = (points[0].x - origin.x)/direction.x;*/ } else{ intersectionFound = false; MGlobal::executeCommand("print \" No Intersection \\n\""); } // yay! return MS::kSuccess; } // just let the base class handle the event*/ return MPxContext::doPress(event); }
MStatus sgCurveEditBrush_context::editCurve( MDagPath dagPathCurve, int beforeX, int beforeY, int currentX, int currentY, float radius, const MDoubleArray& dArrLength, MPointArray &points ) { MStatus status; if( radius < 0 ) return MS::kSuccess; MDagPath dagPathCam; M3dView view = M3dView::active3dView( &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); view.getCamera( dagPathCam ); MPoint camPos = dagPathCam.inclusiveMatrix()[3]; MVector vCamUp = dagPathCam.inclusiveMatrix()[1]; vCamUp.normalize(); radius *= .05; MPoint nearClipBefore; MPoint farClipBefore; view.viewToWorld( beforeX, beforeY, nearClipBefore, farClipBefore ); MVector rayBefore = nearClipBefore - camPos; rayBefore.normalize(); rayBefore *= 20; MPoint posBefore = rayBefore + camPos; MPoint nearClipCurrent; MPoint farClipCurrent; view.viewToWorld( currentX, currentY, nearClipCurrent, farClipCurrent ); MVector rayCurrent = nearClipCurrent - camPos; rayCurrent.normalize(); rayCurrent *= 20; MPoint posCurrent = rayCurrent + camPos; MVector vMove = posCurrent - posBefore; MMatrix mtxCurve = dagPathCurve.inclusiveMatrix(); MFnNurbsCurve fnCurve( dagPathCurve ); fnCurve.getCVs( points ); for( int i=0; i< points.length(); i++ ) { points[i] *= mtxCurve; } for( int i=1; i< points.length(); i++ ) { MPoint cuPoint = points[i]; MVector vPoint = cuPoint - camPos; MVector projV = ( vPoint * rayBefore )/( pow( rayBefore.length(), 2 ) )* rayBefore; MVector vertical = vPoint - projV; float radiusForPoint = vertical.length() / projV.length(); if( radius < radiusForPoint ) continue; MPoint parentPoint = points[i-1]; MVector vCurveDirection = cuPoint - parentPoint; double vDirLength = vCurveDirection.length(); MVector vEditDirection = vCurveDirection + vMove/rayBefore.length()*projV.length(); double dotEdit = vCurveDirection.normal() * vEditDirection.normal(); if( dotEdit < 0 ) continue; vEditDirection = vEditDirection * dotEdit + vCurveDirection*( 1-dotEdit ); MVector vEditLength = vEditDirection / vEditDirection.length() * vCurveDirection.length(); MVector vEdit = (vEditLength - vCurveDirection) * pow((double)(1-radiusForPoint/radius), 1 ); points[i] += vEdit; for( int j=i+1; j< points.length(); j++ ) { MPoint beforePoint = points[j]; MPoint pPoint = points[j-1]; MPoint beforePPoint = pPoint - vEdit; MVector vBefore = points[j] - beforePPoint; MVector vAfter = points[j] - pPoint; MVector vCurrent = vAfter.normal() * dArrLength[j]; points[j] = vCurrent + pPoint; vEdit = points[j] - beforePoint; } } MMatrix invMtxCurve = mtxCurve.inverse(); for( int i=0; i< points.length(); i++ ) { points[i] *= invMtxCurve; } fnCurve.setCVs( points ); fnCurve.updateCurve(); return MS::kSuccess; }