public ExoStrut(bool IsEnd, double SetRadius, double SetHullRadius, LineCurve SetStrut, Plane SetPlane) { Radius = SetRadius; HullRadius = SetHullRadius; Strut = SetStrut; Strut.PerpendicularFrameAt(0.0, out HullPlane); Normal = Normal; if (IsEnd) { Strut.Reverse(); HullPlane.Origin = Strut.PointAtStart; Normal *= -1; } FixPlane = HullPlane; }
public static void Main() { List <Curve> L = new List <Curve>(); int S = 0; List <double> Rs = new List <double>(); List <double> Re = new List <double>(); double D = 0; double ND = 0; int RP = 0; bool O = false; double Sides = (double)S; double Tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; List <ExoNode> ExoNodes = new List <ExoNode>(); List <ExoStrut> ExoStruts = new List <ExoStrut>(); //ExoNodes.Add(new ExoNode()); Rhino.Collections.Point3dList NodeLookup = new Rhino.Collections.Point3dList(); int IdxL = 0; ExoNodes.Add(new ExoNode(L[0].PointAtStart)); NodeLookup.Add(ExoNodes[0].Point3d); //cycle through each input curve to find unique nodes and assign struts to each node foreach (Curve StartL in L) { //strut as linecurve, and LineCurve StartLC = new LineCurve(StartL.PointAtStart, StartL.PointAtEnd); Plane StartPlane; StartLC.PerpendicularFrameAt(0, out StartPlane); //create paired struts for each input curve for (int I = 0; I <= 1; I++) { Point3d TestPoint; double StrutRadius; bool IsEnd; //set variables based on whether the strut is the start or end strut if (I == 0) { IsEnd = false; TestPoint = StartL.PointAtStart; if (Rs.Count - 1 > IdxL) { StrutRadius = Rs[IdxL]; } else { StrutRadius = Rs.Last(); } } else { IsEnd = true; TestPoint = StartL.PointAtEnd; if (Re.Count - 1 > IdxL) { StrutRadius = Re[IdxL]; } else { StrutRadius = Re.Last(); } } //register new nodes int TestIndex = NodeLookup.ClosestIndex(TestPoint); int NodeIndex = -1; if (ExoNodes[TestIndex].Point3d.DistanceTo(TestPoint) < Tol) { NodeIndex = TestIndex; ExoNodes[TestIndex].StrutIndices.Add(ExoStruts.Count); } else { NodeIndex = ExoNodes.Count; ExoNodes.Add(new ExoNode(TestPoint)); ExoNodes.Last().StrutIndices.Add(ExoStruts.Count); } int LastStrut = ExoNodes[NodeIndex].StrutIndices.Last(); //register new struts ExoStruts.Add(new ExoStrut(IsEnd, StrutRadius, StrutRadius / Math.Cos(Math.PI / Sides), StartLC, StartPlane)); //test each new strut in a given node against all of the other struts in a given node to calculate both local //and global vertex offsets, both for hulling operation and for relocating vertices post-hull if (ExoNodes[NodeIndex].StrutIndices.Count > 1) { foreach (int StrutIndex in ExoNodes[NodeIndex].StrutIndices) { if (StrutIndex != LastStrut) { double Radius = Math.Max(ExoStruts[LastStrut].HullRadius, ExoStruts[StrutIndex].HullRadius); double Theta = Vector3d.VectorAngle(ExoStruts[LastStrut].Normal, ExoStruts[StrutIndex].Normal); double TestOffset = Radius * Math.Cos(Theta * 0.5) / Math.Sin(Theta * 0.5); if (TestOffset > ExoNodes[NodeIndex].HullOffset) { ExoNodes[NodeIndex].HullOffset = TestOffset; } if (ExoNodes[NodeIndex].MaxRadius < Radius) { ExoNodes[NodeIndex].MaxRadius = Radius; } double Offset1 = 0; double Offset2 = 0; ExoTools.OffsetCalculator(Theta, ExoStruts[LastStrut].HullRadius, ExoStruts[StrutIndex].HullRadius, ref Offset1, ref Offset2); Offset1 = Math.Max(ND, Offset1); Offset2 = Math.Max(ND, Offset1); if (ExoStruts[LastStrut].FixOffset < Offset1) { ExoStruts[LastStrut].FixOffset = Offset1; } if (ExoStruts[StrutIndex].FixOffset < Offset1) { ExoStruts[StrutIndex].FixOffset = Offset2; } double KnuckleMinSet = Math.Min(ExoStruts[LastStrut].Radius, ExoStruts[StrutIndex].Radius); if (ExoNodes[NodeIndex].KnuckleMin <Tol || ExoNodes[NodeIndex].KnuckleMin> KnuckleMinSet) { ExoNodes[NodeIndex].KnuckleMin = KnuckleMinSet; } } } } } IdxL += 1; } foreach (ExoNode HullNode in ExoNodes) { if (HullNode.StrutIndices.Count == 2) { if (Vector3d.VectorAngle(ExoStruts[HullNode.StrutIndices[0]].Normal, ExoStruts[HullNode.StrutIndices[1]].Normal) - Math.PI < RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) { HullNode.HullOffset = HullNode.MaxRadius * 0.5; } } for (int HV = 0; HV < S; HV++) { foreach (int StrutIdx in HullNode.StrutIndices) { if (HV == 0) { ExoStruts[StrutIdx].HullPlane.Origin = ExoStruts[StrutIdx].HullPlane.Origin + (ExoStruts[StrutIdx].Normal * HullNode.HullOffset); HullNode.HullPoints.Add(HullNode.Point3d + (-ExoStruts[StrutIdx].Normal * (HullNode.HullOffset * 0.5))); HullNode.HullVertexStrut.Add(-1); } HullNode.HullPoints.Add(ExoStruts[StrutIdx].HullPlane.PointAt(Math.Cos((HV / Sides) * Math.PI * 2) * ExoStruts[StrutIdx].Radius, Math.Sin((HV / Sides) * Math.PI * 2) * ExoStruts[StrutIdx].Radius)); HullNode.HullVertexStrut.Add(StrutIdx); } } HullNode.HullVertexLookup.AddRange(HullNode.HullPoints); } }