private void RunScript( Plane P, double R, ref object V, ref object E, ref object F, ref object B) { double phi = (1.0 + Math.Sqrt(5.0)) / 2.0; double invPhi = 1.0 / phi; List localPts = new List(); // Create vertices for (int x = -1; x <= 1; x += 2) { for (int y = -1; y <= 1; y += 2) { for (int z = -1; z <= 1; z += 2) { localPts.Add(new Point3d(x, y, z)); } } } for (int y = -1; y <= 1; y += 2) { for (int z = -1; z <= 1; z += 2) { localPts.Add( new Point3d( 0, y * invPhi, z * phi ) ); } } for (int x = -1; x <= 1; x += 2) { for (int y = -1; y <= 1; y += 2) { localPts.Add( new Point3d( x * invPhi, y * phi, 0 ) ); } } for (int x = -1; x <= 1; x += 2) { for (int z = -1; z <= 1; z += 2) { localPts.Add( new Point3d( x * phi, 0, z * invPhi ) ); } } // Scale and orient to plane List pts = new List(); double scale = R / Math.Sqrt(3.0); foreach (Point3d pt in localPts) { Point3d worldPt = P.Origin + P.XAxis * (pt.X * scale) + P.YAxis * (pt.Y * scale) + P.ZAxis * (pt.Z * scale); pts.Add(worldPt); } // Create edges List edges = new List(); double edgeLength = 2.0 * invPhi * scale; double edgeTol = Math.Max(edgeLength * 0.001, 0.000001); for (int i = 0; i < pts.Count; i++) { for (int j = i + 1; j < pts.Count; j++) { double distance = pts[i].DistanceTo(pts[j]); if (Math.Abs(distance - edgeLength) < edgeTol) { edges.Add( new Line( pts[i], pts[j] ) ); } } } // Create faces List faces = new List(); HashSet usedFaces = new HashSet(); double planeTol = Math.Max(R * 0.0001, 0.000001); for (int i = 0; i < pts.Count - 2; i++) { for (int j = i + 1; j < pts.Count - 1; j++) { for (int k = j + 1; k < pts.Count; k++) { Vector3d v1 = pts[j] - pts[i]; Vector3d v2 = pts[k] - pts[i]; Vector3d cross = Vector3d.CrossProduct(v1, v2); if (cross.Length < planeTol) continue; Plane facePlane = new Plane( pts[i], pts[j], pts[k] ); if (!facePlane.IsValid) continue; List onPlane = new List(); bool positive = false; bool negative = false; for (int n = 0; n < pts.Count; n++) { double d = facePlane.DistanceTo(pts[n]); if (Math.Abs(d) < planeTol) { onPlane.Add(n); } else if (d > 0) { positive = true; } else { negative = true; } } if (onPlane.Count != 5) continue; if (positive && negative) continue; List sortedIDs = new List(onPlane); sortedIDs.Sort(); string key = string.Join("-", sortedIDs); if (usedFaces.Contains(key)) continue; usedFaces.Add(key); double cx = 0; double cy = 0; double cz = 0; foreach (int id in onPlane) { cx += pts[id].X; cy += pts[id].Y; cz += pts[id].Z; } Point3d center = new Point3d( cx / 5.0, cy / 5.0, cz / 5.0 ); Vector3d normal = facePlane.Normal; normal.Unitize(); Vector3d xAxis = pts[onPlane[0]] - center; xAxis.Unitize(); Vector3d yAxis = Vector3d.CrossProduct( normal, xAxis ); yAxis.Unitize(); List> ordered = new List>(); foreach (int id in onPlane) { Vector3d vec = pts[id] - center; double x = Vector3d.Multiply( vec, xAxis ); double y = Vector3d.Multiply( vec, yAxis ); double angle = Math.Atan2(y, x); ordered.Add( new Tuple( angle, pts[id] ) ); } ordered.Sort( delegate( Tuple a, Tuple b) { return a.Item1.CompareTo(b.Item1); } ); Polyline face = new Polyline(); foreach ( Tuple item in ordered) { face.Add(item.Item2); } face.Add(ordered[0].Item2); faces.Add(face); } } } // Create planar Brep for each pentagonal face List faceBreps = new List(); foreach (Polyline face in faces) { PolylineCurve crv = new PolylineCurve(face); Brep[] planarBreps = Brep.CreatePlanarBreps( crv, planeTol ); if (planarBreps != null) { foreach (Brep brep in planarBreps) { faceBreps.Add(brep); } } } // Join all faces into one closed Brep Brep finalBrep = null; Brep[] joinedBreps = Brep.JoinBreps( faceBreps, planeTol ); if (joinedBreps != null && joinedBreps.Length > 0) { finalBrep = joinedBreps[0]; } V = pts; E = edges; F = faces; B = finalBrep; }