/// <summary> /// Initializes a new instance of the <see cref="MeshPoint" /> class. /// </summary> /// <param name="point">3D Point.</param> /// <param name="face">Mesh face.</param> public MeshPoint(MeshFace face, Point3d point) { var adj = face.AdjacentVertices(); var bary = Convert.Point3dToBarycentric(point, adj[0], adj[1], adj[2]); this.U = bary[0]; this.V = bary[1]; this.W = bary[2]; }
/// <summary> /// Compute the level on a specified face. /// </summary> /// <param name="valueKey">Key of the value to be computed per vertex.</param> /// <param name="level">Level value to be computed.</param> /// <param name="face">Face to compute the level in.</param> /// <param name="line">Resulting level line on the face.</param> /// <returns>True if successful, false if not.</returns> public static bool GetFaceLevel(string valueKey, double level, MeshFace face, out Line line) { var adj = face.AdjacentVertices(); var vertexValues = new List <double> { adj[0].UserValues[valueKey], adj[1].UserValues[valueKey], adj[2].UserValues[valueKey] }; var above = new List <int>(); var below = new List <int>(); for (var i = 0; i < vertexValues.Count; i++) { if (vertexValues[i] < level) { below.Add(i); } else { above.Add(i); } } if (above.Count == 3 || below.Count == 3) { // Triangle is above or below level line = new Line(new Point3d(), new Point3d()); return(false); } // Triangle intersects level var intersectionPoints = new List <Point3d>(); foreach (var i in above) { foreach (var j in below) { var diff = vertexValues[i] - vertexValues[j]; var desiredDiff = level - vertexValues[j]; var unitizedDistance = desiredDiff / diff; var edgeV = adj[i] - adj[j]; var levelPoint = adj[j] + edgeV * unitizedDistance; intersectionPoints.Add(levelPoint); } } line = new Line(intersectionPoints[0], intersectionPoints[1]); return(true); }
/// <summary> /// Compute the level on a specified face. /// </summary> /// <param name="valueKey">Key of the value to be computed per vertex.</param> /// <param name="level">Level value to be computed.</param> /// <param name="face">Face to computee the level in.</param> /// <param name="line">Resulting level line on the face.</param> /// <returns>True if successful, false if not.</returns> public static bool GetFaceLevel(string valueKey, double level, MeshFace face, out Line line) { List <MeshVertex> adj = face.AdjacentVertices(); List <double> vertexValues = new List <double> { adj[0].UserValues[valueKey], adj[1].UserValues[valueKey], adj[2].UserValues[valueKey] }; List <int> above = new List <int>(); List <int> below = new List <int>(); for (int i = 0; i < vertexValues.Count; i++) { if (vertexValues[i] < level) { below.Add(i); } else { above.Add(i); } } if (above.Count == 3 || below.Count == 3) { // Triangle is above or below level line = new Line(new Point3d(), new Point3d()); return(false); } else { // Triangle intersects level List <Point3d> intersectionPoints = new List <Point3d>(); foreach (int i in above) { foreach (int j in below) { double diff = vertexValues[i] - vertexValues[j]; double desiredDiff = level - vertexValues[j]; double unitizedDistance = desiredDiff / diff; Vector3d edgeV = adj[i] - adj[j]; Point3d levelPoint = (Point3d)adj[j] + (edgeV * unitizedDistance); intersectionPoints.Add(levelPoint); } } line = new Line(intersectionPoints[0], intersectionPoints[1]); return(true); } }
/// <summary> /// Compute the gradient on a given mesh face given some per-vertex values. /// </summary> /// <param name="valueKey">Key of the values in the vertex.UserData dictionary.</param> /// <param name="face">Face to compute thee gradient.</param> /// <returns>A vector representing the gradient on that mesh face.</returns> public static Vector3d ComputeFaceGradient(string valueKey, MeshFace face) { List <MeshVertex> adjacentVertices = face.AdjacentVertices(); Point3d i = adjacentVertices[0]; Point3d j = adjacentVertices[1]; Point3d k = adjacentVertices[2]; double gi = adjacentVertices[0].UserValues[valueKey]; double gj = adjacentVertices[1].UserValues[valueKey]; double gk = adjacentVertices[2].UserValues[valueKey]; Vector3d faceNormal = face.Normal / (2 * face.Area); Vector3d rotatedGradient = ((gi * (k - j)) + (gj * (i - k)) + (gk * (j - i))) / (2 * face.Area); Vector3d gradient = rotatedGradient.Cross(faceNormal); return(gradient); }
/// <summary> /// Compute the gradient on a given mesh face given some per-vertex values. /// </summary> /// <param name="valueKey">Key of the values in the vertex.UserData dictionary.</param> /// <param name="face">Face to compute thee gradient.</param> /// <returns>A vector representing the gradient on that mesh face.</returns> public static Vector3d ComputeFaceGradient(string valueKey, MeshFace face) { var adjacentVertices = face.AdjacentVertices(); Point3d i = adjacentVertices[0]; Point3d j = adjacentVertices[1]; Point3d k = adjacentVertices[2]; var gi = adjacentVertices[0].UserValues[valueKey]; var gj = adjacentVertices[1].UserValues[valueKey]; var gk = adjacentVertices[2].UserValues[valueKey]; var faceNormal = face.Normal / (2 * face.Area); var rotatedGradient = (gi * (k - j) + gj * (i - k) + gk * (j - i)) / (2 * face.Area); var gradient = rotatedGradient.Cross(faceNormal); return(gradient); }
/// <summary> /// Compute the intersection between a mesh face perimeter and a ray tangent to the face. /// </summary> /// <param name="ray">The tangent ray.</param> /// <param name="face">The mesh face.</param> /// <param name="result">The resulting intersection point.</param> /// <param name="halfEdge">The half-edge on where the intersection lies.</param> /// <returns>Intersection result.</returns> public static ISRayFacePerimeter RayFacePerimeter(Ray ray, MeshFace face, out Point3d result, out MeshHalfEdge halfEdge) { Vector3d faceNormal = MeshGeometry.FaceNormal(face); Vector3d biNormal = Vector3d.CrossProduct(ray.Direction, faceNormal); Plane perpPlane = new Plane(ray.Origin, ray.Direction, faceNormal, biNormal); List <MeshVertex> vertices = face.AdjacentVertices(); Point3d temp = new Point3d(); Line line = new Line(vertices[0], vertices[1]); if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point) { result = null; halfEdge = null; return(ISRayFacePerimeter.Point); } // No intersection found if (temp != ray.Origin && temp != null) { result = temp; halfEdge = null; return(ISRayFacePerimeter.Point); } // Intersection found line = new Line(vertices[1], vertices[2]); if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point) { result = null; halfEdge = null; return(ISRayFacePerimeter.NoIntersection); } // No intersection found if (temp != ray.Origin && temp != null) { result = temp; halfEdge = null; return(ISRayFacePerimeter.Point); } // Intersection found line = new Line(vertices[2], vertices[0]); if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point) { result = null; halfEdge = null; return(ISRayFacePerimeter.NoIntersection); } if (temp != ray.Origin && temp != null) { result = temp; halfEdge = null; return(ISRayFacePerimeter.Point); } else { result = null; halfEdge = null; return(ISRayFacePerimeter.Error); } }
/// <summary> /// Compute the intersection between a mesh face perimeter and a ray tangent to the face. /// </summary> /// <param name="ray">The tangent ray.</param> /// <param name="face">The mesh face.</param> /// <param name="result">The resulting intersection point.</param> /// <param name="halfEdge">The half-edge on where the intersection lies.</param> /// <returns>Intersection result.</returns> public static RayFacePerimeterIntersectionStatus RayFacePerimeter( Ray ray, MeshFace face, out Point3d result, out MeshHalfEdge halfEdge) { var faceNormal = MeshGeometry.FaceNormal(face); var biNormal = Vector3d.CrossProduct(ray.Direction, faceNormal); var perpPlane = new Plane(ray.Origin, ray.Direction, faceNormal, biNormal); var vertices = face.AdjacentVertices(); var temp = new Point3d(); var line = new Line(vertices[0], vertices[1]); if (LinePlane(line, perpPlane, out temp) != LinePlaneIntersectionStatus.Point) { result = null; halfEdge = null; return(RayFacePerimeterIntersectionStatus.Point); } // No intersection found if (temp != ray.Origin && temp != null) { result = temp; halfEdge = null; return(RayFacePerimeterIntersectionStatus.Point); } // Intersection found line = new Line(vertices[1], vertices[2]); if (LinePlane(line, perpPlane, out temp) != LinePlaneIntersectionStatus.Point) { result = null; halfEdge = null; return(RayFacePerimeterIntersectionStatus.NoIntersection); } if (temp != ray.Origin && temp != null) { result = temp; halfEdge = null; return(RayFacePerimeterIntersectionStatus.Point); } line = new Line(vertices[2], vertices[0]); if (LinePlane(line, perpPlane, out temp) != LinePlaneIntersectionStatus.Point) { result = null; halfEdge = null; return(RayFacePerimeterIntersectionStatus.NoIntersection); } if (temp != ray.Origin && temp != null) { result = temp; halfEdge = null; return(RayFacePerimeterIntersectionStatus.Point); } result = null; halfEdge = null; return(RayFacePerimeterIntersectionStatus.Error); }