Beispiel #1
0
        /***************************************************/

        private static PolyCurve Fillet(this ICurve curve1, ICurve curve2, bool tangentExtensions, bool keepCurve1StartPoint, bool keepCurve2StartPoint, double tolerance = Tolerance.Distance)
        {
            //TODO:
            //Write a proper fillet method, test and make it public

            if (!((curve1 is Line || curve1 is Arc) && (curve2 is Line || curve2 is Arc))) //for now works only with combinations of lines and arcs
            {
                Reflection.Compute.RecordError("Private method fillet is implemented only for PolyCurves consisting of Lines or Arcs.");
                return(null);
            }

            List <PolyCurve> joinCurves = Compute.IJoin(new List <ICurve> {
                curve1, curve2
            }, tolerance).ToList();

            if (joinCurves.Count == 1)
            {
                return(joinCurves[0]);
            }

            List <ICurve> resultCurves = new List <ICurve>();

            bool C1SP = keepCurve1StartPoint;
            bool C2SP = keepCurve2StartPoint;

            List <Point> intersections = curve1.ICurveIntersections(curve2, tolerance);

            if (intersections.Count > 2)
            {
                Reflection.Compute.RecordError("Invalid number of intersections between curves. Two lines/arcs can have no more than two intersections.");
            }
            else if (intersections.Count == 2 || intersections.Count == 1)
            {
                Point intersection = intersections[0];
                if (intersections.Count == 2)
                {
                    double maxdist = double.MaxValue;
                    if (C1SP)
                    {
                        foreach (Point p in intersections)
                        {
                            double dist = p.SquareDistance(curve1.IStartPoint());
                            if (dist < maxdist)
                            {
                                intersection = p;
                                maxdist      = dist;
                            }
                        }
                    }
                    else
                    {
                        foreach (Point p in intersections)
                        {
                            double dist = p.SquareDistance(curve1.IEndPoint());
                            if (dist < maxdist)
                            {
                                intersection = p;
                                maxdist      = dist;
                            }
                        }
                    }
                }
                else
                {
                    intersection = intersections[0];
                }

                if (C1SP && C2SP)
                {
                    resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                    resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                    resultCurves[1] = resultCurves[1].IFlip();
                }
                else if (C1SP && !C2SP)
                {
                    resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                    resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                }
                else if (!C1SP && C2SP)
                {
                    resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                    resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                    resultCurves[0] = resultCurves[0].IFlip();
                    resultCurves[1] = resultCurves[1].IFlip();
                }
                else
                {
                    resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                    resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                    resultCurves[0] = resultCurves[0].IFlip();
                }
            }
            else
            {
                if (curve1 is Line && curve2 is Line)
                {
                    Point intersection = (curve1 as Line).LineIntersection(curve2 as Line, true, tolerance);
                    if (C1SP && C2SP)
                    {
                        if ((curve1.IStartPoint().Distance((curve2 as Line), true) < curve1.IEndPoint().Distance((curve2 as Line), true) &&
                             !intersection.IIsOnCurve(curve1)) ||
                            (curve2.IStartPoint().Distance((curve1 as Line), true) < curve2.IEndPoint().Distance((curve1 as Line), true) &&
                             !intersection.IIsOnCurve(curve2)))
                        {
                            Reflection.Compute.RecordWarning("Couldn't provide correct fillet for given input");
                            return(null);
                        }
                        resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                        resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                        resultCurves[1] = resultCurves[1].IFlip();
                    }
                    else if (C1SP && !C2SP)
                    {
                        if ((curve1.IStartPoint().Distance((curve2 as Line), true) < curve1.IEndPoint().Distance((curve2 as Line), true) &&
                             !intersection.IIsOnCurve(curve1)) ||
                            (curve2.IStartPoint().Distance((curve1 as Line), true) > curve2.IEndPoint().Distance((curve1 as Line), true) &&
                             !intersection.IIsOnCurve(curve2)))
                        {
                            Reflection.Compute.RecordWarning("Couldn't provide correct fillet for given input");
                            return(null);
                        }
                        resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                        resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                    }
                    else if (!C1SP && C2SP)
                    {
                        if ((curve1.IStartPoint().Distance((curve2 as Line), true) > curve1.IEndPoint().Distance((curve2 as Line), true) &&
                             !intersection.IIsOnCurve(curve1)) ||
                            (curve2.IStartPoint().Distance((curve1 as Line), true) < curve2.IEndPoint().Distance((curve1 as Line), true) &&
                             !intersection.IIsOnCurve(curve2)))
                        {
                            Reflection.Compute.RecordWarning("Couldn't provide correct fillet for given input");
                            return(null);
                        }
                        resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                        resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                        resultCurves[0] = resultCurves[0].IFlip();
                        resultCurves[1] = resultCurves[1].IFlip();
                    }
                    else
                    {
                        if ((curve1.IStartPoint().Distance((curve2 as Line), true) > curve1.IEndPoint().Distance((curve2 as Line), true) &&
                             !intersection.IIsOnCurve(curve1)) ||
                            (curve2.IStartPoint().Distance((curve1 as Line), true) > curve2.IEndPoint().Distance((curve1 as Line), true) &&
                             !intersection.IIsOnCurve(curve2)))
                        {
                            Reflection.Compute.RecordWarning("Couldn't provide correct fillet for given input");
                            return(null);
                        }
                        resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                        resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                        resultCurves[0] = resultCurves[0].IFlip();
                    }
                }
                else
                {
                    Point intersection;
                    if (!tangentExtensions)
                    {
                        PolyCurve pCurve1 = new PolyCurve();
                        PolyCurve pCurve2 = new PolyCurve();
                        if (curve1 is Arc)
                        {
                            pCurve1.Curves.Add(new Circle {
                                Centre = (curve1 as Arc).Centre(), Normal = (curve1 as Arc).Normal(), Radius = (curve1 as Arc).Radius
                            });
                        }
                        else
                        {
                            pCurve1.Curves.Add(new Line {
                                Start = (curve1 as Line).Start, End = (curve1 as Line).End, Infinite = true
                            });
                        }

                        if (curve2 is Arc)
                        {
                            pCurve2.Curves.Add(new Circle {
                                Centre = (curve2 as Arc).Centre(), Normal = (curve2 as Arc).Normal(), Radius = (curve2 as Arc).Radius
                            });
                        }
                        else
                        {
                            pCurve2.Curves.Add(new Line {
                                Start = (curve2 as Line).Start, End = (curve2 as Line).End, Infinite = true
                            });
                        }

                        List <Point> curveIntersections = pCurve1.CurveIntersections(pCurve2, tolerance);
                        if (curveIntersections.Count == 0)
                        {
                            Reflection.Compute.RecordError("Curves' extensions do not intersect");
                            return(null);
                        }
                        if (C1SP && C2SP)
                        {
                            intersection = curveIntersections.ClosestPoint(curve1.IEndPoint());

                            resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves[1] = resultCurves[1].IFlip();
                        }
                        else if (C1SP && !C2SP)
                        {
                            intersection = curveIntersections.ClosestPoint(curve1.IEndPoint());
                            resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                        }
                        else if (!C1SP && C2SP)
                        {
                            intersection = curveIntersections.ClosestPoint(curve1.IStartPoint());
                            resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves[0] = resultCurves[0].IFlip();
                            resultCurves[1] = resultCurves[1].IFlip();
                        }
                        else
                        {
                            intersection = curveIntersections.ClosestPoint(curve1.IStartPoint());
                            resultCurves.AddRange(curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                            resultCurves[0] = resultCurves[0].IFlip();
                        }
                    }
                    else
                    {
                        if (C1SP && C2SP)
                        {
                            Line tanLine1 = Create.Line(curve1.IEndPoint(), curve1.IEndDir() / tolerance);
                            tanLine1.Infinite = false;
                            PolyCurve pCurve1 = new PolyCurve {
                                Curves = { curve1, tanLine1 }
                            };

                            Line tanLine2 = Create.Line(curve2.IEndPoint(), curve2.IEndDir() / tolerance);
                            tanLine2.Infinite = false;
                            PolyCurve pCurve2 = new PolyCurve {
                                Curves = { curve2, tanLine2 }
                            };

                            List <Point> curveIntersecions = pCurve1.CurveIntersections(pCurve2, tolerance);
                            if (curveIntersecions.Count > 0)
                            {
                                intersection = curveIntersecions.ClosestPoint(curve1.IEndPoint());
                            }
                            else
                            {
                                Reflection.Compute.RecordWarning("Couldn't create fillet");
                                return(null);
                            }

                            PolyCurve subResult1 = new PolyCurve
                            {
                                Curves = curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance).ToList()
                            };

                            PolyCurve subResult2 = new PolyCurve
                            {
                                Curves = curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance).ToList()
                            };

                            subResult2 = subResult2.Flip();

                            resultCurves.AddRange(subResult1.Curves);
                            resultCurves.AddRange(subResult2.Curves);
                        }
                        else if (C1SP && !C2SP)
                        {
                            Line tanLine1 = Create.Line(curve1.IEndPoint(), curve1.IEndDir() / tolerance);
                            tanLine1.Infinite = false;
                            PolyCurve pCurve1 = new PolyCurve {
                                Curves = { curve1, tanLine1 }
                            };

                            Line tanLine2 = Create.Line(curve2.IStartPoint(), curve2.IStartDir().Reverse() / tolerance);
                            tanLine2.Infinite = false;
                            PolyCurve pCurve2 = new PolyCurve {
                                Curves = { tanLine2, curve2 }
                            };

                            List <Point> curveIntersecions = pCurve1.ICurveIntersections(pCurve2, tolerance);

                            if (curveIntersecions.Count > 0)
                            {
                                intersection = curveIntersecions.ClosestPoint(curve1.IEndPoint());
                            }
                            else
                            {
                                Reflection.Compute.RecordWarning("Couldn't create fillet");
                                return(null);
                            }

                            resultCurves.AddRange(curve1.ExtendToPoint(curve1.IStartPoint(), intersection, tangentExtensions, tolerance));
                            resultCurves.AddRange(curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance));
                        }
                        else if (!C1SP && C2SP)
                        {
                            Line tanLine1 = Create.Line(curve1.IStartPoint(), curve1.IStartDir().Reverse() / tolerance);
                            tanLine1.Infinite = false;
                            PolyCurve pCurve1 = new PolyCurve {
                                Curves = { tanLine1, curve1 }
                            };

                            Line tanLine2 = Create.Line(curve2.IEndPoint(), curve2.IEndDir() / tolerance);
                            tanLine2.Infinite = false;
                            PolyCurve pCurve2 = new PolyCurve {
                                Curves = { curve2, tanLine2 }
                            };

                            List <Point> curveIntersecions = pCurve1.ICurveIntersections(pCurve2, tolerance);
                            if (curveIntersecions.Count > 0)
                            {
                                intersection = curveIntersecions.ClosestPoint(curve1.IStartPoint());
                            }
                            else
                            {
                                Reflection.Compute.RecordWarning("Couldn't create fillet");
                                return(null);
                            }
                            PolyCurve subResult1 = new PolyCurve
                            {
                                Curves = curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance).ToList()
                            };
                            PolyCurve subResult2 = new PolyCurve
                            {
                                Curves = curve2.ExtendToPoint(curve2.IStartPoint(), intersection, tangentExtensions, tolerance).ToList()
                            };

                            subResult1 = subResult1.Flip();
                            subResult2 = subResult2.Flip();

                            resultCurves.AddRange(subResult1.Curves);
                            resultCurves.AddRange(subResult2.Curves);
                        }
                        else
                        {
                            Line tanLine1 = Create.Line(curve1.IStartPoint(), curve1.IStartDir().Reverse() / tolerance);
                            tanLine1.Infinite = false;
                            PolyCurve pCurve1 = new PolyCurve {
                                Curves = { tanLine1, curve1 }
                            };

                            Line tanLine2 = Create.Line(curve2.IStartPoint(), curve2.IStartDir().Reverse() / tolerance);
                            tanLine2.Infinite = false;
                            PolyCurve pCurve2 = new PolyCurve {
                                Curves = { tanLine2, curve2 }
                            };

                            List <Point> curveIntersecions = pCurve1.ICurveIntersections(pCurve2, tolerance);
                            if (curveIntersecions.Count > 0)
                            {
                                intersection = curveIntersecions.ClosestPoint(curve1.IStartPoint());
                            }
                            else
                            {
                                Reflection.Compute.RecordWarning("Couldn't create fillet");
                                return(null);
                            }
                            PolyCurve subResult1 = new PolyCurve
                            {
                                Curves = curve1.ExtendToPoint(intersection, curve1.IEndPoint(), tangentExtensions, tolerance).ToList()
                            };
                            PolyCurve subResult2 = new PolyCurve
                            {
                                Curves = curve2.ExtendToPoint(intersection, curve2.IEndPoint(), tangentExtensions, tolerance).ToList()
                            };

                            subResult1 = subResult1.Flip();

                            resultCurves.AddRange(subResult1.Curves);
                            resultCurves.AddRange(subResult2.Curves);
                        }
                    }
                }
            }

            for (int i = resultCurves.Count - 1; i >= 0; i--)
            {
                if (resultCurves[i] is PolyCurve)
                {
                    PolyCurve temp = (PolyCurve)resultCurves[i];
                    resultCurves.RemoveAt(i);
                    resultCurves.InsertRange(i, temp.Curves);
                }
            }

            PolyCurve result = new PolyCurve {
                Curves = resultCurves
            };

            return(result);
        }
Beispiel #2
0
        /***************************************************/
        /**** Private methods                           ****/
        /***************************************************/

        private bool CreateCollection(IEnumerable <Panel> bhomPanels)
        {
            //Code for creating a collection of floors and walls in the software

            List <Panel> panels = bhomPanels.ToList();

            // Register Floor types
            IFloorType ramFloorType;
            IStories   ramStories;
            IStory     ramStory;

            //Create wall and floor lists with individual heights
            List <Panel>  wallPanels   = new List <Panel>();
            List <Panel>  floors       = new List <Panel>();
            List <double> panelHeights = new List <double>();
            List <Point>  panelPoints  = new List <Point>();

            // Split walls and floors and get all elevations
            foreach (Panel panel in panels)
            {
                double panelNormZ = panel.Normal().Z;

                //Split walls and floors
                if (Math.Abs(panelNormZ) < 0.707) // check normal against 45 degree slope
                {
                    wallPanels.Add(panel);
                }
                else
                {
                    floors.Add(panel);
                }
            }

            ramStories = m_Model.GetStories();

            #region Create Floors

            // Cycle through floors and create on story
            foreach (Panel panel in floors)
            {
                RAMId     RAMId           = new RAMId();
                string    name            = panel.Name;
                PolyCurve outlineExternal = panel.OutlineCurve();
                ramStory     = panel.GetStory(ramStories);
                ramFloorType = ramStory.GetFloorType();

                try
                {
                    // Set slab edges on FloorType in RAM for external edges
                    ISlabEdges ramSlabEdges    = ramFloorType.GetAllSlabEdges();
                    ISlabEdges ramOpeningEdges = ramFloorType.GetAllSlabOpenings();

                    // Get external and internal edges of floor panel
                    List <PolyCurve> panelOutlines   = new List <PolyCurve>();
                    List <PolyCurve> openingOutlines = new List <PolyCurve>();

                    Vector zDown = BH.Engine.Geometry.Create.Vector(0, 0, -1);

                    // RAM requires edges clockwise, flip if counterclockwise
                    PolyCurve cwOutline = (outlineExternal.IsClockwise(zDown) == false) ? outlineExternal.Flip() : outlineExternal;

                    List <ICurve> edgeCrvs = cwOutline.Curves;

                    foreach (ICurve crv in edgeCrvs)
                    {
                        Point startPt = crv.IStartPoint();
                        Point endPt   = crv.IEndPoint();
                        ramSlabEdges.Add(startPt.X.ToInch(), startPt.Y.ToInch(), endPt.X.ToInch(), endPt.Y.ToInch(), 0);
                    }

                    List <Opening> panelOpenings = panel.Openings;

                    foreach (Opening opening in panelOpenings)
                    {
                        PolyCurve outlineOpening = opening.OutlineCurve();
                        openingOutlines.Add(outlineOpening);
                    }

                    foreach (PolyCurve outline in openingOutlines)
                    {
                        // RAM requires edges clockwise, flip if counterclockwise
                        PolyCurve cwOpenOutline = (outline.IsClockwise(zDown) == false) ? outline.Flip() : outline;

                        if (!(outlineExternal.IsContaining(cwOpenOutline, false)))
                        {
                            cwOpenOutline = outlineExternal.BooleanIntersection(cwOpenOutline)[0];
                            Engine.Base.Compute.RecordWarning("Panel " + name + " opening intersects floor boundary. Boolean intersection was used to get opening extents on panel, confirm opening extents in RAM.");
                        }

                        List <ICurve> openEdgeCrvs = cwOpenOutline.Curves;

                        foreach (ICurve crv in openEdgeCrvs)
                        {
                            Point startPt = crv.IStartPoint();
                            Point endPt   = crv.IEndPoint();
                            ramOpeningEdges.Add(startPt.X.ToInch(), startPt.Y.ToInch(), endPt.X.ToInch(), endPt.Y.ToInch(), 0);
                        }
                    }

                    // Create Deck
                    List <Point> ctrlPoints = cwOutline.ControlPoints();

                    if (ctrlPoints.First() != ctrlPoints.Last())
                    {
                        ctrlPoints.Add(ctrlPoints.Last().DeepClone());
                    }

                    ISurfaceProperty srfProp = panel.Property;
                    int deckProplUID         = GetAdapterId <int>(srfProp);

                    //Add decks, then set deck points per outline
                    IDecks ramDecks = ramFloorType.GetDecks();
                    IDeck  ramDeck  = ramDecks.Add(deckProplUID, ctrlPoints.Count);

                    IPoints ramPoints = ramDeck.GetPoints();

                    // Create list of SCoordinates for floor outlines
                    List <SCoordinate> cornersExt = new List <SCoordinate>();

                    foreach (Point point in ctrlPoints)
                    {
                        SCoordinate cornerExt = point.ToRAM();
                        cornersExt.Add(cornerExt);
                    }

                    for (int k = 0; k < cornersExt.Count; k++)
                    {
                        ramPoints.Delete(k);
                        ramPoints.InsertAt(k, cornersExt[k]);
                    }

                    ramDeck.SetPoints(ramPoints);

                    // Add warning to report floors flattened to level as required for RAM
                    if (Math.Abs(panel.Normal().Z) < 1)
                    {
                        Engine.Base.Compute.RecordWarning("Panel " + name + " snapped to level " + ramStory.strLabel + ".");
                    }
                }
                catch
                {
                    CreateElementError("panel", name);
                }
            }
            #endregion

            #region Create Walls
            //Cycle through walls; if wall crosses level place at level
            foreach (Panel wallPanel in wallPanels)
            {
                string name = wallPanel.Name;

                try
                {
                    double thickness = 0.2; // default thickness
                    if (wallPanel.Property is ConstantThickness)
                    {
                        ConstantThickness prop = (ConstantThickness)wallPanel.Property;
                        thickness = prop.Thickness;
                    }

                    // Find outline of planar panel
                    PolyCurve    outline       = BH.Engine.Spatial.Query.OutlineCurve(wallPanel);
                    List <Point> wallPts       = outline.DiscontinuityPoints();
                    List <Point> sortedWallPts = wallPts.OrderBy(p => p.X).ToList();
                    Point        leftPt        = sortedWallPts.First();
                    Point        rtPt          = sortedWallPts.Last();
                    bool         downToRight   = leftPt.Y > rtPt.Y;

                    BoundingBox wallBounds = BH.Engine.Geometry.Query.Bounds(outline);
                    Point       wallMin    = wallBounds.Min;
                    Point       wallMax    = wallBounds.Max;
                    double      tempY      = wallMin.Y;

                    wallMin.Y = downToRight ? wallMax.Y : wallMin.Y;
                    wallMax.Y = downToRight ? tempY : wallMax.Y;

                    for (int i = 0; i < ramStories.GetCount(); i++)
                    {
                        ramStory = ramStories.GetAt(i);
                        // If wall crosses level, add wall to ILayoutWalls for that level
                        if (Math.Round(wallMax.Z.ToInch(), 0) >= ramStory.dElevation && Math.Round(wallMin.Z.ToInch(), 0) < ramStory.dElevation)
                        {
                            ramFloorType = ramStory.GetFloorType();

                            //Get ILayoutWalls of FloorType and add wall
                            ILayoutWalls ramLayoutWalls = ramFloorType.GetLayoutWalls();
                            ILayoutWall  ramLayoutWall  = ramLayoutWalls.Add(EMATERIALTYPES.EWallPropConcreteMat, wallMin.X.ToInch(), wallMin.Y.ToInch(), 0, 0, wallMax.X.ToInch(), wallMax.Y.ToInch(), 0, 0, thickness.ToInch());

                            //Set lateral
                            ramLayoutWall.eFramingType = EFRAMETYPE.MemberIsLateral;

                            IWalls ramWalls = ramLayoutWall.GetAssociatedStoryWalls();
                            IWall  ramWall  = ramWalls.GetAt(0);

                            // Find opening location, width, and height from outline and apply
                            foreach (Opening open in wallPanel.Openings)
                            {
                                PolyCurve   openOutline = open.OutlineCurve();
                                BoundingBox openBounds  = BH.Engine.Geometry.Query.Bounds(openOutline);
                                Point       openMin     = openBounds.Min;
                                Point       openMax     = openBounds.Max;

                                if ((openMin.Z.ToInch() >= ramStory.dElevation - ramStory.dFlrHeight) && (openMin.Z.ToInch() < ramStory.dElevation))
                                {
                                    IFinalWallOpenings ramWallOpenings = ramWall.GetFinalOpenings();

                                    int openOverlapCount = 0;

                                    for (int j = 0; i < ramWallOpenings.GetCount(); j++)
                                    {
                                        IFinalWallOpening testOpen   = ramWallOpenings.GetAt(j);
                                        IPoints           openingPts = testOpen.GetOpeningVertices();

                                        //Re-add first point to close Polygon
                                        IPoint      firstOPt    = openingPts.GetAt(0);
                                        SCoordinate firstOCoord = new SCoordinate();
                                        firstOPt.GetCoordinate(ref firstOCoord);
                                        openingPts.Add(firstOCoord);

                                        Polyline     wallOpeningOutline = openingPts.ToPolyline();
                                        List <Point> intPts             = wallOpeningOutline.ICurveIntersections(openOutline);
                                        if (wallOpeningOutline.IsContaining(openOutline) || openOutline.IsContaining(wallOpeningOutline) || intPts.Count > 0)
                                        {
                                            openOverlapCount += 1;
                                        }
                                    }

                                    if (openOverlapCount == 0)
                                    {
                                        //Get opening on wall extents
                                        if (!(outline.IsContaining(openOutline, false)))
                                        {
                                            openOutline = outline.BooleanIntersection(openOutline)[0];
                                            Engine.Base.Compute.RecordWarning("Panel " + name + " opening intersects wall boundary. Boolean intersection was used to get opening extents on panel.");
                                        }

                                        Point  closestOpenPt = BH.Engine.Geometry.Query.ClosestPoint(wallMin, openOutline.ControlPoints());
                                        double distX         = Math.Sqrt(Math.Pow(closestOpenPt.X - wallMin.X, 2) + Math.Pow(closestOpenPt.Y - wallMin.Y, 2));
                                        double distZinch     = openBounds.Min.Z.ToInch() - (ramStory.dElevation - ramStory.dFlrHeight);
                                        double openWidth     = Math.Sqrt(Math.Pow(openBounds.Max.X - openBounds.Min.X, 2) + Math.Pow(openBounds.Max.Y - openBounds.Min.Y, 2));
                                        double openHt        = openBounds.Max.Z - openBounds.Min.Z;

                                        //Add opening to RAM
                                        IRawWallOpenings ramRawWallOpenings = ramWall.GetRawOpenings();
                                        ramRawWallOpenings.Add(EDA_MEMBER_LOC.eBottomStart, distX.ToInch(), distZinch, openWidth.ToInch(), openHt.ToInch());
                                    }
                                }
                            }
                        }
                    }
                }
                catch
                {
                    CreateElementError("panel", name);
                }
            }
            #endregion

            //Save file
            m_IDBIO.SaveDatabase();

            return(true);
        }