public TopoVertex(int _id, RHVector3 _pos, Matrix4 trans) { id = _id; pos = new RHVector3( _pos.x * trans.Column0.X + _pos.y * trans.Column0.Y + _pos.z * trans.Column0.Z + trans.Column0.W, _pos.x * trans.Column1.X + _pos.y * trans.Column1.Y + _pos.z * trans.Column1.Z + trans.Column1.W, _pos.x * trans.Column2.X + _pos.y * trans.Column2.Y + _pos.z * trans.Column2.Z + trans.Column2.W ); }
public bool ContainsPoint(RHVector3 point) { if (minPoint == null) { return(false); } return(point.x >= minPoint.x && point.x <= maxPoint.x && point.y >= minPoint.y && point.y <= maxPoint.y && point.z >= minPoint.z && point.z <= maxPoint.z); }
public int VertexId(RHVector3 v) { //if (rhvertextMap.ContainsKey(v)) // return rhvertextMap[v]; int pos = vertices.Count; vertices.Add(new Vector3((float)v.x, (float)v.y, (float)v.z)); //rhvertextMap.Add(v, pos); return(pos); }
public bool ProjectPoint(RHVector3 p, out double lambda, RHVector3 pProjected) { RHVector3 u = v2.pos.Subtract(v1.pos); lambda = p.Subtract(v1.pos).ScalarProduct(u) / u.ScalarProduct(u); pProjected.x = v1.pos.x + lambda * u.x; pProjected.y = v1.pos.y + lambda * u.y; pProjected.z = v1.pos.z + lambda * u.z; return(lambda >= 0 && lambda <= 1); }
static public double TriangleQualityFromPositions(RHVector3 p1, RHVector3 p2, RHVector3 p3) { double a = p1.Distance(p2); double b = p1.Distance(p3); double c = p2.Distance(p3); double bc2 = 2 * b * c; double sinalpha = Math.Sin(Math.Acos((b * b + c * c - a * a) / (bc2))); return(a * (a + b + c) / (bc2 * sinalpha * sinalpha)); }
public TopoVertex SearchPoint(RHVector3 vertex) { foreach (TopoVertex v in vertices) { if (vertex.Distance(v.pos) < TopoModel.epsilon) { return(v); } } return(null); }
public void AddTriangle(RHVector3 v1, RHVector3 v2, RHVector3 v3, int color) { if (color == MESHCOLOR_ERRORFACE) { trianglesError.Add(new SubmeshTriangle(VertexId(v1), VertexId(v2), VertexId(v3), color)); } else { triangles.Add(new SubmeshTriangle(VertexId(v1), VertexId(v2), VertexId(v3), color)); } }
/// <summary> /// Checks if all vertices are colinear preventing a normal computation. If point are coliniear the center vertex is /// moved in the direction of the edge to allow normal computations. /// </summary> /// <returns></returns> public bool CheckIfColinear() { RHVector3 d1 = vertices[1].pos.Subtract(vertices[0].pos); RHVector3 d2 = vertices[2].pos.Subtract(vertices[1].pos); double angle = d1.Angle(d2); if (angle > 0.001 && angle < Math.PI - 0.001) { return(false); } return(true); }
public void Add(RHVector3 point) { if (minPoint == null) { minPoint = new RHVector3(point); maxPoint = new RHVector3(point); } else { minPoint.StoreMinimum(point); maxPoint.StoreMaximum(point); } }
public int LargestDimension() { RHVector3 size = box.Size; if (size.x > size.y && size.x > size.z) { return(0); } if (size.y > size.z) { return(1); } return(2); }
public TopoVertex SearchPoint(RHVector3 vertex) { int hash = vertextHash(vertex); if (!list.ContainsKey(hash)) { return(null); } foreach (TopoVertex v in list[hash]) { if (vertex.Distance(v.pos) < TopoModel.epsilon) { return(v); } } return(null); }
public double alphaBeta; // Sum of dihedral angles to a virtual shared triangle public TopoEdgePair(TopoEdge _edgeA, TopoEdge _edgeB) { edgeA = _edgeA; edgeB = _edgeB; RHVector3 sharedPoint = null; RHVector3 p1 = null, p2 = null; if (edgeA.v1 == edgeB.v1) { sharedPoint = edgeA.v1.pos; p1 = edgeA.v2.pos; p2 = edgeB.v2.pos; } else if (edgeA.v1 == edgeB.v2) { sharedPoint = edgeA.v1.pos; p1 = edgeA.v2.pos; p2 = edgeB.v1.pos; } else if (edgeA.v2 == edgeB.v1) { sharedPoint = edgeA.v1.pos; p1 = edgeA.v1.pos; p2 = edgeB.v2.pos; } else if (edgeA.v2 == edgeB.v2) { sharedPoint = edgeA.v2.pos; p1 = edgeA.v1.pos; p2 = edgeB.v1.pos; } RHVector3 d1 = p1.Subtract(sharedPoint); RHVector3 d2 = p2.Subtract(sharedPoint); RHVector3 normal = d1.CrossProduct(d2); normal.NormalizeSafe(); alphaBeta = normal.AngleForNormalizedVectors(edgeA.faces.First.Value.normal) + normal.AngleForNormalizedVectors(edgeB.faces.First.Value.normal); if (alphaBeta > Math.PI) // normal was wrong direction { alphaBeta = 2 * Math.PI - alphaBeta; } }
public bool SmoothAspectRatio(TopoModel model, double maxRatio) { double maxLen, minLen; int maxIdx, minIdx; LongestShortestEdgeLength(out maxIdx, out maxLen, out minIdx, out minLen); if (minLen == 0) { return(false); } if (maxLen > 1 && maxLen / minLen > maxRatio) { RHVector3 center = edges[maxIdx].v1.pos.Add(edges[maxIdx].v2.pos); center.Scale(0.5); TopoVertex newVertex = new TopoVertex(0, center); model.addVertex(newVertex); edges[maxIdx].InsertVertex(model, newVertex); return(true); } return(false); }
private bool InPlanePointInside(int d1, int d2, RHVector3 p) { RHVector3 A = vertices[0].pos; double ax = vertices[1].pos[d1] - vertices[0].pos[d1]; double ay = vertices[1].pos[d2] - vertices[0].pos[d2]; double bx = vertices[2].pos[d1] - vertices[0].pos[d1]; double by = vertices[2].pos[d2] - vertices[0].pos[d2]; double det = ax * by - ay * bx; if (det == 0) { return(false); } double alpha = -(bx * p[d2] - by * p[d1] + A[d1] * by - A[d2] * bx) / det; double beta = (ax * p[d2] - ay * p[d1] - ax * A[d2] + ay * A[d1]) / det; bool intersect = alpha >= epsilonZeroMinus && beta >= epsilonZeroMinus && alpha + beta <= epsilonOnePlus; if (intersect && debugIntersections) { Console.WriteLine("InPlanePointInside alpha=" + alpha + ", beta = " + beta); } return(intersect); }
public RHVector3(RHVector3 orig) { x = orig.x; y = orig.y; z = orig.z; }
public void StoreMinimum(RHVector3 vec) { x = Math.Min(x, vec.x); y = Math.Min(y, vec.y); z = Math.Min(z, vec.z); }
public void AddEdge(RHVector3 v1, RHVector3 v2, int color) { edges.Add(new SubmeshEdge(VertexId(v1), VertexId(v2), color)); }
public void StoreMaximum(RHVector3 vec) { x = Math.Max(x, vec.x); y = Math.Max(y, vec.y); z = Math.Max(z, vec.z); }
public void FixColinear(TopoModel model) { RHVector3 center = vertices[0].pos.Add(vertices[1].pos).Add(vertices[2].pos); center.Scale(1 / 3.0); int best = -1; double bestdist = 1e30; for (int i = 0; i < 3; i++) { if (vertices[i].connectedFaces == 1) { continue; } double dist = center.Subtract(vertices[i].pos).Length; if (dist < bestdist) { bestdist = dist; best = i; } } if (best == -1) { throw new Exception("CheckIfColinearAndFix called on isolated triangle"); } edges[(best + 1) % 3].InsertVertex(model, vertices[best]); /* * // Find an other face sharing vertex * TopoTriangle otherFace = null; * TopoVertex moveVertex = vertices[best]; * foreach (TopoTriangle triangle in moveVertex.connectedFacesList) * { * if (triangle != this) * { * otherFace = triangle; * break; * } * } * // Now find the not shared vertex * TopoVertex oppositeVertex = null; * for (int i = 0; i < 3; i++) * { * bool notSame = true; * for (int j = 0; j < 3; j++) * { * if (otherFace.vertices[i] == vertices[j]) * { * notSame = false; * break; * } * } * if (notSame) * { * oppositeVertex = otherFace.vertices[i]; * } * } * RHVector3 line = moveVertex.pos.Subtract(oppositeVertex.pos); * double lineLength = line.Length; * double moveFactor = 0.01; * if (0.99 * lineLength > 0.01) moveFactor = 0.01 / lineLength; * line.Scale(moveFactor); * moveVertex.pos = moveVertex.pos.Add(line); * RecomputeNormal();*/ }
public void ChangeCoordinates(TopoVertex vertex, RHVector3 newPos) { Remove(vertex); vertex.pos = new RHVector3(newPos); Add(vertex); }
public double DistanceToPlane(RHVector3 pos) { double d = vertices[0].pos.ScalarProduct(normal); return(pos.ScalarProduct(normal) - d); }
private bool InPlaneIntersectLineSmall(int idx1, int idx2, RHVector3 a1, RHVector3 a2, RHVector3 b1, RHVector3 b2) { double ax = a2[idx1] - a1[idx1]; double ay = a2[idx2] - a1[idx2]; double bx = b2[idx1] - b1[idx1]; double by = b2[idx2] - b1[idx2]; double det = ax * by - ay * bx; if (det == 0) { return(false); // Parallel is not intersect } double alpha = -(bx * b1[idx2] - by * b1[idx1] + a1[idx1] * by - a1[idx2] * bx) / det; if (alpha < epsilonZero || alpha > epsilonOneMinus) { return(false); } double beta = -(ax * b1[idx2] - ay * b1[idx1] - ax * a1[idx2] + ay * a1[idx1]) / det; bool intersect = beta >= epsilonZero && beta <= epsilonOneMinus; if (intersect && debugIntersections) { Console.WriteLine("InPlane beta=" + beta); } return(intersect); }
public void SetZColumn(RHVector3 v) { xz = v.x; yz = v.y; zz = v.z; }
public double VertexDistance(RHVector3 v) { return(v.x * normal.x + v.y * normal.y + v.z * normal.z - d); }
private void TrySplit() { int newDim = 0; int parentDimension = -1; if (parent != null) { parentDimension = parent.dimension; } RHVector3 size = box.Size; if (parentDimension != 0) { newDim = 0; } if (parentDimension != 1 && size.x < size.y) { newDim = 1; } if (parentDimension != 2 && size.z > size[newDim]) { newDim = 2; } int loop = 0; int maxLoop = 4; double bestCenter = 0; double bestPercentage = 3000; int bestDim = 0; for (int dim = 0; dim < 3; dim++) { if (dim == parentDimension) { continue; } for (loop = 0; loop < maxLoop; loop++) { int count = 0; double testDist = box.minPoint[newDim] + size[newDim] * (1 + loop) / (maxLoop + 1); foreach (TopoTriangle tri in triangles) { if (tri.boundingBox.maxPoint[newDim] < testDist) { count++; } } double percent = 100.0 * (double)count / triangles.Count; if (Math.Abs(50 - percent) < bestPercentage) { bestPercentage = percent; bestCenter = testDist; bestDim = dim; } } } if (bestPercentage < 5) { nextTrySplit = (nextTrySplit * 3) / 2; return; // not effective enough } left = new TopoTriangleNode(this); right = new TopoTriangleNode(this); middle = new TopoTriangleNode(this); dimension = newDim; middlePosition = bestCenter; foreach (TopoTriangle tri in triangles) { if (tri.boundingBox.maxPoint[dimension] < middlePosition) { left.AddTriangle(tri); } else if (tri.boundingBox.minPoint[dimension] > middlePosition) { right.AddTriangle(tri); } else { middle.AddTriangle(tri); } } triangles = null; }
public bool Intersects(TopoTriangle tri) { // First detect shared edges for more reliable and faster tests TopoVertex[] shared = new TopoVertex[3]; TopoVertex[] uniqueA = new TopoVertex[3]; TopoVertex[] uniqueB = new TopoVertex[3]; int nShared = 0, nUniqueA = 0, nUniqueB = 0; for (int i = 0; i < 3; i++) { bool isDouble = false; for (int j = 0; j < 3; j++) { if (vertices[i] == tri.vertices[j]) { shared[nShared++] = vertices[i]; isDouble = true; break; } } if (!isDouble) { uniqueA[nUniqueA++] = vertices[i]; } } if (nShared > 0) { for (int i = 0; i < 3; i++) { bool isDouble = false; for (int j = 0; j < nShared; j++) { if (tri.vertices[i] == shared[j]) { isDouble = true; break; } } if (!isDouble) { uniqueB[nUniqueB++] = tri.vertices[i]; } } if (nShared == 1) { return(IntersectsSharedVertex(shared[0], uniqueA, uniqueB, tri)); } if (nShared == 2) { return(IntersectsSharedEdge(shared, uniqueA[0], uniqueB[0], tri)); } return(true); } // Nice to read but unoptimized intersection computation RHMatrix3 A = new RHMatrix3(); RHVector3 p1 = vertices[1].pos.Subtract(vertices[0].pos); RHVector3 p2 = vertices[2].pos.Subtract(vertices[0].pos); A.SetXColumn(p1); A.SetYColumn(p2); RHVector3 P = new RHVector3(vertices[0].pos); RHVector3 q1 = tri.vertices[1].pos.Subtract(tri.vertices[0].pos); RHVector3 q2 = tri.vertices[2].pos.Subtract(tri.vertices[0].pos); RHVector3 r1 = tri.vertices[0].pos.Subtract(P); // r2 == r1! RHVector3 r3 = tri.vertices[2].pos.Subtract(P); A.SetZColumn(q1); double detAq1 = A.Determinant; A.SetZColumn(q2); double detAq2 = A.Determinant; //A.SetZColumn(q3); double detAq3 = detAq1 - detAq2; // A.Determinant; A.SetZColumn(r1); double detAr1 = A.Determinant; //A.SetZColumn(r3); double detAr3 = detAr1 + detAq2; // A.Determinant; int intersect = 0; if (detAq1 == 0 && detAq2 == 0 && detAq3 == 0) // same plane case { if (detAr1 != 0) { return(false); // other parallel plance } // Select plane for computation x-y or x-z based on normal int idx1, idx2; DominantAxis(out idx1, out idx2); if (InPlaneIntersectLine(idx1, idx2, vertices[0].pos, vertices[1].pos, tri.vertices[0].pos, tri.vertices[1].pos)) { return(true); } if (InPlaneIntersectLine(idx1, idx2, vertices[0].pos, vertices[1].pos, tri.vertices[1].pos, tri.vertices[2].pos)) { return(true); } if (InPlaneIntersectLine(idx1, idx2, vertices[0].pos, vertices[1].pos, tri.vertices[2].pos, tri.vertices[0].pos)) { return(true); } if (InPlaneIntersectLine(idx1, idx2, vertices[1].pos, vertices[2].pos, tri.vertices[0].pos, tri.vertices[1].pos)) { return(true); } if (InPlaneIntersectLine(idx1, idx2, vertices[1].pos, vertices[2].pos, tri.vertices[1].pos, tri.vertices[2].pos)) { return(true); } if (InPlaneIntersectLine(idx1, idx2, vertices[1].pos, vertices[2].pos, tri.vertices[2].pos, tri.vertices[0].pos)) { return(true); } if (InPlaneIntersectLine(idx1, idx2, vertices[2].pos, vertices[0].pos, tri.vertices[0].pos, tri.vertices[1].pos)) { return(true); } if (InPlaneIntersectLine(idx1, idx2, vertices[2].pos, vertices[0].pos, tri.vertices[1].pos, tri.vertices[2].pos)) { return(true); } if (InPlaneIntersectLine(idx1, idx2, vertices[2].pos, vertices[0].pos, tri.vertices[2].pos, tri.vertices[0].pos)) { return(true); } // Test if point inside. 1 test per triangle is enough if (InPlanePointInside(idx1, idx2, tri.vertices[0].pos)) { return(true); } if (InPlanePointInside(idx1, idx2, tri.vertices[1].pos)) { return(true); } if (InPlanePointInside(idx1, idx2, tri.vertices[2].pos)) { return(true); } if (tri.InPlanePointInside(idx1, idx2, vertices[0].pos)) { return(true); } if (tri.InPlanePointInside(idx1, idx2, vertices[1].pos)) { return(true); } if (tri.InPlanePointInside(idx1, idx2, vertices[2].pos)) { return(true); } return(false); } double beta1 = -1, beta2 = -1, beta3 = -1; if (detAq1 != 0) { beta1 = -detAr1 / detAq1; if (beta1 >= epsilonZeroMinus && beta1 <= epsilonOnePlus) { intersect = 1; } } if (detAq2 != 0) { beta2 = -detAr1 / detAq2; if (beta2 >= epsilonZeroMinus && beta2 <= epsilonOnePlus) { intersect |= 2; } } if (detAq3 != 0) { beta3 = -detAr3 / detAq3; if (beta3 >= epsilonZeroMinus && beta3 <= epsilonOnePlus) { intersect |= 4; } } if (intersect == 7) { // Special case intersection in one point caused 3 valid betas if (Math.Abs(beta1) < epsilonZero) { intersect = 6; } else if (Math.Abs(beta3) < epsilonZero) { intersect = 3; } else { intersect = 5; } } //if (intersect == 0) return false; // Lies on wrong side RHVector3 T = null, t = null; if ((intersect & 1) == 1) { T = new RHVector3(q1); T.Scale(beta1); T.AddInternal(tri.vertices[0].pos); } if ((intersect & 2) == 2) { if (T == null) { T = new RHVector3(q2); T.Scale(beta2); T.AddInternal(tri.vertices[0].pos); } else { q2.Scale(beta2); q2.AddInternal(tri.vertices[0].pos); t = q2.Subtract(T); } } if ((intersect & 4) == 4 && T != null && (t == null || t.Length < epsilonZero)) { RHVector3 q3 = tri.vertices[1].pos.Subtract(tri.vertices[2].pos); q3.Scale(beta3); q3.AddInternal(tri.vertices[2].pos); t = q3.Subtract(T); } if (t == null) { return(false); } if (t.Length < epsilonZero) { // Only one point touches the plane int idx1, idx2; DominantAxis(out idx1, out idx2); return(InPlanePointInside(idx1, idx2, T)); } // Compute intersection points with this triangle double d1 = p1.x * t.y - p1.y * t.x; double d2 = p1.x * t.z - p1.z * t.x; double delta1 = -1, delta2 = -1, delta3 = -1, gamma1 = -1, gamma2 = -1, gamma3 = -1; if (Math.Abs(d1) > epsilonZero || Math.Abs(d2) > epsilonZero) { if (Math.Abs(d1) > Math.Abs(d2)) { delta1 = -(t.x * T.y - t.y * T.x + P.x * t.y - P.y * t.x) / d1; gamma1 = -(p1.x * T.y - p1.y * T.x - p1.x * P.y + p1.y * P.x) / d1; } else { delta1 = -(t.x * T.z - t.z * T.x + P.x * t.z - P.z * t.x) / d2; gamma1 = -(p1.x * T.z - p1.z * T.x - p1.x * P.z + p1.z * P.x) / d2; } } d1 = p2.x * t.y - p2.y * t.x; d2 = p2.x * t.z - p2.z * t.x; if (Math.Abs(d1) > epsilonZero || Math.Abs(d2) > epsilonZero) { if (Math.Abs(d1) > Math.Abs(d2)) { delta2 = -(t.x * T.y - t.y * T.x + P.x * t.y - P.y * t.x) / d1; gamma2 = -(p2.x * T.y - p2.y * T.x - p2.x * P.y + p2.y * P.x) / d1; } else { delta2 = -(t.x * T.z - t.z * T.x + P.x * t.z - P.z * t.x) / d2; gamma2 = -(p2.x * T.z - p2.z * T.x - p2.x * P.z + p2.z * P.x) / d2; } } P.AddInternal(p1); p2.SubtractInternal(p1); // p2 is now p3! d1 = p2.x * t.y - p2.y * t.x; d2 = p2.x * t.z - p2.z * t.x; if (Math.Abs(d1) > epsilonZero || Math.Abs(d2) > epsilonZero) { if (Math.Abs(d1) > Math.Abs(d2)) { delta3 = -(t.x * T.y - t.y * T.x + P.x * t.y - P.y * t.x) / d1; gamma3 = -(p2.x * T.y - p2.y * T.x - p2.x * P.y + p2.y * P.x) / d1; } else { delta3 = -(t.x * T.z - t.z * T.x + P.x * t.z - P.z * t.x) / d2; gamma3 = -(p2.x * T.z - p2.z * T.x - p2.x * P.z + p2.z * P.x) / d2; } } // Check for line intersection inside the line. Hits at the vertices to not count! if (delta1 >= epsilonZero && delta1 <= epsilonOneMinus && gamma1 >= epsilonZero && gamma1 <= epsilonOneMinus) { return(true); } if (delta2 >= epsilonZero && delta2 <= epsilonOneMinus && gamma2 >= epsilonZero && gamma2 <= epsilonOneMinus) { return(true); } if (delta3 >= epsilonZero && delta3 <= epsilonOneMinus && gamma3 >= epsilonZero && gamma3 <= epsilonOneMinus) { return(true); } // Test if intersection is inside triangle intersect = 0; if (delta1 >= epsilonZeroMinus && delta1 <= epsilonOnePlus) { intersect |= 1; } if (delta2 >= epsilonZeroMinus && delta2 <= epsilonOnePlus) { intersect |= 2; } if (delta3 >= epsilonZeroMinus && delta3 <= epsilonOnePlus) { intersect |= 4; } /* if (gamma1 == 0) gamma1 = -1; * if (gamma2 == 0) gamma2 = -1; * if (gamma3 == 0) gamma3 = -1;*/ if (gamma1 == 0) { intersect &= ~1; } if (gamma2 == 0) { intersect &= ~2; } if (gamma3 == 0) { intersect &= ~4; } /* if ((intersect & 3) == 3) return gamma1 * gamma2 < 0; * if ((intersect & 5) == 5) return gamma1 * gamma3 < 0; * if ((intersect & 6) == 6) return gamma3 * gamma2 < 0;*/ if ((intersect & 3) == 3) { if (gamma1 * gamma2 < 0) { return(true); } else { return(false); } } if ((intersect & 5) == 5) { if (gamma1 * gamma3 < 0) { return(true); } else { return(false); } } if ((intersect & 6) == 6) { if (gamma3 * gamma2 < 0) { return(true); } else { return(false); } } // if (intersect!=0) happens only with numeric problems // return true; return(false); // No intersection found :-) }
public TopoPlane(RHVector3 _normal, RHVector3 pointOnPlane) { normal = new RHVector3(_normal); normal.NormalizeSafe(); d = pointOnPlane.ScalarProduct(normal); }
public void SetXColumn(RHVector3 v) { xx = v.x; yx = v.y; zx = v.z; }
public void addIntersectionToSubmesh(Submesh mesh, TopoTriangle triangle, bool addEdges, int color) { int[] outside = new int[3]; int[] inside = new int[3]; int nOutside = 0, nInside = 0; int i; for (i = 0; i < 3; i++) { if (VertexDistance(triangle.vertices[i].pos) > 0) { outside[nOutside++] = i; } else { inside[nInside++] = i; } } if (nOutside != 1 && nOutside != 2) { return; } RHVector3[] intersections = new RHVector3[3]; int nIntersections = 0; for (int iInside = 0; iInside < nInside; iInside++) { for (int iOutside = 0; iOutside < nOutside; iOutside++) { RHVector3 v1 = triangle.vertices[inside[iInside]].pos; RHVector3 v2 = triangle.vertices[outside[iOutside]].pos; double dist1 = VertexDistance(v1); double dist2 = VertexDistance(v2); double pos = Math.Abs(dist1) / Math.Abs(dist2 - dist1); intersections[nIntersections++] = new RHVector3( v1.x + pos * (v2.x - v1.x), v1.y + pos * (v2.y - v1.y), v1.z + pos * (v2.z - v1.z) ); } } if (nInside == 2) { if (outside[0] == 1) { mesh.AddTriangle(triangle.vertices[inside[1]].pos, triangle.vertices[inside[0]].pos, intersections[1], color); mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[0], intersections[1], color); } else { mesh.AddTriangle(triangle.vertices[inside[0]].pos, triangle.vertices[inside[1]].pos, intersections[0], color); mesh.AddTriangle(triangle.vertices[inside[1]].pos, intersections[1], intersections[0], color); } } else { if (inside[0] == 1) { mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[1], intersections[0], color); } else { mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[0], intersections[1], color); } } if (addEdges) { if (nInside == 2) { mesh.AddEdge(triangle.vertices[inside[0]].pos, triangle.vertices[inside[1]].pos, triangle.edges[0].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); mesh.AddEdge(triangle.vertices[inside[0]].pos, intersections[0], triangle.edges[1].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); mesh.AddEdge(triangle.vertices[inside[1]].pos, intersections[1], triangle.edges[2].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); } else { for (int iInter = 0; iInter < nIntersections; iInter++) { mesh.AddEdge(triangle.vertices[inside[0]].pos, intersections[iInter], triangle.edges[(inside[0] + 2 * iInter) % 3].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); } } } if (nIntersections == 2) { mesh.AddEdge(intersections[0], intersections[1], Submesh.MESHCOLOR_CUT_EDGE); } }
public void SetYColumn(RHVector3 v) { xy = v.x; yy = v.y; zy = v.z; }