private List <double> checkCoplanarity(SpringMesh sMesh, double thickness, List <Line> linesUp, List <Line> linesDown) { List <double> coplanarity = new List <double>(); foreach (Edge edge in sMesh.Edges) { if (edge.SecondTriangleIndex >= 0) { int triLeft = edge.FirstTriangleIndex; int triRight = edge.SecondTriangleIndex; Point3d centreLeftO = sMesh.ComputeTriangleCentroid(triLeft); Point3d centreRightO = sMesh.ComputeTriangleCentroid(triRight); Point3d centreLeft = sMesh.ComputeTPI(triLeft); Point3d centreRight = sMesh.ComputeTPI(triRight); if (ICD.Utils.Distance(centreLeftO, centreLeft) < iMaxThickness && ICD.Utils.Distance(centreRightO, centreRight) < iMaxThickness) { Vector3d normalLeft = sMesh.ComputeTriangleNormal(triLeft); Vector3d normalRight = sMesh.ComputeTriangleNormal(triRight); Point3d centreLeftUp = centreLeft + normalLeft * thickness; Point3d centreRightUp = centreRight + normalRight * thickness; Point3d centreLeftDown = centreLeft - normalLeft * thickness; Point3d centreRightDown = centreRight - normalRight * thickness; linesUp.Add(new Line(centreLeftUp, centreRightUp)); linesDown.Add(new Line(centreLeftDown, centreRightDown)); Line planarCheckLine01 = new Line(centreLeftUp, centreRightDown); Line planarCheckLine02 = new Line(centreRightUp, centreLeftDown); double dist = planarCheckLine01.MinimumDistanceTo(planarCheckLine02); coplanarity.Add(dist); } } } return(coplanarity); }
protected override void SolveInstance(IGH_DataAccess DA) { // ============================================================================================================= // Reset // ============================================================================================================= DA.GetData <bool>("Reset", ref iReset); if (iReset) { DA.GetData <SpringMesh>("Spring Mesh", ref iSpringMesh); DA.GetData <int>("Population Size", ref iPopulationSize); triangleCentres = new List <Point3d>(); trianglePlanes = new List <Plane>(); triangleNormals = new List <Vector3d>(); for (int i = 0; i < iSpringMesh.Triangles.Count; i++) { triangleCentres.Add(iSpringMesh.ComputeCircumscribedCircleCenter(i)); trianglePlanes.Add(new Plane( iSpringMesh.Vertices[iSpringMesh.Triangles[i].FirstVertexIndex].Position, iSpringMesh.Vertices[iSpringMesh.Triangles[i].SecondVertexIndex].Position, iSpringMesh.Vertices[iSpringMesh.Triangles[i].ThirdVertexIndex].Position )); triangleNormals.Add(iSpringMesh.ComputeTriangleNormal(i)); } edgeXAxes = new List <Vector3d>(); edgeYAxes = new List <Vector3d>(); edgeZAxes = new List <Vector3d>(); edgePlanes = new List <Plane>(); edgeOrigins = new List <Point3d>(); List <double> geneMinValues = new List <double>(); List <double> geneMaxValues = new List <double>(); foreach (Edge edge in iSpringMesh.Edges) { if (edge.SecondTriangleIndex >= 0) { Vector3d edgeXAxis = iSpringMesh.Vertices[edge.SecondVertexIndex].Position - iSpringMesh.Vertices[edge.FirstVertexIndex].Position; edgeXAxes.Add(edgeXAxis); Vector3d edgeZAxis = triangleNormals[edge.FirstTriangleIndex] + triangleNormals[edge.SecondTriangleIndex]; edgeZAxis.Unitize(); edgeZAxes.Add(edgeZAxis); Vector3d edgeYAxis = Vector3d.CrossProduct(edgeZAxis, edgeXAxis); edgeYAxes.Add(edgeYAxis); Point3d edgePlaneOrigin = 0.5 * (iSpringMesh.Vertices[edge.FirstVertexIndex].Position + iSpringMesh.Vertices[edge.SecondVertexIndex].Position); edgeOrigins.Add(edgePlaneOrigin); edgePlanes.Add(new Plane(edgePlaneOrigin, edgeXAxis, edgeYAxis)); double angle = Utils.AngleBetweenTwoUnitVectors(edgeZAxis, triangleNormals[edge.FirstTriangleIndex]); geneMinValues.Add(-angle); geneMaxValues.Add(angle); } else { Vector3d edgeXAxis = iSpringMesh.Vertices[edge.SecondVertexIndex].Position - iSpringMesh.Vertices[edge.FirstVertexIndex].Position; edgeXAxes.Add(edgeXAxis); Vector3d edgeZAxis = triangleNormals[edge.FirstTriangleIndex]; if (edgeZAxis.Z < 0.0) { edgeZAxis += -Vector3d.ZAxis; } else { Vector3d temp = new Vector3d(-edgeZAxis.X, -edgeZAxis.Y, 0.0); temp.Unitize(); edgeZAxis += temp; } edgeZAxis.Unitize(); edgeZAxes.Add(edgeZAxis); Vector3d edgeYAxis = Vector3d.CrossProduct(triangleNormals[edge.FirstTriangleIndex], edgeXAxis); edgeYAxes.Add(edgeYAxis); Point3d edgePlaneOrigin = 0.5 * (iSpringMesh.Vertices[edge.FirstVertexIndex].Position + iSpringMesh.Vertices[edge.SecondVertexIndex].Position); edgeOrigins.Add(edgePlaneOrigin); edgePlanes.Add(new Plane(edgePlaneOrigin, edgeXAxis, edgeYAxis)); double angle = Utils.AngleBetweenTwoUnitVectors(edgeZAxis, triangleNormals[edge.FirstTriangleIndex]); geneMinValues.Add(-angle); geneMaxValues.Add(angle); } } beagle = new Beagle(iPopulationSize, geneMinValues, geneMaxValues); foreach (Genome genome in beagle.Genomes) { computeFitness(genome); } goto Conclusion; } DA.GetData <bool>("Play", ref iPlay); if (iPlay) { ExpireSolution(true); } else { List <double> values = new List <double>(); foreach (Gene gene in beagle.Genomes[0].Genes) { values.Add(gene.Value); } DA.SetDataList(4, values); goto Conclusion; } //if (!iPlay) goto Conclusion; // ==================================================================================================== // Evolution // ==================================================================================================== DA.GetData <int>("Subiteration Count", ref iSubiterationCount); DA.GetData <double>("Max. Coupling Distance", ref iMaxCouplingDistance); DA.GetData <double>("Mutation Rate", ref iMutationRate); DA.GetData <double>("Mutation Amount", ref iMutationAmount); beagle.MaxCouplingDistance = iMaxCouplingDistance; beagle.MutationRate = iMutationRate; beagle.MutationAmount = iMutationAmount; for (int i = 0; i < iSubiterationCount; i++) { beagle.SelectParents(); beagle.Reproduce(); for (int j = beagle.PopulationSize; j < beagle.Genomes.Count; j++) { computeFitness(beagle.Genomes[j]); } beagle.SelectFittests(); } DA.SetDataList(3, new List <double> { beagle.Genomes[0].Fitness }); // ==================================================================================================== // Conclusion // ==================================================================================================== Conclusion: Genome bestGenome = beagle.Genomes[0]; for (int i = 0; i < bestGenome.Genes.Count; i++) { double angle = bestGenome.Genes[i].Value; Vector3d planeNormal = Math.Sin(angle) * edgeYAxes[i] + Math.Cos(angle) * edgeZAxes[i]; edgePlanes[i] = new Plane( edgePlanes[i].Origin, edgePlanes[i].XAxis, Vector3d.CrossProduct(planeNormal, edgePlanes[i].XAxis) ); } //List<Plane> nastyPlanes = new List<Plane>(); List <Point3d> planeTripletIntersections = new List <Point3d>(); foreach (Triangle triangle in iSpringMesh.Triangles) { Point3d intersectionPoint; if (Intersection.PlanePlanePlane(edgePlanes[triangle.FirstEdgeIndex], edgePlanes[triangle.SecondEdgeIndex], edgePlanes[triangle.ThirdEdgeIndex], out intersectionPoint)) { planeTripletIntersections.Add(intersectionPoint); } //else //{ // nastyPlanes.Add(edgePlanes[triangle.FirstEdgeIndex]); // nastyPlanes.Add(edgePlanes[triangle.FirstEdgeIndex]); // nastyPlanes.Add(edgePlanes[triangle.FirstEdgeIndex]); //} } DA.SetDataList(1, edgePlanes); DA.SetDataList(2, planeTripletIntersections); //DA.SetDataList(1, edgePlanes); //DA.SetDataList(2, edgeOrigins); //DA.SetDataList(3, edgeXAxes); //DA.SetDataList(4, edgeYAxes); //DA.SetDataList(5, edgeZAxes); }
protected override void SolveInstance(IGH_DataAccess DA) { iPoints = new List <Point3d>(); DA.GetDataList <Point3d>("Points", iPoints); iApicals = new List <Circle>(); DA.GetDataList <Circle>("Apicals", iApicals); iMasses = new List <double>(); DA.GetDataList <double>("Masses", iMasses); DA.GetData <Curve>("Boundary Curve", ref iBoundaryCurve); DA.GetData <double>("Rest Length Scale", ref iRestLengthScale); DA.GetData <double>("Rest Length Offset", ref iRestLengthOffset); DA.GetData <double>("Stiffness", ref iStiffness); DA.GetData <double>("Bending Stiffness", ref iBendingStiffness); DA.GetData <bool>("In/Out Switch", ref iInOutSwitch); DA.GetData <double>("In/Out Threshold", ref iInOutThreshold); DA.GetData <double>("Fixed Point Threshold", ref iFixedPointThreshold); iFixedPointExclusion = new List <Curve>(); DA.GetDataList <Curve>("Fixed Point Exclusion", iFixedPointExclusion); iFixedPointInclusion = new List <Curve>(); DA.GetDataList <Curve>("Fixed Point Inclusion", iFixedPointInclusion); // =========================================================================================== // Compute Delaunay Triangulation // =========================================================================================== List <DelaunayVertex> delaunayVertices = new List <DelaunayVertex>(); foreach (Point3d point in iPoints) { delaunayVertices.Add(new DelaunayVertex(point.X, point.Y)); } List <Triad> triads = new DelaunayTriangulator().Triangulation(delaunayVertices); HashSet <Tuple <int, int> > delaunayEdgeTuples = new HashSet <Tuple <int, int> >(); for (int i = 0; i < triads.Count; i++) { Triad triad = triads[i]; delaunayEdgeTuples.Add(triad.a < triad.b ? new Tuple <int, int>(triad.a, triad.b) : new Tuple <int, int>(triad.b, triad.a)); delaunayEdgeTuples.Add(triad.b < triad.c ? new Tuple <int, int>(triad.b, triad.c) : new Tuple <int, int>(triad.c, triad.b)); delaunayEdgeTuples.Add(triad.c < triad.a ? new Tuple <int, int>(triad.c, triad.a) : new Tuple <int, int>(triad.a, triad.c)); } // =========================================================================================== // Convert Delaunay mesh to particle-spring mesh // =========================================================================================== oSpringMesh = new SpringMesh(); // Create edge list ----------------------------------------------------------------------------------------------- foreach (Tuple <int, int> delaunayEdgeTuple in delaunayEdgeTuples) { Point3d A = iPoints[delaunayEdgeTuple.Item1]; Point3d B = iPoints[delaunayEdgeTuple.Item2]; Point3d M = 0.5 * (A + B); // Skip if the edge lies outside of the boundary double t; iBoundaryCurve.ClosestPoint(M, out t); Point3d N = iBoundaryCurve.PointAt(t); if (Vector3d.CrossProduct(iBoundaryCurve.TangentAt(t), M - N).Z *(iInOutSwitch ? -1.0 : 1.0) < 0.0 && Utils.DistanceSquared(M, N) > iInOutThreshold * iInOutThreshold) { continue; } double edgeLength = Utils.Distance(A, B); double restLength = iRestLengthScale * edgeLength + iRestLengthOffset; oSpringMesh.Edges.Add(new Edge(delaunayEdgeTuple.Item1, delaunayEdgeTuple.Item2, restLength, iStiffness, Math.PI, iBendingStiffness)); } // Create vertex list ----------------------------------------------------------------------------------------------- List <HashSet <int> > neighborVerticesSets = new List <HashSet <int> >(); for (int i = 0; i < iPoints.Count; i++) { neighborVerticesSets.Add(new HashSet <int>()); } foreach (Edge edge in oSpringMesh.Edges) { neighborVerticesSets[edge.FirstVertexIndex].Add(edge.SecondVertexIndex); neighborVerticesSets[edge.SecondVertexIndex].Add(edge.FirstVertexIndex); } for (int i = 0; i < iPoints.Count; i++) { Point3d p = iPoints[i]; double t; iBoundaryCurve.ClosestPoint(p, out t); bool vertexFixedness = true; if (Utils.Distance(p, iBoundaryCurve.PointAt(t)) > iFixedPointThreshold) { vertexFixedness = false; } else { foreach (Curve curve in iFixedPointExclusion) { if (curve.Contains(p) == PointContainment.Inside) { vertexFixedness = false; break; } } } foreach (Curve curve in iFixedPointInclusion) { if (curve.Contains(p) == PointContainment.Inside) { vertexFixedness = true; break; } } Vertex vertex = new Vertex(p, Vector3d.Zero, neighborVerticesSets[i].ToList <int>(), iMasses.Count == 1 ? iMasses[0] : iMasses[i], vertexFixedness); oSpringMesh.Vertices.Add(vertex); } // Set boundary edge ----------------------------------------------------------------------------------------------- foreach (Edge edge in oSpringMesh.Edges) { if (oSpringMesh.Vertices[edge.FirstVertexIndex].IsFixed && oSpringMesh.Vertices[edge.SecondVertexIndex].IsFixed) { edge.IsBoundaryEdge = true; } } // Create triangle list ------------------------------------------------------------------------------------------------ Dictionary <Tuple <int, int, int>, int> tripletDict = new Dictionary <Tuple <int, int, int>, int>(); for (int k = 0; k < oSpringMesh.Edges.Count; k++) { Edge edge = oSpringMesh.Edges[k]; Vertex A = oSpringMesh.Vertices[edge.FirstVertexIndex]; Vertex B = oSpringMesh.Vertices[edge.SecondVertexIndex]; for (int i = 0; i < A.NeighborVertexIndices.Count; i++) { for (int j = 0; j < B.NeighborVertexIndices.Count; j++) { if (A.NeighborVertexIndices[i] == B.NeighborVertexIndices[j]) { Tuple <int, int, int> triplet = sortTriplet(edge.FirstVertexIndex, edge.SecondVertexIndex, A.NeighborVertexIndices[i]); if (tripletDict.ContainsKey(triplet)) { if (edge.FirstTriangleIndex < 0) { edge.FirstTriangleIndex = tripletDict[triplet]; edge.FirstAdjacentVertexIndex = A.NeighborVertexIndices[i]; } else { edge.SecondTriangleIndex = tripletDict[triplet]; edge.SecondAdjacentVertexIndex = A.NeighborVertexIndices[i]; } } else { oSpringMesh.Triangles.Add(new Triangle(triplet.Item1, triplet.Item2, triplet.Item3)); int triangleIndex = oSpringMesh.Triangles.Count - 1; if (edge.FirstTriangleIndex < 0) { edge.FirstTriangleIndex = triangleIndex; edge.FirstAdjacentVertexIndex = A.NeighborVertexIndices[i]; } else { edge.SecondTriangleIndex = triangleIndex; edge.SecondAdjacentVertexIndex = A.NeighborVertexIndices[i]; } tripletDict.Add(triplet, triangleIndex); } } } } } // =========================================================================================== // Compute edge indices for each triangle // =========================================================================================== for (int i = 0; i < oSpringMesh.Edges.Count; i++) { Edge edge = oSpringMesh.Edges[i]; Triangle triangle = oSpringMesh.Triangles[edge.FirstTriangleIndex]; if (triangle.FirstEdgeIndex == -1) { triangle.FirstEdgeIndex = i; } else if (triangle.SecondEdgeIndex == -1) { triangle.SecondEdgeIndex = i; } else { triangle.ThirdEdgeIndex = i; } if (edge.SecondTriangleIndex == -1) { continue; } triangle = oSpringMesh.Triangles[edge.SecondTriangleIndex]; if (triangle.FirstEdgeIndex == -1) { triangle.FirstEdgeIndex = i; } else if (triangle.SecondEdgeIndex == -1) { triangle.SecondEdgeIndex = i; } else { triangle.ThirdEdgeIndex = i; } } // =========================================================================================== // Rearange the vertex order in each triangle so the normal calculation is consistent // =========================================================================================== for (int i = 0; i < oSpringMesh.Triangles.Count; i++) { if (oSpringMesh.ComputeTriangleNormal(i).Z < 0.0) { int temp = oSpringMesh.Triangles[i].SecondVertexIndex; oSpringMesh.Triangles[i].SecondVertexIndex = oSpringMesh.Triangles[i].ThirdVertexIndex; oSpringMesh.Triangles[i].ThirdVertexIndex = temp; } } // =========================================================================================== // Rearranging edge adjacent vertex indices for consitency // =========================================================================================== foreach (Edge edge in oSpringMesh.Edges) { if (edge.SecondAdjacentVertexIndex == -1) { Point3d A = oSpringMesh.Vertices[edge.FirstVertexIndex].Position; Point3d B = oSpringMesh.Vertices[edge.SecondVertexIndex].Position; Point3d M = oSpringMesh.Vertices[edge.FirstAdjacentVertexIndex].Position; if (Vector3d.CrossProduct(B - A, M - A) * oSpringMesh.ComputeTriangleNormal(edge.FirstTriangleIndex) < 0.0) { Point3d temp = A; A = B; B = temp; } } else { Point3d A = oSpringMesh.Vertices[edge.FirstVertexIndex].Position; Point3d B = oSpringMesh.Vertices[edge.SecondVertexIndex].Position; Point3d M = oSpringMesh.Vertices[edge.FirstAdjacentVertexIndex].Position; Point3d N = oSpringMesh.Vertices[edge.SecondAdjacentVertexIndex].Position; if (Vector3d.CrossProduct(B - A, M - A) * oSpringMesh.ComputeTriangleNormal(edge.FirstAdjacentVertexIndex) < 0.0) { int temp = edge.FirstAdjacentVertexIndex; edge.FirstAdjacentVertexIndex = edge.SecondAdjacentVertexIndex; edge.SecondAdjacentVertexIndex = temp; temp = edge.FirstTriangleIndex; edge.FirstTriangleIndex = edge.SecondTriangleIndex; edge.SecondTriangleIndex = temp; } } } // =========================================================================================== // Compute adjacent vertex index for each triangle // =========================================================================================== //foreach (Triangle triangle in oSpringMesh.Triangles) //{ // Vertex firstVertex = oSpringMesh.Vertices[triangle.FirstVertexIndex]; // Vertex secondVertex = oSpringMesh.Vertices[triangle.SecondVertexIndex]; // Vertex thirdVertex = oSpringMesh.Vertices[triangle.ThirdVertexIndex]; // foreach (int firstNeighbourIndex in firstVertex.NeighborVertexIndices) // foreach (int secondNeighbourIndex in secondVertex.NeighborVertexIndices) // if (firstNeighbourIndex == secondNeighbourIndex && firstNeighbourIndex != triangle.ThirdVertexIndex) // triangle.FirstSecondAdjacentVertexIndex = firstNeighbourIndex; // foreach (int secondNeighbourIndex in secondVertex.NeighborVertexIndices) // foreach (int thirdNeighbourIndex in thirdVertex.NeighborVertexIndices) // if (secondNeighbourIndex == thirdNeighbourIndex && secondNeighbourIndex != triangle.FirstVertexIndex) // triangle.SecondThirdAdjacentVertexIndex = secondNeighbourIndex; // foreach (int thirdNeighbourIndex in thirdVertex.NeighborVertexIndices) // foreach (int firstNeighbourIndex in firstVertex.NeighborVertexIndices) // if (thirdNeighbourIndex == firstNeighbourIndex && thirdNeighbourIndex != triangle.SecondVertexIndex) // triangle.ThirdFirstAdjacentVertexIndex = thirdNeighbourIndex; //} // =========================================================================================== // Initial curving bias // =========================================================================================== DA.GetData <double>("Initial Curving Bias", ref iInitialCurvingBias); DA.GetData <bool>("Bias Apical Regions", ref iBiasApicalRegion); foreach (Vertex vertex in oSpringMesh.Vertices) { vertex.Position.Z = computeBiasHeight(vertex.Position, iBiasApicalRegion); } // =========================================================================================== // Conclusion // =========================================================================================== foreach (Edge edge in oSpringMesh.Edges) { oDebugCurves1.Add(new LineCurve(oSpringMesh.Vertices[edge.FirstVertexIndex].Position, oSpringMesh.Vertices[edge.SecondVertexIndex].Position)); } DA.SetData(0, oInfo); DA.SetDataList(1, oDebugCurves1); DA.SetData(6, oSpringMesh); }
protected override void SolveInstance(IGH_DataAccess DA) { DA.GetData <SpringMesh>("Spring Mesh", ref iSpringMesh); DA.GetData <bool>("Reset", ref iReset); DA.GetData <bool>("Play", ref iPlay); DA.GetData <int>("Subiteration Count", ref iSubiterationCount); DA.GetData <int>("Population Size", ref iPopulationSize); DA.GetData <double>("Mutation Rate", ref iMutationRate); DA.GetData <double>("Mutation Amount", ref iMutationAmount); // ------------------------------------------------------------------------------------------------------- List <Vector3d> triangleNormals = new List <Vector3d>(); for (int i = 0; i < iSpringMesh.Triangles.Count; i++) { triangleNormals.Add(iSpringMesh.ComputeTriangleNormal(i)); } List <List <Plane> > planeTriplets = new List <List <Plane> >(); for (int i = 0; i < iSpringMesh.Triangles.Count; i++) { planeTriplets.Add(new List <Plane>()); } List <Plane> edgePlanes = new List <Plane>();; foreach (Edge edge in iSpringMesh.Edges) { if (edge.SecondTriangleIndex >= 0) { Vector3d planeNormal = triangleNormals[edge.FirstTriangleIndex] + triangleNormals[edge.SecondTriangleIndex]; Point3d planeOrigin = 0.5 * (iSpringMesh.Vertices[edge.FirstVertexIndex].Position + iSpringMesh.Vertices[edge.SecondVertexIndex].Position); Vector3d localX = iSpringMesh.Vertices[edge.SecondVertexIndex].Position - iSpringMesh.Vertices[edge.FirstVertexIndex].Position; localX.Unitize(); planeNormal.Unitize(); Vector3d localY = Vector3d.CrossProduct(localX, planeNormal); Plane plane = new Plane(planeOrigin, localX, localY); planeTriplets[edge.FirstTriangleIndex].Add(plane); planeTriplets[edge.SecondTriangleIndex].Add(plane); edgePlanes.Add(plane); } else { ///////////////////// } } List <Plane> nastyPlanes = new List <Plane>(); List <Point3d> planeTripletIntersections = new List <Point3d>(); foreach (List <Plane> planeTriplet in planeTriplets) { if (planeTriplet.Count != 3) { continue; } Point3d intersectionPoint; if (Intersection.PlanePlanePlane(planeTriplet[0], planeTriplet[1], planeTriplet[2], out intersectionPoint)) { planeTripletIntersections.Add(intersectionPoint); } else { nastyPlanes.Add(planeTriplet[0]); nastyPlanes.Add(planeTriplet[1]); nastyPlanes.Add(planeTriplet[2]); } } DA.SetDataList(1, edgePlanes); DA.SetDataList(2, planeTripletIntersections); DA.SetDataList(3, nastyPlanes); //for (int i = 0; i < planeTriplets.Count; i++) //{ // if (planeTriplets[i].Count == 3) //////// remove later // { // Point3d intersectionPoint; // if (Intersection.PlanePlanePlane(planeTriplets[i][0], planeTriplets[i][1], planeTriplets[i][2], out intersectionPoint)) // trianglePoints.Add(intersectionPoint); // else // trianglePoints.Add(iSpringMesh.ComputeTriangleCentroid(i)); // } // else // { // Line intersectionLine; // if (Intersection.PlanePlane(planeTriplets[i][0], planeTriplets[i][1], out intersectionLine)) // { // trianglePoints.Add( // Utils.ClosestPointOnLine( // iSpringMesh.ComputeTriangleCentroid(i), // intersectionLine.PointAt(0.0), // intersectionLine.PointAt(1.0))); // } // else // trianglePoints.Add(iSpringMesh.ComputeTriangleCentroid(i)); // } //} //Mesh oRhinoMesh = new Mesh(); //List<PolylineCurve> quadPolylines = new List<PolylineCurve>(); //foreach (Edge edge in iSpringMesh.Edges) //{ // if (edge.SecondTriangleIndex >= 0) // { // Point3d A = iSpringMesh.Vertices[edge.FirstVertexIndex].Position; // Point3d C = iSpringMesh.Vertices[edge.SecondVertexIndex].Position; // Point3d B = trianglePoints[edge.FirstTriangleIndex]; // Point3d D = trianglePoints[edge.SecondTriangleIndex]; // oRhinoMesh.Vertices.Add(A); // oRhinoMesh.Vertices.Add(B); // oRhinoMesh.Vertices.Add(C); // oRhinoMesh.Vertices.Add(D); // oRhinoMesh.Faces.AddFace(oRhinoMesh.Vertices.Count - 4, oRhinoMesh.Vertices.Count - 3, oRhinoMesh.Vertices.Count - 2, oRhinoMesh.Vertices.Count - 1); // quadPolylines.Add(new PolylineCurve(new List<Point3d>() { A, B, C, D , A})); // } //} }
public bool CalculateSurface(SpringMesh sMesh, double thickness, List <Curve> curvesRight, List <Curve> curvesLeft) { foreach (Edge edge in sMesh.Edges) { if (edge.SecondTriangleIndex >= 0) { // first vertex // first triangle #region curve01 int firstPtId = edge.FirstVertexIndex; int firstTriangleIdRight = edge.FirstTriangleIndex; Vertex firstPtVertex = sMesh.Vertices[firstPtId]; //Point3d firstTriCentreRight = sMesh.ComputeTriangleCenter(firstTriangleIdRight); Point3d firstTriCentreRight = sMesh.ComputeCircumscribedCircleCenter(firstTriangleIdRight); Vector3d firstNormalRight = thickness * sMesh.ComputeTriangleNormal(firstTriangleIdRight); Point3d firstTriCentreUpRight = firstTriCentreRight + firstNormalRight; // the first control point Point3d firstTriCentreDownRight = firstTriCentreRight - firstNormalRight; // the seventh control point Point3d firstCPt02Right = (firstPtVertex.Factor - 0.2) * firstPtVertex.Position + (1 - firstPtVertex.Factor + 0.2) * firstTriCentreRight; Point3d firstCPt02UpRight = firstCPt02Right + firstNormalRight; // the second control point Point3d firstCPt02DownRight = firstCPt02Right - firstNormalRight; // the sixth control point Point3d firstCPt03Right = firstPtVertex.Factor * firstPtVertex.Position + (1 - firstPtVertex.Factor) * firstTriCentreRight; Point3d firstCPt03UpRight = firstCPt03Right + firstNormalRight; // the third control point Point3d firstCPt03DownRight = firstCPt03Right - firstNormalRight; // the fifth control point Point3d firstUpPtRight = firstPtVertex.Position; // the fourth control point List <Point3d> firstControlPointRight = new List <Point3d>() { firstTriCentreUpRight, firstCPt02UpRight, firstCPt03UpRight, firstUpPtRight, firstCPt03DownRight, firstCPt02DownRight, firstTriCentreDownRight }; #endregion NurbsCurve firstNurbCurveRight = NurbsCurve.Create(false, 5, firstControlPointRight); // second triangle #region curve02 int firstTriangleIdLeft = edge.SecondTriangleIndex; //Point3d firstTriCentreLeft = sMesh.ComputeTriangleCenter(firstTriangleIdLeft); Point3d firstTriCentreLeft = sMesh.ComputeCircumscribedCircleCenter(firstTriangleIdLeft); Vector3d firstNormalLeft = thickness * sMesh.ComputeTriangleNormal(firstTriangleIdLeft); Point3d firstTriCentreUpLeft = firstTriCentreLeft + firstNormalLeft; // the first control point Point3d firstTriCentreDownLeft = firstTriCentreLeft - firstNormalLeft; // the seventh control point Point3d firstCPt02Left = (firstPtVertex.Factor - 0.2) * firstPtVertex.Position + (1 - firstPtVertex.Factor + 0.2) * firstTriCentreLeft; Point3d firstCPt02UpLeft = firstCPt02Left + firstNormalLeft; // the second control point Point3d firstCPt02DownLeft = firstCPt02Left - firstNormalLeft; // the sixth control point Point3d firstCPt03Left = firstPtVertex.Factor * firstPtVertex.Position + (1 - firstPtVertex.Factor) * firstTriCentreLeft; Point3d firstCPt03UpLeft = firstCPt03Left + firstNormalLeft; // the third control point Point3d firstCPt03DownLeft = firstCPt03Left - firstNormalLeft; // the fifth control point Point3d firstUpPtLeft = firstPtVertex.Position; // the fourth control point List <Point3d> firstControlPointLeft = new List <Point3d>() { firstTriCentreUpLeft, firstCPt02UpLeft, firstCPt03UpLeft, firstUpPtLeft, firstCPt03DownLeft, firstCPt02DownLeft, firstTriCentreDownLeft }; #endregion NurbsCurve firstNurbCurveLeft = NurbsCurve.Create(false, 5, firstControlPointLeft); curvesRight.Add(firstNurbCurveRight); curvesLeft.Add(firstNurbCurveLeft); /* * Brep[] brep1 = Brep.CreateFromLoft( * new List<Curve>() { firstNurbCurveRight, firstNurbCurveLeft }, * Point3d.Unset, Point3d.Unset, LoftType.Developable, false); * * if (brep1.Length > 0) breps.Add(brep1[0]); */ // second vertex // first triangle #region curve03 int secondPtId = edge.SecondVertexIndex; int secondTriangleIdRight = edge.FirstTriangleIndex; Vertex secondPtVertex = sMesh.Vertices[secondPtId]; //Point3d secondTriCentreRight = sMesh.ComputeTriangleCenter(secondTriangleIdRight); Point3d secondTriCentreRight = sMesh.ComputeCircumscribedCircleCenter(secondTriangleIdRight); Vector3d secondNormalRight = thickness * sMesh.ComputeTriangleNormal(secondTriangleIdRight); Point3d secondTriCentreUpRight = secondTriCentreRight + secondNormalRight; // the second control point Point3d secondTriCentreDownRight = secondTriCentreRight - secondNormalRight; // the seventh control point Point3d secondCPt02Right = (secondPtVertex.Factor - 0.2) * secondPtVertex.Position + (1 - secondPtVertex.Factor + 0.2) * secondTriCentreRight; Point3d secondCPt02UpRight = secondCPt02Right + secondNormalRight; // the second control point Point3d secondCPt02DownRight = secondCPt02Right - secondNormalRight; // the sixth control point Point3d secondCPt03Right = secondPtVertex.Factor * secondPtVertex.Position + (1 - secondPtVertex.Factor) * secondTriCentreRight; Point3d secondCPt03UpRight = secondCPt03Right + secondNormalRight; // the third control point Point3d secondCPt03DownRight = secondCPt03Right - secondNormalRight; // the fifth control point Point3d secondUpPtRight = secondPtVertex.Position; // the fourth control point List <Point3d> secondControlPointRight = new List <Point3d>() { secondTriCentreUpRight, secondCPt02UpRight, secondCPt03UpRight, secondUpPtRight, secondCPt03DownRight, secondCPt02DownRight, secondTriCentreDownRight }; #endregion NurbsCurve secondNurbCurveRight = NurbsCurve.Create(false, 5, secondControlPointRight); // second triangle #region curve04 int secondTriangleIdLeft = edge.SecondTriangleIndex; //Point3d secondTriCentreLeft = sMesh.ComputeTriangleCenter(secondTriangleIdLeft); Point3d secondTriCentreLeft = sMesh.ComputeCircumscribedCircleCenter(secondTriangleIdLeft); Vector3d secondNormalLeft = thickness * sMesh.ComputeTriangleNormal(secondTriangleIdLeft); Point3d secondTriCentreUpLeft = secondTriCentreLeft + secondNormalLeft; // the second control point Point3d secondTriCentreDownLeft = secondTriCentreLeft - secondNormalLeft; // the seventh control point Point3d secondCPt02Left = (secondPtVertex.Factor - 0.2) * secondPtVertex.Position + (1 - secondPtVertex.Factor + 0.2) * secondTriCentreLeft; Point3d secondCPt02UpLeft = secondCPt02Left + secondNormalLeft; // the second control point Point3d secondCPt02DownLeft = secondCPt02Left - secondNormalLeft; // the sixth control point Point3d secondCPt03Left = secondPtVertex.Factor * secondPtVertex.Position + (1 - secondPtVertex.Factor) * secondTriCentreLeft; Point3d secondCPt03UpLeft = secondCPt03Left + secondNormalLeft; // the third control point Point3d secondCPt03DownLeft = secondCPt03Left - secondNormalLeft; // the fifth control point Point3d secondUpPtLeft = secondPtVertex.Position; // the fourth control point List <Point3d> secondControlPointLeft = new List <Point3d>() { secondTriCentreUpLeft, secondCPt02UpLeft, secondCPt03UpLeft, secondUpPtLeft, secondCPt03DownLeft, secondCPt02DownLeft, secondTriCentreDownLeft }; #endregion NurbsCurve secondNurbCurveLeft = NurbsCurve.Create(false, 5, secondControlPointLeft); curvesRight.Add(secondNurbCurveRight); curvesLeft.Add(secondNurbCurveLeft); /* * Brep[] brep2 = Brep.CreateFromLoft( * new List<Curve>() { firstNurbCurveRight, firstNurbCurveLeft }, * Point3d.Unset, Point3d.Unset, LoftType.Developable, false); * * if (brep2.Length > 0) breps.Add(brep2[0]); */ } } return(true); }
public void DualTPI(bool flip) { List <List <LineCurve> > dualVertices = new List <List <LineCurve> >(); for (int i = 0; i < oSpringMesh.Vertices.Count; i++) { dualVertices.Add(new List <LineCurve>()); } ////// this is to create planar plate foreach (Edge edge in oSpringMesh.Edges) { if (edge.SecondTriangleIndex >= 0) { int firstVertexIndex = edge.FirstVertexIndex; int secondVertexIndex = edge.SecondVertexIndex; int firstTriangleIndex = edge.FirstTriangleIndex; int secondTriangleIndex = edge.SecondTriangleIndex; Point3d firstTPI = oSpringMesh.ComputeDoubleLayerTPI(firstTriangleIndex, othickness, flip, iPlatesOffset); Point3d secondTPI = oSpringMesh.ComputeDoubleLayerTPI(secondTriangleIndex, othickness, flip, iPlatesOffset); Point3d firstTPIO = oSpringMesh.ComputeTPI(firstTriangleIndex); Point3d secondTPIO = oSpringMesh.ComputeTPI(secondTriangleIndex); Point3d firstCenterPtO = oSpringMesh.ComputeTriangleCentroid(firstTriangleIndex); Point3d secondCenterPtO = oSpringMesh.ComputeTriangleCentroid(secondTriangleIndex); Point3d firstCenterPt; Point3d secondCenterPt; if (!flip) { firstCenterPt = oSpringMesh.ComputeTriangleCentroid(firstTriangleIndex) + oSpringMesh.ComputeTriangleNormal(firstTriangleIndex); secondCenterPt = oSpringMesh.ComputeTriangleCentroid(secondTriangleIndex) + oSpringMesh.ComputeTriangleNormal(secondTriangleIndex); } else { firstCenterPt = oSpringMesh.ComputeTriangleCentroid(firstTriangleIndex) - oSpringMesh.ComputeTriangleNormal(firstTriangleIndex); secondCenterPt = oSpringMesh.ComputeTriangleCentroid(secondTriangleIndex) - oSpringMesh.ComputeTriangleNormal(secondTriangleIndex); } // =========================================================================== // Added 14/06/2015 to make some tolerance for plates Circle firstCircle = oSpringMesh.ComputeDoubleLayerIncircle(firstTriangleIndex, iPlatesThreadsP, othickness, flip, iPlatesOffset); Circle secondCircle = oSpringMesh.ComputeDoubleLayerIncircle(secondTriangleIndex, iPlatesThreadsP, othickness, flip, iPlatesOffset); //Circle firstCircle = oSpringMesh.ComputeDoubleLayerCircumscribedCircle(firstTriangleIndex, iPlatesThreadsP, othickness, flip, iPlatesOffset); //Circle secondCircle = oSpringMesh.ComputeDoubleLayerCircumscribedCircle(secondTriangleIndex, iPlatesThreadsP, othickness, flip, iPlatesOffset); Circle firstCircleO = oSpringMesh.ComputeIncircle(firstTriangleIndex, iPlatesThreadsP); // iPlatesThreads = 0.0-1.0 Circle secondCircleO = oSpringMesh.ComputeIncircle(secondTriangleIndex, iPlatesThreadsP); Plane firstPO = oSpringMesh.ComputePlane(firstTriangleIndex); Plane secondPO = oSpringMesh.ComputePlane(secondTriangleIndex); Point3d projectFirstTPIO = firstPO.ClosestPoint(firstTPIO); Point3d projectSecondTPIO = secondPO.ClosestPoint(secondTPIO); Point3d newFirstTPI = firstCircle.ClosestPoint(firstTPI); Point3d newSecondTPI = secondCircle.ClosestPoint(secondTPI); // manuel selected plates foreach (int id in iID) { if (id == firstVertexIndex) { dualVertices[firstVertexIndex].Add(new LineCurve(newFirstTPI, newSecondTPI)); } if (id == secondVertexIndex) { dualVertices[secondVertexIndex].Add(new LineCurve(newFirstTPI, newSecondTPI)); } } // auto generated plates if (ICD.Utils.Distance(projectFirstTPIO, firstCenterPtO) < iPlatesThreads && ICD.Utils.Distance(projectSecondTPIO, secondCenterPtO) < iPlatesThreads && iAutoGenPlates && !iID.Contains(firstVertexIndex) && !iID.Contains(secondVertexIndex)) { dualVertices[firstVertexIndex].Add(new LineCurve(newFirstTPI, newSecondTPI)); dualVertices[secondVertexIndex].Add(new LineCurve(newFirstTPI, newSecondTPI)); } } else { } } int counter = -1; for (int i = 0; i < oSpringMesh.Vertices.Count; i++) { // if is close and all right if (dualVertices[i].Count == oSpringMesh.Vertices[i].NeighborVertexIndices.Count && !iID.Contains(i)) { Curve dualcurve = Curve.JoinCurves(dualVertices[i])[0]; oInfo += dualcurve.IsClosed.ToString() + "\n"; if (dualcurve.IsClosed) { oPolyLine.Add(dualcurve); counter++; // change the vertex staus to be occupied oVertexStatus[i] = true; oPolyLineID[i] = counter; } } // manuel selected plate foreach (int id in iID) { if (id == i) { Curve dualcurve = Curve.JoinCurves(dualVertices[i])[0]; if (dualcurve.IsClosed) { oPolyLine.Add(dualcurve); counter++; // change the vertex staus to be occupied oVertexStatus[i] = true; oPolyLineID[i] = counter; } } } } }