Ejemplo n.º 1
0
        public override Mesh GetBoundingMesh(double offset = 0.0, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR)
        {
            //Curve CL = Centreline.Extend(CurveEnd.Both, offset, CurveExtensionStyle.Line);

            Mesh m = new Mesh();

            double[] parameters;
            Plane[]  frames;
            int      N = 2;

            GenerateCrossSectionPlanes(N, out frames, out parameters, interpolation);

            double hW = Data.NumWidth * Data.LamWidth / 2 + offset;
            double hH = Data.NumHeight * Data.LamHeight / 2 + offset;

            Plane pplane;

            // vertex index and next frame vertex index
            int i4;
            int ii4;

            double Length = Centreline.GetLength() + offset * 2;
            double MaxT   = parameters.Last() - parameters.First();
            double Width  = Data.NumWidth * Data.LamWidth / 1000;
            double Height = Data.NumHeight * Data.LamHeight / 1000;


            for (int i = 0; i < parameters.Length; ++i)
            {
                i4  = i * 8;
                ii4 = i4 - 8;

                pplane = frames[i];

                for (int j = -1; j <= 1; j += 2)
                {
                    for (int k = -1; k <= 1; k += 2)
                    {
                        Point3d v = pplane.Origin + hW * j * pplane.XAxis + hH * k * pplane.YAxis;
                        m.Vertices.Add(v);
                        m.Vertices.Add(v);
                    }
                }

                //double DivV = DivParams[i] / MaxT;
                double DivV = parameters[i] / MaxT * Length / 1000;
                m.TextureCoordinates.Add(2 * Width + 2 * Height, DivV);
                m.TextureCoordinates.Add(0.0, DivV);

                m.TextureCoordinates.Add(Height, DivV);
                m.TextureCoordinates.Add(Height, DivV);

                m.TextureCoordinates.Add(2 * Height + Width, DivV);
                m.TextureCoordinates.Add(2 * Height + Width, DivV);

                m.TextureCoordinates.Add(Width + Height, DivV);
                m.TextureCoordinates.Add(Width + Height, DivV);


                if (i > 0)
                {
                    m.Faces.AddFace(i4 + 2,
                                    ii4 + 2,
                                    ii4 + 1,
                                    i4 + 1);
                    m.Faces.AddFace(i4 + 6,
                                    ii4 + 6,
                                    ii4 + 3,
                                    i4 + 3);
                    m.Faces.AddFace(i4 + 4,
                                    ii4 + 4,
                                    ii4 + 7,
                                    i4 + 7);
                    m.Faces.AddFace(i4,
                                    ii4,
                                    ii4 + 5,
                                    i4 + 5);
                }
            }

            // Start cap
            pplane = GetPlane(parameters.First());
            Point3d vc = pplane.Origin + hW * -1 * pplane.XAxis + hH * -1 * pplane.YAxis;

            m.Vertices.Add(vc);
            vc = pplane.Origin + hW * -1 * pplane.XAxis + hH * 1 * pplane.YAxis;
            m.Vertices.Add(vc);
            vc = pplane.Origin + hW * 1 * pplane.XAxis + hH * -1 * pplane.YAxis;
            m.Vertices.Add(vc);
            vc = pplane.Origin + hW * 1 * pplane.XAxis + hH * 1 * pplane.YAxis;
            m.Vertices.Add(vc);

            m.TextureCoordinates.Add(0, 0);
            m.TextureCoordinates.Add(0, Height);
            m.TextureCoordinates.Add(Width, 0);
            m.TextureCoordinates.Add(Width, Height);

            m.Faces.AddFace(m.Vertices.Count - 4,
                            m.Vertices.Count - 3,
                            m.Vertices.Count - 1,
                            m.Vertices.Count - 2);

            // End cap
            pplane = GetPlane(parameters.Last());
            vc     = pplane.Origin + hW * -1 * pplane.XAxis + hH * -1 * pplane.YAxis;
            m.Vertices.Add(vc);
            vc = pplane.Origin + hW * -1 * pplane.XAxis + hH * 1 * pplane.YAxis;
            m.Vertices.Add(vc);
            vc = pplane.Origin + hW * 1 * pplane.XAxis + hH * -1 * pplane.YAxis;
            m.Vertices.Add(vc);
            vc = pplane.Origin + hW * 1 * pplane.XAxis + hH * 1 * pplane.YAxis;
            m.Vertices.Add(vc);

            m.TextureCoordinates.Add(0, 0);
            m.TextureCoordinates.Add(0, Height);
            m.TextureCoordinates.Add(Width, 0);
            m.TextureCoordinates.Add(Width, Height);

            m.Faces.AddFace(m.Vertices.Count - 2,
                            m.Vertices.Count - 1,
                            m.Vertices.Count - 3,
                            m.Vertices.Count - 4);

            m.Vertices.CullUnused();
            m.Compact();

            //m.UserDictionary.ReplaceContentsWith(GetArchivableDictionary());
            //m.UserDictionary.Set("glulam", GetArchivableDictionary());
            return(m);
        }
Ejemplo n.º 2
0
        public override void GenerateCrossSectionPlanes(int N, out Plane[] planes, out double[] t, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR)
        {
            //Curve CL = Centreline.Extend(CurveEnd.Both, offset, CurveExtensionStyle.Line);
            Curve CL = Centreline;

            t = new double[] { CL.Domain.Min, CL.Domain.Max };
            Array.Sort(t);

            planes = new Plane[] { GetPlane(t[0]), GetPlane(t[1]) };
        }
Ejemplo n.º 3
0
 public virtual Mesh ToMesh(double offset = 0.0, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR)
 {
     return(new Mesh());
 }
Ejemplo n.º 4
0
 public abstract void GenerateCrossSectionPlanes(int N, out Plane[] planes, out double[] t, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR);
Ejemplo n.º 5
0
        /// <summary>
        /// Generate a series of planes on the glulam cross-section. TODO: Re-implement as GlulamOrientation function
        /// </summary>
        /// <param name="N">Number of planes to extract.</param>
        /// <param name="extension">Extension of the centreline curve</param>
        /// <param name="frames">Output cross-section planes.</param>
        /// <param name="parameters">Output t-values along centreline curve.</param>
        /// <param name="interpolation">Type of interpolation to use (default is Linear).</param>
        public override void GenerateCrossSectionPlanes(int N, out Plane[] frames, out double[] parameters, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR)
        {
            Curve curve = Centreline;

            double multiplier = RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, UnitSystem.Millimeters);

            //PolylineCurve discrete = curve.ToPolyline(Glulam.Tolerance * 10, Glulam.AngleTolerance, 0.0, 0.0);
            PolylineCurve discrete = curve.ToPolyline(multiplier * Tolerance, AngleTolerance, multiplier * MininumSegmentLength, curve.GetLength() / MinimumNumSegments);

            if (discrete.TryGetPolyline(out Polyline discrete2))
            {
                N          = discrete2.Count;
                parameters = new double[N];

                for (int i = 0; i < N; ++i)
                {
                    curve.ClosestPoint(discrete2[i], out parameters[i]);
                }
            }
            else
            {
                parameters = curve.DivideByCount(N - 1, true).ToArray();
            }

            //frames = parameters.Select(x => GetPlane(x)).ToArray();
            //return;

            frames = new Plane[parameters.Length];

            var vectors = Orientation.GetOrientations(curve, parameters);

            Plane temp;

            for (int i = 0; i < parameters.Length; ++i)
            {
                temp = Misc.PlaneFromNormalAndYAxis(
                    curve.PointAt(parameters[i]),
                    curve.TangentAt(parameters[i]),
                    vectors[i]);

                if (temp.IsValid)
                {
                    frames[i] = temp;
                }
                else
                {
                    throw new Exception(string.Format("Plane is invalid: vector {0} tangent {1}", vectors[i], curve.TangentAt(parameters[i])));
                }
                // TODO: Make back-up orientation direction in this case.
            }

            return;

            N = Math.Max(N, 2);

            frames = new Plane[N];
            Curve  CL;
            double extension = 0;

            if (Centreline.IsClosed)
            {
                CL = Centreline.DuplicateCurve();
            }
            else
            {
                CL = Centreline.Extend(CurveEnd.Both, extension, CurveExtensionStyle.Smooth);
            }

            parameters = CL.DivideByCount(N - 1, true);

            GlulamOrientation TempOrientation = Orientation.Duplicate();

            TempOrientation.Remap(Centreline, CL);

            for (int i = 0; i < N; ++i)
            {
                Vector3d v = TempOrientation.GetOrientation(CL, parameters[i]);
                frames[i] = tas.Core.Util.Misc.PlaneFromNormalAndYAxis(CL.PointAt(parameters[i]), CL.TangentAt(parameters[i]), v);
            }

            return;

            /*
             * double[] ft = new double[Frames.Count];
             * double[] fa = new double[Frames.Count];
             *
             * Plane temp;
             * for (int i = 0; i < Frames.Count; ++i)
             * {
             *  CL.PerpendicularFrameAt(Frames[i].Item1, out temp);
             *  ft[i] = Frames[i].Item1;
             *  //fa[i] = Math.Acos(temp.YAxis * Frames[i].Item2.YAxis);
             *  fa[i] = Vector3d.VectorAngle(temp.YAxis, Frames[i].Item2.YAxis, Frames[i].Item2);
             * }
             *
             * for (int i = 1; i < fa.Length; ++i)
             * {
             *  if (fa[i] - fa[i - 1] > Math.PI)
             *      fa[i] -= Constants.Tau;
             *  else if (fa[i] - fa[i - 1] < -Math.PI)
             *      fa[i] += Constants.Tau;
             * }
             *
             * int res;
             * int max = ft.Length - 1;
             * double mu;
             *
             * double[] angles = new double[N];
             *
             * if (Frames.Count < 3)
             *  interpolation = GlulamData.Interpolation.LINEAR;
             *
             * switch (interpolation)
             * {
             *  case (GlulamData.Interpolation.HERMITE): // Hermite Interpolation
             *      for (int i = 0; i < N; ++i)
             *      {
             *          if (t[i] < ft[0])
             *          {
             *              angles[i] = fa[0];
             *              continue;
             *          }
             *          else if (t[i] > ft.Last())
             *          {
             *              angles[i] = fa.Last();
             *              continue;
             *          }
             *
             *          res = Array.BinarySearch(ft, t[i]);
             *          if (res < 0)
             *          {
             *              res = ~res;
             *              res--;
             *          }
             *
             *          if (res == 0 && res < max - 1)
             *          {
             *              mu = (t[i] - ft[0]) / (ft[1] - ft[0]);
             *              angles[i] = Interpolation.HermiteInterpolate(fa[0], fa[0], fa[1], fa[2], mu, 0, 0);
             *          }
             *          else if (res > 0 && res < max - 1)
             *          {
             *              mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]);
             *              angles[i] = Interpolation.HermiteInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 2], mu, 0, 0);
             *
             *          }
             *          else if (res > 0 && res < max)
             *          {
             *              mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]);
             *              angles[i] = Interpolation.HermiteInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 1], mu, 0, 0);
             *          }
             *          else if (res == max)
             *          {
             *              angles[i] = fa[res];
             *          }
             *
             *          else
             *              continue;
             *      }
             *      break;
             *
             *  case (GlulamData.Interpolation.CUBIC): // Cubic Interpolation
             *      for (int i = 0; i < N; ++i)
             *      {
             *          if (t[i] <= ft[0])
             *          {
             *              angles[i] = fa[0];
             *              continue;
             *          }
             *          else if (t[i] >= ft.Last())
             *          {
             *              angles[i] = fa.Last();
             *              continue;
             *          }
             *
             *          res = Array.BinarySearch(ft, t[i]);
             *          if (res < 0)
             *          {
             *              res = ~res;
             *              res--;
             *          }
             *
             *          if (res == 0 && res < max - 1)
             *          {
             *              mu = (t[i] - ft[0]) / (ft[1] - ft[0]);
             *              angles[i] = Interpolation.CubicInterpolate(fa[0], fa[0], fa[1], fa[2], mu);
             *          }
             *          else if (res > 0 && res < max - 1)
             *          {
             *              mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]);
             *              angles[i] = Interpolation.CubicInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 2], mu);
             *
             *          }
             *          else if (res > 0 && res < max)
             *          {
             *              mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]);
             *              angles[i] = Interpolation.CubicInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 1], mu);
             *          }
             *          else if (res == max)
             *          {
             *              angles[i] = fa[res];
             *          }
             *
             *          else
             *              continue;
             *      }
             *      break;
             *
             *  default: // Default linear interpolation
             *      for (int i = 0; i < N; ++i)
             *      {
             *          res = Array.BinarySearch(ft, t[i]);
             *          if (res < 0)
             *          {
             *              res = ~res;
             *              res--;
             *          }
             *          if (res >= 0 && res < max)
             *          {
             *              if (ft[res + 1] - ft[res] == 0)
             *                  mu = 0.5;
             *              else
             *                  mu = Math.Min(1.0, Math.Max(0, (t[i] - ft[res]) / (ft[res + 1] - ft[res])));
             *              angles[i] = Interpolation.Lerp(fa[res], fa[res + 1], mu);
             *          }
             *          else if (res < 0)
             *              angles[i] = fa[0];
             *          else if (res >= max)
             *              angles[i] = fa[max];
             *      }
             *      break;
             * }
             *
             * for (int i = 0; i < N; ++i)
             * {
             *  CL.PerpendicularFrameAt(t[i], out temp);
             *  temp.Transform(Rhino.Geometry.Transform.Rotation(angles[i], temp.ZAxis, temp.Origin));
             *  planes[i] = temp;
             * }
             */
        }
Ejemplo n.º 6
0
        public override Mesh GetBoundingMesh(double offset = 0.0, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR)
        {
            Mesh m = new Mesh();

            int N = Math.Max(Data.Samples, 6);

            GenerateCrossSectionPlanes(N, out Plane[] frames, out double[] parameters, Data.InterpolationType);

            GetSectionOffset(out double offsetX, out double offsetY);
            Point3d[] m_corners = GenerateCorners();

            double hW = Data.NumWidth * Data.LamWidth / 2 + offset;
            double hH = Data.NumHeight * Data.LamHeight / 2 + offset;

            // vertex index and next frame vertex index
            int i4;
            int ii4;

            //double texLength = (Centreline.GetLength() + offset * 2) / 1000;
            //double MaxT = parameters.Last() - parameters.First();

            double texWidth  = Width / 1000.0;  // Width in meters
            double texHeight = Height / 1000.0; // Height in meters

            for (int i = 0; i < frames.Length; ++i)
            {
                i4  = i * 8;
                ii4 = i4 - 8;

                double texLength = Centreline.GetLength(
                    new Interval(Centreline.Domain.Min, parameters[i])) / 1000;

                for (int j = 0; j < m_corners.Length; ++j)
                {
                    Point3d v = frames[i].PointAt(m_corners[j].X, m_corners[j].Y);
                    m.Vertices.Add(v);
                    m.Vertices.Add(v);
                }

                //double DivV = parameters[i] / MaxT * Length / 1000;
                m.TextureCoordinates.Add(texLength, 2 * texWidth + 2 * texHeight);
                m.TextureCoordinates.Add(texLength, 0.0);

                m.TextureCoordinates.Add(texLength, texHeight);
                m.TextureCoordinates.Add(texLength, texHeight);

                m.TextureCoordinates.Add(texLength, 2 * texHeight + texWidth);
                m.TextureCoordinates.Add(texLength, 2 * texHeight + texWidth);

                m.TextureCoordinates.Add(texLength, texWidth + texHeight);
                m.TextureCoordinates.Add(texLength, texWidth + texHeight);

                if (i > 0)
                {
                    m.Faces.AddFace(i4 + 2,
                                    ii4 + 2,
                                    ii4 + 1,
                                    i4 + 1);
                    m.Faces.AddFace(i4 + 5,
                                    ii4 + 5,
                                    ii4 + 3,
                                    i4 + 3);
                    m.Faces.AddFace(i4 + 7,
                                    ii4 + 7,
                                    ii4 + 4,
                                    i4 + 4);

                    m.Faces.AddFace(i4,
                                    ii4,
                                    ii4 + 7,
                                    i4 + 7);
                }
            }

            Plane pplane;

            // Start cap
            pplane = frames.First();

            //m_section_corners.Select(x => frames.Select(y => m.Vertices.Add(y.PointAt(x.X, x.Y))));

            for (int j = 0; j < m_corners.Length; ++j)
            {
                m.Vertices.Add(pplane.PointAt(m_corners[j].X, m_corners[j].Y));
            }

            m.TextureCoordinates.Add(0, 0);
            m.TextureCoordinates.Add(0, texHeight);
            m.TextureCoordinates.Add(texWidth, 0);
            m.TextureCoordinates.Add(texWidth, texHeight);

            m.Faces.AddFace(m.Vertices.Count - 4,
                            m.Vertices.Count - 3,
                            m.Vertices.Count - 2,
                            m.Vertices.Count - 1);

            // End cap
            pplane = frames.Last();
            for (int j = 0; j < m_corners.Length; ++j)
            {
                m.Vertices.Add(pplane.PointAt(m_corners[j].X, m_corners[j].Y));
            }

            m.TextureCoordinates.Add(0, 0);
            m.TextureCoordinates.Add(0, texHeight);
            m.TextureCoordinates.Add(texWidth, 0);
            m.TextureCoordinates.Add(texWidth, texHeight);

            m.Faces.AddFace(m.Vertices.Count - 1,
                            m.Vertices.Count - 2,
                            m.Vertices.Count - 3,
                            m.Vertices.Count - 4);
            //m.UserDictionary.ReplaceContentsWith(GetArchivableDictionary());
            //m.UserDictionary.Set("glulam", GetArchivableDictionary());

            return(m);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Generate a series of planes on the glulam cross-section. TODO: Re-implement as GlulamOrientation function
        /// </summary>
        /// <param name="N">Number of planes to extract.</param>
        /// <param name="extension">Extension of the centreline curve</param>
        /// <param name="frames">Output cross-section planes.</param>
        /// <param name="parameters">Output t-values along centreline curve.</param>
        /// <param name="interpolation">Type of interpolation to use (default is Linear).</param>
        public override void GenerateCrossSectionPlanes(int N, out Plane[] frames, out double[] parameters, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR)
        {
            Curve curve = Centreline;

            double multiplier = RhinoMath.UnitScale(UnitSystem.Millimeters, Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem);

            //PolylineCurve discrete = curve.ToPolyline(Glulam.Tolerance * 10, Glulam.AngleTolerance, 0.0, 0.0);
            PolylineCurve discrete = curve.ToPolyline(multiplier * Tolerance, AngleTolerance, multiplier * MininumSegmentLength, curve.GetLength() / MinimumNumSegments);

            if (discrete == null)
            {
                parameters = curve.DivideByCount(N - 1, true).ToArray();

                //discrete = new PolylineCurve(new Point3d[] { curve.PointAtStart, curve.PointAtEnd });
            }
            else
            {
                if (discrete.TryGetPolyline(out Polyline discrete2))
                {
                    N          = discrete2.Count;
                    parameters = new double[N];

                    for (int i = 0; i < N; ++i)
                    {
                        curve.ClosestPoint(discrete2[i], out parameters[i]);
                    }
                }
                else
                {
                    parameters = curve.DivideByCount(N - 1, true).ToArray();
                }
            }

            //frames = parameters.Select(x => GetPlane(x)).ToArray();
            //return;

            frames = new Plane[parameters.Length];

            var vectors = Orientation.GetOrientations(curve, parameters);

            Plane temp;

            for (int i = 0; i < parameters.Length; ++i)
            {
                temp = Utility.PlaneFromNormalAndYAxis(
                    curve.PointAt(parameters[i]),
                    curve.TangentAt(parameters[i]),
                    vectors[i]);

                if (temp.IsValid)
                {
                    frames[i] = temp;
                }
                else
                {
                    throw new Exception(string.Format("Plane is invalid: vector {0} tangent {1}", vectors[i], curve.TangentAt(parameters[i])));
                }
            }

            return;
        }