/// <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)
        {
            Brep[] a_Blend = new Brep[] { };
            Brep[] o_Wall  = new Brep[] { };

            Brep        BrepItem   = null;
            double      o_Distance = 4;
            List <Brep> OutputLs   = new List <Brep>();

            if (!DA.GetData(0, ref BrepItem))
            {
                return;
            }
            if (!DA.GetData(1, ref o_Distance))
            {
                return;
            }

            if (o_Distance < 0)
            {
                o_Distance = Math.Abs(o_Distance);
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "面偏移的距离不能为负数");
                o_Distance = 0;
            }
            OutputLs = Brep.CreateOffsetBrep(BrepItem, o_Distance, true, false, 0.001, out a_Blend, out o_Wall).ToList();

            DA.SetDataList(0, OutputLs);
        }
示例#2
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);
        }
示例#3
0
        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);
        }