protected override void BeforeSolveInstance() { // input iSpringMesh = new SpringMesh(); iPolyLine = new List<Curve>(); iVertexStatus = new List<bool>(); // true is plate occupied, false should put triLoop iPolyLineID = new List<int>(); // for vertex status access the order of polyline iThickness = new List<double>(); // output oInfo = string.Empty; oDebugList = new List<Point3d>(); oTriLoop = new List<Brep>(); oDualLoop = new List<Brep>(); // internal use data topCenterPts = new List<Point3d>(); bottomCenterPts = new List<Point3d>(); topCenterPolygonOccupied = new List<bool>(); // not use at this moment bottomCps = new List<Point3d>(); topCps = new List<Point3d>(); indexSortPolygon = new List<int[]>(); }
protected override void SolveInstance(IGH_DataAccess DA) { SpringMesh iSpringMesh = new SpringMesh(); List <Circle> iCircles = new List <Circle>(); double iBendingStiffness = double.NaN; double iStiffness = double.NaN; List <double> iPlanarRegionBendingStiffness = new List <double>(); List <double> iPlanarRegionStiffness = new List <double>(); DA.GetData <SpringMesh>(0, ref iSpringMesh); DA.GetDataList <Circle>(1, iCircles); DA.GetData <double>(2, ref iBendingStiffness); DA.GetData <double>(3, ref iStiffness); DA.GetDataList <double>(4, iPlanarRegionBendingStiffness); DA.GetDataList <double>(5, iPlanarRegionStiffness); SpringMesh oSpringMesh = new SpringMesh(iSpringMesh); foreach (Edge edge in iSpringMesh.Edges) { edge.RestLength = Utils.Distance(oSpringMesh.Vertices[edge.FirstVertexIndex].Position, oSpringMesh.Vertices[edge.SecondVertexIndex].Position); edge.Stiffness = iStiffness; if (edge.SecondTriangleIndex >= 0) { edge.RestAngle = Utils.AngleBetweenTwoTriangles( iSpringMesh.Vertices[edge.FirstVertexIndex].Position, iSpringMesh.Vertices[edge.SecondVertexIndex].Position, iSpringMesh.Vertices[edge.FirstAdjacentVertexIndex].Position, iSpringMesh.Vertices[edge.SecondAdjacentVertexIndex].Position ); } edge.BendingStiffness = iBendingStiffness; } for (int i = 0; i < oSpringMesh.Vertices.Count; i++) { for (int j = 0; j < iCircles.Count; j++) { if (Utils.Distance(iCircles[j].Center, oSpringMesh.Vertices[i].Position) <= iCircles[j].Radius) { foreach (Edge edge in oSpringMesh.Edges) { if (edge.FirstVertexIndex == i || edge.SecondVertexIndex == i) { edge.Stiffness = iPlanarRegionStiffness[j]; edge.RestAngle = Math.PI; edge.BendingStiffness = iPlanarRegionBendingStiffness[j]; } } break; } } } DA.SetData(0, oSpringMesh); }
protected override void SolveInstance(IGH_DataAccess DA) { SpringMesh iSpringMesh = new SpringMesh(); List<Circle> iCircles = new List<Circle>(); double iBendingStiffness = double.NaN; double iStiffness = double.NaN; List<double> iPlanarRegionBendingStiffness = new List<double>(); List<double> iPlanarRegionStiffness = new List<double>(); DA.GetData<SpringMesh>(0, ref iSpringMesh); DA.GetDataList<Circle>(1, iCircles); DA.GetData<double>(2, ref iBendingStiffness); DA.GetData<double>(3, ref iStiffness); DA.GetDataList<double>(4, iPlanarRegionBendingStiffness); DA.GetDataList<double>(5, iPlanarRegionStiffness); SpringMesh oSpringMesh = new SpringMesh(iSpringMesh); foreach (Edge edge in iSpringMesh.Edges) { edge.RestLength = Utils.Distance(oSpringMesh.Vertices[edge.FirstVertexIndex].Position, oSpringMesh.Vertices[edge.SecondVertexIndex].Position); edge.Stiffness = iStiffness; if (edge.SecondTriangleIndex >= 0) { edge.RestAngle = Utils.AngleBetweenTwoTriangles( iSpringMesh.Vertices[edge.FirstVertexIndex].Position, iSpringMesh.Vertices[edge.SecondVertexIndex].Position, iSpringMesh.Vertices[edge.FirstAdjacentVertexIndex].Position, iSpringMesh.Vertices[edge.SecondAdjacentVertexIndex].Position ); } edge.BendingStiffness = iBendingStiffness; } for (int i = 0; i < oSpringMesh.Vertices.Count; i++) for (int j = 0; j < iCircles.Count; j++ ) if (Utils.Distance(iCircles[j].Center, oSpringMesh.Vertices[i].Position) <= iCircles[j].Radius) { foreach (Edge edge in oSpringMesh.Edges) if (edge.FirstVertexIndex == i || edge.SecondVertexIndex == i) { edge.Stiffness = iPlanarRegionStiffness[j]; edge.RestAngle = Math.PI; edge.BendingStiffness = iPlanarRegionBendingStiffness[j]; } break; } DA.SetData(0, oSpringMesh); }
protected override void BeforeSolveInstance() { // input iID = new List<int>(); iAttrThicknessPts = new List<Point3d>(); iClosedPanelPts = new List<Point3d>(); // output oInfo = string.Empty; oDebugList = new List<Curve>(); oSMeshLine = new List<Curve>(); oSpringMesh = new SpringMesh(); oPolyLine = new List<Curve>(); oVertexStatus = new List<bool>(); // true is plate occupied, false should put triLoop oPolyLineID = new List<int>(); // for vertex status access the order of polyline othickness = new List<double>(); oVertexPanel2 = new List<bool>(); // internal use data }
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); }
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 List<Line> SubdivideThreeLines(SpringMesh sMesh, double factor) { List<Line> allLines = new List<Line>(); foreach (Edge edge in sMesh.Edges) { if (edge.SecondTriangleIndex >= 0) { int triangle1 = edge.FirstTriangleIndex; int triangle2 = edge.SecondTriangleIndex; //Point3d centreTri1 = sMesh.ComputeTriangleCenter(triangle1); //Point3d centreTri2 = sMesh.ComputeTriangleCenter(triangle2); Point3d centreTri1 = sMesh.ComputeCircumscribedCircleCenter(triangle1); Point3d centreTri2 = sMesh.ComputeCircumscribedCircleCenter(triangle2); List<Point3d> pointOnTri1 = sMesh.ComputeTriangleThreePts(triangle1, factor); List<Point3d> pointOnTri2 = sMesh.ComputeTriangleThreePts(triangle2, factor); foreach (Point3d IntPtr in pointOnTri1) allLines.Add(new Line(centreTri1, IntPtr)); foreach (Point3d IntPtr in pointOnTri2) allLines.Add(new Line(centreTri2, IntPtr)); } } return allLines; }
public 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 centreLeft = sMesh.ComputeTriangleCenter(triLeft); //Point3d centreRight = sMesh.ComputeTriangleCenter(triRight); Point3d centreLeft = sMesh.ComputeCircumscribedCircleCenter(triLeft); Point3d centreRight = sMesh.ComputeCircumscribedCircleCenter(triRight); 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; }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { sMesh = null; DA.GetData<SpringMesh>(0, ref sMesh); factor = 0; DA.GetData<double>(1, ref factor); thickness = 0; DA.GetData<double>(2, ref thickness); List<Line> lines = SubdivideThreeLines(sMesh, factor); DA.SetDataList(0, lines); List<Curve> curveRight = new List<Curve>(); List<Curve> curveLeft = new List<Curve>(); vertexFactors = ComputeVertexFactor(sMesh); CalculateSurface(sMesh, thickness, curveRight, curveLeft); DA.SetDataList(1, curveRight); DA.SetDataList(2, curveLeft); List<Line> linesUp = new List<Line>(); List<Line> linesDown = new List<Line>(); List<double> planarity = checkCoplanarity(sMesh, thickness, linesUp, linesDown); DA.SetDataList(3, planarity); DA.SetDataList(4, linesUp); DA.SetDataList(5, linesDown); }
public List<double> ComputeVertexFactor(SpringMesh sMesh) { List<double> vertexFactors = new List<double>(); for (int i = 0; i < sMesh.Vertices.Count; i++) { vertexFactors.Add(0.5); } return vertexFactors; }
protected override void SolveInstance(IGH_DataAccess DA) { // ================================================================================== // Reset // ================================================================================== DA.GetData<bool>("Reset", ref iReset); if (iReset) { iteration = 0; DA.GetData<SpringMesh>("Spring Mesh", ref iSpringMesh); oSpringMesh = new SpringMesh(iSpringMesh); DA.GetData<int>(1, ref iIntegrator); oSpringMesh.Integrator = iIntegrator; goto Conclusion; } DA.GetData<bool>("Play", ref iPlay); if (!iPlay) goto Conclusion; if ((iIterationCount != 0) && (iteration >= iIterationCount)) goto Conclusion; iteration++; // ================================================================================== // Update the mesh // ================================================================================== DA.GetData<double>("Damping", ref iDamping); oSpringMesh.Damping = iDamping; DA.GetData<double>("Time Step", ref iTimeStep); oSpringMesh.DeltaT = iTimeStep; DA.GetData<double>("Gravity Scale", ref iGravityScale); oSpringMesh.GravityScale = iGravityScale; DA.GetData<double>("Rest Length Scale", ref iRestLengthScale); oSpringMesh.RestLengthScale = iRestLengthScale; DA.GetData<double>("Rest Length Offset", ref iRestLengthOffset); oSpringMesh.RestLengthOffset = iRestLengthOffset; DA.GetData<double>("Stiffness Offset", ref iStiffnessOffset); oSpringMesh.Stiffness = iStiffnessOffset; DA.GetData<double>("Bending Stiffness Offset", ref iBendingStiffness); oSpringMesh.BendingStiffness = iBendingStiffness; DA.GetData<bool>("Enable Boundary Bending Stiffness", ref iEnableBendingStiffnessOffset); oSpringMesh.EnableBoundaryBendingStiffness = iEnableBendingStiffnessOffset; DA.GetData<double>("Boundary Bending Stiffness", ref iBoundaryBendingStiffness); oSpringMesh.BoundaryBendingStiffness = iBoundaryBendingStiffness; DA.GetData<bool>("Enable Column Bending Stiffness", ref iEnableColumnStiffnessOffset); oSpringMesh.EnableColumnBendingStiffness = iEnableColumnStiffnessOffset; DA.GetData<double>("Column Bending Stiffness", ref iColumnBendingStiffness); oSpringMesh.ColumnnBendingStiffness = iColumnBendingStiffness; // Added by Gene ================================================================ DA.GetData<int>("Enable Equilateral Triangle", ref iEnableEquilateralTriangle); oSpringMesh.EnableEquilateralTriangle = iEnableEquilateralTriangle; DA.GetData<double>("Equilateral Strength", ref iEquilateralStrength); oSpringMesh.EquilateralStrength = iEquilateralStrength; // ================================================================================ oSpringMesh.Update(); // ================================================================================== // Conclusion // ================================================================================== Conclusion: DA.GetData<int>("Iteration Count", ref iIterationCount); if (iPlay && (iteration < iIterationCount || iIterationCount == 0)) ExpireSolution(true); oInfo += "Iteration: " + iteration.ToString(); 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.SetDataList(2, new List<Mesh> { oSpringMesh.ConvertToRhinoMesh() }); DA.SetData(6, oSpringMesh); }
protected override void BeforeSolveInstance() { // input iSpringMesh = new SpringMesh(); iPolyLine = new List<Curve>(); iVertexStatus = new List<bool>(); // true is plate occupied, false should put triLoop iPolyLineID = new List<int>(); // for vertex status access the order of polyline iThickness = new List<double>(); iAttractors = new List<Point3d>(); iVertexPanel2 = new List<bool>(); //ManualValueTree = new GH_Structure<GH_Number>(); // output oInfo = string.Empty; oDebugList = new List<Vector3d>(); oTriLoop = new DataTree<Brep>(); oTriLoopID = new DataTree<string>(); oTriLoopCurves = new DataTree<Curve>(); oDualLoop1 = new DataTree<Brep>(); oDualLoop2 = new DataTree<Brep>(); oDualLoop1ID = new DataTree<string>(); oDualLoop2ID = new DataTree<string>(); oDualLoop1Curves = new DataTree<Curve>(); oDualLoop2Curves = new DataTree<Curve>(); oClosedPanel = new DataTree<Brep>(); oTriLoopPlanCrv = new DataTree<Curve>(); oTriLoopEffectorHoles = new DataTree<Point3d>(); // internal use data topCenterPts = new List<Point3d>(); bottomCenterPts = new List<Point3d>(); topCenterPolygonOccupied = new List<bool>(); // not be used at this moment bottomCps = new List<Point3d>(); topCps = new List<Point3d>(); indexSortPolygon = new List<int[]>(); // array is reference type in csharp verticesValues = new List<double>(); curveVerticesValues = new List<double>(); planarVerticesValues = new List<double>(); openingWidthVerticesValues = new List<double>(); pointinessValues = new List<double>(); ManualAdjustedVertexIndexies = new List<int>(); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh iRhinoMesh = null; DA.GetData<Mesh>(0, ref iRhinoMesh); SpringMesh oSpringMesh = new SpringMesh(); bool [] naked = iRhinoMesh.GetNakedEdgePointStatus(); for (int i = 0; i < iRhinoMesh.Vertices.Count; i++) { Point3d vertex = iRhinoMesh.Vertices[i]; oSpringMesh.Vertices.Add(new Vertex(vertex, Vector3d.Zero, new List<int>())); // boundary and fixed condition if (naked[i] == true) { oSpringMesh.Vertices[i].IsBoundaryVertex = true; oSpringMesh.Vertices[i].IsFixed = true; } // vertex neighbours int topoIndex = iRhinoMesh.TopologyVertices.TopologyVertexIndex(i); int[] connectIndex = iRhinoMesh.TopologyVertices.ConnectedTopologyVertices(topoIndex); for (int j = 0; j < connectIndex.Length; j++) oSpringMesh.Vertices[i].NeighborVertexIndices.Add(iRhinoMesh.TopologyVertices.MeshVertexIndices(connectIndex[j])[0]); } foreach (MeshFace face in iRhinoMesh.Faces) oSpringMesh.Triangles.Add(new Triangle(face.A, face.B, face.C)); for (int i = 0; i < iRhinoMesh.TopologyEdges.Count; i++) { IndexPair indexPair = iRhinoMesh.TopologyEdges.GetTopologyVertices(i); // should convert TopologyVertices to mesh vertices first int firstIndex = iRhinoMesh.TopologyVertices.MeshVertexIndices(indexPair.I)[0]; int secondIndex = iRhinoMesh.TopologyVertices.MeshVertexIndices(indexPair.J)[0]; double len = iRhinoMesh.TopologyEdges.EdgeLine(i).Length; oSpringMesh.Edges.Add(new Edge(firstIndex, secondIndex, len, 1.0, Math.PI * 0.8, 0.0)); // edge vertex oSpringMesh.Edges[i].FirstVertexIndex = firstIndex; oSpringMesh.Edges[i].SecondVertexIndex = secondIndex; } for (int i = 0; i < iRhinoMesh.TopologyEdges.Count; i++) { // connected faces int[] connectedFacesIndex = iRhinoMesh.TopologyEdges.GetConnectedFaces(i); int firstTriIndex = -1; int secondTriIndex = -1; IndexPair indexPair = iRhinoMesh.TopologyEdges.GetTopologyVertices(i); int firstIndex = iRhinoMesh.TopologyVertices.MeshVertexIndices(indexPair.I)[0]; int secondIndex = iRhinoMesh.TopologyVertices.MeshVertexIndices(indexPair.J)[0]; if (connectedFacesIndex.Length == 2) { firstTriIndex = connectedFacesIndex[0]; oSpringMesh.Edges[i].FirstTriangleIndex = firstTriIndex; secondTriIndex = connectedFacesIndex[1]; oSpringMesh.Edges[i].SecondTriangleIndex = secondTriIndex; int triangleAdj01 = 0; int triangleAdj02 = 0; int vertex01 = oSpringMesh.Triangles[firstTriIndex].FirstVertexIndex; int vertex02 = oSpringMesh.Triangles[firstTriIndex].SecondVertexIndex; int vertex03 = oSpringMesh.Triangles[firstTriIndex].ThirdVertexIndex; int vertex11 = oSpringMesh.Triangles[secondTriIndex].FirstVertexIndex; int vertex12 = oSpringMesh.Triangles[secondTriIndex].SecondVertexIndex; int vertex13 = oSpringMesh.Triangles[secondTriIndex].ThirdVertexIndex; int[] triangleVertexList01 = {vertex01, vertex02, vertex03}; int[] triangleVertexList02 = {vertex11, vertex12, vertex13}; for (int j = 0; j < triangleVertexList01.Length; j++) if (triangleVertexList01[j] != firstIndex && triangleVertexList01[j] != secondIndex) triangleAdj01 = triangleVertexList01[j]; for (int j = 0; j < triangleVertexList02.Length; j++) if (triangleVertexList02[j] != firstIndex && triangleVertexList02[j] != secondIndex) triangleAdj02 = triangleVertexList02[j]; oSpringMesh.Edges[i].FirstAdjacentVertexIndex = triangleAdj01; oSpringMesh.Edges[i].SecondAdjacentVertexIndex = triangleAdj02; oSpringMesh.Edges[i].IsBoundaryEdge = false; } if (connectedFacesIndex.Length == 1) { firstTriIndex = connectedFacesIndex[0]; oSpringMesh.Edges[i].FirstTriangleIndex = firstTriIndex; int triangleAdj01 = 0; int vertex01 = oSpringMesh.Triangles[firstTriIndex].FirstVertexIndex; int vertex02 = oSpringMesh.Triangles[firstTriIndex].SecondVertexIndex; int vertex03 = oSpringMesh.Triangles[firstTriIndex].ThirdVertexIndex; int[] triangleVertexList01 = { vertex01, vertex02, vertex03 }; for (int j = 0; j < triangleVertexList01.Length; j++) if (triangleVertexList01[j] != firstIndex && triangleVertexList01[j] != secondTriIndex) triangleAdj01 = triangleVertexList01[j]; oSpringMesh.Edges[i].FirstAdjacentVertexIndex = triangleAdj01; oSpringMesh.Edges[i].IsBoundaryEdge = true; } } DA.SetData(1, oSpringMesh); List<LineCurve> oDebugCurves = new List<LineCurve>(); foreach (Edge edge in oSpringMesh.Edges) oDebugCurves.Add(new LineCurve(oSpringMesh.Vertices[edge.FirstVertexIndex].Position, oSpringMesh.Vertices[edge.SecondVertexIndex].Position)); DA.SetDataList(0, oDebugCurves); }