Beispiel #1
0
        static public Glulam CreateGlulamFromBeamGeometry2(Curve curve, Mesh beam, out double true_width, out double true_height, out double true_length, double extra = 0.0)
        {
            Mesh mm = curve.MapToCurveSpace(beam);

            BoundingBox bb = mm.GetBoundingBox(true);

            double x = bb.Center.X;
            double y = bb.Center.Y;

            double tmin, tmax;

            curve.LengthParameter(bb.Min.Z, out tmin);
            curve.LengthParameter(bb.Max.Z, out tmax);

            Plane    twist = Plane.WorldXY;
            Polyline ch;

            mm = mm.FitToAxes(Plane.WorldXY, out ch, ref twist);

            bb = mm.GetBoundingBox(true);
            double dx = bb.Max.X - bb.Min.X;
            double dy = bb.Max.Y - bb.Min.Y;

            Plane cp;

            curve.PerpendicularFrameAt(tmin, out cp);


            double angle = Vector3d.VectorAngle(Vector3d.XAxis, twist.XAxis);
            int    sign  = Math.Sign(twist.YAxis * Vector3d.XAxis);


            Curve[] segments = curve.Split(new double[] { tmin, tmax });
            if (segments.Length == 3)
            {
                curve = segments[1];
            }
            else
            {
                curve = segments[0];
            }

            Beam b = new Beam(curve, null, new Plane[] { cp });

            //curve = b.CreateOffsetCurve(-x, -y);
            curve = b.CreateOffsetCurve(x, y);
            curve = curve.Extend(CurveEnd.Both, extra, CurveExtensionStyle.Smooth);

            cp.Transform(Rhino.Geometry.Transform.Rotation(angle * sign, cp.ZAxis, cp.Origin));

            GlulamData data = GlulamData.FromCurveLimits(curve, dx + extra * 2, dy + extra * 2, new Plane[] { cp });

            true_length = curve.GetLength();
            true_width  = dx + extra * 2;
            true_height = dy + extra * 2;

            return(Glulam.CreateGlulam(curve, new Plane[] { cp }, data));
        }
Beispiel #2
0
        /// <summary>
        /// Glulam factory methods.
        /// </summary>
        /// <param name="curve">Input curve.</param>
        /// <param name="planes">Input orientation planes.</param>
        /// <param name="data">Input glulam data.</param>
        /// <returns>New glulam.</returns>
        static public Glulam CreateGlulam(Curve curve, Plane[] planes = null, GlulamData data = null)
        {
            if (data == null)
            {
                data = GlulamData.FromCurveLimits(curve);
            }


            Glulam glulam;

            if (planes == null || planes.Length < 1)
            // if there are no planes defined, create defaults
            {
                Plane p;
                if (curve.IsLinear(Tolerance))
                {
                    curve.PerpendicularFrameAt(curve.Domain.Min, out p);
                    glulam = new StraightGlulam(curve, new Plane[] { p });
                }
                else if (curve.IsPlanar(Tolerance))
                {
                    curve.TryGetPlane(out p, Tolerance);
                    glulam = new SingleCurvedGlulam(curve, new Plane[]
                    {
                        new Plane(
                            curve.PointAtStart,
                            p.ZAxis,
                            Vector3d.CrossProduct(
                                curve.TangentAtStart, p.ZAxis
                                )
                            ),
                        new Plane(
                            curve.PointAtEnd,
                            p.ZAxis,
                            Vector3d.CrossProduct(
                                curve.TangentAtEnd, p.ZAxis
                                )
                            )
                    });
                }
                else
                {
                    Plane start, end;
                    curve.PerpendicularFrameAt(curve.Domain.Min, out start);
                    curve.PerpendicularFrameAt(curve.Domain.Max, out end);
                    glulam = new DoubleCurvedGlulam(curve, new Plane[] { start, end });
                }
            }
            else // if there are planes defined
            {
                if (curve.IsLinear(Tolerance))
                {
                    if (planes.Length == 1)
                    {
                        glulam = new StraightGlulam(curve, planes);
                    }
                    else
                    {
                        glulam = new StraightGlulam(curve, planes, true);
                        // glulam = new StraightGlulamWithTwist(curve, planes);
                        Console.WriteLine("Not implemented...");
                    }
                }
                else if (curve.IsPlanar(Tolerance))
                {
                    Plane crv_plane;
                    curve.TryGetPlane(out crv_plane);

                    /*
                     * Are all the planes perpendicular to the curve normal?
                     *    Yes: basic SC Glulam
                     * Are all the planes consistently aligned from the curve normal?
                     *    Yes: SC Glulam with rotated cross-section
                     * SC Glulam with twisting
                     */

                    bool HasTwist = false;

                    foreach (Plane p in planes)
                    {
                        if (Math.Abs(p.XAxis * crv_plane.ZAxis) > Tolerance)
                        {
                            HasTwist = true;
                        }
                    }
                    if (HasTwist)
                    {
                        glulam = new DoubleCurvedGlulam(curve, planes);
                    }
                    else
                    {
                        Plane first = new Plane(curve.PointAtStart, crv_plane.ZAxis, Vector3d.CrossProduct(curve.TangentAtStart, crv_plane.ZAxis));
                        Plane last  = new Plane(curve.PointAtEnd, crv_plane.ZAxis, Vector3d.CrossProduct(curve.TangentAtEnd, crv_plane.ZAxis));
                        glulam = new SingleCurvedGlulam(curve, new Plane[] { first, last });
                    }
                }
                else
                {
                    Plane  temp;
                    double t;
                    bool   Twisted = false;
                    curve.PerpendicularFrameAt(curve.Domain.Min, out temp);

                    double Angle = Vector3d.VectorAngle(planes[0].YAxis, temp.YAxis);

                    for (int i = 0; i < planes.Length; ++i)
                    {
                        curve.ClosestPoint(planes[i].Origin, out t);
                        curve.PerpendicularFrameAt(t, out temp);

                        if (Math.Abs(Vector3d.VectorAngle(planes[0].YAxis, temp.YAxis) - Angle) > AngleTolerance)
                        {
                            // Twisting Glulam
                            Twisted = true;
                            break;
                        }
                    }

                    /*
                     * Are all the planes consistently aligned from some plane?
                     *    Yes: DC Glulam with constant cross-section
                     * Are all the planes at a consistent angle from the perpendicular frame of the curve?
                     *    Yes: DC Glulam with minimal twisting
                     * DC Glulam with twisting
                     */

                    if (Twisted)
                    {
                        // TODO: differentiate between DC Glulam with minimal twist, and DC Glulam with twist
                        glulam = new DoubleCurvedGlulam(curve, planes);
                    }
                    else
                    {
                        glulam = new DoubleCurvedGlulam(curve, planes);
                    }
                }
            }

            //glulam.ValidateFrames();

            int nh = data.NumHeight;
            int nw = data.NumWidth;

            if (glulam is DoubleCurvedGlulam)
            {
                if (data.NumHeight < 2)
                {
                    nh              = 2;
                    data.LamHeight /= 2;
                }

                if (data.NumWidth < 2)
                {
                    nw             = 2;
                    data.LamWidth /= 2;
                }

                data.Lamellae.ResizeArray(nw, nh);
            }
            else if (glulam is SingleCurvedGlulam)
            {
                if (data.NumHeight < 2)
                {
                    nh              = 2;
                    data.LamHeight /= 2;
                }
                data.Lamellae.ResizeArray(nw, nh);
            }

            glulam.Data = data;

            return(glulam);
        }
Beispiel #3
0
        /// <summary>
        /// Create a Glulam from arbitrary geometry and a guide curve. The curve describes the fibre direction of the Glulam. This will
        /// create a Glulam which completely envelops the input geometry and whose centreline is offset from the input guide curve, to
        /// preserve the desired fibre orientation.
        /// </summary>
        /// <param name="curve">Guide curve to direct the Glulam.</param>
        /// <param name="beam">Beam geometry as Mesh.</param>
        /// <param name="extra">Extra material tolerance to leave on Glulam (the width and height of the Glulam will be
        /// increased by this much).</param>
        /// <returns>A new Glulam which envelops the input beam geometry, plus an extra tolerance as defined above.</returns>
        static public Glulam CreateGlulamFromBeamGeometry(Curve curve, Mesh beam, out double true_width, out double true_height, out double true_length, double extra = 0.0)
        {
            double   t, l;
            Plane    cp = Plane.Unset;
            Plane    cpp;
            Polyline ch;
            Mesh     m = new Mesh();

            List <Plane> frames = new List <Plane>();

            double[] tt = curve.DivideByCount(20, true);

            if (curve.IsLinear())
            {
                m = beam.DuplicateMesh();
                curve.PerpendicularFrameAt(curve.Domain.Min, out cp);
                m.Transform(Rhino.Geometry.Transform.PlaneToPlane(cp, Plane.WorldXY));
                m.Faces.Clear();

                Plane twist = Plane.WorldXY;
                m = m.FitToAxes(Plane.WorldXY, out ch, ref twist);

                double angle = Vector3d.VectorAngle(Vector3d.XAxis, twist.XAxis);
                int    sign  = Math.Sign(twist.YAxis * Vector3d.XAxis);

                cp.Transform(Rhino.Geometry.Transform.Rotation(angle * sign, cp.ZAxis, cp.Origin));
                frames.Add(cp);
            }
            else if (curve.TryGetPlane(out cpp, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance))
            {
                for (int i = 0; i < tt.Length; ++i)
                {
                    Vector3d xaxis = Vector3d.CrossProduct(cpp.ZAxis, curve.TangentAt(tt[i]));
                    cp = new Plane(curve.PointAt(tt[i]), xaxis, cpp.ZAxis);
                    frames.Add(cp);
                }
                for (int i = 0; i < beam.Vertices.Count; ++i)
                {
                    Point3d p = new Point3d(beam.Vertices[i]);
                    curve.ClosestPoint(p, out t);
                    l = curve.GetLength(new Interval(curve.Domain.Min, t));
                    Vector3d xaxis = Vector3d.CrossProduct(cpp.ZAxis, curve.TangentAt(t));
                    cp = new Plane(curve.PointAt(t), xaxis, cpp.ZAxis);
                    p.Transform(Rhino.Geometry.Transform.PlaneToPlane(cp, Plane.WorldXY));
                    p.Z = l;
                    m.Vertices.Add(p);
                }
            }
            else
            {
                for (int i = 0; i < beam.Vertices.Count; ++i)
                {
                    Point3d p = new Point3d(beam.Vertices[i]);
                    curve.ClosestPoint(p, out t);
                    l = curve.GetLength(new Interval(curve.Domain.Min, t));
                    curve.PerpendicularFrameAt(t, out cp);
                    p.Transform(Rhino.Geometry.Transform.PlaneToPlane(cp, Plane.WorldXY));
                    p.Z = l;

                    m.Vertices.Add(p);
                }

                Plane twist = Plane.WorldXY;
                m = m.FitToAxes(Plane.WorldXY, out ch, ref twist);
                double angle = Vector3d.VectorAngle(Vector3d.XAxis, twist.XAxis);
                int    sign  = Math.Sign(twist.YAxis * Vector3d.XAxis);

                for (int i = 0; i < tt.Length; ++i)
                {
                    curve.PerpendicularFrameAt(tt[i], out cp);
                    cp.Transform(Rhino.Geometry.Transform.Rotation(angle * sign, cp.ZAxis, cp.Origin));
                    frames.Add(cp);
                }
            }

            m.Faces.AddFaces(beam.Faces);
            m.FaceNormals.ComputeFaceNormals();

            BoundingBox bb = m.GetBoundingBox(true);

            double offsetX = bb.Center.X;
            double offsetY = bb.Center.Y;

            Brep bb2 = bb.ToBrep();

            bb2.Transform(Rhino.Geometry.Transform.PlaneToPlane(Plane.WorldXY, cp));

            true_width  = bb.Max.X - bb.Min.X + extra;
            true_height = bb.Max.Y - bb.Min.Y + extra;

            // Now we create the glulam...

            //tasTools.Lam.Glulam glulam = tasTools.Lam.Glulam.CreateGlulam(curve, frames.ToArray());
            Beam  temp_beam = new Beam(curve, null, frames.ToArray());
            int   samples   = (int)(curve.GetLength() / GlulamData.DefaultSampleDistance);
            Curve new_curve = temp_beam.CreateOffsetCurve(offsetX, offsetY, samples, true);

            new_curve = new_curve.Extend(CurveEnd.Both, 5.0 + extra, CurveExtensionStyle.Smooth);

            GlulamData data = GlulamData.FromCurveLimits(new_curve, frames.ToArray());

            if (new_curve.IsPlanar())
            {
                data.LamHeight = Math.Ceiling(true_height);
                data.Lamellae  = new Stick[(int)(Math.Ceiling(true_width / data.LamWidth)), 1];
            }
            else if (new_curve.IsLinear())
            {
                data.LamHeight = Math.Ceiling(true_height);
                data.LamWidth  = Math.Ceiling(true_width);
                data.Lamellae  = new Stick[1, 1];
            }
            else
            {
                data.Lamellae = new Stick[(int)(Math.Ceiling(true_width / data.LamWidth)), (int)(Math.Ceiling(true_height / data.LamHeight))];
            }


            Glulam glulam = tas.Lam.Glulam.CreateGlulam(new_curve, frames.ToArray(), data);

            /*
             * tt = glulam.Centreline.DivideByCount(100, true);
             * double maxK = 0.0;
             *
             * int index = 0;
             * Vector3d kvec = Vector3d.Unset;
             * Vector3d temp;
             *
             * for (int i = 0; i < tt.Length; ++i)
             * {
             *  temp = glulam.Centreline.CurvatureAt(tt[i]);
             *  if (temp.Length > maxK)
             *  {
             *      index = i;
             *      kvec = temp;
             *      maxK = temp.Length;
             *  }
             * }
             * Plane frame = glulam.GetPlane(tt[index]);
             *
             * double min_lam_width = 1.0;
             * double min_lam_height = 1.0;
             * double max_lam_width = (double)((int)Math.Ceiling(true_width / 10.0) * 10.0);
             * double max_lam_height = (double)((int)Math.Ceiling(true_height / 10.0) * 10.0);
             *
             * double lam_width = Math.Ceiling(Math.Min(1 / (Math.Abs(kvec * frame.XAxis) * 200), max_lam_width));
             * double lam_height = Math.Ceiling(Math.Min(1 / (Math.Abs(kvec * frame.YAxis) * 200), max_lam_height));
             *
             * if (lam_width == 0.0) lam_width = max_lam_width;
             * if (lam_height == 0.0) lam_height = max_lam_height;
             *
             * glulam.Data.LamHeight = lam_height;
             * glulam.Data.LamWidth = lam_width;
             * glulam.Data.NumHeight = (int)(Math.Ceiling(true_height / lam_height));
             * glulam.Data.NumWidth = (int)(Math.Ceiling(true_width / lam_width));
             *
             * //double new_lam_height, new_lam_width;
             *
             * if (glulam.Data.NumHeight * glulam.Data.LamHeight - true_height > 20.0)
             *  glulam.Data.LamHeight = Math.Ceiling((true_height + 10.0) / glulam.Data.NumHeight);
             * if (glulam.Data.NumWidth * glulam.Data.LamWidth - true_width > 20.0)
             *  glulam.Data.LamWidth = Math.Ceiling((true_width + 10.0) / glulam.Data.NumWidth);
             */
            true_length = new_curve.GetLength();

            return(glulam);
        }