/// <summary>
 ///
 /// </summary>
 /// <param name="cur1"></param>
 /// <param name="cur2"></param>
 /// <param name="mergedCur"></param>
 /// <returns></returns>
 public static bool Merge(Bcurve cur1, Bcurve cur2, out Bcurve mergedCur)
 {
     mergedCur = new Bcurve();
     if ((cur1.Id == cur2.Id) && (cur1.Curve is Line) &&
         (cur2.Curve is Line))
     {
         Line lin1 = cur1.Curve as Line;
         Line lin2 = cur2.Curve as Line;
         if ((lin1.Direction.Normalize().IsAlmostEqualTo
                  (lin2.Direction.Normalize())) &&
             (lin1.IsBound) && (lin2.IsBound))
         {
             XYZ lin1s = lin1.GetEndPoint(0);
             XYZ lin1e = lin1.GetEndPoint(1);
             XYZ lin2s = lin2.GetEndPoint(0);
             XYZ lin2e = lin2.GetEndPoint(1);
             if (lin1s.IsAlmostEqualTo(lin2e))
             {
                 mergedCur = new Bcurve
                                 (Line.CreateBound(lin2s, lin1e), cur1);
                 return(true);
             }
             else if (lin1e.IsAlmostEqualTo(lin2s))
             {
                 mergedCur = new Bcurve(
                     Line.CreateBound(lin1s, lin2e), cur1);
                 return(true);
             }
         }
     }
     return(false);
 }
 public Bcurve(Curve curve, Bcurve root)
 {
     Curve         = curve;
     Length        = curve.Length;
     Id            = root.Id;
     BaseIsWall    = root.BaseIsWall;
     BaseWallCurve = root.BaseWallCurve;
     BaseWallWidth = root.BaseWallWidth;
 }
        /// <summary>
        /// Calculate the boundary of a room with elementId attached to it.
        /// </summary>
        /// <param name="room"></param>
        /// <returns></returns>
        public static List <List <Bcurve> > GetBoundary
            (Room room, out List <List <XYZ> > vertexList)
        {
            List <List <Bcurve> > boundaryList =
                new List <List <Bcurve> >();

            vertexList = new List <List <XYZ> >();

            IList <IList <BoundarySegment> > BSlist =
                room.GetBoundarySegments
                    (new SpatialElementBoundaryOptions())
                as IList <IList <BoundarySegment> >;


            foreach (IList <BoundarySegment> BSegs in BSlist)
            {
                List <Bcurve> boundaries =
                    new List <Bcurve>();
                List <XYZ>     vertexes   = new List <XYZ>();
                Stack <Bcurve> boundCurs  = new Stack <Bcurve>();
                Queue <Bcurve> cursMerged = new Queue <Bcurve>();
                foreach (BoundarySegment Seg in BSegs)
                {
                    Document  doc      = room.Document;
                    Element   wallOrNo = doc.GetElement(Seg.ElementId);
                    ElementId wallId   = doc.Settings.Categories
                                         .get_Item(BuiltInCategory.OST_Walls).Id;
                    if (wallOrNo.Category.Id.Equals(wallId))
                    {
                        Wall          w    = wallOrNo as Wall;
                        LocationCurve wLoc = w.Location as LocationCurve;
                        boundCurs.Push(new Bcurve
                                           (Seg.GetCurve(), Seg.ElementId, true, wLoc.Curve, w.Width));
                    }
                    else
                    {
                        boundCurs.Push(new Bcurve
                                           (Seg.GetCurve(), Seg.ElementId, false, Seg.GetCurve(), -1));
                    }
                }
                #region Merge curves
                while (boundCurs.Count > 1)
                {
                    Bcurve cur1 = boundCurs.Pop();
                    Bcurve cur2 = boundCurs.Pop();
                    if (Merge(cur1, cur2, out Bcurve curM))
                    {
                        boundCurs.Push(curM);
                        continue;
                    }
                    boundCurs.Push(cur2);
                    cursMerged.Enqueue(cur1);
                }
                Bcurve cur3 = boundCurs.Pop();
                Bcurve cur4 = cursMerged.Peek();
                if (Merge(cur3, cur4, out Bcurve curveM))
                {
                    cursMerged.Dequeue();
                    cursMerged.Enqueue(curveM);
                }
                else
                {
                    cursMerged.Enqueue(cur3);
                }
                cursMerged.Reverse();
                #endregion
                foreach (Bcurve bcur in cursMerged)
                {
                    boundaries.Add(bcur);
                    vertexes.Add(bcur.Curve.GetEndPoint(0));
                }
                boundaryList.Add(boundaries);
                vertexList.Add(vertexes);
            }
            return(boundaryList);
        }