/// <summary>
        /// 取得所有的梁
        /// </summary>
        /// <returns></returns>
        private List <LINE> GetAllBeams()
        {
            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
                {
                    LocationCurve Locurve = beam.Location as LocationCurve;
                    Line          line    = Locurve.Curve as Line;
                    LINE          LINE    = new LINE(line.Origin, new XYZ(line.Origin.X + line.Length * line.Direction.X,
                                                                          line.Origin.Y + line.Length * line.Direction.Y,
                                                                          line.Origin.Z + line.Length * line.Direction.Z));


                    ElementType type      = revitDoc.GetElement(beam.GetTypeId()) as ElementType;
                    Parameter   mLevel    = beam.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM);
                    string      levelName = mLevel.AsValueString();
                    LINE.Name      = beam.Name;
                    LINE.LevelName = levelName;

                    //to get width of section
                    Parameter b = type.LookupParameter("b");
                    LINE.Width = b.AsDouble();

                    ////to get height of section
                    //Parameter h = type.LookupParameter("h");
                    //double height = h.AsDouble();

                    if (Math.Round(LINE.GetStartPoint().Z, 3) == Math.Round(LINE.GetEndPoint().Z, 3))
                    {
                        if (LINE.GetDirection().X == 1 || LINE.GetDirection().Y == 1 || LINE.GetDirection().X == -1 || LINE.GetDirection().Y == -1)
                        {
                            Beams.Add(LINE);
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
            return(Beams);
        }
 private void ConnectedEdge(ref List <List <LINE> > NewBeamGroup)
 {
     foreach (List <LINE> Beams in NewBeamGroup)
     {
         Dictionary <int, LINE> tmpAddLines = new Dictionary <int, LINE>();
         for (int i = 0; i < Beams.Count; i++)
         {
             LINE L1 = Beams[i];
             LINE L2 = i + 1 == Beams.Count ? Beams[0] : Beams[i + 1];
             if (!L1.IsSameDirection(L2.GetDirection(), true))
             {
                 XYZ crossPoint = L1.GetCrossPoint(L2);
                 Beams[i].ResetParameters(crossPoint, "EndPoint");
                 if (i + 1 == Beams.Count)
                 {
                     Beams[0].ResetParameters(crossPoint, "StartPoint");
                 }
                 else
                 {
                     Beams[i + 1].ResetParameters(crossPoint, "StartPoint");
                 }
             }
         }
     }
 }
        /// <summary>
        /// 判斷兩線段是否同向
        /// </summary>
        /// <param name="line1"></param>
        /// <param name="line2"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        private bool IsSameDirection(LINE line1, LINE line2, ref double distance)
        {
            distance = -1;
            XYZ  Dir_1           = line1.GetDirection();
            XYZ  Dir_2           = line2.GetDirection();
            bool isSameDirection = IsSamePoint(Dir_1, Dir_2);

            if (!isSameDirection)
            {
                return(false);
            }

            /// 若端點重疊則回傳false
            if (IsSamePoint(line1.GetStartPoint(), line2.GetStartPoint()) ||
                IsSamePoint(line1.GetEndPoint(), line2.GetEndPoint()) ||
                IsSamePoint(line1.GetStartPoint(), line2.GetEndPoint()) ||
                IsSamePoint(line1.GetEndPoint(), line2.GetStartPoint()))
            {
                return(false);
            }

            /// 判斷是否在同一直線上 if == 0
            distance = Math.Round(line1.GetDistanceFromPoint(line2.GetStartPoint()), IG_POINT);

            return(true);
        }
        private XYZ GetNewEndedPoint(XYZ ColTarget_, XYZ EndPoint, LINE Beam)
        {
            XYZ    ColTarget    = new XYZ(ColTarget_.X, ColTarget_.Y, Beam.GetStartPoint().Z);
            XYZ    startPoint   = Beam.GetStartPoint();
            XYZ    oriDir       = Beam.GetDirection();
            XYZ    newDir       = new XYZ(oriDir.Y, -oriDir.X, oriDir.Z);
            LINE   VerticalLINE = new LINE(ColTarget, newDir, 1);
            XYZ    newPoint     = VerticalLINE.GetCrossPoint(Beam);
            double dist         = Math.Sqrt((newPoint.X - EndPoint.X) * (newPoint.X - EndPoint.X) +
                                            (newPoint.Y - EndPoint.Y) * (newPoint.Y - EndPoint.Y));

            if (dist > Beam.GetLength())
            {
                return(EndPoint);
            }
            return(VerticalLINE.GetCrossPoint(Beam));
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="NewBeamGroup"></param>
        /// <returns></returns>
        private List <List <LINE> > ConnectedEdgeFromMiddleColumns(List <List <LINE> > NewBeamGroup)
        {
            List <List <LINE> > newFloorGroup = new List <List <LINE> >();

            foreach (List <LINE> Beams in NewBeamGroup)
            {
                //SaveTmp(Beams);
                Dictionary <int, LINE> tmpAddLines = new Dictionary <int, LINE>();
                for (int i = 0; i < Beams.Count; i++)
                {
                    LINE L1 = Beams[i];
                    LINE L2 = i + 1 == Beams.Count ? Beams[0] : Beams[i + 1];
                    if (L1.IsSameDirection(L2.GetDirection(), true) && !L1.IsPointInLine(L2.GetStartPoint()))
                    {
                        tmpAddLines[i] = new LINE(L1.GetEndPoint(), L2.GetStartPoint());
                    }
                }

                foreach (int ii in tmpAddLines.Keys)
                {
                    Beams.Add(tmpAddLines[ii]);
                }
                SaveTmp(Beams);
                int         kk       = 0;
                List <LINE> newBeams = new List <LINE>();
                int[]       flag     = new int[Beams.Count];
                flag[kk] = -1;
                newBeams.Add(Beams[0]);
                while (kk < Beams.Count)
                {
                    if (flag[kk] != -1 && newBeams[newBeams.Count - 1].IsPointInLine(Beams[kk].GetStartPoint()))
                    {
                        flag[kk] = -1;
                        newBeams.Add(Beams[kk]);
                        kk = 0;
                    }
                    kk = kk + 1;
                }

                newFloorGroup.Add(newBeams);
                //SaveTmp(newBeams);
            }

            return(newFloorGroup);
        }
Beispiel #6
0
        public XYZ GetCrossPoint(LINE line2)
        {
            if (this.IsSameDirection(line2.GetDirection(), true))
            {
                LINE tmpLine = new LINE(this.GetEndPoint(), line2.GetStartPoint());
                if (this.IsSameDirection(tmpLine.Direction, true))
                {
                    if (this.IsSameDirection(line2.Direction, true))
                    {
                        return((this.GetEndPoint() + line2.GetStartPoint()) / 2);
                    }
                    else
                    {
                        return((this.GetStartPoint() + line2.GetStartPoint()) / 2);
                    }
                }
                else
                {
                    return(this.GetEndPoint());
                }
            }

            MATRIX m1 = new MATRIX(new double[, ] {
                { this.Direction.X, -line2.Direction.X },
                { this.Direction.Y, -line2.Direction.Y }
            });
            MATRIX m2 = new MATRIX(new double[, ] {
                { line2.OriPoint.X - this.OriPoint.X }, { line2.OriPoint.Y - this.OriPoint.Y }
            });

            MATRIX m3  = m1.InverseMatrix();
            MATRIX res = m3.CrossMatrix(m2);

            double[,] tt = res.Matrix;
            double newX = this.OriPoint.X + this.Direction.X * tt[0, 0];
            double newY = this.OriPoint.Y + this.Direction.Y * tt[0, 0];

            return(new XYZ(newX, newY, this.OriPoint.Z));
        }
        /// <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));
        }
        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);
        }
        /// <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);
        }