/// <summary> /// Join a glulam onto another one. Returns null if join is not possible. /// </summary> /// <param name="glulam"></param> /// <returns></returns> public Glulam Join(Glulam glulam) { Rhino.Geometry.Intersect.CurveIntersections ci; ci = Rhino.Geometry.Intersect.Intersection.CurveCurve(Centreline, glulam.Centreline, Tolerance, OverlapTolerance); if (ci.Count != 1) { return(null); } if (ci[0].IsOverlap) { return(null); } if (Math.Abs(Centreline.TangentAt(ci[0].ParameterA) * glulam.Centreline.TangentAt(ci[0].ParameterB)) < AngleTolerance) { return(null); } Curve[] NewCentreline = Curve.JoinCurves(new Curve[] { Centreline, glulam.Centreline }); if (NewCentreline.Length != 1) { return(null); } GlulamOrientation NewOrientation = Orientation.Duplicate(); NewOrientation.Join(glulam.Orientation); Glulam new_glulam = CreateGlulam(NewCentreline[0], NewOrientation, Data.Duplicate()); new_glulam.Data.Samples = Data.Samples + glulam.Data.Samples; return(new_glulam); }
public ArchivableDictionary GetArchivableDictionary() { ArchivableDictionary ad = new ArchivableDictionary(); ad.Set("id", ID); ad.Set("centreline", Centreline); ad.Set("width", Width); ad.Set("height", Height); ad.Set("length", Centreline.GetLength()); ad.Set("lamella_width", Data.LamWidth); ad.Set("lamella_height", Data.LamHeight); ad.Set("lamella_count_width", Data.NumWidth); ad.Set("lamella_count_height", Data.NumHeight); ad.Set("volume", GetVolume()); ad.Set("samples", Data.Samples); //var planes = GetAllPlanes(); //ArchivableDictionary pd = new ArchivableDictionary(); //for (int i = 0; i < planes.Length; ++i) //{ // pd.Set(string.Format("Frame_{0}", i), planes[i]); //} //ad.Set("frames", pd); double max_kw = 0.0, max_kh = 0.0; ad.Set("max_curvature", GetMaxCurvature(ref max_kw, ref max_kh)); ad.Set("max_curvature_width", max_kw); ad.Set("max_curvature_height", max_kh); ad.Set("type", ToString()); ad.Set("type_id", (int)Type()); return(ad); }
/// <summary> /// Checks the glulam to see if its lamella sizes are appropriate for its curvature. /// </summary> /// <param name="param">Parameter with maximum curvature.</param> /// <returns>True if glulam is within curvature limits.</returns> public bool InKLimits(out double param) { double[] t = Centreline.DivideByCount(CurvatureSamples, false); double max_k = 0.0; int index = 0; double temp; for (int i = 0; i < t.Length; ++i) { temp = Centreline.CurvatureAt(t[i]).Length; if (temp > max_k) { max_k = temp; index = i; } } param = t[index]; double ratio = (1 / max_k) / RadiusMultiplier; if (Math.Abs(ratio - Data.LamHeight) > RadiusTolerance || Math.Abs(ratio - Data.LamWidth) > RadiusTolerance) { return(false); } return(true); }
public override void CalculateLamellaSizes(double width, double height) { Plane cPlane; Centreline.TryGetPlane(out cPlane); var normal = cPlane.ZAxis; var tt = Centreline.DivideByCount(Data.Samples, true); double k = 0.0; Vector3d kVec; for (int i = 0; i < tt.Length; ++i) { kVec = Centreline.CurvatureAt(tt[i]); k = Math.Max(k, kVec.Length); } double lh = Math.Floor((1 / Math.Abs(k)) * Glulam.RadiusMultiplier); Data.LamWidth = width; int num_height = (int)Math.Ceiling(height / lh); Data.LamHeight = height / Data.LamHeight; if (num_height < 2) { num_height = 2; Data.LamHeight /= 2; } Data.Lamellae.ResizeArray(Data.NumWidth, num_height); }
public override bool InKLimitsComponent(out bool width, out bool height) { width = height = false; double[] t = Centreline.DivideByCount(CurvatureSamples, false); double max_kw = 0.0, max_kh = 0.0; Plane temp; Vector3d k; for (int i = 0; i < t.Length; ++i) { temp = GetPlane(t[i]); k = Centreline.CurvatureAt(t[i]); max_kw = Math.Max(max_kw, Math.Abs(k * temp.XAxis)); max_kh = Math.Max(max_kh, Math.Abs(k * temp.YAxis)); } double rw = (1 / max_kw) / RadiusMultiplier; double rh = (1 / max_kh) / RadiusMultiplier; if (rw - Data.LamWidth > -RadiusTolerance || double.IsInfinity(1 / max_kw)) { width = true; } if (rh - Data.LamHeight > -RadiusTolerance || double.IsInfinity(1 / max_kh)) { height = true; } return(width && height); }
public override Mesh MapToCurveSpace(Mesh m) { Plane cp, cpp = Plane.Unset; if (!Centreline.TryGetPlane(out cp, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance)) { throw new Exception("SingleCurvedGlulam: Centreline is not planar!"); } double t, l; Mesh mesh = new Mesh(); for (int i = 0; i < m.Vertices.Count; ++i) { Point3d p = new Point3d(m.Vertices[i]); Centreline.ClosestPoint(p, out t); l = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); //Vector3d xaxis = Vector3d.CrossProduct(cp.ZAxis, Centreline.TangentAt(t)); //cpp = new Plane(Centreline.PointAt(t), xaxis, cp.ZAxis); cpp = GetPlane(t); p.Transform(Rhino.Geometry.Transform.PlaneToPlane(cpp, Plane.WorldXY)); p.Z = l; mesh.Vertices.Add(p); } mesh.Faces.AddFaces(m.Faces); mesh.FaceNormals.ComputeFaceNormals(); return(mesh); }
public override List <Curve> GetLamellaCurves() { List <Curve> lam_crvs = new List <Curve>(); double hWidth = Data.NumWidth * Data.LamWidth / 2; double hHeight = Data.NumHeight * Data.LamHeight / 2; Plane plane = Misc.PlaneFromNormalAndYAxis( Centreline.PointAtStart, Centreline.TangentAtStart, Orientation.GetOrientation(Centreline, Centreline.Domain.Min)); double hLw = Data.LamWidth / 2; double hLh = Data.LamHeight / 2; Transform xform = Rhino.Geometry.Transform.PlaneToPlane(Plane.WorldXY, plane); for (int i = 0; i < Data.NumHeight; ++i) { for (int j = 0; j < Data.NumWidth; ++j) { Point3d p = new Point3d(j * Data.LamWidth - hWidth + hLw, i * Data.LamHeight - hHeight + hLh, 0.0); Line l = new Line(p, Vector3d.ZAxis * Centreline.GetLength()); l.Transform(xform); lam_crvs.Add(l.ToNurbsCurve()); } } return(lam_crvs); }
public Dictionary <string, object> GetProperties() { Dictionary <string, object> props = new Dictionary <string, object>(); props.Add("id", ID); props.Add("centreline", Centreline); props.Add("width", Width); props.Add("height", Height); props.Add("length", Centreline.GetLength()); props.Add("lamella_width", Data.LamWidth); props.Add("lamella_height", Data.LamHeight); props.Add("lamella_count_width", Data.NumWidth); props.Add("lamella_count_height", Data.NumHeight); props.Add("volume", GetVolume()); props.Add("samples", Data.Samples); //props.Add("frames", GetAllPlanes()); double max_kw = 0.0, max_kh = 0.0; props.Add("max_curvature", GetMaxCurvature(ref max_kw, ref max_kh)); props.Add("max_curvature_width", max_kw); props.Add("max_curvature_height", max_kh); props.Add("type", ToString()); props.Add("type_id", (int)Type()); props.Add("orientation", Orientation); return(props); }
public Curve CreateOffsetCurve(double x, double y, int samples = 100, bool rebuild = false, int rebuild_pts = 20) { List <Point3d> pts = new List <Point3d>(); double[] t = Centreline.DivideByCount(samples, true); for (int i = 0; i < t.Length; ++i) { Plane p = GetPlane(t[i]); pts.Add(p.Origin + p.XAxis * x + p.YAxis * y); } Curve new_curve = Curve.CreateInterpolatedCurve(pts, 3, CurveKnotStyle.Uniform, Centreline.TangentAtStart, Centreline.TangentAtEnd); double len = new_curve.GetLength(); new_curve.Domain = new Interval(0.0, len); if (rebuild) { new_curve = new_curve.Rebuild(rebuild_pts, new_curve.Degree, true); } return(new_curve); }
public bool Extend(CurveEnd end, double length) { Curve c = Centreline.Extend(end, length, CurveExtensionStyle.Smooth); Centreline = c; return(true); }
public virtual double GetVolume(bool accurate = false) { if (accurate) { Rhino.Geometry.VolumeMassProperties vmp = VolumeMassProperties.Compute(GetBoundingBrep()); return(vmp.Volume); } return(Centreline.GetLength() * Width * Height); }
/// <summary> /// Reverse direction of glulam. /// </summary> public void Reverse() { Curve Reversed = Centreline.DuplicateCurve(); Reversed.Reverse(); Orientation.Remap(Centreline, Reversed); Centreline = Reversed; }
public Plane ToBeamSpace(Plane plane) { Centreline.ClosestPoint(plane.Origin, out double t); Plane m_plane = GetPlane(t); plane.Transform(Rhino.Geometry.Transform.PlaneToPlane(m_plane, Plane.WorldXY)); plane.OriginZ = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); return(plane); }
public Point3d MapToGlulamSpace(Point3d pt) { Centreline.ClosestPoint(pt, out double t); Plane m_plane = GetPlane(t); pt.Transform(Rhino.Geometry.Transform.PlaneToPlane(m_plane, Plane.WorldXY)); pt.Z = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); return(pt); }
public override Curve CreateOffsetCurve(double x, double y, bool rebuild = false, int rebuild_pts = 20) { Vector3d v = Orientation.GetOrientation(Centreline, Centreline.Domain.Min); Plane p = tas.Core.Util.Misc.PlaneFromNormalAndYAxis(Centreline.PointAtStart, Centreline.TangentAtStart, v); Curve copy = Centreline.DuplicateCurve(); copy.Transform(Rhino.Geometry.Transform.Translation(p.XAxis * x + p.YAxis * y)); return(copy); }
public List <Point3d> DiscretizeCentreline(bool adaptive = true) { if (adaptive) { var pCurve = Centreline.ToPolyline(Glulam.Tolerance, Glulam.AngleTolerance, 0.0, 0.0); return(pCurve.ToPolyline().ToList()); } var tt = Centreline.DivideByCount(Data.Samples, true); return(tt.Select(x => Centreline.PointAt(x)).ToList()); }
public bool Extend(CurveEnd end, double length, CurveExtensionStyle style = CurveExtensionStyle.Smooth) { Curve c = Centreline.Extend(end, length, style); if (c == null) { return(false); } Centreline = c; return(true); }
public override Mesh MapToCurveSpace(Mesh m) { Plane cp; double t, l; Mesh mesh = new Mesh(); List <Point3d> verts = new List <Point3d>(m.Vertices.Count); object m_lock = new object(); Parallel.For(0, m.Vertices.Count, i => //for (int i = 0; i < m.Vertices.Count; ++i) { Point3d temp1, temp2; temp1 = m.Vertices[i]; Centreline.ClosestPoint(temp1, out t); l = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); cp = GetPlane(t); //Centreline.PerpendicularFrameAt(t, out cp); //p.Transform(Rhino.Geometry.Transform.PlaneToPlane(cp, Plane.WorldXY)); cp.RemapToPlaneSpace(temp1, out temp2); temp2.Z = l; //lock(m_lock) //{ verts[i] = temp2; //} //} }); /* * for (int i = 0; i < m.Vertices.Count; ++i) * { * Point3d p = new Point3d(m.Vertices[i]); * Centreline.ClosestPoint(p, out t); * l = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); * cp = GetPlane(t); * //Centreline.PerpendicularFrameAt(t, out cp); * p.Transform(Rhino.Geometry.Transform.PlaneToPlane(cp, Plane.WorldXY)); * p.Z = l; * * } */ mesh.Vertices.AddVertices(verts); mesh.Faces.AddFaces(m.Faces); mesh.FaceNormals.ComputeFaceNormals(); return(mesh); }
public override List <Brep> GetLamellaBreps() { double Length = Centreline.GetLength(); double hW = Data.NumWidth * Data.LamWidth / 2; double hH = Data.NumHeight * Data.LamHeight / 2; double[] DivParams = new double[] { Centreline.Domain.Min, Centreline.Domain.Max }; List <Curve>[,] LoftCurves = new List <Curve> [Data.NumWidth, Data.NumHeight]; List <Brep> LamellaBreps = new List <Brep>(); // Initialize curve lists for (int i = 0; i < Data.NumWidth; ++i) { for (int j = 0; j < Data.NumHeight; ++j) { LoftCurves[i, j] = new List <Curve>(); } } for (int i = 0; i < DivParams.Length; ++i) { Plane p = GetPlane(DivParams[i]); for (int j = 0; j < Data.NumWidth; ++j) { for (int k = 0; k < Data.NumHeight; ++k) { Rectangle3d rec = new Rectangle3d(p, new Interval(-hW + j * Data.LamWidth, -hW + (j + 1) * Data.LamWidth), new Interval(-hH + k * Data.LamHeight, -hH + (k + 1) * Data.LamHeight)); LoftCurves[j, k].Add(rec.ToNurbsCurve()); } } } for (int i = 0; i < Data.NumWidth; ++i) { for (int j = 0; j < Data.NumHeight; ++j) { Brep[] brep = Brep.CreateFromLoft(LoftCurves[i, j], Point3d.Unset, Point3d.Unset, LoftType.Normal, false); if (brep != null && brep.Length > 0) { LamellaBreps.Add(brep[0].CapPlanarHoles(Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance)); } } } return(LamellaBreps); }
// MAPPING METHODS public Point3d ToBeamSpace(Point3d pt) { Plane m_plane; Point3d m_temp; double t; Centreline.ClosestPoint(pt, out t); m_plane = GetPlane(t); m_plane.RemapToPlaneSpace(pt, out m_temp); if (t > Centreline.Domain.Max) { m_temp.Z = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); } return(m_temp); }
public override void CalculateLamellaSizes(double width, double height) { var tt = Centreline.DivideByCount(Data.Samples, true); Plane kPlane; Vector3d kVec; double maxKX = 0.0, maxKY = 0.0; double dotKX, dotKY; for (int i = 0; i < tt.Length; ++i) { kPlane = GetPlane(tt[i]); kVec = Centreline.CurvatureAt(tt[i]); dotKX = kVec * kPlane.XAxis; dotKY = kVec * kPlane.YAxis; maxKX = Math.Max(dotKX, maxKX); maxKY = Math.Max(dotKY, maxKY); } double lh = Math.Floor((1 / Math.Abs(maxKY)) * Glulam.RadiusMultiplier); double lw = Math.Floor((1 / Math.Abs(maxKX)) * Glulam.RadiusMultiplier); int num_height = (int)Math.Ceiling(height / lh); Data.LamHeight = height / num_height; int num_width = (int)Math.Ceiling(width / lw); Data.LamWidth = width / num_width; if (Data.NumHeight < 2) { num_height = 2; Data.LamHeight /= 2; } if (Data.NumWidth < 2) { num_width = 2; Data.LamWidth /= 2; } Data.Lamellae.ResizeArray(num_width, num_height); }
public override Curve CreateOffsetCurve(double x, double y, bool offset_start, bool offset_end, bool rebuild = false, int rebuild_pts = 20) { if (!offset_start && !offset_end) { return(Centreline.DuplicateCurve()); } if (offset_start && offset_end) { return(CreateOffsetCurve(x, y, rebuild, rebuild_pts)); } List <Point3d> pts = new List <Point3d>(); double[] t = Centreline.DivideByCount(this.Data.Samples, true); double tmin = offset_start ? t.First() : t.Last(); double tmax = offset_end ? t.Last() : t.First(); for (int i = 0; i < t.Length; ++i) { Plane p = GetPlane(t[i]); double l = Ease.QuadOut(Interpolation.Unlerp(tmin, tmax, t[i])); pts.Add(p.Origin + p.XAxis * l * x + p.YAxis * l * y); } Curve new_curve = Curve.CreateInterpolatedCurve(pts, 3, CurveKnotStyle.Uniform, Centreline.TangentAtStart, Centreline.TangentAtEnd); if (new_curve == null) { throw new Exception(this.ToString() + "::CreateOffsetCurve:: Failed to create interpolated curve!"); } double len = new_curve.GetLength(); new_curve.Domain = new Interval(0.0, len); if (rebuild) { new_curve = new_curve.Rebuild(rebuild_pts, new_curve.Degree, true); } return(new_curve); }
public Glulam Trim(Interval domain, double overlap) { double l1 = Centreline.GetLength(new Interval(Centreline.Domain.Min, domain.Min)); double l2 = Centreline.GetLength(new Interval(Centreline.Domain.Min, domain.Max)); double t1, t2; if (!Centreline.LengthParameter(l1 - overlap, out t1)) { t1 = domain.Min; } if (!Centreline.LengthParameter(l2 + overlap, out t2)) { t2 = domain.Max; } domain = new Interval( Math.Max(t1, Centreline.Domain.Min), Math.Min(t2, Centreline.Domain.Max)); double length = Centreline.GetLength(domain); if (domain.IsDecreasing || length < overlap || length < Glulam.OverlapTolerance) { return(null); } double percentage = length / Centreline.GetLength(); GlulamData data = Data.Duplicate(); data.Samples = Math.Max(6, (int)(data.Samples * percentage)); Curve trimmed_curve = Centreline.Trim(domain); GlulamOrientation trimmed_orientation = Orientation.Trim(domain); trimmed_orientation.Remap(Centreline, trimmed_curve); Glulam glulam = CreateGlulam(trimmed_curve, trimmed_orientation, data); return(glulam); }
public Point3d[] MapToGlulamSpace(IList <Point3d> pts) { Point3d[] m_output_pts = new Point3d[pts.Count]; Plane m_plane; Point3d m_temp; double t; for (int i = 0; i < pts.Count; ++i) { Centreline.ClosestPoint(pts[i], out t); m_plane = GetPlane(t); m_plane.RemapToPlaneSpace(pts[i], out m_temp); m_temp.Z = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); m_output_pts[i] = m_temp; } return(m_output_pts); }
public override Glulam Overbend(double t) { PolyCurve pc = Centreline.DuplicateCurve() as PolyCurve; if (pc == null) { return(this); } // fix this domain issue... not working for some reason PolyCurve pco = pc.OverBend(t); pco.Domain = pc.Domain; FreeformGlulam g = this.Duplicate() as FreeformGlulam; g.Centreline = pco; return(g); }
public override double GetMaxCurvature(ref double width, ref double height) { double[] t = Centreline.DivideByCount(CurvatureSamples, false); double max_kw = 0.0, max_kh = 0.0, max_k = 0.0; Plane temp; Vector3d k; for (int i = 0; i < t.Length; ++i) { temp = GetPlane(t[i]); k = Centreline.CurvatureAt(t[i]); max_kw = Math.Max(max_kw, Math.Abs(k * temp.XAxis)); max_kh = Math.Max(max_kh, Math.Abs(k * temp.YAxis)); max_k = Math.Max(max_k, k.Length); } width = max_kw; height = max_kh; return(max_k); }
public Brep ToBrep() { var tt = Centreline.DivideByLength((int)(Centreline.GetLength() / 50.0), true); var planes = GetPlanes(tt); var xsections = new List <Curve>(); foreach (Plane plane in planes) { var rec = new Rectangle3d(plane, new Interval(-Width * 0.5, Width * 0.5), new Interval(-Height * 0.5, Height * 0.5)).ToNurbsCurve(); xsections.Add(rec); } var loft = Brep.CreateFromLoft(xsections, Point3d.Unset, Point3d.Unset, LoftType.Normal, false); loft[0] = loft[0].CapPlanarHoles(0.01); loft[0].Flip(); return(loft[0]); }
public Plane[] MapToGlulamSpace(IList <Plane> planes) { Plane[] m_output_planes = new Plane[planes.Count]; Plane m_plane; Plane m_temp; double t; for (int i = 0; i < planes.Count; ++i) { Centreline.ClosestPoint(planes[i].Origin, out t); m_plane = GetPlane(t); m_temp = planes[i]; m_temp.Transform(Rhino.Geometry.Transform.PlaneToPlane(m_plane, Plane.WorldXY)); m_temp.OriginZ = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); m_output_planes[i] = m_temp; } return(m_output_planes); }
public override Curve GetLamellaCurve(int i, int j) { double hWidth = Data.NumWidth * Data.LamWidth / 2; double hHeight = Data.NumHeight * Data.LamHeight / 2; Plane plane = Utility.PlaneFromNormalAndYAxis( Centreline.PointAtStart, Centreline.TangentAtStart, Orientation.GetOrientation(Centreline, Centreline.Domain.Min)); double hLw = Data.LamWidth / 2; double hLh = Data.LamHeight / 2; Transform xform = Rhino.Geometry.Transform.PlaneToPlane(Plane.WorldXY, plane); Point3d p = new Point3d(j * Data.LamWidth - hWidth + hLw, i * Data.LamHeight - hHeight + hLh, 0.0); Line l = new Line(p, Vector3d.ZAxis * Centreline.GetLength()); l.Transform(xform); return(l.ToNurbsCurve()); }
public Plane[] GetPlanes(IList <Point3d> pts) { var tt = new double[pts.Count]; Parallel.For(0, pts.Count, i => { Centreline.ClosestPoint(pts[i], out tt[i]); }); var orientations = Orientation.GetOrientations(Centreline, tt); var planes = new Plane[tt.Length]; Parallel.For(0, tt.Length, i => { planes[i] = Utility.PlaneFromNormalAndYAxis( Centreline.PointAt(tt[i]), Centreline.TangentAt(tt[i]), orientations[i]); }); return(planes); }