/// <summary>
        /// Determines whether the specified PolylineSegment instances are considered equal.
        /// </summary>
        /// <param name="obj">The object to compare.</param>
        /// <returns>true if the objects are considered equal; otherwise, nil.</returns>
        public override bool Equals(object obj)
        {
            PolylineSegment seg = obj as PolylineSegment;

            if (seg == null)
            {
                return(false);
            }
            if (seg.GetHashCode() != this.GetHashCode())
            {
                return(false);
            }
            if (!_startPoint.IsEqualTo(seg.StartPoint))
            {
                return(false);
            }
            if (!_endPoint.IsEqualTo(seg.EndPoint))
            {
                return(false);
            }
            if (_bulge != seg.Bulge)
            {
                return(false);
            }
            if (_startWidth != seg.StartWidth)
            {
                return(false);
            }
            if (_endWidth != seg.EndWidth)
            {
                return(false);
            }
            return(true);
        }
コード例 #2
0
        private void ResolveLineType(Point2d segPt1, Point2d segPt2,
                                     List <LineSegment2d> verticalLines, List <LineSegment2d> horizontalLines)
        {
            if (!segPt1.IsEqualTo(segPt2))
            {
                List <Point2d> pts = new List <Point2d>()
                {
                    segPt1, segPt2
                };

                Vector2d vector = segPt2 - segPt1;
                if (vector.IsParallelTo(Vector2d.YAxis))
                {
                    //Это вертикальная линия
                    pts.Sort((p1, p2) =>
                    {
                        return(p1.Y.CompareTo(p2.Y));//Сначала нижняя, потом верхняя
                    });

                    verticalLines.Add(new LineSegment2d(pts[0], pts[1]));
                }
                else if (vector.IsParallelTo(Vector2d.XAxis))
                {
                    //Это горизонтальная линия
                    pts.Sort((p1, p2) =>
                    {
                        return(p1.X.CompareTo(p2.X));//Сначала левая, потом правая
                    });

                    horizontalLines.Add(new LineSegment2d(pts[0], pts[1]));
                }
            }
        }
コード例 #3
0
        private int GetVisiblePt(HoleInfo hi)
        {
            //Обозначения точек согласно https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
            Point2d M = hi.MaxXPt;
            Point2d I = Point2d.Origin;

            int[] edge = GetEdgeOnHorizontalRay(M, out I);
            if (edge == null)
            {
                throw new Exception("Ошибка при определении видимой точки. Не найдено ребро, пересекающееся с горизонтальным лучем");
            }
            int     vertexOnEdgeIndex = Polygon[edge[0]].X > Polygon[edge[1]].X ? edge[0] : edge[1];
            Point2d P = GetPt2DAt(vertexOnEdgeIndex);

            if (P.IsEqualTo(I))
            {
                //Если точки совпали
                return(vertexOnEdgeIndex);
            }

            List <int> reflexPtsIndices = GetReflexVertsInTriangle(M, I, P);

            if (reflexPtsIndices.Count > 0)
            {
                return(GetVisiblePtFromReflexPts(M, reflexPtsIndices));
            }
            else
            {
                return(vertexOnEdgeIndex);
            }
        }
コード例 #4
0
 private bool IsEar(Point2d p1, Point2d p2, Point2d p3)
 {
     foreach (LinkedListNode <int> reflVertNode in reflexVerts)
     {
         Point2d reflVert = Utils.Point2DBy3D(this.polygon[reflVertNode.Value]);
         double  lambda1, lambda2;
         if (!reflVert.IsEqualTo(p1) && !reflVert.IsEqualTo(p2) && !reflVert.IsEqualTo(p3)
             //Если одна из точек точно совпала с другой, значит это дублирующиеся точки, появившиеся при объединении с отверстиями
             //Эти точки не должны влиять отбор ear
             && Utils.BarycentricCoordinates(reflVert, p1, p2, p3, out lambda1, out lambda2))
         {
             //Вогнутая вершина попала в треугольник. Это не Ear
             return(false);
         }
     }
     return(true);
 }
コード例 #5
0
 /// <summary>
 ///     Gets a value indicating whether the specified point belongs to the collection.
 /// </summary>
 /// <param name="pts">The instance to which the method applies.</param>
 /// <param name="pt">The point to search.</param>
 /// <param name="tol">The tolerance to use in comparisons.</param>
 /// <returns>true if the point is found; otherwise, false.</returns>
 public static bool Contains(this Point2dCollection pts, Point2d pt, Tolerance tol)
 {
     for (var i = 0; i < pts.Count; i++)
     {
         if (pt.IsEqualTo(pts[i], tol))
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #6
0
        /// <summary>
        /// Gets a value indicating whether the specified point belongs to the collection.
        /// </summary>
        /// <param name="pts">The instance to which the method applies.</param>
        /// <param name="pt">The point to search.</param>
        /// <param name="tol">The tolerance to use in comparisons.</param>
        /// <returns>true if the point is found; otherwise, false.</returns>
        public static bool Contains([NotNull] this Point2dCollection pts, Point2d pt, Tolerance tol)
        {
            foreach (var t in pts)
            {
                if (pt.IsEqualTo(t, tol))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #7
0
 /// <summary>
 /// Gets a value indicating whether the specified point belongs to the collection.
 /// </summary>
 /// <param name="source">The instance to which the method applies.</param>
 /// <param name="pt">The point to search.</param>
 /// <param name="tol">The tolerance to use in comparisons.</param>
 /// <returns>true if the point is found; otherwise, false.</returns>
 public static bool Contains(this Point2dCollection source, Point2d pt, Tolerance tol)
 {
     if (source == null)
     {
         throw new ArgumentNullException("source");
     }
     for (int i = 0; i < source.Count; i++)
     {
         if (pt.IsEqualTo(source[i], tol))
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #8
0
        /// <summary>
        /// Определение граничных точек задающих тень по отношению к расчетной точке, среди всех точек
        /// </summary>
        private IIlluminationArea GetIllumShadow(List <Point2d> points)
        {
            IIlluminationArea ilum = null;
            // список точек и их углов к расчетной точке
            var angles = new List <Tuple <Point2d, double> >();

            foreach (var iPt in points)
            {
                // угол к расчетной точке (от 0 по часовой стрелке)
                if (!ptCalc2d.IsEqualTo(iPt))
                {
                    var angle = values.GetInsAngleFromAcad((iPt - ptCalc2d).Angle);
                    angles.Add(new Tuple <Point2d, double>(iPt, angle));
                }
            }
            if (angles.Count > 1)
            {
                angles.Sort((p1, p2) => p1.Item2.CompareTo(p2.Item2));

                ilum = CreateIllumShadow(angles[0], angles[angles.Count - 1]);
            }
            return(ilum);
        }
コード例 #9
0
            protected override SamplerStatus Sampler(JigPrompts prompts)
            {
                //throw new System.Exception("The method or operation is not implemented.");


                if (GetPoint)
                {
                    JigPromptPointOptions jppo = new JigPromptPointOptions("Select Measeared jackpanel Position : \n");

                    jppo.UserInputControls = (UserInputControls.Accept3dCoordinates |
                                              UserInputControls.NullResponseAccepted |
                                              UserInputControls.NoNegativeResponseAccepted);

                    PromptPointResult ppr = prompts.AcquirePoint(jppo);

                    if (ppr.Status == PromptStatus.OK)
                    {
                        Point2d NewPoint = new Point2d(ppr.Value.X, ppr.Value.Y);

                        if (NewPoint.IsEqualTo(BasePoint))
                        {
                            //v2d = new Vector2d(0, 0);

                            return(SamplerStatus.NoChange);
                        }
                        else
                        {
                            //v2d = BasePoint - NewPoint;

                            BasePoint = new Point2d(ppr.Value.X, ppr.Value.Y);

                            //ed.WriteMessage("POINT OK. \n");

                            return(SamplerStatus.OK);
                        }
                    }
                    else
                    {
                        //v2d = new Vector2d(0, 0);

                        return(SamplerStatus.Cancel);
                    }
                }
                else if (GetAngle)
                {
                    JigPromptAngleOptions jpao = new JigPromptAngleOptions("Select Measured jackpanel Angle : \n");

                    jpao.UseBasePoint = true;

                    jpao.BasePoint = new Point3d(BasePoint.X, BasePoint.Y, 0);

                    PromptDoubleResult pdr = prompts.AcquireAngle(jpao);

                    if (pdr.Status == PromptStatus.OK)
                    {
                        if (pdr.Value == NewAngle)
                        {
                            return(SamplerStatus.NoChange);
                        }
                        else
                        {
                            NewAngle = pdr.Value;// -NewAngle;

                            return(SamplerStatus.OK);
                        }
                    }
                    else
                    {
                        return(SamplerStatus.Cancel);
                    }
                }

                return(SamplerStatus.NoChange);
            }
コード例 #10
0
        /// <summary>
        /// point1과 point2가 tolerance 오차 내에서 같은지 반환합니다.
        /// </summary>
        /// <param name="point1">비교할 점1 입니다.</param>
        /// <param name="point2">비교할 점2 입니다.</param>
        /// <param name="tolerance">같다고 볼 오차범위 입니다.</param>
        /// <returns></returns>
        public static bool IsEqualPoint(Point2d point1, Point2d point2, double tolerance)
        {
            Tolerance oTol = new Tolerance(Tolerance.Global.EqualVector, tolerance);

            return(point1.IsEqualTo(point2, oTol));
        }
コード例 #11
0
        /// <summary>
        /// Creates a new instance of PolylineSegmentCollection from an Ellipse.
        /// </summary>
        /// <param name="ellipse">An Ellipse instance.</param>
        public PolylineSegmentCollection(Ellipse ellipse)
        {
            // PolylineSegmentCollection figuring the closed ellipse
            double  pi     = Math.PI;
            Plane   plane  = new Plane(Point3d.Origin, ellipse.Normal);
            Point3d cen3d  = ellipse.Center;
            Point3d pt3d0  = cen3d + ellipse.MajorAxis;
            Point3d pt3d4  = cen3d + ellipse.MinorAxis;
            Point3d pt3d2  = ellipse.GetPointAtParameter(pi / 4.0);
            Point2d cen    = cen3d.Convert2d(plane);
            Point2d pt0    = pt3d0.Convert2d(plane);
            Point2d pt2    = pt3d2.Convert2d(plane);
            Point2d pt4    = pt3d4.Convert2d(plane);
            Line2d  line01 = new Line2d(pt0, (pt4 - cen).GetNormal() + (pt2 - pt0).GetNormal());
            Line2d  line21 = new Line2d(pt2, (pt0 - pt4).GetNormal() + (pt0 - pt2).GetNormal());
            Line2d  line23 = new Line2d(pt2, (pt4 - pt0).GetNormal() + (pt4 - pt2).GetNormal());
            Line2d  line43 = new Line2d(pt4, (pt0 - cen).GetNormal() + (pt2 - pt4).GetNormal());
            Line2d  majAx  = new Line2d(cen, pt0);
            Line2d  minAx  = new Line2d(cen, pt4);
            Point2d pt1    = line01.IntersectWith(line21)[0];
            Point2d pt3    = line23.IntersectWith(line43)[0];
            Point2d pt5    = pt3.TransformBy(Matrix2d.Mirroring(minAx));
            Point2d pt6    = pt2.TransformBy(Matrix2d.Mirroring(minAx));
            Point2d pt7    = pt1.TransformBy(Matrix2d.Mirroring(minAx));
            Point2d pt8    = pt0.TransformBy(Matrix2d.Mirroring(minAx));
            Point2d pt9    = pt7.TransformBy(Matrix2d.Mirroring(majAx));
            Point2d pt10   = pt6.TransformBy(Matrix2d.Mirroring(majAx));
            Point2d pt11   = pt5.TransformBy(Matrix2d.Mirroring(majAx));
            Point2d pt12   = pt4.TransformBy(Matrix2d.Mirroring(majAx));
            Point2d pt13   = pt3.TransformBy(Matrix2d.Mirroring(majAx));
            Point2d pt14   = pt2.TransformBy(Matrix2d.Mirroring(majAx));
            Point2d pt15   = pt1.TransformBy(Matrix2d.Mirroring(majAx));
            double  bulge1 = Math.Tan((pt4 - cen).GetAngleTo(pt1 - pt0) / 2.0);
            double  bulge2 = Math.Tan((pt1 - pt2).GetAngleTo(pt0 - pt4) / 2.0);
            double  bulge3 = Math.Tan((pt4 - pt0).GetAngleTo(pt3 - pt2) / 2.0);
            double  bulge4 = Math.Tan((pt3 - pt4).GetAngleTo(pt0 - cen) / 2.0);

            _contents.Add(new PolylineSegment(pt0, pt1, bulge1));
            _contents.Add(new PolylineSegment(pt1, pt2, bulge2));
            _contents.Add(new PolylineSegment(pt2, pt3, bulge3));
            _contents.Add(new PolylineSegment(pt3, pt4, bulge4));
            _contents.Add(new PolylineSegment(pt4, pt5, bulge4));
            _contents.Add(new PolylineSegment(pt5, pt6, bulge3));
            _contents.Add(new PolylineSegment(pt6, pt7, bulge2));
            _contents.Add(new PolylineSegment(pt7, pt8, bulge1));
            _contents.Add(new PolylineSegment(pt8, pt9, bulge1));
            _contents.Add(new PolylineSegment(pt9, pt10, bulge2));
            _contents.Add(new PolylineSegment(pt10, pt11, bulge3));
            _contents.Add(new PolylineSegment(pt11, pt12, bulge4));
            _contents.Add(new PolylineSegment(pt12, pt13, bulge4));
            _contents.Add(new PolylineSegment(pt13, pt14, bulge3));
            _contents.Add(new PolylineSegment(pt14, pt15, bulge2));
            _contents.Add(new PolylineSegment(pt15, pt0, bulge1));

            // if the ellipse is an elliptical arc:
            if (!ellipse.Closed)
            {
                double  startParam, endParam;
                Point2d startPoint = ellipse.StartPoint.Convert2d(plane);
                Point2d endPoint   = ellipse.EndPoint.Convert2d(plane);

                // index of the PolylineSegment closest to the ellipse start point
                int startIndex = GetClosestSegmentIndexTo(startPoint);
                // start point on the PolylineSegment
                Point2d pt = _contents[startIndex].ToCurve2d().GetClosestPointTo(startPoint).Point;
                // if the point is equal to the PolylineSegment end point, jump the next segment in collection
                if (pt.IsEqualTo(_contents[startIndex].EndPoint))
                {
                    if (startIndex == 15)
                    {
                        startIndex = 0;
                    }
                    else
                    {
                        startIndex++;
                    }
                    startParam = 0.0;
                }
                // else get the 'parameter' at point on the PolylineSegment
                else
                {
                    startParam = _contents[startIndex].GetParameterOf(pt);
                }

                // index of the PolylineSegment closest to the ellipse end point
                int endIndex = GetClosestSegmentIndexTo(endPoint);
                // end point on the PolylineSegment
                pt = _contents[endIndex].ToCurve2d().GetClosestPointTo(endPoint).Point;
                // if the point is equals to the PolylineSegment startPoint, jump to the previous segment
                if (pt.IsEqualTo(_contents[endIndex].StartPoint))
                {
                    if (endIndex == 0)
                    {
                        endIndex = 15;
                    }
                    else
                    {
                        endIndex--;
                    }
                    endParam = 1.0;
                }
                // else get the 'parameter' at point on the PolylineSegment
                else
                {
                    endParam = _contents[endIndex].GetParameterOf(pt);
                }

                // if the parameter at start point is not equal to 0.0, calculate the bulge
                if (startParam != 0.0)
                {
                    _contents[startIndex].StartPoint = startPoint;
                    _contents[startIndex].Bulge      = _contents[startIndex].Bulge * (1.0 - startParam);
                }

                // if the parameter at end point is not equal to 1.0, calculate the bulge
                if (endParam != 1.0) //(endParam != 0.0)
                {
                    _contents[endIndex].EndPoint = endPoint;
                    _contents[endIndex].Bulge    = _contents[endIndex].Bulge * (endParam);
                }

                // if both points are on the same segment
                if (startIndex == endIndex)
                {
                    PolylineSegment segment = _contents[startIndex];
                    _contents.Clear();
                    _contents.Add(segment);
                }

                else if (startIndex < endIndex)
                {
                    _contents.RemoveRange(endIndex + 1, 15 - endIndex);
                    _contents.RemoveRange(0, startIndex);
                }
                else
                {
                    _contents.AddRange(_contents.GetRange(0, endIndex + 1));
                    _contents.RemoveRange(0, startIndex);
                }
            }
        }
コード例 #12
0
        public void SurfaceMeshByBoundary()
        {
            Document adoc = Application.DocumentManager.MdiActiveDocument;

            if (adoc == null)
            {
                return;
            }

            Database db = adoc.Database;

            DB = db;

            Editor ed = adoc.Editor;

            ED = ed;

            CivilDocument cdok = CivilDocument.GetCivilDocument(adoc.Database);


            try
            {
                Color currColor = db.Cecolor;
                if (!currColor.IsByLayer)//Если текущий слой не по слою, то расчитать более темный цвет для границ участков
                {
                    Color dimmerColor = Utils.GetDimmerColor(currColor, BORDER_DIM_MULTIPLIER);

                    ColorForBorder = dimmerColor;
                }
                else
                {
                    ColorForBorder = Color.FromColorIndex(ColorMethod.ByAci, 256);
                }


                if (!TinSurfIdIsValid())
                {
                    //Выбрать поверхность
                    if (!PickTinSurf(ed))
                    {
                        return;//Если выбор не успешен, прервать выполнение
                    }
                }
                //Подсветить поверхность
                HighlightTinSurf(true);


                //Запрос ключевых слов
                while (true)
                {
                    const string kw1 = "ПОВерхность";
                    const string kw2 = "ВОЗвышение";
                    const string kw3 = "ОТКлонкниеОтДуг";
                    const string kw4 = "СОЗдаватьГраницы";

                    PromptKeywordOptions pko = new PromptKeywordOptions("\nЗадайте параметры или пустой ввод для продолжения");
                    pko.Keywords.Add(kw1);
                    pko.Keywords.Add(kw2);
                    pko.Keywords.Add(kw3);
                    pko.Keywords.Add(kw4);
                    pko.AllowNone = true;
                    PromptResult pr = ed.GetKeywords(pko);
                    if (pr.Status == PromptStatus.Cancel)
                    {
                        return;
                    }

                    if (String.IsNullOrEmpty(pr.StringResult))
                    {
                        break;
                    }

                    switch (pr.StringResult)
                    {
                    case kw1:
                        if (!PickTinSurf(ed))
                        {
                            return;
                        }
                        break;

                    case kw2:
                        if (!GetMeshElevation(ed))
                        {
                            return;
                        }
                        break;

                    case kw3:
                        if (!GetApproxParam(ed))
                        {
                            return;
                        }
                        break;

                    case kw4:
                        if (!GetCreateBorders(ed))
                        {
                            return;
                        }

                        break;
                    }
                }


                //Проверка текущего набора выбора
                acSSet = null;
                PromptSelectionResult acSSPrompt;
                acSSPrompt = ed.SelectImplied();
                if (acSSPrompt.Status == PromptStatus.OK)
                {
                    acSSet = acSSPrompt.Value;
                }
                else
                {
                    //Множественный выбор блоков
                    TypedValue[] tv = new TypedValue[]
                    {
                        new TypedValue(0, "INSERT")
                    };
                    SelectionFilter flt = new SelectionFilter(tv);


                    PromptSelectionOptions pso = new PromptSelectionOptions();
                    pso.MessageForAdding = "\nВыберите блоки участков";

                    acSSPrompt = adoc.Editor.GetSelection(pso, flt);
                    if (acSSPrompt.Status == PromptStatus.OK)
                    {
                        acSSet = acSSPrompt.Value;
                    }
                }

                if (acSSet != null)
                {
                    Common.Timer timerMain = new Common.Timer();
                    timerMain.Start();
                    foreach (SelectedObject acSSObj in acSSet)
                    {
                        string       blockName = null;
                        Common.Timer timer     = new Common.Timer();
                        timer.Start();
                        try
                        {
                            if (acSSObj != null)
                            {
                                //полилинии внутри блока
                                List <ObjectId> polylines      = new List <ObjectId>();
                                BlockReference  blockReference = null;
                                ObjectId        btrId          = ObjectId.Null;
                                using (Transaction tr = db.TransactionManager.StartTransaction())
                                {
                                    //блок внутри набора выбора
                                    blockReference = tr.GetObject(acSSObj.ObjectId, OpenMode.ForRead) as BlockReference;
                                    tr.Commit();
                                }
                                Matrix3d transform = Matrix3d.Identity;
                                if (blockReference != null)
                                {
                                    //трансформация из системы координат блока в мировую систему координат
                                    transform = blockReference.BlockTransform;

                                    //Перебор всех объектов внутри блока
                                    //Найти все правильные полилинии в блоке
                                    using (Transaction tr = db.TransactionManager.StartTransaction())
                                    {
                                        btrId = blockReference.BlockTableRecord;
                                        BlockTableRecord blockTableRecord = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;

                                        if (blockTableRecord.XrefStatus == XrefStatus.NotAnXref)
                                        {
                                            blockName = blockTableRecord.Name;
                                            foreach (ObjectId id in blockTableRecord)
                                            {
                                                using (Polyline poly = tr.GetObject(id, OpenMode.ForRead) as Polyline)
                                                {
                                                    if (poly != null &&
                                                        (poly.Closed || poly.GetPoint2dAt(0).Equals(poly.GetPoint2dAt(poly.NumberOfVertices - 1))) &&//Полилиния замкнута
                                                        !Utils.PolylineIsSelfIntersecting(poly) &&//Не имеет самопересечений
                                                        poly.Visible == true &&//Учет многовидовых блоков
                                                        poly.Bounds != null
                                                        )
                                                    {
                                                        polylines.Add(id);
                                                    }
                                                }

                                                AcadDb.Entity ent = tr.GetObject(id, OpenMode.ForRead) as AcadDb.Entity;
                                                if (ent is Polyline)
                                                {
                                                    Polyline poly = ent as Polyline;
                                                }
                                            }


                                            if (polylines.Count > 0)
                                            {
                                                //Проверить все линии на пересечение друг с другом. Удалить из списка те, которые имеют пересечения
                                                HashSet <ObjectId> polylinesWithNoIntersections = new HashSet <ObjectId>(polylines);
                                                //Сделать RBush для всех полилиний
                                                RBush <SpatialEntity> polylinesTree   = new RBush <SpatialEntity>();
                                                List <SpatialEntity>  spatialEntities = new List <SpatialEntity>();
                                                foreach (ObjectId polyId in polylines)
                                                {
                                                    spatialEntities.Add(new SpatialEntity(polyId));
                                                }
                                                polylinesTree.BulkLoad(spatialEntities);

                                                foreach (SpatialEntity se in spatialEntities)
                                                {
                                                    //Нахождение всех объектов, расположенных в пределах BoundingBox для этой полилинии
                                                    IReadOnlyList <SpatialEntity> nearestNeighbors = polylinesTree.Search(se.Envelope);
                                                    if (nearestNeighbors.Count > 1)
                                                    {
                                                        Polyline thisPoly = tr.GetObject(se.ObjectId, OpenMode.ForRead) as Polyline;

                                                        foreach (SpatialEntity n in nearestNeighbors)
                                                        {
                                                            if (!n.Equals(se))//Всегда будет находиться та же самая полилиния
                                                            {
                                                                Polyline          otherPoly = tr.GetObject(n.ObjectId, OpenMode.ForRead) as Polyline;
                                                                Point3dCollection pts       = new Point3dCollection();
                                                                thisPoly.IntersectWith(otherPoly, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
                                                                if (pts.Count > 0)
                                                                {
                                                                    polylinesWithNoIntersections.Remove(thisPoly.Id);
                                                                    polylinesWithNoIntersections.Remove(otherPoly.Id);
                                                                    break;
                                                                }
                                                            }
                                                        }
                                                    }
                                                }

                                                //Аппроксимация всех полилиний, которые имеют кривизну
                                                List <Polyline> polylinesToProcess = new List <Polyline>();
                                                foreach (ObjectId polyId in polylinesWithNoIntersections)
                                                {
                                                    using (Polyline poly = tr.GetObject(polyId, OpenMode.ForRead) as Polyline)
                                                    {
                                                        polylinesToProcess.Add(ApproximatePolyBulges(poly, approxParam));//Какой допуск оптимален?
                                                    }
                                                }

                                                //Удалить все повторяющиеся подряд точки полилинии
                                                foreach (Polyline poly in polylinesToProcess)
                                                {
                                                    for (int i = 0; i < poly.NumberOfVertices;)
                                                    {
                                                        Point2d curr      = poly.GetPoint2dAt(i);
                                                        int     nextIndex = (i + 1) % poly.NumberOfVertices;
                                                        Point2d next      = poly.GetPoint2dAt(nextIndex);

                                                        if (next.IsEqualTo(curr, new Tolerance(0.001, 0.001)))//Прореживать точки, расположенные слишком близко//TODO: Учесть масштабирование блока
                                                        {
                                                            poly.RemoveVertexAt(nextIndex);
                                                        }
                                                        else
                                                        {
                                                            i++;
                                                        }
                                                    }
                                                }


                                                //Построение дерева вложенности полилиний
                                                using (TinSurface tinSurf = tr.GetObject(tinSurfId, OpenMode.ForRead) as TinSurface)
                                                {
                                                    using (PolylineNesting polylineNesting = new PolylineNesting(tinSurf))
                                                    {
                                                        foreach (Polyline poly in polylinesToProcess)
                                                        {
                                                            poly.TransformBy(transform);
                                                            polylineNesting.Insert(poly);
                                                        }

                                                        //Расчет полигонов
                                                        polylineNesting.CalculatePoligons();

                                                        //Построение сети
                                                        using (SubDMesh sdm = polylineNesting.CreateSubDMesh())
                                                        {
                                                            List <Line> lines = new List <Line>();
                                                            if (createBorders)
                                                            {
                                                                //Создание 3d линий по границе
                                                                lines = polylineNesting.CreateBorderLines();
                                                            }

                                                            //Объекты постоены в координатах пространства модели
                                                            if (sdm != null)
                                                            {
                                                                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite);
                                                                if (btr.GetBlockReferenceIds(true, false).Count > 1)
                                                                {
                                                                    //Если у блока несколько вхождений, то создавать объекты в пространстве модели
                                                                    BlockTable       bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
                                                                    BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                                                                    ms.AppendEntity(sdm);
                                                                    tr.AddNewlyCreatedDBObject(sdm, true);

                                                                    foreach (Line line in lines)
                                                                    {
                                                                        ms.AppendEntity(line);
                                                                        tr.AddNewlyCreatedDBObject(line, true);
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    //Если у блока только одно вхождение, то создавать сеть внутри блока
                                                                    sdm.TransformBy(transform.Inverse());
                                                                    btr.AppendEntity(sdm);
                                                                    tr.AddNewlyCreatedDBObject(sdm, true);

                                                                    foreach (Line line in lines)
                                                                    {
                                                                        line.TransformBy(transform.Inverse());
                                                                        btr.AppendEntity(line);
                                                                        tr.AddNewlyCreatedDBObject(line, true);
                                                                    }
                                                                }
                                                            }

                                                            foreach (Line line in lines)
                                                            {
                                                                line.Dispose();
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        tr.Commit();
                                    }
                                }
                            }
                        }
                        catch (System.Exception ex)
                        {
                            string message = "Возникла ошибка при обработке одного из выбранных объектов";
                            if (!String.IsNullOrEmpty(blockName))
                            {
                                message = "Возникла ошибка при обработке вхождения блока " + blockName;
                            }
                            Utils.ErrorToCommandLine(ed, message, ex);
                        }
                        timer.TimeOutput(blockName);
                    }

                    ed.WriteMessage("\n" +
                                    timerMain.TimeOutput("Затрачено времени (параметр аппроксимации - " + approxParam + ")")
                                    );

                    ed.Regen();
                }
            }
            catch (System.Exception ex)
            {
                CommonException(ex, "Ошибка при создании сетей по участкам поверхности");
            }
            finally
            {
                HighlightTinSurf(false);
            }
        }
コード例 #13
0
        void HatchPerimeter(ObjectId entId)
        {
            Document activeDoc = Application.DocumentManager.MdiActiveDocument;

            Database db = activeDoc.Database;

            Editor ed = activeDoc.Editor;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Hatch hatch = tr.GetObject(entId, OpenMode.ForRead) as Hatch;

                int    nLoops = hatch.NumberOfLoops;
                double totalExternalPerimeter = 0.0;
                double totalInternalPerimeter = 0.0;

                for (int i = 0; i < nLoops; i++)
                {
                    double loopLength = 0.0;

                    HatchLoopTypes hlt = hatch.LoopTypeAt(i);

                    HatchLoop hatchLoop = hatch.GetLoopAt(i);

                    if ((hatch.LoopTypeAt(i) & HatchLoopTypes.Polyline) == HatchLoopTypes.Polyline)
                    {
                        BulgeVertexCollection bulges = hatchLoop.Polyline;
                        int nVertices = bulges.Count;

                        Polyline testPoly = new Polyline(nVertices);

                        for (int vx = 0; vx < bulges.Count; vx++)
                        {
                            BulgeVertex bv = bulges[vx];

                            testPoly.AddVertexAt(vx, bv.Vertex, bv.Bulge, 1.0, 1.0);
                        }

                        LineSegment3d ls = new LineSegment3d();

                        CircularArc3d cs = new CircularArc3d();

                        double d = 0.0, p1 = 0.0, p2 = 1.0;

                        for (int ver = 0; ver < nVertices - 1; ver++)
                        {
                            d = testPoly.GetBulgeAt(ver);

                            if (d <= 1e-5)
                            {
                                ls = testPoly.GetLineSegmentAt(ver);

                                loopLength += ls.Length;
                            }

                            else
                            {
                                Point2d v1 = new Point2d(bulges[ver].Vertex.X, bulges[ver].Vertex.Y);

                                Point2d v2 = new Point2d(bulges[ver + 1].Vertex.X, bulges[ver + 1].Vertex.Y);

                                if (v1.IsEqualTo(v2) == false)
                                {
                                    cs = testPoly.GetArcSegmentAt(ver);

                                    p1 = cs.GetParameterOf(cs.StartPoint);

                                    p2 = cs.GetParameterOf(cs.EndPoint);

                                    loopLength += cs.GetLength
                                                      (p1, p2, Tolerance.Global.EqualPoint);
                                }
                            }
                        }
                    }

                    else
                    {
                        Curve2dCollection curves = hatchLoop.Curves;

                        if (curves != null)
                        {
                            foreach (Curve2d curve in curves)
                            {
                                if (hatchLoop.LoopType == HatchLoopTypes.External)
                                {
                                    totalExternalPerimeter += curve.GetLength(0.0, 1.0);
                                }

                                else
                                {
                                    totalInternalPerimeter += curve.GetLength(0.0, 1.0);
                                }
                            }
                        }
                    }

                    if (nLoops > 1 &&

                        ((hlt & HatchLoopTypes.External) != HatchLoopTypes.External))
                    {
                        totalInternalPerimeter += loopLength;
                    }
                    else
                    {
                        totalExternalPerimeter += loopLength;
                    }
                }
                ed.WriteMessage(string.Format("\nExternal Perimeter : {0}", totalExternalPerimeter));

                ed.WriteMessage(string.Format("\nInternal Perimeter : {0}", totalInternalPerimeter));

                tr.Commit();
            }
        }