コード例 #1
0
        static void Main(string[] args)
        {
            Rhino.Compute.ComputeServer.ApiToken = "*****@*****.**";

            // create a couple Circles using a local copy of Rhino3dmIo
            var c1 = new Circle(new Point3d(0, 0, 0), 100);
            var c2 = new Circle(new Point3d(30, 30, 0), 70);

            // call compute to perform a curve boolean operation
            var intersectionCurves = Rhino.Compute.CurveCompute.CreateBooleanIntersection(c1.ToNurbsCurve(), c2.ToNurbsCurve());

            Mesh[] intersectionMeshes = null;
            if (intersectionCurves != null)
            {
                // use local Rhino3dmIo to create a Brep from the curves
                var brep = Brep.CreateTrimmedPlane(c1.Plane, intersectionCurves);

                // call compute to mesh the Brep
                intersectionMeshes = Rhino.Compute.MeshCompute.CreateFromBrep(brep, MeshingParameters.FastRenderMesh);
            }

            // just some helper routines to create an SVG file of the results so we can see what was generated
            string path = "circle_intersection.svg";

            WriteSvgFile(path, c1, c2, intersectionMeshes);
            System.Diagnostics.Process.Start(path);
        }
コード例 #2
0
        private void _shortenEndHelperNew(bool start)
        {
            var   tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
            var   end = start ? "start" : "end";
            Plane plane;

            if (start)
            {
                plane = new Plane(Axis.PointAt(_startParam), -_startTangent);
            }
            else
            {
                plane = new Plane(Axis.PointAt(_endParam), -_endTangent);
            }

            var interval     = new Interval(-1, 1);
            var trimmedPlane = Brep.CreateTrimmedPlane(plane,
                                                       new Rectangle3d(plane, interval, interval).ToNurbsCurve());
            var split = _geometry.Split(trimmedPlane, tol * 2.0);

            if (split.Length != 2)
            {
                RhinoApp.WriteLine($"ShortenEnds WARNING: Planesplit at {end} failed");
            }
            else
            {
                var areas = (from part in split select part.GetArea()).ToArray();
                Array.Sort(areas, split);
                _geometry = split[1];
            }
        }
コード例 #3
0
        private void _shortenEndHelper(bool start)
        {
            var   tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
            var   end = start ? "start" : "end";
            Plane plane;

            if (start)
            {
                plane = new Plane(Axis.PointAt(_startParam), -_startTangent);
            }
            else
            {
                plane = new Plane(Axis.PointAt(_endParam), -_endTangent);
            }

            var trimmed = _geometry.Trim(plane, tol * 2.0);

            if (trimmed.Length != 1)
            {
                // Try harder
                RhinoApp.WriteLine($"ShortenEnds WARNING: Planesplit at {end} failed");
                var interval     = new Interval(-0.5, 0.5);
                var trimmedPlane = Brep.CreateTrimmedPlane(plane,
                                                           new Rectangle3d(plane, interval, interval).ToNurbsCurve());
                var split = _geometry.Split(trimmedPlane, tol * 2.0);
                if (split.Length != 2)
                {
                    RhinoApp.WriteLine("ShortenEnds WARNING: Could not recover split :/");
                    Intersection.BrepPlane(_geometry, plane, tol, out var intCrvs, out var intPts);
                    List <Guid> ids = new List <Guid>();
                    foreach (var intCrv in intCrvs)
                    {
                        ids.Add(RhinoDoc.ActiveDoc.Objects.AddCurve(intCrv));
                    }

                    ids.Add(RhinoDoc.ActiveDoc.Objects.AddBrep(_geometry));
                    ids.Add(RhinoDoc.ActiveDoc.Objects.AddBrep(trimmedPlane));

                    RhinoDoc.ActiveDoc.Groups.Add(end, ids);
                }
                else
                {
                    var areas = (from part in split select part.GetArea()).ToArray();
                    Array.Sort(areas, split);
                    _geometry = split[1];
                }
            }

            else
            {
                _geometry = trimmed[0];
            }
        }
コード例 #4
0
ファイル: Feature_Drillings.cs プロジェクト: tsvilans/tas
        public override bool Compute()
        {
            Vector3d z         = m_workplane.ZAxis;
            double   clearance = 10.0;

            Plane wp = m_workplane;

            m_result = new List <Brep>();

            Circle[] lofts = new Circle[4];
            wp.Origin = m_workplane.Origin + z * clearance;
            lofts[0]  = new Circle(wp, m_cs_radius);

            wp.Origin = m_workplane.Origin - z * m_cs_depth;
            lofts[1]  = new Circle(wp, m_cs_radius);

            wp.Origin = m_workplane.Origin - z * m_cs_depth;
            lofts[2]  = new Circle(wp, m_drill_radius);

            wp.Origin = m_workplane.Origin - z * m_drill_depth;
            lofts[3]  = new Circle(wp, m_drill_radius);

            Brep[] res = Brep.CreateFromLoft(lofts.Select(x => x.ToNurbsCurve()), Point3d.Unset, Point3d.Unset, LoftType.Straight, false);

            if (res.Length < 1)
            {
                return(false);
            }

            Brep cap    = Brep.CreateTrimmedPlane(lofts[3].Plane, lofts[3].ToNurbsCurve());
            Brep joined = res[0];

            joined.Join(cap, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, true);

            m_result.Add(joined);

            return(true);

            /*
             * m_result.Add(Brep.CreateFromCylinder(
             * new Cylinder(
             * new Circle(
             * new Plane(plane.Origin - plane.ZAxis * drill_depth / 2
             + plane.YAxis * m_length / 3.6,
             + plane.XAxis, plane.YAxis),
             + 12.0), drill_depth),
             + false, false));
             */
        }
コード例 #5
0
        static void Main(string[] args)
        {
            Rhino.Compute.ComputeServer.AuthToken = "Set Your AuthToken";

            var model = new Rhino.FileIO.File3dm();

            // Create a couple Circles using a Local copy of rhino3dmIO
            var c1 = new Circle(new Point3d(0, 0, 0), 100);
            var c2 = new Circle(new Point3d(30, 30, 0), 70);

            model.Objects.AddCircle(c1);
            model.Objects.AddCircle(c2);


            // call compute to perform a curve boolean operation
            var intersectionCurves = Rhino.Compute.CurveCompute.CreateBooleanIntersection(c1.ToNurbsCurve(), c2.ToNurbsCurve());

            Mesh[] intersectionMeshes = null;
            if (intersectionCurves != null)
            {
                // use local Rhino3dmIO to Create a Brep from curves
                var brep = Brep.CreateTrimmedPlane(c1.Plane, intersectionCurves);

                // call compute to mesh the Brep
                intersectionMeshes = Rhino.Compute.MeshCompute.CreateFromBrep(brep, MeshingParameters.FastRenderMesh);
                for (int i = 0; i < intersectionMeshes.Length; i++)
                {
                    model.Objects.AddMesh(intersectionMeshes[i]);
                }
            }

            // just some helper routines to create on SVG files of the results so we can see what was generated
            string path = "circle_intersection.svg";

            WriteSvgFiles(path, c1, c2, intersectionMeshes);
            System.Diagnostics.Process.Start(path);

            // Output Rhino 3dm file
            var path_3dm = System.IO.Directory.GetCurrentDirectory() + "/Outputs/circle_intersection.3dm";

            model.Write(path_3dm, 5);

            Console.WriteLine("press any key to exit");
            Console.ReadKey();
        }
コード例 #6
0
        public override bool Construct(bool append = false)
        {
            if (!append)
            {
                foreach (var part in Parts)
                {
                    part.Geometry.Clear();
                }
            }

            debug = new List <object>();

            if (InnerSurface == null || OuterSurface == null)
            {
                throw new Exception("Surfaces not defined!");
            }

            // Sort elements around the joint normal
            var dirs = SortPartsClockwise();

            var beams = new Beam[4];

            for (int i = 0; i < 4; ++i)
            {
                beams[i] = (Parts[i].Element as BeamElement).Beam;
            }

            // Get beam planes for each beam
            var planes = new Plane[4];

            for (int i = 0; i < 4; ++i)
            {
                planes[i] = beams[i].GetPlane(this.Plane.Origin);
            }


            // Construct proper planes for each element
            for (int i = 0; i < 4; ++i)
            {
                int signX = 1, signY = 1, signZ = 1;
                if (planes[i].ZAxis * dirs[i] < 0)
                {
                    signZ = -1;
                }
                if (planes[i].YAxis * Normal < 0)
                {
                    signY = -1;
                }

                planes[i] = new Plane(planes[i].Origin, planes[i].XAxis * signX * signZ, planes[i].YAxis * signY);
            }

            debug.Add(Plane);
            //debug.Add(planes[1]);
            //debug.Add(planes[2]);

            //debug.Add(beams[0].Centreline);
            //debug.Add(beams[1].Centreline);
            //debug.Add(beams[2].Centreline);
            //debug.Add(beams[3].Centreline);

            // Array of lines that describe the seams between
            // neighbouring beams.
            // From = point on inner surface
            // To = point on outer surface
            // The first line is to the right of the beam
            // I.e. the 2 seams for beam[0] are seams[0] and seams[3]
            var seams = new Line[4];

            for (int i = 0; i < 4; ++i)
            {
                int ii = (i + 1).Modulus(4);

                // Create side planes for each seam
                var p0 = new Plane(planes[i].Origin - planes[i].XAxis * beams[i].Width * 0.5,
                                   planes[i].ZAxis, planes[i].YAxis);
                var p1 = new Plane(planes[ii].Origin + planes[ii].XAxis * beams[ii].Width * 0.5,
                                   planes[ii].ZAxis, planes[ii].YAxis);

                // Find intersection of planes = find seam
                Line xline;
                Rhino.Geometry.Intersect.Intersection.PlanePlane(p0, p1, out xline);
                xline.Transform(Transform.Scale((xline.From + xline.To) * 0.5, 500));
                var xlineCrv = xline.ToNurbsCurve();

                // Find intersection between surfaces and seam
                Point3d[] xpts;
                Curve[]   overlapCurves;
                Rhino.Geometry.Intersect.Intersection.CurveBrep(xlineCrv, InnerSurface, 0.01,
                                                                out overlapCurves, out xpts);

                var innerPt = xpts[0];

                Rhino.Geometry.Intersect.Intersection.CurveBrep(xlineCrv, OuterSurface, 0.01,
                                                                out overlapCurves, out xpts);

                var outerPt = xpts[0];

                seams[i] = new Line(innerPt, outerPt);
                debug.Add(seams[i]);
            }

            // Vectors that describe the direction between opposing seams
            var innerCrosses = new Vector3d[4];
            var outerCrosses = new Vector3d[4];

            for (int i = 0; i < 4; ++i)
            {
                int ii = (i + 2).Modulus(4);
                outerCrosses[i] = seams[ii].To - seams[i].To;
                innerCrosses[i] = seams[ii].From - seams[i].From;
            }

            debug.Add(new Line(seams[0].To, outerCrosses[0]));
            debug.Add(new Line(seams[1].To, outerCrosses[1]));
            debug.Add(new Line(seams[0].From, innerCrosses[0]));
            debug.Add(new Line(seams[1].From, innerCrosses[1]));

            var cutterInterval = new Interval(-1000, 1000);

            /* INTERIOR JOINT SURFACES */

            // Construct cutters
            for (int i = 0; i < 4; ++i)
            {
                int ii = (i + 3).Modulus(4);

                Point3d  origin;
                Vector3d xaxis, yaxis;
                double   d   = CutterExtension;
                double   lip = CutterLipWidth;

                // Handle first seam

                var pts     = new Point3d[8];
                var cutter0 = new Brep[4];

                // Construct outer surface for first seam
                origin = seams[i].To;
                xaxis  = seams[i].From - seams[i].To;
                yaxis  = outerCrosses[i];

                Plane pOuter0    = new Plane(origin, xaxis, yaxis);
                var   projOuter0 = this.Plane.ProjectAlongVector(xaxis);

                pts[0] = origin + pOuter0.XAxis * d + pOuter0.YAxis * d;
                pts[1] = origin + pOuter0.XAxis * d - pOuter0.YAxis * CutterToleranceExtension;
                pts[2] = origin - pOuter0.XAxis * d - pOuter0.YAxis * CutterToleranceExtension;
                pts[3] = origin - pOuter0.XAxis * d + pOuter0.YAxis * d;

                pts[0].Transform(projOuter0); pts[0] = pts[0] - pOuter0.XAxis * lip;
                pts[1].Transform(projOuter0); pts[1] = pts[1] - pOuter0.XAxis * lip;

                cutter0[0] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[2], pts[3], 0.01);

                // Construct inner surface for first seam
                origin = seams[i].From;
                xaxis  = seams[i].To - seams[i].From;
                yaxis  = innerCrosses[i];

                Plane pInner0    = new Plane(origin, xaxis, yaxis);
                var   projInner0 = this.Plane.ProjectAlongVector(xaxis);

                pts[4] = origin + pInner0.XAxis * d + pInner0.YAxis * d;
                pts[5] = origin + pInner0.XAxis * d - pInner0.YAxis * CutterToleranceExtension;
                pts[6] = origin - pInner0.XAxis * d - pInner0.YAxis * CutterToleranceExtension;
                pts[7] = origin - pInner0.XAxis * d + pInner0.YAxis * d;

                pts[4].Transform(projInner0); pts[4] = pts[4] - pInner0.XAxis * lip;
                pts[5].Transform(projInner0); pts[5] = pts[5] - pInner0.XAxis * lip;

                cutter0[1] = Brep.CreateFromCornerPoints(pts[4], pts[5], pts[6], pts[7], 0.01);
                cutter0[2] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[5], 0.01);
                cutter0[3] = Brep.CreateFromCornerPoints(pts[5], pts[4], pts[0], 0.01);

                debug.Add(pts[0]);
                //debug.Add(pts[1]);
                //debug.Add(pts[4]);
                //debug.Add(pts[5]);

                var cutter0Joined = Brep.JoinBreps(cutter0, 0.01);

                Parts[i].Geometry.AddRange(cutter0Joined);

                // Handle second seam

                var cutter1 = new Brep[4];

                // Construct outer surface for second seam
                origin = seams[ii].To;
                xaxis  = seams[ii].From - seams[ii].To;
                yaxis  = outerCrosses[ii];

                Plane pOuter1    = new Plane(origin, xaxis, yaxis);
                var   projOuter1 = this.Plane.ProjectAlongVector(xaxis);

                pts[0] = origin + pOuter1.XAxis * d + pOuter1.YAxis * d;
                pts[1] = origin + pOuter1.XAxis * d - pOuter1.YAxis * CutterToleranceExtension;
                pts[2] = origin - pOuter1.XAxis * d - pOuter1.YAxis * CutterToleranceExtension;
                pts[3] = origin - pOuter1.XAxis * d + pOuter1.YAxis * d;

                pts[0].Transform(projOuter1); pts[0] = pts[0] - pOuter1.XAxis * lip;
                pts[1].Transform(projOuter1); pts[1] = pts[1] - pOuter1.XAxis * lip;

                cutter1[0] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[2], pts[3], 0.01);

                // Construct inner surface for second seam
                origin = seams[ii].From;
                xaxis  = seams[ii].To - seams[ii].From;
                yaxis  = innerCrosses[ii];

                Plane pInner1    = new Plane(origin, xaxis, yaxis);
                var   projInner1 = this.Plane.ProjectAlongVector(xaxis);

                pts[4] = origin + pInner1.XAxis * d + pInner1.YAxis * d;
                pts[5] = origin + pInner1.XAxis * d - pInner1.YAxis * CutterToleranceExtension;
                pts[6] = origin - pInner1.XAxis * d - pInner1.YAxis * CutterToleranceExtension;
                pts[7] = origin - pInner1.XAxis * d + pInner1.YAxis * d;

                pts[4].Transform(projInner1); pts[4] = pts[4] - pInner1.XAxis * lip;
                pts[5].Transform(projInner1); pts[5] = pts[5] - pInner1.XAxis * lip;

                cutter1[1] = Brep.CreateFromCornerPoints(pts[4], pts[5], pts[6], pts[7], 0.01);
                //cutter1[2] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[5], pts[4], 0.01);
                cutter1[2] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[5], 0.01);
                cutter1[3] = Brep.CreateFromCornerPoints(pts[5], pts[4], pts[0], 0.01);

                var cutter1Joined = Brep.JoinBreps(cutter1, 0.01);

                Parts[i].Geometry.AddRange(cutter1Joined);
            }

            /* PLATE AND DOWELS */
            // Create interior plate cutter and dowel positions

            var endPlanes    = new Plane[4];
            var dowelPlanes  = new Plane[4];
            var dowelCutters = new Brep[4];

            for (int i = 0; i < 4; ++i)
            {
                var dir = dirs[i];
                dir.Unitize();

                endPlanes[i] = new Plane(this.Plane.Origin + dir * PlateLength, dir);
                var dowelPt = this.Plane.Origin + dir * DowelPosition;

                var dp = beams[i].GetPlane(dowelPt);

                debug.Add(endPlanes[i]);

                dowelCutters[i] = new Cylinder(
                    new Circle(new Plane(dp.Origin - dp.YAxis * DowelLength * 0.5, dp.YAxis),
                               DowelDiameter * 0.5), DowelLength).ToBrep(true, true);

                dowelPlanes[i] = dp;
            }

            var platePlane0 = new Plane(this.Plane.Origin - this.Plane.ZAxis * PlateThickness * 0.5,
                                        this.Plane.XAxis, this.Plane.YAxis);

            var platePlane1 = new Plane(this.Plane.Origin + this.Plane.ZAxis * PlateThickness * 0.5,
                                        this.Plane.XAxis, this.Plane.YAxis);

            var platePts = new Point3d[4];

            for (int i = 0; i < 4; ++i)
            {
                int ii = (i + 1).Modulus(4);
                Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(
                    endPlanes[i], endPlanes[ii], platePlane0, out platePts[i]);
            }

            // Create plate outline and cutter
            var plateOutline = new Polyline()
            {
                platePts[0], platePts[1], platePts[2], platePts[3], platePts[0]
            }.ToNurbsCurve();
            var plateSrf = Brep.CreateTrimmedPlane(platePlane0, plateOutline);

            Brep[] outBlends, outWalls;
            var    plateBrep = Brep.CreateOffsetBrep(plateSrf, PlateThickness, true, true, 0.01, out outBlends, out outWalls)[0];

            plateBrep.Flip();

            for (int i = 0; i < 4; ++i)
            {
                Parts[i].Geometry.Add(plateBrep);
                Parts[i].Geometry.Add(dowelCutters[i]);
                debug.Add(dowelCutters[i]);
            }

            return(true);
        }
コード例 #7
0
ファイル: MG_Terrain.cs プロジェクト: MarcinMulti/multiv1
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //inputs
            List <string> strings = new List <string>();

            DA.GetDataList(0, strings);

            //variables
            List <string> infos = new List <string>();

            infos.Add("The process started");

            //methods
            //create points on terrain base on string list from csv file, comma is the separtor, coord X is 1, coord Y is 2 and coord Z is 3 of the point
            var pts = CreateListOfPoints(strings);

            var terrain = new Geo_Terrain(pts);

            //project point on XY plane
            var fpts = Methods.Plaxis.ProjectPointsOnXY(pts);

            var ghfpts = new List <GH_Point>();

            foreach (var fp in fpts)
            {
                ghfpts.Add(new GH_Point(fp));
            }

            //mesh
            var   hull = Grasshopper.Kernel.Geometry.ConvexHull.Solver.ComputeHull(ghfpts);
            Curve crv  = hull.ToNurbsCurve();

            Curve[]        crvs = new Curve[] { crv };
            Brep           b1   = Brep.CreateTrimmedPlane(Plane.WorldXY, crv);
            Brep           b2   = Brep.CreatePlanarBreps(crvs, 0.00001)[0];
            List <Surface> srfs = new List <Surface>();

            double        ang       = 2 * Math.PI;
            int           precision = 20;
            double        dang      = ang / Convert.ToDouble(precision);
            List <double> angles    = new List <double>();
            List <Curve>  pls       = new List <Curve>();

            for (int i = 0; i < precision; i++)
            {
                double angle = dang * i;
                angles.Add(angle);
            }

            Dictionary <double, double> dicAngleArea = new Dictionary <double, double>();

            foreach (var a in angles)
            {
                Polyline pl1 = new Polyline();
                crv.TryGetPolyline(out pl1);
                var t = Transform.Rotation(a, new Point3d(0, 0, 0));
                pl1.Transform(t);
                var bbpl1 = new BoundingBox(pl1);


                var a1 = AreaMassProperties.Compute(pl1.ToNurbsCurve()).Area;
                var a2 = bbpl1.Area;

                double difA = Math.Abs(a1 - a2);
                dicAngleArea.Add(a, difA);

                pls.Add(pl1.ToNurbsCurve());
                var lbbpl1 = bbpl1.GetCorners();
                pls.Add(new Polyline(lbbpl1).ToNurbsCurve());
            }


            //take the best rotation angle, which means the rotation to fit the bounding box the best
            var keyAngle = dicAngleArea.OrderBy(kvp => kvp.Value).First().Key;


            //outputs
            DA.SetData(0, terrain);
            DA.SetDataList(1, infos);
            DA.SetDataList(2, pts);
            DA.SetDataList(3, srfs);
            DA.SetDataList(4, pls);
            DA.SetData(5, keyAngle);
        }
コード例 #8
0
ファイル: KJoint_Plate.cs プロジェクト: tsvilans/glulamb
        public override bool Construct(bool append = false)
        {
            debug = new List <object>();
            var cutterInterval = new Interval(-CutterSize, CutterSize);

            var beams = Parts.Select(x => (x.Element as BeamElement).Beam).ToArray();

            var kplane = beams[2].GetPlane(Parts[2].Parameter);

            debug.Add(kplane);

            var dirs   = new Vector3d[2];
            var planes = new Plane[2];

            for (int i = 0; i < 2; ++i)
            {
                var d0 = beams[i].Centreline.PointAt(beams[i].Centreline.Domain.Mid) - kplane.Origin;
                //debug.Add(new Line(kplane.Origin, d0));
                planes[i] = beams[i].GetPlane(Parts[i].Parameter);
                //debug.Add(planes[i]);
                int signX = 1, signY = 1, signZ = 1;

                if (planes[i].ZAxis * d0 < 0)
                {
                    signZ = -1;
                }
                if (planes[i].YAxis * kplane.YAxis < 0)
                {
                    signY = -1;
                }

                planes[i] = new Plane(planes[i].Origin, planes[i].XAxis * signX * signZ, planes[i].YAxis * signY);
                dirs[i]   = planes[i].ZAxis;
                debug.Add(planes[i]);
            }

            // dsum is actually the plate insertion direction
            var dsum = dirs[0] + dirs[1];

            dsum.Unitize();

            var xside = dsum * kplane.XAxis < 0 ? -1 : 1;

            // Check the order of the V-beams and flip if necessary.
            // This is important for getting correct Seam and Outside planes, among other things.
            if (((dirs[0] * kplane.ZAxis) < (dirs[1] * kplane.ZAxis) && xside > 0) ||
                ((dirs[0] * kplane.ZAxis) > (dirs[1] * kplane.ZAxis) && xside < 0))
            {
                var dirTemp = dirs[0];
                dirs[0] = dirs[1];
                dirs[1] = dirTemp;

                var planeTemp = planes[0];
                planes[0] = planes[1];
                planes[1] = planeTemp;

                var beamTemp = beams[0];
                beams[0] = beams[1];
                beams[1] = beamTemp;

                var partTemp = Parts[0];
                Parts[0] = Parts[1];
                Parts[1] = partTemp;
            }

            debug.Add(new Line(kplane.Origin, dsum * 200.0));
            //debug.Add(new Line(kplane.Origin, dirs[0] * 200.0));
            //debug.Add(new Line(kplane.Origin, dirs[1] * 200.0));

            // Find correct plane axis
            Vector3d xaxis;
            double   dotx = kplane.XAxis * dsum;
            double   doty = kplane.YAxis * dsum;
            double   width;

            if (Math.Abs(dotx) > Math.Abs(doty))
            {
                width = beams[2].Width;
                if (dotx < 0)
                {
                    xaxis = -kplane.XAxis;
                }
                else
                {
                    xaxis = kplane.XAxis;
                }
            }
            else
            {
                width = beams[2].Height;
                if (doty < 0)
                {
                    xaxis = -kplane.YAxis;
                }
                else
                {
                    xaxis = kplane.YAxis;
                }
            }

            var yaxis = kplane.YAxis;

            this.Plane = new Plane(kplane.Origin, xaxis, kplane.ZAxis);

            // plane0 is the plane on top of the sill beam, where the two V-beams meet
            var plane0 = new Plane(kplane.Origin + xaxis * width * 0.5, kplane.ZAxis, kplane.YAxis);
            // planeOffset0 is the safety plane for making cutters with a slight overlap
            var planeOffset0 = new Plane(plane0.Origin - plane0.ZAxis * 3.0, plane0.XAxis, plane0.YAxis);
            //debug.Add(plane0);
            // dowelPlane is the plane on which all the dowel points lie
            var dowelPlane = new Plane(plane0.Origin + xaxis * DowelPosition, plane0.XAxis, plane0.YAxis);

            //debug.Add(dowelPlane);

            // Create sill cutters
            for (int i = 0; i < 2; ++i)
            {
                Point3d xpt;
                var     res = Rhino.Geometry.Intersect.Intersection.CurvePlane(beams[i].Centreline, plane0, 0.01);
                if (res != null && res.Count > 0)
                {
                    xpt = res[0].PointA;
                }
                else
                {
                    xpt = plane0.ClosestPoint(planes[i].Origin);
                }

                var cutterPlane = new Plane(xpt, plane0.XAxis, plane0.YAxis);
                var cutterRec   = new Rectangle3d(cutterPlane, cutterInterval, cutterInterval);
                var cutterBrep  = Brep.CreatePlanarBreps(new Curve[] { cutterRec.ToNurbsCurve() }, 0.01)[0];

                Parts[i].Geometry.Add(cutterBrep);
            }

            // END sill cutters

            // Find the seam between the V-beams

            // Find all seam and outside planes, including offsets

            double PlaneOffset      = 5.0;
            var    seamPlanes       = new Plane[2];
            var    seamOffsetPlanes = new Plane[2];

            var endPlanes = new Plane[2];
            var endPts    = new Point3d[2];

            endPts[0] = planes[0].Origin;
            endPts[0].Transform(dowelPlane.ProjectAlongVector(planes[0].ZAxis));
            endPts[0] = endPts[0] + planes[0].ZAxis * 30.0;

            endPts[1] = planes[1].Origin;
            endPts[1].Transform(dowelPlane.ProjectAlongVector(planes[1].ZAxis));
            endPts[1] = endPts[1] + planes[1].ZAxis * 30.0;

            endPlanes[0] = new Plane(endPts[0], planes[0].XAxis, planes[0].YAxis);
            endPlanes[1] = new Plane(endPts[1], planes[1].XAxis, planes[1].YAxis);

            //debug.Add(endPlanes[0]);
            //debug.Add(endPlanes[1]);

            seamPlanes[0] = new Plane(planes[0].Origin + planes[0].XAxis * beams[0].Width * 0.5, planes[0].ZAxis, planes[0].YAxis);
            seamPlanes[1] = new Plane(planes[1].Origin - planes[1].XAxis * beams[1].Width * 0.5, planes[1].ZAxis, planes[1].YAxis);


            var outPlanes       = new Plane[2];
            var outOffsetPlanes = new Plane[2];

            outPlanes[0] = new Plane(planes[0].Origin - planes[0].XAxis * beams[0].Width * 0.5, planes[0].ZAxis, planes[0].YAxis);
            outPlanes[1] = new Plane(planes[1].Origin + planes[1].XAxis * beams[1].Width * 0.5, planes[1].ZAxis, planes[1].YAxis);

            int sign = -1;

            for (int i = 0; i < 2; ++i)
            {
                sign += i * 2;
                seamOffsetPlanes[i] = new Plane(seamPlanes[i].Origin + seamPlanes[i].ZAxis * sign * PlaneOffset, seamPlanes[i].XAxis, seamPlanes[i].YAxis);
                outOffsetPlanes[i]  = new Plane(outPlanes[i].Origin - outPlanes[i].ZAxis * sign * PlaneOffset, outPlanes[i].XAxis, outPlanes[i].YAxis);

                //debug.Add(seamPlanes[i]);
                //debug.Add(outPlanes[i]);
                //debug.Add(seamOffsetPlanes[i]);
                //debug.Add(outOffsetPlanes[i]);
            }

            Plane       seamPlane;
            Rectangle3d seamRec;
            Brep        seamBrep;

            // Pick method of intersecting the 2 arms beams
            switch (Mode)
            {
            case (-1):     // beam0 into the side of beam1
                seamRec  = new Rectangle3d(seamPlanes[1], cutterInterval, cutterInterval);
                seamBrep = Brep.CreatePlanarBreps(new Curve[] { seamRec.ToNurbsCurve() }, 0.01)[0];
                Parts[0].Geometry.Add(seamBrep);
                break;

            case (1):     // beam1 into the side of beam0
                seamRec  = new Rectangle3d(seamPlanes[0], cutterInterval, cutterInterval);
                seamBrep = Brep.CreatePlanarBreps(new Curve[] { seamRec.ToNurbsCurve() }, 0.01)[0];
                Parts[1].Geometry.Add(seamBrep);
                break;

            default:     // centre split
                Line seam;
                Rhino.Geometry.Intersect.Intersection.PlanePlane(seamPlanes[0], seamPlanes[1], out seam);

                seamPlane = new Plane(seam.From, seam.Direction, dsum);

                seamRec  = new Rectangle3d(seamPlane, cutterInterval, cutterInterval);
                seamBrep = Brep.CreatePlanarBreps(new Curve[] { seamRec.ToNurbsCurve() }, 0.01)[0];

                Parts[0].Geometry.Add(seamBrep);
                Parts[1].Geometry.Add(seamBrep);
                break;
            }

            // END seam

            // Find plate plane and figure out geometry
            var platePlane = new Plane(kplane.Origin, dsum, dirs[0]);

            platePlane.Origin = platePlane.Origin - platePlane.ZAxis * PlateThickness * 0.5;
            var sillproj = plane0.ProjectAlongVector(dsum);

            var pts = new Point3d[9];

            var proj0 = platePlane.ProjectAlongVector(planes[0].YAxis);
            var proj1 = platePlane.ProjectAlongVector(planes[1].YAxis);

            // Get first arm of plate
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(endPlanes[0], outOffsetPlanes[0], platePlane, out pts[0]);
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(endPlanes[0], seamOffsetPlanes[0], platePlane, out pts[1]);

            if (SingleInsertionDirection)
            {
                pts[1] = pts[0];
                pts[1].Transform(seamOffsetPlanes[0].ProjectAlongVector(dsum));
            }

            // Get point on seam
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(seamOffsetPlanes[0], seamOffsetPlanes[1], platePlane, out pts[2]);

            // Get second arm of plate
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(endPlanes[1], outOffsetPlanes[1], platePlane, out pts[3]);
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(endPlanes[1], seamOffsetPlanes[1], platePlane, out pts[4]);

            if (SingleInsertionDirection)
            {
                pts[4] = pts[3];
                pts[4].Transform(seamOffsetPlanes[1].ProjectAlongVector(dsum));
            }

            // Get intersection of first arm and sill
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(outOffsetPlanes[0], planeOffset0, platePlane, out pts[5]);
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(outOffsetPlanes[1], planeOffset0, platePlane, out pts[6]);

            for (int i = 0; i < 9; ++i)
            {
                debug.Add(pts[i]);
            }

            // Create outline for arms
            var plateOutline0 = new Polyline()
            {
                pts[0], pts[1], pts[2], pts[4], pts[3], pts[6], pts[5], pts[0]
            };

            //plateOutline0.
            debug.Add(plateOutline0);

            var plateSrf0 = Brep.CreateTrimmedPlane(platePlane, plateOutline0.ToNurbsCurve());

            Brep[] outBlends, outWalls;
            var    plateBreps = Brep.CreateOffsetBrep(plateSrf0, PlateThickness, true, true, 0.01, out outBlends, out outWalls);

            if (plateBreps != null && plateBreps.Length > 0)
            {
                if (plateBreps[0].SolidOrientation != BrepSolidOrientation.Outward)
                {
                    plateBreps[0].Flip();
                }

                for (int i = 0; i < 2; ++i)
                {
                    Parts[i].Geometry.Add(plateBreps[0]);
                }
            }

            //var plateBrep0 = Brep.CreateOffsetBrep(plateSrf0, PlateThickness, true, true, 0.01, out outBlends, out outWalls)[0];
            //plateBrep0.Flip();

            //for (int i = 0; i < 2; ++i)
            //{
            //  Parts[i].Geometry.Add(plateBrep0);
            //}

            // Create outline for sill
            planeOffset0.Origin = plane0.Origin + plane0.ZAxis * 5.0;
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(outPlanes[0], plane0, platePlane, out pts[0]);
            Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(outPlanes[1], plane0, platePlane, out pts[1]);

            pts[2] = pts[1] - dsum * PlateDepth;
            pts[3] = pts[0] - dsum * PlateDepth;

            pts[0] = pts[0] + dsum * 10.0;
            pts[1] = pts[1] + dsum * 10.0;

            var plateOutline1 = new Polyline()
            {
                pts[0], pts[1], pts[2], pts[3], pts[0]
            };

            debug.Add(plateOutline1);

            var plateSrf1 = Brep.CreateTrimmedPlane(platePlane, plateOutline1.ToNurbsCurve());

            plateBreps = Brep.CreateOffsetBrep(plateSrf1, PlateThickness, true, true, 0.01, out outBlends, out outWalls);
            if (plateBreps != null && plateBreps.Length > 0)
            {
                if (plateBreps[0].SolidOrientation != BrepSolidOrientation.Outward)
                {
                    plateBreps[0].Flip();
                }

                this.Beam.Geometry.Add(plateBreps[0]);
            }

            //var plateBrep1 = Brep.CreateOffsetBrep(plateSrf1, PlateThickness, true, true, 0.01, out outBlends, out outWalls)[0];
            //plateBrep1.Flip();

            //this.Beam.Geometry.Add(plateBrep1);

            // Create dowels
            var dowelPoints = new Point3d[3];

            var dproj0 = dowelPlane.ProjectAlongVector(planes[0].ZAxis);
            var dproj1 = dowelPlane.ProjectAlongVector(planes[1].ZAxis);

            dowelPoints[0] = planes[0].PointAt(0, 0, DowelPosition); dowelPoints[0].Transform(dproj0);
            dowelPoints[1] = planes[1].PointAt(0, 0, DowelPosition); dowelPoints[1].Transform(dproj1);
            dowelPoints[2] = kplane.Origin;

            var dowelPlane2 = new Plane(dowelPoints[2] - kplane.YAxis * DowelLength * 0.5, kplane.YAxis);
            var dowelCyl2   = new Cylinder(
                new Circle(dowelPlane2, DowelDiameter * 0.5), DowelLength).ToBrep(true, true);

            this.Beam.Geometry.Add(dowelCyl2);

            for (int i = 0; i < 2; ++i)
            {
                var dowelPlane01 = new Plane(dowelPoints[i] - planes[i].YAxis * DowelLength * 0.5, planes[i].YAxis);
                var dowelCyl     = new Cylinder(
                    new Circle(dowelPlane01, DowelDiameter * 0.5), DowelLength).ToBrep(true, true);

                Parts[i].Geometry.Add(dowelCyl);
            }

            // END plate

            return(true);
        }