/// <summary>
        /// 取得所有的梁(水平與垂直向)
        /// </summary>
        /// <returns></returns>
        private List <LINE> GetAllBeams(Level targetLevel_)
        {
            FilteredElementCollector collector = new FilteredElementCollector(revitDoc);

            collector.OfCategory(BuiltInCategory.OST_StructuralFraming);
            collector.OfClass(typeof(FamilyInstance));
            IList <Element> beams = collector.ToElements();
            List <LINE>     Beams = new List <LINE>();

            foreach (Element beam in beams)
            {
                try
                {
                    ///// 取得梁的Level
                    Parameter mLevel    = beam.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM);
                    string    levelName = mLevel.AsValueString();

                    //// 取得梁的類型與其寬度
                    ElementType type  = revitDoc.GetElement(beam.GetTypeId()) as ElementType;
                    Parameter   b     = type.LookupParameter("b");
                    double      width = b.AsDouble();



                    ///檢查梁中心線是否有偏移
                    BuiltInParameter paraIndex = BuiltInParameter.START_Y_JUSTIFICATION;
                    Parameter        p1        = beam.get_Parameter(paraIndex);
                    string           offset    = p1.AsValueString();

                    // 取得梁偏移量
                    BuiltInParameter paraIndex1 = BuiltInParameter.STRUCTURAL_BEAM_END0_ELEVATION;
                    Parameter        of1        = beam.get_Parameter(paraIndex1);
                    string           offset1    = of1.AsValueString();
                    BuiltInParameter paraIndex2 = BuiltInParameter.STRUCTURAL_BEAM_END1_ELEVATION;
                    Parameter        of2        = beam.get_Parameter(paraIndex2);
                    string           offset2    = of2.AsValueString();

                    if (offset1 != offset2)
                    {
                        continue;
                    }



                    double shift = Convert.ToDouble(offset1) / 304.8;

                    LocationCurve Locurve = beam.Location as LocationCurve;
                    Line          line    = Locurve.Curve as Line;

                    XYZ direction = line.Direction;

                    XYZ VertiDir = offset == "左" ? new XYZ(line.Direction.Y, -line.Direction.X, line.Direction.Z) :
                                   offset == "右" ? new XYZ(-line.Direction.Y, line.Direction.X, line.Direction.Z) : line.Direction;


                    XYZ pp1 = line.GetEndPoint(0);
                    XYZ pp2 = line.GetEndPoint(1);

                    ///Ori Points
                    XYZ stPoint = new XYZ(pp1.X + width / 2 * VertiDir.X,
                                          pp1.Y + width / 2 * VertiDir.Y,
                                          pp1.Z + width / 2 * VertiDir.Z);

                    XYZ enPoint = new XYZ(pp1.X + line.Length * line.Direction.X + width / 2 * VertiDir.X,
                                          pp1.Y + line.Length * line.Direction.Y + width / 2 * VertiDir.Y,
                                          pp1.Z + line.Length * line.Direction.Z + width / 2 * VertiDir.Z);

                    LINE LINE = new LINE(stPoint, enPoint);

                    LINE.Name      = beam.Name;
                    LINE.LevelName = levelName;
                    LINE.Width     = width;


                    if (Math.Round(LINE.GetStartPoint().Z, 3) == Math.Round(LINE.GetEndPoint().Z, 3))
                    {
                        Beams.Add(LINE);
                    }
                }
                catch (Exception)
                {
                }
            }
            return(Beams);
        }
예제 #2
0
        private List <LINE> GetPolylineAndLineClosedRegion(List <LINE> Lines, string RadioCase)
        {
            List <LINE> RESULT = new List <LINE>();

            List <LINE> newResult    = new List <LINE>();
            List <LINE> processLines = new List <LINE>();

            foreach (LINE line in Lines)
            {
                if (line.Name == "Circle" && RadioCase == "Circle")
                {
                    newResult.Add(line);
                }
                else if (RadioCase != "Circle")
                {
                    processLines.Add(line);
                }
            }
            if (RadioCase == "Circle")
            {
                return(newResult);
            }


            List <int> flag = new List <int>()
            {
            };

            for (int i = 0; i < processLines.Count; i++)
            {
                int j = 0;
                flag.Add(i);
                List <LINE> polyline = new List <LINE>()
                {
                    processLines[i]
                };
                while (j < processLines.Count)
                {
                    if (flag.Contains(j))
                    {
                        j++;
                        continue;
                    }

                    foreach (LINE tmpLine in polyline)
                    {
                        if (IsConnected(tmpLine, processLines[j]))
                        {
                            polyline.Add(processLines[j]);
                            flag.Add(j);
                            j = -1;
                            break;
                        }
                    }
                    j++;
                }

                if (polyline.Count != 1)
                {
                    double newX     = polyline.Sum(tt => tt.GetStartPoint().X) / polyline.Count;
                    double newY     = polyline.Sum(tt => tt.GetStartPoint().Y) / polyline.Count;
                    XYZ    newPoint = new XYZ(newX, newY, 0);
                    LINE   newLine  = new LINE(newPoint, newPoint, 10);
                    newResult.Add(newLine);
                }
            }

            RESULT = newResult;


            return(RESULT);
        }
        private List <LINE> TakeOffColumnEdge(Dictionary <string, List <LINE> > columns, List <LINE> floor)
        {
            foreach (KeyValuePair <string, List <LINE> > column in columns)
            {
                List <LINE> newFloor = new List <LINE>();
                Dictionary <int, List <LINE> > tmpData = new Dictionary <int, List <LINE> >();
                for (int ii = 0; ii < column.Value.Count; ii++)
                {
                    LINE columnEdge = column.Value[ii];
                    for (int jj = 0; jj < floor.Count; jj++)
                    {
                        LINE floorEdge = floor[jj];
                        if (Math.Round(floorEdge.GetSlope(), 3) == Math.Round(columnEdge.GetSlope(), 3))
                        {
                            continue;
                        }
                        if (Math.Abs(Math.Round(floorEdge.GetDirection().X, 3)) == Math.Abs(Math.Round(columnEdge.GetDirection().X, 3)) &&
                            Math.Abs(Math.Round(floorEdge.GetDirection().Y, 3)) == Math.Abs(Math.Round(columnEdge.GetDirection().Y, 3)))
                        {
                            continue;
                        }

                        XYZ crossPoint = floorEdge.GetCrossPoint(columnEdge);


                        try
                        {
                            if (floorEdge.IsPointInLine(crossPoint) && columnEdge.IsPointInLine(crossPoint))
                            {
                                XYZ innerPoint = IsInner(columnEdge.GetStartPoint(), floor) ?
                                                 columnEdge.GetStartPoint() : columnEdge.GetEndPoint();

                                double      dis1    = (crossPoint - floorEdge.GetStartPoint()).GetLength();
                                double      dis2    = (crossPoint - floorEdge.GetEndPoint()).GetLength();
                                LINE        newLine = null;
                                List <LINE> newList = new List <LINE>();
                                if (dis1 > dis2)
                                {
                                    floorEdge.ResetParameters(crossPoint, "EndPoint");
                                    newLine = new LINE(crossPoint, innerPoint);
                                    newList.Add(floorEdge);
                                    if (dis2 != 0)
                                    {
                                        newList.Add(newLine);
                                    }
                                }
                                else
                                {
                                    newLine = new LINE(innerPoint, crossPoint);
                                    floorEdge.ResetParameters(crossPoint, "StartPoint");
                                    if (dis1 != 0)
                                    {
                                        newList.Add(newLine);
                                    }
                                    newList.Add(floorEdge);
                                }
                                tmpData[jj] = newList;
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }
                }


                for (int kk = 0; kk < floor.Count; kk++)
                {
                    if (tmpData.ContainsKey(kk))
                    {
                        foreach (LINE item in tmpData[kk])
                        {
                            newFloor.Add(item);
                        }
                    }
                    else
                    {
                        newFloor.Add(floor[kk]);
                    }
                }
                floor = new List <LINE>();
                floor = newFloor;
            }

            return(floor);
        }
예제 #4
0
        /// <summary>
        /// Pick a DWG import instance, extract polylines
        /// from it visible in the current view and create
        /// filled regions from them.
        /// </summary>
        public Dictionary <string, List <LINE> > GeneralCAD(UIDocument uidoc)
        {
            Document doc         = uidoc.Document;
            View     active_view = doc.ActiveView;
            List <GeometryObject> visible_dwg_geo = new List <GeometryObject>();

            // Pick Import Instance
            Reference r      = uidoc.Selection.PickObject(ObjectType.Element, new JtElementsOfClassSelectionFilter <ImportInstance>());
            var       import = doc.GetElement(r) as ImportInstance;

            // Get Geometry
            var ge = import.get_Geometry(new Options());

            foreach (var go in ge)
            {
                if (go is GeometryInstance)
                {
                    var gi  = go as GeometryInstance;
                    var ge2 = gi.GetInstanceGeometry();
                    if (ge2 != null)
                    {
                        foreach (var obj in ge2)
                        {
                            // Only work on PolyLines
                            if (obj is PolyLine | obj is Arc | obj is Line)
                            {
                                // Use the GraphicsStyle to get the
                                // DWG layer linked to the Category
                                // for visibility.

                                var gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle;
                                // Check if the layer is visible in the view.

                                if (!active_view.GetCategoryHidden(gStyle.GraphicsStyleCategory.Id))
                                {
                                    visible_dwg_geo.Add(obj);
                                }
                            }
                        }
                    }
                }
            }


            // Do something with the info
            Dictionary <string, List <LINE> > res = new Dictionary <string, List <LINE> >();

            if (visible_dwg_geo.Count > 0)
            {
                // Retrieve first filled region type
                var filledType = new FilteredElementCollector(doc)
                                 .WhereElementIsElementType()
                                 .OfClass(typeof(FilledRegionType))
                                 .OfType <FilledRegionType>()
                                 .First();

                using (var t = new Transaction(doc))
                {
                    t.Start("ProcessDWG");
                    List <LINE> tmp = new List <LINE>();
                    foreach (var obj in visible_dwg_geo)
                    {
                        var    gStyle    = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle;
                        string layerName = gStyle.GraphicsStyleCategory.Name;

                        tmp = res.ContainsKey(layerName) ? res[layerName] : new List <LINE>();
                        //if (obj is PolyLine)
                        //{
                        //    // Create loops for detail region
                        //    var poly = obj as PolyLine;
                        //    var points = poly.GetCoordinates();
                        //    for (int kk = 0; kk < points.Count - 1; kk++)
                        //    {
                        //        tmp.Add(new LINE(points[kk], points[kk + 1]));
                        //    }
                        //}
                        //else if (obj is Line)
                        //{
                        //    var line = obj as Line;
                        //    tmp.Add(new LINE(line.GetEndPoint(0),
                        //                         line.GetEndPoint(1)));
                        //}
                        //else if (obj is Arc)
                        //{
                        //    var Arc = obj as Arc;
                        //    pp[0] = Arc.Center;
                        //    pp[1] = Arc.Center;
                        //}
                        if (obj is Arc)
                        {
                            var  Arc      = obj as Arc;
                            XYZ  newPoint = new XYZ(Arc.Center.X, Arc.Center.Y, 0);
                            LINE newLine  = new LINE(newPoint, newPoint, 10);
                            newLine.Name = "Circle";
                            tmp.Add(newLine);
                        }
                        if (obj is PolyLine)
                        {
                            // Create loops for detail region
                            var poly   = obj as PolyLine;
                            var points = poly.GetCoordinates();
                            //List<XYZ> POINTs = points.ToList();
                            //double meanX = POINTs.Sum(tt => tt.X) / POINTs.Count;
                            //double meanY = POINTs.Sum(tt => tt.Y) / POINTs.Count;
                            //XYZ newPoint = new XYZ(meanX, meanY, 0);
                            //LINE newLine = new LINE(newPoint, newPoint, 10);
                            //newLine.Name = "PolyLine-" + POINTs.Count.ToString();
                            //tmp.Add(newLine);
                            for (int kk = 0; kk < points.Count - 1; kk++)
                            {
                                LINE newLine = new LINE(points[kk], points[kk + 1]);
                                newLine.Name = "Polyline";
                                tmp.Add(newLine);
                            }
                        }
                        else if (obj is Line)
                        {
                            var  line    = obj as Line;
                            LINE newLine = new LINE(line.GetEndPoint(0), line.GetEndPoint(1));
                            newLine.Name = "Line";
                            tmp.Add(newLine);
                        }
                        res[layerName] = tmp;
                    }
                }
            }

            return(res);
        }
예제 #5
0
        /// <summary>
        /// Pick a DWG import instance, extract polylines
        /// from it visible in the current view and create
        /// filled regions from them.
        /// </summary>
        public Dictionary <string, List <LINE> > ProcessVisible(UIDocument uidoc)
        {
            Document doc         = uidoc.Document;
            View     active_view = doc.ActiveView;
            List <GeometryObject> visible_dwg_geo = new List <GeometryObject>();

            // Pick Import Instance
            Reference r      = uidoc.Selection.PickObject(ObjectType.Element, new JtElementsOfClassSelectionFilter <ImportInstance>());
            var       import = doc.GetElement(r) as ImportInstance;

            // Get Geometry
            var ge = import.get_Geometry(new Options());

            foreach (var go in ge)
            {
                if (go is GeometryInstance)
                {
                    var gi  = go as GeometryInstance;
                    var ge2 = gi.GetInstanceGeometry();
                    if (ge2 != null)
                    {
                        foreach (var obj in ge2)
                        {
                            // Only work on PolyLines
                            if (obj is PolyLine | obj is Arc | obj is Line)
                            {
                                // Use the GraphicsStyle to get the
                                // DWG layer linked to the Category
                                // for visibility.

                                var gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle;
                                // Check if the layer is visible in the view.

                                if (!active_view.GetCategoryHidden(gStyle.GraphicsStyleCategory.Id))
                                {
                                    visible_dwg_geo.Add(obj);
                                }
                            }
                        }
                    }
                }
            }

            // Do something with the info
            Dictionary <string, List <LINE> > res = new Dictionary <string, List <LINE> >();

            if (visible_dwg_geo.Count > 0)
            {
                // Retrieve first filled region type
                var filledType = new FilteredElementCollector(doc)
                                 .WhereElementIsElementType()
                                 .OfClass(typeof(FilledRegionType))
                                 .OfType <FilledRegionType>()
                                 .First();

                using (var t = new Transaction(doc))
                {
                    t.Start("ProcessDWG");
                    List <LINE> tmp = new List <LINE>();
                    foreach (var obj in visible_dwg_geo)
                    {
                        var    gStyle    = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle;
                        string layerName = gStyle.GraphicsStyleCategory.Name;
                        LINE   pp        = null;
                        if (obj is PolyLine)
                        {
                            // Create loops for detail region
                            var poly   = obj as PolyLine;
                            var points = poly.GetCoordinates();
                            pp = new LINE(points[0], points[2]);
                        }
                        else if (obj is Arc)
                        {
                            var Arc = obj as Arc;
                            pp = new LINE(Arc.Center, Arc.Center);
                        }
                        else if (obj is Line)
                        {
                            var line = obj as Line;
                            pp = new LINE(line.GetEndPoint(0), line.GetEndPoint(1));
                        }
                        tmp = res.ContainsKey(layerName) ? res[layerName] : new List <LINE>();
                        tmp.Add(pp);
                        res[layerName] = tmp;
                    }
                }
            }

            return(res);
        }
예제 #6
0
        /// <summary>
        /// 多邊形中心處理
        /// </summary>
        /// <param name="Lines"></param>
        /// <param name="RadioCase"></param>
        /// <returns></returns>
        private List <LINE> GetPolylineAndLineClosedRegion(List <LINE> Lines, string RadioCase)
        {
            List <LINE> RESULT = new List <LINE>();

            List <LINE> newResult    = new List <LINE>();
            List <LINE> processLines = new List <LINE>();

            foreach (LINE line in Lines)
            {
                if (line.Name == "Circle" && RadioCase == "Circle")
                {
                    newResult.Add(line);
                }
                else if (RadioCase != "Circle" && line.Name != "Circle")
                {
                    processLines.Add(line);
                }
            }
            if (RadioCase == "Circle")
            {
                return(newResult);
            }


            List <int> flag = new List <int>()
            {
            };

            for (int i = 0; i < processLines.Count; i++)
            {
                int j = 0;
                flag.Add(i);
                List <LINE> polyline = new List <LINE>()
                {
                    processLines[i]
                };
                while (j < processLines.Count)
                {
                    if (flag.Contains(j))
                    {
                        j++;
                        continue;
                    }

                    foreach (LINE tmpLine in polyline)
                    {
                        if (IsConnected(tmpLine, processLines[j]))
                        {
                            polyline.Add(processLines[j]);
                            flag.Add(j);
                            j = -1;
                            break;
                        }
                    }
                    j++;
                }

                bool IsSquare = false;
                if (RadioCase == "Square" && polyline.Count == 4 &&
                    Math.Round(polyline[0].GetLength(true), 3) == Math.Round(polyline[1].GetLength(true), 3) &&
                    Math.Round(polyline[1].GetLength(true), 3) == Math.Round(polyline[2].GetLength(true), 3) &&
                    Math.Round(polyline[2].GetLength(true), 3) == Math.Round(polyline[3].GetLength(true), 3))
                {
                    IsSquare = true;
                }

                if (RadioCase == "Square" && !IsSquare)
                {
                    continue;
                }


                if (polyline.Count != 1)
                {
                    double newX1    = polyline.Sum(tt => tt.GetStartPoint().X) / polyline.Count;
                    double newY1    = polyline.Sum(tt => tt.GetStartPoint().Y) / polyline.Count;
                    double newX2    = polyline.Sum(tt => tt.GetEndPoint().X) / polyline.Count;
                    double newY2    = polyline.Sum(tt => tt.GetEndPoint().Y) / polyline.Count;
                    double newX     = (newX1 + newX2) / 2;
                    double newY     = (newY1 + newY2) / 2;
                    XYZ    newPoint = new XYZ(newX, newY, 0);
                    LINE   newLine  = new LINE(newPoint, newPoint, 10);
                    newResult.Add(newLine);
                }
            }

            RESULT = newResult;


            return(RESULT);
        }
예제 #7
0
 public BEAM(LINE line1, LINE line2)
 {
     this.E_LINE_1    = line1;
     this.E_LINE_2    = line2;
     this.Center_Line = GetCenterLine();
 }
예제 #8
0
 public static bool Is_Horizontal(LINE line)
 {
     return(line.GetStartPoint().Y == line.GetEndPoint().Y ? true : false);
 }
예제 #9
0
 public static bool Is_Vertical(LINE line)
 {
     return(line.GetStartPoint().X == line.GetEndPoint().X ? true : false);
 }
예제 #10
0
        /// <summary>
        /// Classify Lines to "closed curve" or "H_dir_lines" or "V_dir_lines" or "else_dir_lines"
        /// </summary>
        /// <param name="LINES"></param>
        /// <param name="Collect"></param>
        /// <param name="H_Direction_Lines"></param>
        /// <param name="V_Direction_Lines"></param>
        /// <param name="Else_Direction_Lines"></param>
        public static void ClassifyLines(List <LINE> LINES,
                                         out List <List <LINE> > Collect,
                                         out List <LINE> H_Direction_Lines,
                                         out List <LINE> V_Direction_Lines,
                                         out List <LINE> Else_Direction_Lines)
        {
            Collect = new List <List <LINE> >();
            int[] is_pickup = new int[LINES.Count];
            for (int i = 0; i < LINES.Count; i++)
            {
                if (is_pickup[i] == 1)
                {
                    continue;
                }

                LINE        baseLine = LINES[i];
                List <LINE> tmpData  = new List <LINE>();
                tmpData.Add(baseLine);
                int j = 0;

                while (j < LINES.Count)
                {
                    LINE cmpLine = LINES[j];
                    if (is_pickup[j] == 1 || j == i)
                    {
                        j = j + 1;
                        continue;
                    }
                    if (cmpLine.GetStartPoint().X == baseLine.GetEndPoint().X&& cmpLine.GetStartPoint().Y == baseLine.GetEndPoint().Y)
                    {
                        baseLine = cmpLine;
                        tmpData.Add(baseLine);
                        is_pickup[j] = 1;
                        j            = 0;
                    }
                    else if (cmpLine.GetEndPoint().X == baseLine.GetEndPoint().X&& cmpLine.GetEndPoint().Y == baseLine.GetEndPoint().Y)
                    {
                        baseLine = new LINE(cmpLine.GetEndPoint(), cmpLine.GetStartPoint());
                        tmpData.Add(baseLine);
                        is_pickup[j] = 1;
                        j            = 0;
                    }
                    else if (tmpData[0].GetStartPoint().X == cmpLine.GetStartPoint().X&& tmpData[0].GetStartPoint().Y == cmpLine.GetStartPoint().Y)
                    {
                        tmpData.Insert(0, new LINE(cmpLine.GetEndPoint(), cmpLine.GetStartPoint()));
                        is_pickup[j] = 1;
                        j            = 0;
                    }
                    else if (tmpData[0].GetStartPoint().X == cmpLine.GetEndPoint().X&& tmpData[0].GetStartPoint().Y == cmpLine.GetEndPoint().Y)
                    {
                        tmpData.Insert(0, cmpLine);
                        is_pickup[j] = 1;
                        j            = 0;
                    }
                    else
                    {
                        j = j + 1;
                    }
                }

                if (tmpData.Count != 1)
                {
                    Collect.Add(tmpData);
                    is_pickup[i] = 1;
                }
            }

            H_Direction_Lines    = new List <LINE>();
            V_Direction_Lines    = new List <LINE>();
            Else_Direction_Lines = new List <LINE>();

            for (int ii = 0; ii < is_pickup.Count(); ii++)
            {
                if (is_pickup[ii] == 0)
                {
                    LINE line = LINES[ii];
                    if (GeometryResult.Is_Horizontal(line))
                    {
                        H_Direction_Lines.Add(line);
                    }
                    else if (GeometryResult.Is_Vertical(line))
                    {
                        V_Direction_Lines.Add(line);
                    }
                    else
                    {
                        Else_Direction_Lines.Add(line);
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Get Beam parameter Lines using to Create beam those lines is the center line of beam
        /// </summary>
        /// <param name="Collect"></param>
        /// <param name="H_Direction_Lines"></param>
        /// <param name="V_Direction_Lines"></param>
        /// <param name="H_Beams"></param>
        /// <param name="V_Beams"></param>
        public static List <LINE> GetBeamDrawLines(List <List <LINE> > Collect, List <LINE> H_Direction_Lines, List <LINE> V_Direction_Lines)
        {
            List <LINE> RESULT = new List <LINE>();

            /// Collect Part
            foreach (List <LINE> co in Collect)
            {
                if (co.Count() <= 4)
                {
                    LINE   line1 = co[0];
                    LINE   line2 = co[1];
                    XYZ    p1    = null;
                    XYZ    p2    = null;
                    double ll1   = GeometryResult.Get_Length(line1);
                    double ll2   = GeometryResult.Get_Length(line2);
                    if (ll1 > ll2)
                    {
                        if (line1.GetStartPoint().Y == line1.GetEndPoint().Y)
                        {
                            p1 = new XYZ(line1.GetStartPoint().X, (line1.GetStartPoint().Y + line2.GetEndPoint().Y) / 2, 0);
                            p2 = new XYZ(line1.GetEndPoint().X, (line1.GetStartPoint().Y + line2.GetEndPoint().Y) / 2, 0);
                        }
                        else if (line1.GetStartPoint().X == line1.GetEndPoint().X)
                        {
                            p1 = new XYZ((line1.GetStartPoint().X + line2.GetEndPoint().X) / 2, line1.GetStartPoint().Y, 0);
                            p2 = new XYZ((line1.GetStartPoint().X + line2.GetEndPoint().X) / 2, line1.GetEndPoint().Y, 0);
                        }
                    }
                    else
                    {
                        if (line2.GetStartPoint().Y == line2.GetEndPoint().Y)
                        {
                            p1 = new XYZ(line2.GetStartPoint().X, (line1.GetStartPoint().Y + line2.GetEndPoint().Y) / 2, 0);
                            p2 = new XYZ(line2.GetEndPoint().X, (line1.GetStartPoint().Y + line2.GetEndPoint().Y) / 2, 0);
                        }
                        else if (line2.GetStartPoint().X == line2.GetEndPoint().X)
                        {
                            p1 = new XYZ((line1.GetStartPoint().X + line1.GetEndPoint().X) / 2, line2.GetStartPoint().Y, 0);
                            p2 = new XYZ((line1.GetStartPoint().X + line1.GetEndPoint().X) / 2, line2.GetEndPoint().Y, 0);
                        }
                    }

                    if (p1 != null)
                    {
                        RESULT.Add(new LINE(p1, p2));
                    }
                }
            }

            /// H-Beam Part
            List <LINE> sorted_H = H_Direction_Lines.OrderBy(e => e.GetStartPoint().Y).ToList();
            List <LINE> H_Beams  = new List <LINE>();

            int[] is_pickup = new int[sorted_H.Count()];
            for (int i = 0; i < sorted_H.Count(); i++)
            {
                if (is_pickup[i] == 1)
                {
                    continue;
                }

                LINE baseLine = sorted_H[i];
                for (int j = 0; j < sorted_H.Count(); j++)
                {
                    if (j == i || is_pickup[j] == 1)
                    {
                        continue;
                    }

                    LINE cmpLine = sorted_H[j];

                    if (baseLine.GetSlope() == -cmpLine.GetSlope())
                    {
                        cmpLine = new LINE(cmpLine.GetEndPoint(), cmpLine.GetStartPoint());
                    }

                    if (baseLine.GetStartPoint().X == cmpLine.GetStartPoint().X&& baseLine.GetEndPoint().X == cmpLine.GetEndPoint().X)
                    {
                        is_pickup[i] = 1;
                        is_pickup[j] = 1;
                        XYZ p1 = new XYZ((baseLine.GetStartPoint().X + cmpLine.GetStartPoint().X) / 2, (baseLine.GetStartPoint().Y + cmpLine.GetStartPoint().Y) / 2, 0);
                        XYZ p2 = new XYZ((baseLine.GetEndPoint().X + cmpLine.GetEndPoint().X) / 2, (baseLine.GetEndPoint().Y + cmpLine.GetEndPoint().Y) / 2, 0);
                        H_Beams.Add(new LINE(p1, p2));
                        RESULT.Add(new LINE(p1, p2));
                        break;
                    }
                }
            }

            /// V-Beam Part
            List <LINE> V_Beams  = new List <LINE>();
            List <LINE> sorted_V = V_Direction_Lines.OrderBy(e => e.GetStartPoint().X).ToList();

            is_pickup = new int[sorted_V.Count()];
            for (int i = 0; i < sorted_V.Count(); i++)
            {
                if (is_pickup[i] == 1)
                {
                    continue;
                }

                LINE baseLine = sorted_V[i];
                for (int j = 0; j < sorted_V.Count(); j++)
                {
                    if (j == i || is_pickup[j] == 1)
                    {
                        continue;
                    }

                    LINE cmpLine = sorted_V[j];

                    if (baseLine.GetSlope() == -cmpLine.GetSlope())
                    {
                        cmpLine = new LINE(cmpLine.GetEndPoint(), cmpLine.GetStartPoint());
                    }

                    if (baseLine.GetStartPoint().Y == cmpLine.GetStartPoint().Y&& baseLine.GetEndPoint().Y == cmpLine.GetEndPoint().Y)
                    {
                        is_pickup[i] = 1;
                        is_pickup[j] = 1;
                        XYZ p1 = new XYZ((baseLine.GetStartPoint().X + cmpLine.GetStartPoint().X) / 2, (baseLine.GetStartPoint().Y + cmpLine.GetStartPoint().Y) / 2, 0);
                        XYZ p2 = new XYZ((baseLine.GetEndPoint().X + cmpLine.GetEndPoint().X) / 2, (baseLine.GetEndPoint().Y + cmpLine.GetEndPoint().Y) / 2, 0);
                        V_Beams.Add(new LINE(p1, p2));
                        RESULT.Add(new LINE(p1, p2));
                        break;
                    }
                }
            }


            return(RESULT);
        }
예제 #12
0
        private List <FloorEdges> SplitFloorBySubBeam(List <LINE> floor, LINE subbeam)
        {
            List <FloorEdges> Floors = new List <FloorEdges>();
            /////// 檢查subBeam與板邊界是否有兩個交點
            List <int> CrossPo = new List <int>();

            for (int i = 0; i < floor.Count; i++)
            {
                LINE floorEdge = floor[i];
                if (Math.Abs(Math.Round(floorEdge.GetSlope(), 3)) == Math.Abs(Math.Round(subbeam.GetSlope(), 3)))
                {
                    continue;
                }

                XYZ crossPoint = floorEdge.GetCrossPoint(subbeam);

                if (IsCloseEndsPoint(subbeam, crossPoint) && floorEdge.IsPointInLine(crossPoint))
                {
                    CrossPo.Add(i);
                }
            }

            /////// 沒有兩個交點則不處理直接回傳
            if (CrossPo.Count != 2)
            {
                FloorEdges Floor = new FloorEdges(floor);
                Floors.Add(Floor);
                return(Floors);
            }

            /////// 有兩個交點則開始處理梁的分離

            /// 將板轉換成節點
            List <XYZ> nodes = new List <XYZ>();

            foreach (LINE item in floor)
            {
                nodes.Add(item.GetStartPoint());
            }
            nodes.Add(floor[floor.Count - 1].GetEndPoint());

            /// 取的偏移後的交點
            XYZ        targetPoint  = floor[CrossPo[0]].GetStartPoint();
            LINE       offSetLine_1 = subbeam.GetShiftLines(floor[CrossPo[0]].GetStartPoint(), subbeam.Width / 2, "IN")[0];
            LINE       offSetLine_2 = subbeam.GetShiftLines(floor[CrossPo[0]].GetEndPoint(), subbeam.Width / 2, "IN")[0];
            XYZ        crossPoint1  = offSetLine_1.GetCrossPoint(floor[CrossPo[0]]);
            XYZ        crossPoint2  = offSetLine_1.GetCrossPoint(floor[CrossPo[1]]);
            XYZ        crossPoint3  = offSetLine_2.GetCrossPoint(floor[CrossPo[0]]);
            XYZ        crossPoint4  = offSetLine_2.GetCrossPoint(floor[CrossPo[1]]);
            List <XYZ> crossPoint_1 = new List <XYZ>()
            {
                crossPoint1, crossPoint2
            };
            List <XYZ> crossPoint_2 = new List <XYZ>()
            {
                crossPoint3, crossPoint4
            };

            /// Part 1
            int        kk     = 0;
            List <XYZ> part_1 = new List <XYZ>();

            for (int i = 0; i < nodes.Count; i++)
            {
                if (i > CrossPo[0] && i <= CrossPo[1] && kk < 2)
                {
                    part_1.Add(crossPoint_1[kk]);
                    kk = kk + 1;
                }
                else if (i <= CrossPo[0] || i > CrossPo[1])
                {
                    part_1.Add(nodes[i]);
                }
            }

            /// Part 2
            kk = 0;
            List <XYZ> part_2 = new List <XYZ>();

            for (int i = 0; i < nodes.Count; i++)
            {
                if (i > CrossPo[0] && i <= CrossPo[1])
                {
                    part_2.Add(nodes[i]);
                }
                else if ((i == CrossPo[0] || i == CrossPo[1] + 1) && kk < 2)
                {
                    part_2.Add(crossPoint_2[kk]);
                    kk = kk + 1;
                }
            }
            part_2.Add(crossPoint_2[0]);

            try
            {
                /// 將節點轉換成LINE
                List <LINE> newFloor_1 = new List <LINE>();
                for (int i = 0; i < part_1.Count() - 1; i++)
                {
                    newFloor_1.Add(new LINE(part_1[i], part_1[i + 1]));
                }

                List <LINE> newFloor_2 = new List <LINE>();
                for (int i = 0; i < part_2.Count() - 1; i++)
                {
                    newFloor_2.Add(new LINE(part_2[i], part_2[i + 1]));
                }

                Floors.Add(new FloorEdges(newFloor_1));
                Floors.Add(new FloorEdges(newFloor_2));
            }
            catch (Exception)
            {
                return(new List <FloorEdges>()
                {
                    new FloorEdges(floor)
                });
            }

            return(Floors);
        }
        /// <summary>
        /// Pick a DWG import instance, extract polylines
        /// from it visible in the current view and create
        /// filled regions from them.
        /// </summary>
        private void GeneralCAD(UIDocument uidoc)
        {
            Document doc         = uidoc.Document;
            View     active_view = doc.ActiveView;
            List <GeometryObject> visible_dwg_geo = new List <GeometryObject>();

            // 點選匯入之CAD
            Reference r      = uidoc.Selection.PickObject(ObjectType.Element, new JtElementsOfClassSelectionFilter <ImportInstance>());
            var       import = doc.GetElement(r) as ImportInstance;

            // 取得幾何
            var ge = import.get_Geometry(new Options());

            foreach (GeometryObject go in ge)
            {
                if (go is GeometryInstance)
                {
                    GeometryInstance gi  = go as GeometryInstance;
                    GeometryElement  ge2 = gi.GetInstanceGeometry();
                    this.Origin       = gi.Transform.Origin;
                    this.Rotation_Dir = new List <XYZ>()
                    {
                        gi.Transform.BasisX, gi.Transform.BasisY, gi.Transform.BasisZ
                    };
                    this.Rotation = GetSita(this.Rotation_Dir[0]);
                    this.Scale    = gi.Transform.Scale;

                    if (ge2 != null)
                    {
                        foreach (var obj in ge2)
                        {
                            /// 如果Object為幾何物件
                            if ((obj is PolyLine && IsPloyLine) || (obj is Arc && IsArc) || (obj is Line && IsLine))
                            {
                                GraphicsStyle gStyle = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle;
                                // Check if the layer is visible in the view.
                                if (!active_view.GetCategoryHidden(gStyle.GraphicsStyleCategory.Id))
                                {
                                    visible_dwg_geo.Add(obj);
                                }
                            }
                            else if (obj is Solid)
                            {
                                try
                                {
                                    Solid  soild     = obj as Solid;
                                    string layerName = "";
                                    foreach (PlanarFace planarFace in soild.Faces)
                                    {
                                        EdgeArrayArray Eaa = planarFace.EdgeLoops;
                                        foreach (EdgeArray edgearray in Eaa)
                                        {
                                            List <LINE> edges = new List <LINE>();
                                            foreach (Edge edge in edgearray)
                                            {
                                                var gStyle = doc.GetElement(edge.GraphicsStyleId) as GraphicsStyle;
                                                layerName = gStyle.GraphicsStyleCategory.Name;
                                                Line curve   = edge.AsCurve() as Line;
                                                LINE newLine = new LINE(curve.GetEndPoint(0), curve.GetEndPoint(1));
                                                edges.Add(newLine);
                                            }

                                            List <List <LINE> > EDGEs = this.LayersAndClosedRegions.Keys.Contains(layerName) ?
                                                                        this.LayersAndClosedRegions[layerName] : new List <List <LINE> >();
                                            EDGEs.Add(edges);
                                            this.LayersAndClosedRegions[layerName] = EDGEs;
                                        }
                                    }
                                }
                                catch (Exception)
                                {
                                }
                            }
                        }
                    }
                }
            }


            /// 取得各格圖層的幾何資訊
            Dictionary <string, List <LINE> > res = new Dictionary <string, List <LINE> >();

            if (visible_dwg_geo.Count > 0)
            {
                // Retrieve first filled region type
                var filledType = new FilteredElementCollector(doc)
                                 .WhereElementIsElementType()
                                 .OfClass(typeof(FilledRegionType))
                                 .OfType <FilledRegionType>()
                                 .First();

                using (var t = new Transaction(doc))
                {
                    t.Start("ProcessDWG");
                    List <LINE> tmp = new List <LINE>();
                    foreach (var obj in visible_dwg_geo)
                    {
                        var    gStyle    = doc.GetElement(obj.GraphicsStyleId) as GraphicsStyle;
                        string layerName = gStyle.GraphicsStyleCategory.Name;

                        tmp = res.ContainsKey(layerName) ? res[layerName] : new List <LINE>();
                        if (obj is Arc)
                        {
                            var  Arc      = obj as Arc;
                            XYZ  newPoint = new XYZ(Arc.Center.X, Arc.Center.Y, 0);
                            LINE newLine  = new LINE(newPoint, newPoint, 10);
                            newLine.Name = "Circle";
                            tmp.Add(newLine);
                        }
                        if (obj is PolyLine)
                        {
                            // Create loops for detail region
                            var poly   = obj as PolyLine;
                            var points = poly.GetCoordinates();
                            for (int kk = 0; kk < points.Count - 1; kk++)
                            {
                                if (GetDistance(points[kk], points[kk + 1]) != 0)
                                {
                                    LINE newLine = new LINE(points[kk], points[kk + 1]);
                                    newLine.Name = "Polyline";
                                    tmp.Add(newLine);
                                }
                            }
                        }
                        else if (obj is Line)
                        {
                            var  line    = obj as Line;
                            LINE newLine = new LINE(line.GetEndPoint(0), line.GetEndPoint(1));
                            newLine.Name = "Line";
                            tmp.Add(newLine);
                        }
                        res[layerName] = tmp;
                    }
                }
            }

            this.LayersAndGeometries = res;
            try
            {
            }
            catch (Exception e)
            {
            }
        }
예제 #14
0
        /// <summary>
        /// 取得所有梁並將轉換至各樓板邊緣線
        /// </summary>
        /// <param name="BEAMS"></param>
        /// <returns></returns>
        private List <List <LINE> > GetBeamGroup(List <LINE> BEAMS)
        {
            double SHIFTDIST = 2000 / 304.8;

            int number = 0;

            int[] count = new int[BEAMS.Count];
            Dictionary <string, List <int> >  pickNumbers = new Dictionary <string, List <int> >();
            Dictionary <string, List <LINE> > DictRes     = new Dictionary <string, List <LINE> >();

            for (int i = 0; i < BEAMS.Count; i++)
            {
                List <LINE> ResTmp         = new List <LINE>();
                List <int>  tmpcheckPicked = new List <int>()
                {
                };
                for (int j = 0; j < BEAMS.Count; j++)
                {
                    if (j == i)
                    {
                        continue;
                    }
                    if (CMPPoints(BEAMS[i].GetEndPoint(), BEAMS[j].GetStartPoint(), SHIFTDIST))
                    {
                        ResTmp.Add(BEAMS[j]);
                        tmpcheckPicked.Add(j);
                    }
                    else if (CMPPoints(BEAMS[i].GetEndPoint(), BEAMS[j].GetEndPoint(), SHIFTDIST))
                    {
                        ResTmp.Add(new LINE(BEAMS[j].GetEndPoint(),
                                            BEAMS[j].GetStartPoint(),
                                            BEAMS[j].Name,
                                            BEAMS[j].LevelName,
                                            BEAMS[j].Width));
                        tmpcheckPicked.Add(j);
                    }
                }

                List <LINE> Res = null;
                for (int pp = 0; pp < ResTmp.Count; pp++)
                {
                    bool open = true;
                    Res = new List <LINE> {
                        BEAMS[i], ResTmp[pp]
                    };
                    List <int> checkPicked = new List <int>()
                    {
                        i, tmpcheckPicked[pp]
                    };

                    while (open)
                    {
                        int         j      = 0;
                        List <LINE> tmpRes = new List <LINE>();
                        tmpRes = Res.ToList();
                        List <int> tmpCheckPicked = new List <int>();
                        while (j < BEAMS.Count)
                        {
                            if (!checkPicked.Contains(j))
                            {
                                if (CMPPoints(Res[Res.Count - 1].GetEndPoint(), BEAMS[j].GetStartPoint(), SHIFTDIST))
                                {
                                    tmpRes.Add(BEAMS[j]);
                                    tmpCheckPicked.Add(j);
                                }
                                else if (CMPPoints(Res[Res.Count - 1].GetEndPoint(), BEAMS[j].GetEndPoint(), SHIFTDIST))
                                {
                                    tmpRes.Add(new LINE(BEAMS[j].GetEndPoint(),
                                                        BEAMS[j].GetStartPoint(),
                                                        BEAMS[j].Name,
                                                        BEAMS[j].LevelName,
                                                        BEAMS[j].Width));
                                    tmpCheckPicked.Add(j);
                                }
                            }
                            j++;
                        }

                        if (tmpRes.Count != Res.Count)
                        {
                            LINE          tmp  = tmpRes[0];
                            List <double> diff = new List <double>();
                            for (int ii = Res.Count; ii < tmpRes.Count; ii++)
                            {
                                if (!IsSamePoint(tmp.GetStartPoint(), tmpRes[ii].GetEndPoint()))
                                {
                                    diff.Add(new LINE(tmp.GetStartPoint(), tmpRes[ii].GetEndPoint()).GetLength());
                                }
                                else
                                {
                                    diff.Add(0);
                                }
                            }
                            int po = diff.FindIndex(item => item.Equals(diff.Min()));
                            checkPicked.Add(tmpCheckPicked[po]);
                            Res.Add(tmpRes[Res.Count + po]);
                            tmpCheckPicked.Clear();
                            if (diff.Min() < SHIFTDIST)
                            {
                                open = false;
                            }
                            else if (CMPPoints(Res[0].GetEndPoint(), Res[Res.Count - 1].GetEndPoint(), SHIFTDIST))
                            {
                                open = false;
                                SaveTmp(Res);
                                Res.RemoveAt(0);
                                checkPicked.RemoveAt(0);
                            }
                        }
                        else
                        {
                            open = false;
                        }
                    }

                    pickNumbers[number.ToString()] = checkPicked;
                    DictRes[number.ToString()]     = Res;
                    number++;
                }
            }


            ////// Filter Groups
            List <int>    sumOf = new List <int>();
            List <string> keys  = pickNumbers.Keys.ToList();

            foreach (KeyValuePair <string, List <int> > item in pickNumbers)
            {
                sumOf.Add(item.Value.Sum());
            }

            int[] flag = new int[sumOf.Count];
            for (int ii = 0; ii < sumOf.Count; ii++)
            {
                if (flag[ii] == -1)
                {
                    continue;
                }
                for (int j = 0; j < sumOf.Count; j++)
                {
                    List <LINE> tmpBeams = DictRes[keys[j]];
                    double      Len      = IsSamePoint(tmpBeams[0].GetStartPoint(), tmpBeams[tmpBeams.Count - 1].GetEndPoint()) ?
                                           0 : (new LINE(tmpBeams[0].GetStartPoint(), tmpBeams[tmpBeams.Count - 1].GetEndPoint())).GetLength();

                    if (ii != j && sumOf[ii] == sumOf[j])
                    {
                        flag[j] = -1;
                    }
                    else if (Len > SHIFTDIST)
                    {
                        flag[j] = -1;
                    }
                }
            }
            List <int> Flag = flag.ToList();

            int[] lastPo = FindAllIndexof(Flag, 0);

            Dictionary <string, List <LINE> > DictResult = new Dictionary <string, List <LINE> >();
            List <List <LINE> >           RESULT         = new List <List <LINE> >();
            Dictionary <int, List <int> > poo            = new Dictionary <int, List <int> >();

            foreach (int pp in lastPo)
            {
                DictResult[keys[pp]] = DictRes[keys[pp]];
                RESULT.Add(DictRes[keys[pp]]);
                poo[pp] = pickNumbers[pp.ToString()];
            }
            return(RESULT);
        }
        private List <List <LINE> > DataPreProcessing(Level targetLevel, Level targetLevelCol, List <LINE> BEAMs)
        {
            ///// 取得所有梁平均寬度
            double SHIFTs_Width_Of_Beam = 0;

            foreach (LINE item in BEAMs)
            {
                SHIFTs_Width_Of_Beam += item.Width;
            }
            SHIFTs_Width_Of_Beam = SHIFTs_Width_Of_Beam / BEAMs.Count;

            ///// 取得目標樓層所有的柱
            Dictionary <string, List <LINE> > columns = GetAllColumnsBoundary(targetLevelCol);
            int        kk              = 0;
            double     SHIFTs          = 0;
            List <XYZ> colCenterPoints = new List <XYZ>();

            foreach (KeyValuePair <string, List <LINE> > item in columns)
            {
                foreach (LINE line in item.Value)
                {
                    SHIFTs += line.GetLength();
                    kk      = kk + 1;
                }

                if (item.Value.Count != 0)
                {
                    double All_X = item.Value.Sum(t => t.GetStartPoint().X) / item.Value.Count;
                    double All_Y = item.Value.Sum(t => t.GetStartPoint().Y) / item.Value.Count;
                    colCenterPoints.Add(new XYZ(All_X, All_Y, 0));
                }
            }
            SHIFTs = SHIFTs / kk;


            ////// 延伸梁的邊緣線至柱中心
            /// 找出subBeam,將不做延伸處理
            List <int> NonePo = new List <int>();

            for (int i = 0; i < BEAMs.Count; i++)
            {
                for (int j = 0; j < BEAMs.Count; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    LINE b1 = BEAMs[i];
                    LINE b2 = BEAMs[j];
                    if (Math.Round(b1.GetSlope(), 3) == Math.Round(b2.GetSlope(), 3))
                    {
                        continue;
                    }
                    try
                    {
                        XYZ crossPoint = b1.GetCrossPoint(b2);
                        if (IsCloseEndsPoint(b1, crossPoint, SHIFTs_Width_Of_Beam) && b2.IsPointInLine(crossPoint))
                        {
                            NonePo.Add(i);
                            break;
                        }
                        ;
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            List <LINE> Beams_Connect = new List <LINE>();

            for (int i = 0; i < BEAMs.Count; i++)
            {
                if (NonePo.Contains(i))
                {
                    Beams_Connect.Add(BEAMs[i]);
                    continue;
                }
                ;

                List <XYZ> col = GetClosedColumn(colCenterPoints, BEAMs[i]);

                XYZ newStartPoint = GetNewEndedPoint(col[0], BEAMs[i].GetStartPoint(), BEAMs[i]);
                XYZ newEndPoint   = GetNewEndedPoint(col[1], BEAMs[i].GetEndPoint(), BEAMs[i]);
                if (newStartPoint.X == newEndPoint.X && newStartPoint.Y == newEndPoint.Y)
                {
                    Beams_Connect.Add(BEAMs[i]);
                    continue;
                }
                LINE newBeam = new LINE(newStartPoint, newEndPoint);
                newBeam.Name      = BEAMs[i].Name;
                newBeam.Width     = BEAMs[i].Width;
                newBeam.LevelName = BEAMs[i].LevelName;
                Beams_Connect.Add(newBeam);
            }



            /// 將所有的梁轉換至各樓板邊緣線
            List <LINE>         nonSelected = new List <LINE>();
            List <List <LINE> > BeamGroup   = GetBeamGroup(Beams_Connect, ref nonSelected, SHIFTs);

            SaveTmp(BeamGroup);
            /// 將樓板邊緣線偏移並連接
            List <List <LINE> > NewBeamGroup = BeamConnectAndShiftProcessing(BeamGroup);

            SaveTmp(NewBeamGroup);

            if (NewBeamGroup.Count == 0)
            {
                return(NewBeamGroup);
            }

            double newHeight = NewBeamGroup[0][0].GetStartPoint().Z;
            ///// 重設目標樓層所有的柱的高度
            Dictionary <string, List <LINE> > columns2 = new Dictionary <string, List <LINE> >();

            foreach (KeyValuePair <string, List <LINE> > item in columns)
            {
                SaveTmp(item.Value);
                List <LINE> newFloor = new List <LINE>();
                foreach (LINE floor in item.Value)
                {
                    XYZ newSt = new XYZ(floor.GetStartPoint().X,
                                        floor.GetStartPoint().Y,
                                        newHeight);
                    XYZ newEn = new XYZ(floor.GetEndPoint().X,
                                        floor.GetEndPoint().Y,
                                        newHeight);
                    newFloor.Add(new LINE(newSt, newEn));
                }
                columns2[item.Key] = newFloor;
            }

            List <List <LINE> > Result = new List <List <LINE> >();

            foreach (List <LINE> item in NewBeamGroup)
            {
                Result.Add(TakeOffColumnEdge(columns2, item));
            }

            SaveTmp(Result);
            Result = ConnectedEdgeFromMiddleColumns(Result);

            SaveTmp(Result);
            /// 拿掉第一輪subBeam
            List <List <LINE> > Res  = TakeOffSubBeams(Result, nonSelected, SHIFTs_Width_Of_Beam);
            List <List <LINE> > Res2 = TakeOffSubBeams(Res, nonSelected, SHIFTs_Width_Of_Beam);

            SaveTmp(Res2);
            return(Res2);
        }
예제 #16
0
 public static double Get_Length(LINE Line)
 {
     return(Math.Sqrt(
                (Line.GetStartPoint().X - Line.GetEndPoint().X) * (Line.GetStartPoint().X - Line.GetEndPoint().X) +
                (Line.GetStartPoint().Y - Line.GetEndPoint().Y) * (Line.GetStartPoint().Y - Line.GetEndPoint().Y)));
 }
        /// <summary>
        /// 取得所有梁並將轉換至各樓板邊緣線
        /// </summary>
        /// <param name="BEAMS"></param>
        /// <returns></returns>
        private List <List <LINE> > GetBeamGroup(List <LINE> BEAMS, ref List <LINE> nonSelected, double SHIFTDIST)
        {
            //double SHIFTDIST = 2000 / 304.8;

            /// 計算梁的平均長度
            //double SHIFTDIST = BEAMS.Sum(m => m.GetLength()) / BEAMS.Count / 3;

            SHIFTDIST = SHIFTDIST * 3;

            Dictionary <string, List <int> >  pickNumbers = new Dictionary <string, List <int> >();
            Dictionary <string, List <LINE> > DictRes     = new Dictionary <string, List <LINE> >();

            for (int i = 0; i < BEAMS.Count; i++)
            {
                int        j      = 0;
                List <int> picked = new List <int>()
                {
                    i
                };
                List <LINE> tmpBeams = new List <LINE>();
                tmpBeams.Add(BEAMS[i]);
                string direction = "";

                while (j < BEAMS.Count)
                {
                    if (tmpBeams.Count > 1 && CMPPoints(tmpBeams[0].GetStartPoint(), tmpBeams[tmpBeams.Count - 1].GetEndPoint(), SHIFTDIST))
                    {
                        break;
                    }

                    LINE        target    = tmpBeams[tmpBeams.Count - 1];
                    List <int>  PickedTmp = new List <int>();
                    List <LINE> ResTmp    = GetClosedBeams(BEAMS, target, ref PickedTmp, picked, SHIFTDIST);
                    JudgeDir(tmpBeams, ref direction);
                    List <double> angle = new List <double>();
                    for (int p = 0; p < ResTmp.Count; p++)
                    {
                        XYZ tarDir   = target.GetDirection();
                        XYZ itemDir  = ResTmp[p].GetDirection();
                        XYZ CrossRes = GetCross(tarDir, itemDir);

                        double DotRes = -tarDir.X * itemDir.X + -tarDir.Y * itemDir.Y;
                        double ang    = Math.Acos(Math.Round(DotRes, 2)) * 180 / Math.PI;
                        if (CrossRes.Z > 0)
                        {
                            ang = 360 - ang;
                        }

                        if (direction == "逆")
                        {
                            ang = 360 - ang;
                        }
                        angle.Add(ang);
                    }

                    if (ResTmp.Count != 0)
                    {
                        double minAng = angle.Min();
                        int    po1    = FindAllIndexof(angle, minAng)[0];
                        tmpBeams.Add(ResTmp[po1]);
                        picked.Add(PickedTmp[po1]);
                        j = 0;
                    }
                    else
                    {
                        j++;
                    }
                }

                DictRes[i.ToString()]     = tmpBeams;
                pickNumbers[i.ToString()] = picked;
            }

            return(TakeOffSameRegion(ref nonSelected, pickNumbers, DictRes, BEAMS, SHIFTDIST));
        }
        /// <summary>
        /// 梁群組處理
        /// </summary>
        /// <param name="LINES"></param>
        /// <returns></returns>
        private List <BEAM> BeamCenterLineProcessing(List <LINE> LINES)
        {
            List <BEAM> Beams = new List <BEAM>();
            List <int>  flag  = new List <int>();

            for (int i = 0; i < LINES.Count; i++)
            {
                if (flag.Contains(i))
                {
                    continue;
                }

                List <int> tmpFlag = new List <int>()
                {
                };
                List <LINE>   tmpLine     = new List <LINE>();
                List <double> tmpDistance = new List <double>();
                for (int j = 0; j < LINES.Count; j++)
                {
                    double dist = 0;
                    if (i == j || tmpFlag.Contains(j))
                    {
                        continue;
                    }
                    bool IsSameDir = IsSameDirection(LINES[i], LINES[j], ref dist);
                    if (IsSameDir && dist != 0)
                    {
                        LINE tmpLine1 = LINES[i];
                        LINE tmpLine2 = LINES[j];
                        bool IsReverse = IsReverseDirection(tmpLine1.GetDirection(), tmpLine2.GetDirection());
                        XYZ  stPoint_1; XYZ stPoint_2; XYZ enPoint_1; XYZ enPoint_2;
                        if (IsReverse)
                        {
                            stPoint_1 = tmpLine1.GetStartPoint();
                            stPoint_2 = tmpLine2.GetEndPoint();
                            enPoint_1 = tmpLine1.GetEndPoint();
                            enPoint_2 = tmpLine2.GetStartPoint();
                        }
                        else
                        {
                            stPoint_1 = tmpLine1.GetStartPoint();
                            stPoint_2 = tmpLine2.GetStartPoint();
                            enPoint_1 = tmpLine1.GetEndPoint();
                            enPoint_2 = tmpLine2.GetEndPoint();
                        }
                        double dist_1 = GetDistanceByTwoPoint(stPoint_1, stPoint_2);
                        double dist_2 = GetDistanceByTwoPoint(enPoint_1, enPoint_2);

                        if (dist == dist_1 && dist_1 == dist_2)
                        {
                            LINE newLINE = LINES[j];
                            if (IsReverse)
                            {
                                newLINE           = new LINE(LINES[j].GetEndPoint(), LINES[j].GetStartPoint());
                                newLINE.Name      = LINES[j].Name;
                                newLINE.LevelName = LINES[j].LevelName;
                                newLINE.Width     = LINES[j].Width;
                            }
                            tmpFlag.Add(j);
                            tmpLine.Add(newLINE);
                            tmpDistance.Add(dist);
                        }
                    }
                }

                if (tmpFlag.Count > 0)
                {
                    double minDist = tmpDistance.Min();
                    int    po      = FindAllIndexof(tmpDistance, minDist)[0];
                    flag.Add(i);
                    flag.Add(tmpFlag[po]);
                    Beams.Add(new BEAM(LINES[i], tmpLine[po]));
                }
            }

            return(Beams);
        }