Example #1
0
        /// <summary>
        /// Определение границ блока панели для вида формы или фасада
        /// </summary>
        private Extents3d getPanelExt(BlockReference blRef, bool isFacadeView)
        {
            Extents3d resVal      = new Extents3d();
            string    ignoreLayer = isFacadeView ? Settings.Default.LayerDimensionForm : Settings.Default.LayerDimensionFacade;

            var btr = blRef.DynamicBlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;

            foreach (ObjectId idEnt in btr)
            {
                if (!idEnt.IsValidEx())
                {
                    continue;
                }
                var ent = idEnt.GetObject(OpenMode.ForRead, false, true) as Entity;
                if (ent.Layer.Equals(ignoreLayer, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                try
                {
                    var curExt = ent.GeometricExtents;
                    if (!IsEmptyExt(ref curExt))
                    {
                        resVal.AddExtents(curExt);
                    }
                }
                catch { }
            }
            resVal.TransformBy(blRef.BlockTransform);
            return(resVal);
        }
Example #2
0
        /// <summary>
        /// Выделение объектов и зумирование по границе
        /// </summary>
        /// <param name="ids">Элементв</param>
        /// <param name="ed">Редактор</param>
        public static void SetSelectionAndZoom([NotNull] this List <ObjectId> ids, Editor ed = null)
        {
            try
            {
                var doc = AcadHelper.Doc;
                ed = doc.Editor;
                using (doc.LockDocument())
                    using (var t = doc.TransactionManager.StartTransaction())
                    {
                        if (!ids.Any())
                        {
                            "Нет объектов для выделения.".WriteToCommandLine();
                            return;
                        }

                        var ext = new Extents3d();
                        ids.Select(s => s.GetObject(OpenMode.ForRead)).Iterate(o =>
                        {
                            if (o.Bounds.HasValue)
                            {
                                ext.AddExtents(o.Bounds.Value);
                            }
                        });
                        ed.Zoom(ext);
                        Autodesk.AutoCAD.Internal.Utils.SelectObjects(ids.ToArray());
                        t.Commit();
                    }
            }
            catch (Exception ex)
            {
                $"Ошибка выделения объектов - {ex.Message}.".WriteToCommandLine();
            }
        }
Example #3
0
        public void AddItem(Drawable item)
        {
            if (IsDesigner)
            {
                return;
            }

            Init();
            Extents3d?itemExtents = item.Bounds;

            if (itemExtents.HasValue)
            {
                if (items.Count == 0)
                {
                    extents.Set(itemExtents.Value.MinPoint, itemExtents.Value.MaxPoint);
                }
                else
                {
                    extents.AddExtents(itemExtents.Value);
                }
            }
            items.Add(item);

            Refresh();
        }
Example #4
0
        public AnnotationOverlapCheckResult(PolygonIntersect intersect)
            : base(ActionType.AnnotationOverlap, new ObjectId[0])
        {
            using (var transaction = intersect.SourceId.Database.TransactionManager.StartTransaction())
            {
                var polyline = transaction.GetObject(intersect.SourceId, OpenMode.ForRead) as AcadPolyline;
                if (polyline != null)
                {
                    _intersectionPaths.Add((AcadPolyline)polyline.Clone());
                }
                polyline = transaction.GetObject(intersect.TargetId, OpenMode.ForRead) as AcadPolyline;
                if (polyline != null)
                {
                    _intersectionPaths.Add((AcadPolyline)polyline.Clone());
                }
            }

            _extents = _intersectionPaths[0].GeometricExtents;
            for (int i = 1; i < _intersectionPaths.Count; i++)
            {
                _extents.AddExtents(_intersectionPaths[i].GeometricExtents);
            }

            _position       = _extents.MinPoint + (_extents.MaxPoint - _extents.MinPoint) / 2;
            HighlightEntity = false;
        }
Example #5
0
        public static Extents3d GetExtents(this IEnumerable <Entity> entities)
        {
            Extents3d extent = entities.First().GeometricExtents;

            foreach (var ent in entities)
            {
                extent.AddExtents(ent.GeometricExtents);
            }
            return(extent);
        }
Example #6
0
        public static Extents3d Union([NotNull] this IEnumerable <Extents3d> exts)
        {
            var ext = new Extents3d();

            foreach (var extents3D in exts)
            {
                ext.AddExtents(extents3D);
            }

            return(ext);
        }
Example #7
0
        public static Extents3d GeometricExtentsVisible([NotNull] this BlockReference blRef)
        {
#pragma warning disable 618
            using var btr = (BlockTableRecord)blRef.BlockTableRecord.Open(OpenMode.ForRead);
            var ext = new Extents3d();
            foreach (var extents3D in btr.GetObjects <Entity>().Where(w => w.Visible && w.Bounds.HasValue)
                     .Select(s => s.Bounds !.Value))
            {
                ext.AddExtents(extents3D);
            }

            return(ext);
        }
Example #8
0
 // Повортот подписи марки (Марки СБ и Марки Покраски) и добавление фоновой штриховки
 public void Convert(BlockTableRecord btr)
 {
     // Расположение и поворот марки СБ
     if (!panelBtr.IdCaptionMarkSb.IsNull)
     {
         Point3d   posMarkSb    = new Point3d(panelBtr.ExtentsNoEnd.MinPoint.X + 230, panelBtr.ExtentsNoEnd.MinPoint.Y + 20, 0);
         Extents3d extMarkSb    = convertText(panelBtr.IdCaptionMarkSb, 90, posMarkSb, true);
         Point3d   posMarkPaint = new Point3d(posMarkSb.X + 250, posMarkSb.Y + 20, 0);
         Extents3d extPaint     = convertText(panelBtr.IdCaptionPaint, 90, posMarkPaint, false);
         Extents3d extTexts     = extMarkSb;
         extTexts.AddExtents(extPaint);
         сreateHatch(extTexts, btr);
     }
 }
Example #9
0
        public static Extents3d GetExtents(this Transaction tr, ObjectId[] ids)
        {
            var ext = new Extents3d();

            foreach (var id in ids)
            {//teste
                var ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                if (ent != null)
                {
                    ext.AddExtents(ent.GeometricExtents);
                }
            }
            return(ext);
        }
Example #10
0
        public Extents3d GetExtents()
        {
            if (Contour != null)
            {
                return(Contour.GeometricExtents);
            }

            var ext = new Extents3d();

            foreach (var item in Sections)
            {
                ext.AddExtents(item.ExtentsInModel);
            }
            return(ext);
        }
Example #11
0
        /// <summary>
        /// 计算图形数据库模型空间中所有实体的包围框
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <returns>返回模型空间中所有实体的包围框</returns>
        public static Extents3d GetAllEntsExtent(this Database db)
        {
            Extents3d totalExt = new Extents3d();

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable       bt    = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btRcd = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                foreach (ObjectId entId in btRcd)
                {
                    Entity ent = trans.GetObject(entId, OpenMode.ForRead) as Entity;
                    totalExt.AddExtents(ent.GeometricExtents);
                }
            }
            return(totalExt);
        }
Example #12
0
        public IntersectPolygonCheckResult(PolygonIntersect intersect)
            : base(ActionType.IntersectPolygon, new ObjectId[] { intersect.SourceId, intersect.TargetId })
        {
            _intersectionPaths = intersect.Intersections;

            Extents3d extents = _intersectionPaths[0].GeometricExtents;

            for (int i = 1; i < _intersectionPaths.Count; i++)
            {
                extents.AddExtents(_intersectionPaths[i].GeometricExtents);
            }

            _position       = extents.MinPoint + (extents.MaxPoint - extents.MinPoint) / 2;
            _basesize       = (extents.MaxPoint - extents.MinPoint).Length;
            HighlightEntity = false;
        }
Example #13
0
 /// <summary>
 /// Рекурсивное получение габаритного контейнера блока.
 /// </summary>
 /// <param name="element">Имя примитива</param>
 /// <param name="boundaries">Габаритный контейнер</param>
 /// <param name="mat">Матрица преобразования из системы координат блока в МСК.</param>
 void GetBlockExtents(Entity element, ref Extents3d boundaries)
 {
     if (!IsLayerOn(element.LayerId))
     {
         return;
     }
     if (element is BlockReference)
     {
         BlockReference blockRef = element as BlockReference;
         using (BlockTableRecord blockTR =
                    blockRef.BlockTableRecord.Open(OpenMode.ForRead) as BlockTableRecord)
         {
             foreach (ObjectId id in blockTR)
             {
                 using (DBObject obj = id.Open(OpenMode.ForRead) as DBObject)
                 {
                     Entity entityCur = obj as Entity;
                     if (entityCur == null || entityCur.Visible != true)
                     {
                         continue;
                     }
                     // Пропускаем неконстантные и невидимые определения атрибутов
                     AttributeDefinition attDef = entityCur as AttributeDefinition;
                     if (attDef != null)
                     {
                         continue;
                     }
                     GetBlockExtents(entityCur, ref boundaries);
                 }
             }
         }
     }
     else
     {
         if (IsEmptyBound(ref boundaries))
         {
             try { boundaries = (Extents3d)element.Bounds; } catch { };
         }
         else
         {
             try { boundaries.AddExtents((Extents3d)element.Bounds); } catch { };
         }
         return;
     }
     return;
 }
            private Extents3d?_getSymbolsBounds(IEnumerable <Entity> symbols)
            {
                if (symbols.Count() < 1)
                {
                    return(null);
                }
                Extents3d res = new Extents3d();

                symbols.ToList().ForEach(ent =>
                {
                    /*var clone = ent.GetTransformedCopy(_lineTarnsform.Inverse());
                     * if (clone.Bounds.HasValue)
                     *  res.AddExtents(ent.Bounds.Value);*/
                    if (ent is DBText)
                    {
                        var rectg = ((DBText)ent).GetTextBoxCorners();
                        if (rectg.HasValue)
                        {
                            Point3d lowerLeft  = rectg.Value.LowerLeft.TransformBy(_lineTarnsform.Inverse());
                            Point3d upperRight = rectg.Value.UpperRight.TransformBy(_lineTarnsform.Inverse());

                            ///////////////////////////////////////////////////////////!!!!!!!!!!//////////////////////////
                            if (lowerLeft.X > upperRight.X)
                            {
                                lowerLeft = new Point3d(upperRight.X - 1d, lowerLeft.Y, lowerLeft.Z);
                            }
                            ///////////////////////////////////////////////////////////!!!!!!!!!!//////////////////////////

                            try
                            {
                                Extents3d ext = new Extents3d(lowerLeft, upperRight);
                                res.AddExtents(ext);
                            }
                            catch { }
                        }
                    }
                });
                if (res == null)
                {
                    return(null);
                }
                res.TransformBy(_lineTarnsform);
                return(res);
            }
Example #15
0
        [CommandMethod("GEG")]//获取实体包围盒
        public void GeometricExtentsGet()
        {
            ed.WriteMessage("确定实体包围盒\n");

            SelectionSet sSet = this.SelectSsGet("GetSelection", null, null);

            // 范围对象
            Extents3d extend = new Extents3d();

            // 判断选择集是否为空
            if (sSet != null)
            {
                // 遍历选择对象
                foreach (SelectedObject selObj in sSet)
                {
                    // 确认返回的是合法的SelectedObject对象
                    if (selObj != null) //
                    {
                        //开启事务处理
                        using (Transaction trans = db.TransactionManager.StartTransaction())
                        {
                            Entity ent = trans.GetObject(selObj.ObjectId, OpenMode.ForRead) as Entity;
                            // 获取多个实体合在一起的获取其总范围
                            extend.AddExtents(ent.GeometricExtents);

                            trans.Commit();
                        }
                    }
                }
                if (extend != null)
                {
                    // 绘制包围盒
                    Point3d point1  = extend.MinPoint; // 范围最大点
                    Point3d point2  = extend.MaxPoint; // 范围最小点
                    Point3d point11 = new Point3d(point1.X, point2.Y, 0);
                    Point3d point22 = new Point3d(point2.X, point1.Y, 0);

                    this.CreatePolyline(new Point3dCollection {
                        point11, point2, point22, point1
                    }, null, 256, 0, true);
                }
            }
        }
Example #16
0
        private void ZoomObjects(ObjectIdCollection idCol)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db  = doc.Database;
            Editor   ed  = doc.Editor;

            using (Transaction tr = db.TransactionManager.StartTransaction())
                using (ViewTableRecord view = ed.GetCurrentView())
                {
                    Matrix3d WCS2DCS = Matrix3d.PlaneToWorld(view.ViewDirection);
                    WCS2DCS = Matrix3d.Displacement(view.Target - Point3d.Origin) * WCS2DCS;
                    WCS2DCS = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) * WCS2DCS;
                    WCS2DCS = WCS2DCS.Inverse();
                    Entity    ent = (Entity)tr.GetObject(idCol[0], OpenMode.ForRead);
                    Extents3d ext = ent.GeometricExtents;
                    ext.TransformBy(WCS2DCS);
                    for (int i = 1; i < idCol.Count; i++)
                    {
                        ent = (Entity)tr.GetObject(idCol[i], OpenMode.ForRead);
                        Extents3d tmp = ent.GeometricExtents;
                        tmp.TransformBy(WCS2DCS);
                        ext.AddExtents(tmp);
                    }
                    double ratio  = view.Width / view.Height;
                    double width  = ext.MaxPoint.X - ext.MinPoint.X;
                    double height = ext.MaxPoint.Y - ext.MinPoint.Y;
                    if (width > (height * ratio))
                    {
                        height = width / ratio;
                    }
                    Point2d center =
                        new Point2d((ext.MaxPoint.X + ext.MinPoint.X) / 2.0, (ext.MaxPoint.Y + ext.MinPoint.Y) / 2.0);
                    view.Height      = height;
                    view.Width       = width;
                    view.CenterPoint = center;
                    ed.SetCurrentView(view);
                    tr.Commit();
                }
        }
Example #17
0
        public static Extents3d SafeGetGeometricExtents(ObjectIdCollection entityIds)
        {
            var result = new Extents3d(new Point3d(0, 0, 0), new Point3d(1, 1, 1));

            using (var transaction = entityIds[0].Database.TransactionManager.StartTransaction())
            {
                var first = true;
                foreach (ObjectId objId in entityIds)
                {
                    if (!objId.IsValid)
                    {
                        continue;
                    }

                    var entity = transaction.GetObject(objId, OpenMode.ForRead) as Entity;
                    if (entity != null)
                    {
                        // 如果有图形几何是NullExtent,直接skip掉
                        var extents = SafeGetGeometricExtents(entity);
                        if (extents == null)
                        {
                            continue;
                        }

                        if (first)
                        {
                            result = extents.Value;
                            first  = false;
                        }
                        else
                        {
                            result.AddExtents(extents.Value);
                        }
                    }
                }
            }

            return(result);
        }
Example #18
0
        public static Extents3d getExtents(ObjectId[] ids)
        {
            Extents3d r       = new Extents3d();
            Document  acDoc   = Application.DocumentManager.MdiActiveDocument;
            Database  acCurDb = acDoc.Database;
            Editor    ed      = acDoc.Editor;

            // Start a transaction
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                for (int i = 0; i < ids.Length; i++)
                {
                    Autodesk.AutoCAD.DatabaseServices.DBObject obj = acTrans.GetObject(ids[i], OpenMode.ForRead);
                    Extents3d?ext = obj.Bounds;
                    if (ext != null)
                    {
                        r.AddExtents(ext.Value);
                    }
                }
            }
            return(r);
        }
Example #19
0
        /// <summary>
        /// 获取实体包围盒-实体
        /// </summary>
        public static Point2d[] GetGeometricExtents(this Database db, Entity ent)
        {
            // 范围对象
            Extents3d extend = new Extents3d();

            Point2d[] result = new Point2d[2];

            //开启事务处理
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                // 获取多个实体合在一起的获取其总范围
                extend.AddExtents(ent.GeometricExtents);
                trans.Commit();
            }

            if (extend != null)
            {
                // 绘制包围盒
                result[0] = new Point2d(extend.MinPoint.X, extend.MinPoint.Y);  // 范围最大点
                result[1] = new Point2d(extend.MaxPoint.X, extend.MaxPoint.Y);  // 范围最小点
            }
            return(result);
        }
Example #20
0
        public void DefineGeom(ObjectId idBtrPanelAkr)
        {
            string blName;

            _extentsTiles = new Extents3d();
            using (var btrAkr = idBtrPanelAkr.Open(OpenMode.ForRead) as BlockTableRecord)
            {
                blName = btrAkr.Name;
                foreach (ObjectId idEnt in btrAkr)
                {
                    if (idEnt.IsValidEx() && idEnt.ObjectClass.Name == "AcDbBlockReference")
                    {
                        using (var blRefTile = idEnt.Open(OpenMode.ForRead, false, true) as BlockReference)
                        {
                            if (string.Equals(blRefTile.GetEffectiveName(), Settings.Default.BlockTileName, StringComparison.CurrentCultureIgnoreCase))
                            {
                                _extentsTiles.AddExtents(blRefTile.GeometricExtents);
                            }
                        }
                    }
                }
                Image = AcadLib.Blocks.Visual.BlockPreviewHelper.GetPreview(btrAkr);
            }
            HeightPanelByTile = _extentsTiles.MaxPoint.Y - _extentsTiles.MinPoint.Y + Settings.Default.TileSeam;
            double shiftEnd = 0;

            if (blName.IndexOf(Settings.Default.EndLeftPanelSuffix, StringComparison.OrdinalIgnoreCase) != -1)
            {
                shiftEnd = -Settings.Default.FacadeEndsPanelIndent * 0.5;// 445;// Торец слева - сдвинуть влево FacadeEndsPanelIndent
            }
            else if (blName.IndexOf(Settings.Default.EndRightPanelSuffix, StringComparison.OrdinalIgnoreCase) != -1)
            {
                shiftEnd = -Settings.Default.FacadeEndsPanelIndent * 0.5;// 445;// Торец спрва - сдвинуть вправо
            }
            var test = _extentsTiles.MaxPoint.X - _extentsTiles.MinPoint.X;
            //_distToCenterFromBase = (_extentsTiles.MaxPoint.X - _extentsTiles.MinPoint.X) * 0.5 + shiftEnd;
        }
Example #21
0
        // Zooms to given objects
        public static void ZoomToObjects(Database db, IEnumerable <ObjectId> ids)
        {
            Autodesk.AutoCAD.EditorInput.Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            Extents3d outerext = new Extents3d();

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    foreach (ObjectId id in ids)
                    {
                        Autodesk.AutoCAD.DatabaseServices.Entity ent = tr.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Entity;
                        Extents3d ext = ent.GeometricExtents;
                        outerext.AddExtents(ext);
                    }
                }
                catch
                {
                    ;
                }

                tr.Commit();
            }

            outerext.TransformBy(ed.CurrentUserCoordinateSystem.Inverse());
            Point2d min2d = new Point2d(outerext.MinPoint.X, outerext.MinPoint.Y);
            Point2d max2d = new Point2d(outerext.MaxPoint.X, outerext.MaxPoint.Y);

            ViewTableRecord view = new ViewTableRecord();

            view.CenterPoint = min2d + ((max2d - min2d) / 2.0);
            view.Height      = max2d.Y - min2d.Y;
            view.Width       = max2d.X - min2d.X;

            ed.SetCurrentView(view);
        }
Example #22
0
        /// <summary>
        /// 获取实体包围盒-选择集
        /// </summary>
        public static Point2d[] GetGeometricExtents(this Database db, SelectionSet sSet)
        {
            // 范围对象
            Extents3d extend = new Extents3d();

            Point2d[] result = new Point2d[2];

            // 判断选择集是否为空
            if (sSet != null)
            {
                // 遍历选择对象
                foreach (SelectedObject selObj in sSet)
                {
                    // 确认返回的是合法的SelectedObject对象
                    if (selObj != null) //
                    {
                        //开启事务处理
                        using (Transaction trans = db.TransactionManager.StartTransaction())
                        {
                            Entity ent = trans.GetObject(selObj.ObjectId, OpenMode.ForRead) as Entity;
                            // 获取多个实体合在一起的获取其总范围
                            extend.AddExtents(ent.GeometricExtents);

                            trans.Commit();
                        }
                    }
                }
                if (extend != null)
                {
                    // 绘制包围盒
                    result[0] = new Point2d(extend.MinPoint.X, extend.MinPoint.Y);  // 范围最大点
                    result[1] = new Point2d(extend.MaxPoint.X, extend.MaxPoint.Y);  // 范围最小点
                }
            }
            return(result);
        }
Example #23
0
        /// <summary>
        /// Рекурсивное получение габаритного контейнера для выбранного примитива.
        /// </summary>
        /// <param name="en">Имя примитива</param>
        /// <param name="ext">Габаритный контейнер</param>
        /// <param name="mat">Матрица преобразования из системы координат блока в МСК.</param>
        private static Extents3d GetBlockExtents(Entity en, ref Matrix3d mat, Extents3d ext)
        {
            if (en is BlockReference bref)
            {
                var matIns = mat * bref.BlockTransform;
#pragma warning disable 618
                using (var btr = (BlockTableRecord)bref.BlockTableRecord.Open(OpenMode.ForRead))
#pragma warning restore 618
                {
                    foreach (var id in btr)
                    {
                        // Пропускаем все тексты.
                        if (id.ObjectClass.IsDerivedFrom(General.ClassDbTextRX) ||
                            id.ObjectClass.IsDerivedFrom(General.ClassMTextRX) ||
                            id.ObjectClass.IsDerivedFrom(General.ClassMLeaderRX) ||
                            id.ObjectClass.IsDerivedFrom(General.ClassDimension))
                        {
                            continue;
                        }
#pragma warning disable 618
                        using (var obj = id.Open(OpenMode.ForRead, false, true))
#pragma warning restore 618
                        {
                            var enCur = obj as Entity;
                            if (enCur == null || enCur.Visible != true)
                            {
                                continue;
                            }
                            if (IsEmptyExt(ref ext))
                            {
                                ext.AddExtents(GetBlockExtents(enCur, ref matIns, ext));
                            }
                            else
                            {
                                ext = GetBlockExtents(enCur, ref matIns, ext);
                            }
                        }
                    }
                }
            }
            else
            {
                if (mat.IsUniscaledOrtho())
                {
                    using (var enTr = en.GetTransformedCopy(mat))
                    {
                        switch (enTr)
                        {
                        case Dimension dim:
                            dim.RecomputeDimensionBlock(true);
                            break;

                        case Table table:
                            table.RecomputeTableBlock(true);
                            break;
                        }

                        if (IsEmptyExt(ref ext))
                        {
                            try
                            {
                                ext = enTr.GeometricExtents;
                            }
                            catch
                            {
                                // ignored
                            }
                        }
                        else
                        {
                            try
                            {
                                ext.AddExtents(enTr.GeometricExtents);
                            }
                            catch
                            {
                                // ignored
                            }
                        }

                        return(ext);
                    }
                }

                try
                {
                    var curExt = en.GeometricExtents;
                    curExt.TransformBy(mat);
                    if (IsEmptyExt(ref ext))
                    {
                        ext = curExt;
                    }
                    else
                    {
                        ext.AddExtents(curExt);
                    }
                }
                catch
                {
                    // ignored
                }

                return(ext);
            }

            return(ext);
        }
Example #24
0
        /// <summary>
        /// Рекурсивное получение габаритного контейнера для выбранного примитива.
        /// </summary>
        /// <param name="en">Имя примитива</param>
        /// <param name="ext">Габаритный контейнер</param>
        /// <param name="mat">Матрица преобразования из системы координат блока в МСК.</param>
        void GetBlockExtents(Entity en, ref Extents3d ext, ref Matrix3d mat)
        {
            if (!IsLayerOn(en.LayerId))
            {
                return;
            }
            if (en is BlockReference)
            {
                BlockReference bref   = en as BlockReference;
                Matrix3d       matIns = mat * bref.BlockTransform;
                using (BlockTableRecord btr =
                           bref.BlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord)
                {
                    foreach (ObjectId id in btr)
                    {
                        using (DBObject obj = id.GetObject(OpenMode.ForRead) as DBObject)
                        {
                            Entity enCur = obj as Entity;
                            if (enCur == null || enCur.Visible != true)
                            {
                                continue;
                            }
                            // Пропускаем неконстантные и невидимые определения атрибутов
                            AttributeDefinition attDef = enCur as AttributeDefinition;
                            if (attDef != null && (!attDef.Constant || attDef.Invisible))
                            {
                                continue;
                            }
                            GetBlockExtents(enCur, ref ext, ref matIns);
                        }
                    }
                }

                // Отдельно обрабатываем атрибуты блока
                if (bref.AttributeCollection.Count > 0)
                {
                    foreach (ObjectId idAtt in bref.AttributeCollection)
                    {
                        using (AttributeReference attRef =
                                   idAtt.GetObject(OpenMode.ForRead) as AttributeReference)
                        {
                            if (!attRef.Invisible && attRef.Visible)
                            {
                                GetBlockExtents(attRef, ref ext, ref mat);
                            }
                        }
                    }
                }
            }
            else
            {
                if (mat.IsUniscaledOrtho())
                {
                    using (Entity enTr = en.GetTransformedCopy(mat))
                    {
                        if (enTr is Dimension)
                        {
                            (enTr as Dimension).RecomputeDimensionBlock(true);
                        }
                        if (enTr is Table)
                        {
                            (enTr as Table).RecomputeTableBlock(true);
                        }
                        if (IsEmptyExt(ref ext))
                        {
                            try
                            {
                                ext = enTr.GeometricExtents;
                            }
                            catch
                            {
                                // ignored
                            }
                        }
                        else
                        {
                            try
                            {
                                ext.AddExtents(enTr.GeometricExtents);
                            }
                            catch
                            {
                                // ignored
                            }
                        }

                        return;
                    }
                }
                else
                {
                    try
                    {
                        Extents3d curExt = en.GeometricExtents;
                        curExt.TransformBy(mat);
                        if (IsEmptyExt(ref ext))
                        {
                            ext = curExt;
                        }
                        else
                        {
                            ext.AddExtents(curExt);
                        }
                    }
                    catch
                    {
                    }

                    return;
                }
            }
        }
Example #25
0
        public void fMESHAUTO()
        {
            Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor;

            try
            {
                Utils.Utils.Init();

                Document acDoc   = acApp.DocumentManager.MdiActiveDocument;
                Database acCurDb = acDoc.Database;

                if (!Utils.Layers.CurrentLayer().Contains("!FDS_MESH"))
                {
                    Utils.Layers.SetLayer("!FDS_MESH");
                }

                Utils.Utils.SetOrtho(false);

                PromptDoubleOptions snapO = new PromptDoubleOptions("\nEnter cell size:");
                snapO.DefaultValue = Utils.Utils.snapUnit.X;
                PromptDoubleResult snap = ed.GetDouble(snapO);
                if (snap.Status != PromptStatus.OK || snap.Status == PromptStatus.Cancel)
                {
                    goto End;
                }
                Utils.Utils.SetSnapUnit(new Point2d(snap.Value, snap.Value));

                PromptPointOptions p1Option = new PromptPointOptions("\nSpecify mesh area first corner:");
                p1Option.AllowNone = false;
                PromptPointResult p1 = ed.GetPoint(p1Option);
                if (p1.Status != PromptStatus.OK || p1.Status == PromptStatus.Cancel)
                {
                    goto End;
                }

                var p2 = ed.GetUcsCorner("Pick mesh area opposite corner:", p1.Value);
                if (p2.Status != PromptStatus.OK || p2.Status == PromptStatus.Cancel)
                {
                    goto End;
                }

                ObjectId recId = Utils.Utils.CreateRectangle(p1.Value, p2.Value, "!FDS_MESH");
                // Vertical - pionowy
                // Horizontal - poziomy

                PromptIntegerOptions noMeshVerO = new PromptIntegerOptions("\nEnter vertical mesh number:");
                noMeshVerO.DefaultValue = 1;
                PromptIntegerResult noMeshVer = ed.GetInteger(noMeshVerO);
                if (noMeshVer.Status != PromptStatus.OK || noMeshVer.Status == PromptStatus.Cancel)
                {
                    goto End;
                }

                PromptIntegerOptions noMeshHorO = new PromptIntegerOptions("\nEnter horizontal mesh number:");
                noMeshHorO.DefaultValue = 1;
                PromptIntegerResult noMeshHor = ed.GetInteger(noMeshHorO);
                if (noMeshHor.Status != PromptStatus.OK || noMeshHor.Status == PromptStatus.Cancel)
                {
                    goto End;
                }

                // Usun zaznaczenie
                Utils.Utils.DeleteObject(recId);

                double horizontalDistance = Math.Abs(p2.Value.X - p1.Value.X);
                double verticalDistance   = Math.Abs(p2.Value.Y - p1.Value.Y);

                double horizontalUnitDistance = Math.Ceiling(horizontalDistance / noMeshHor.Value / snap.Value) * snap.Value;
                double verticalUnitDistance   = Math.Ceiling(verticalDistance / noMeshVer.Value / snap.Value) * snap.Value;

                horizontalUnitDistance = horizontalUnitDistance + (horizontalUnitDistance % snap.Value);
                verticalUnitDistance   = verticalUnitDistance + (verticalUnitDistance % snap.Value);

                ed.WriteMessage("\nHorizontal distance:");
                ed.WriteMessage(horizontalDistance.ToString());

                ed.WriteMessage("\nHorizontal unit distance:");
                ed.WriteMessage(horizontalUnitDistance.ToString());

                Extents3d ext = new Extents3d();
                ext.AddPoint(p1.Value);
                ext.AddPoint(p2.Value);

                List <double> horizontalPoints = new List <double>();
                for (int i = 0; i < noMeshHor.Value; i++)
                {
                    horizontalPoints.Add(ext.MinPoint.X + i * horizontalUnitDistance);
                }

                List <double> verticalPoints = new List <double>();
                for (int i = 0; i < noMeshVer.Value; i++)
                {
                    verticalPoints.Add(ext.MinPoint.Y + i * verticalUnitDistance);
                }

                List <double[]> boxes = new List <double[]>();

                horizontalPoints.ForEach(delegate(double xPoint1)
                {
                    double xPoint2 = xPoint1 + horizontalUnitDistance;
                    if (xPoint1 == horizontalPoints.Last())
                    {
                        xPoint2 = ext.MaxPoint.X;
                    }

                    verticalPoints.ForEach(delegate(double yPoint1)
                    {
                        double yPoint2 = yPoint1 + verticalUnitDistance;
                        if (yPoint1 == verticalPoints.Last())
                        {
                            yPoint2 = ext.MaxPoint.Y;
                        }

                        // Wyznaczanie Z do siatek

                        // !!! Dodać filtr warstw ...
                        // !!! Czy po Z rysujemy tez kilka siatek ...
                        PromptSelectionResult acSSPrompt;
                        acSSPrompt = ed.SelectCrossingWindow(new Point3d(xPoint1, yPoint1, 0), new Point3d(xPoint2, yPoint2, 0));
                        if (acSSPrompt.Status == PromptStatus.OK)
                        {
                            Extents3d extZ      = new Extents3d();
                            SelectionSet acSSet = acSSPrompt.Value;

                            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                            {
                                foreach (var id in acSSet.GetObjectIds())
                                {
                                    var ent = acTrans.GetObject(id, OpenMode.ForRead) as Entity;
                                    if (ent != null)
                                    {
                                        extZ.AddExtents(ent.GeometricExtents);
                                    }
                                }
                            }
                            // !!! Sprawdzic czy z jest wielokrotnoscia skoku - rysowane na innym skoku
                            boxes.Add(new double[6] {
                                xPoint1, xPoint2, yPoint1, yPoint2, extZ.MinPoint.Z, extZ.MaxPoint.Z
                            });
                        }
                        else
                        {
                            //acApp.ShowAlertDialog("No objects of objects in area");
                            ed.WriteMessage("\nNo mesh needed");
                        }
                    });
                });

                if (boxes.Count > 0)
                {
                    boxes.ForEach(delegate(double[] point)
                    {
                        Utils.Utils.CreateBox(point[0], point[1], point[2], point[3], point[4], point[5], "!FDS_MESH");
                    });
                }

                End :;
                Utils.Utils.End();
            }
            catch (System.Exception e)
            {
                ed.WriteMessage("\nProgram exception: " + e.ToString());
            }
        }
Example #26
0
 public void DefineGeom(ObjectId idBtrPanelAkr)
 {
     string blName;
     _extentsTiles = new Extents3d();
     using (var btrAkr = idBtrPanelAkr.Open(OpenMode.ForRead) as BlockTableRecord)
     {
         blName = btrAkr.Name;
         foreach (ObjectId idEnt in btrAkr)
         {
             if (idEnt.ObjectClass.Name == "AcDbBlockReference")
             {
                 using (var blRefTile = idEnt.Open(OpenMode.ForRead, false, true) as BlockReference)
                 {
                     if (string.Equals(blRefTile.GetEffectiveName(), Settings.Default.BlockTileName, StringComparison.CurrentCultureIgnoreCase))
                     {
                         _extentsTiles.AddExtents(blRefTile.GeometricExtents);
                     }
                 }
             }
         }
         Image = AcadLib.Blocks.Visual.BlockPreviewHelper.GetPreview(btrAkr);
     }
     HeightPanelByTile = _extentsTiles.MaxPoint.Y - _extentsTiles.MinPoint.Y + Settings.Default.TileSeam;
     double shiftEnd = 0;
     if (blName.IndexOf(Settings.Default.EndLeftPanelSuffix, StringComparison.OrdinalIgnoreCase) != -1)
     {
         shiftEnd = -Settings.Default.FacadeEndsPanelIndent * 0.5;// 445;// Торец слева - сдвинуть влево FacadeEndsPanelIndent
     }
     else if (blName.IndexOf(Settings.Default.EndRightPanelSuffix, StringComparison.OrdinalIgnoreCase) != -1)
     {
         shiftEnd = -Settings.Default.FacadeEndsPanelIndent * 0.5;// 445;// Торец спрва - сдвинуть вправо
     }
     var test = _extentsTiles.MaxPoint.X - _extentsTiles.MinPoint.X;
     //_distToCenterFromBase = (_extentsTiles.MaxPoint.X - _extentsTiles.MinPoint.X) * 0.5 + shiftEnd;
 }
Example #27
0
        /// <summary>
        /// Рекурсивное получение габаритного контейнера для выбранного примитива.
        /// </summary>
        /// <param name="en">Имя примитива</param>
        /// <param name="ext">Габаритный контейнер</param>
        /// <param name="mat">Матрица преобразования из системы координат блока в МСК.</param>
        private static Extents3d GetBlockExtents(Entity en, ref Matrix3d mat, Extents3d ext)
        {
            if (en is BlockReference)
            {
                var bref = en as BlockReference;
                Matrix3d matIns = mat * bref.BlockTransform;
                using (var btr = bref.BlockTableRecord.Open(OpenMode.ForRead) as BlockTableRecord)
                {
                    foreach (ObjectId id in btr)
                    {
                        // Пропускаем все тексты.
                        if (id.ObjectClass.IsDerivedFrom(DbTextRXClass) ||
                           id.ObjectClass.IsDerivedFrom(MTextRXClass) ||
                           id.ObjectClass.IsDerivedFrom(MLeaderRXClass) ||
                           id.ObjectClass.IsDerivedFrom(DimensionRXClass))
                        {
                            continue;
                        }
                        using (DBObject obj = id.Open(OpenMode.ForRead) as DBObject)
                        {
                            Entity enCur = obj as Entity;
                            if (enCur == null || enCur.Visible != true)
                                continue;
                            if (IsEmptyExt(ref ext))
                            {
                                ext.AddExtents(GetBlockExtents(enCur, ref matIns, ext));
                            }
                            else
                            {
                                ext = GetBlockExtents(enCur, ref matIns, ext);
                            }
                        }
                    }
                }
            }
            else
            {
                if (mat.IsUniscaledOrtho())
                {
                    using (Entity enTr = en.GetTransformedCopy(mat))
                    {
                        if (enTr is Dimension)
                            (enTr as Dimension).RecomputeDimensionBlock(true);
                        if (enTr is Table)
                            (enTr as Table).RecomputeTableBlock(true);

                        if (IsEmptyExt(ref ext))
                        {
                            try { ext = enTr.GeometricExtents; } catch { };
                        }
                        else
                        {
                            try { ext.AddExtents(enTr.GeometricExtents); } catch { };
                        }
                        return ext;
                    }
                }
                else
                {
                    try
                    {
                        Extents3d curExt = en.GeometricExtents;
                        curExt.TransformBy(mat);
                        if (IsEmptyExt(ref ext))
                            ext = curExt;
                        else
                            ext.AddExtents(curExt);
                    }
                    catch { }
                    return ext;
                }
            }
            return ext;
        }
Example #28
0
        public string CreateGraph(string jsonArgs)
        {
            // The radius for our node circles and the height of our text

            const double rad = 20, txtHeight = 10;

            var doc = Application.DocumentManager.MdiActiveDocument;

            if (doc == null)
            {
                return("");
            }
            var db = doc.Database;
            var ed = doc.Editor;

            JArray jedges = null, jnodes = null;

            using (var sr = new StringReader(jsonArgs))
            {
                var jr = new JsonTextReader(sr);
                var js = new JsonSerializer();
                var jo = js.Deserialize(jr) as JObject;
                if (jo != null)
                {
                    foreach (var jp in jo.Properties())
                    {
                        if (jp.Name == "edges")
                        {
                            jedges = jp.Value as JArray;
                        }
                        else if (jp.Name == "nodes")
                        {
                            jnodes = jp.Value as JArray;
                        }
                    }
                }
            }

            var nodes = new Dictionary <String, Node>();
            var edges = new Dictionary <String, Edge>();

            GetNodesAndEdges(jnodes, jedges, nodes, edges);

            if (nodes.Count > 0)
            {
                using (var dlock = doc.LockDocument())
                {
                    using (var tr = doc.TransactionManager.StartTransaction())
                    {
                        var btr =
                            (BlockTableRecord)tr.GetObject(
                                db.CurrentSpaceId, OpenMode.ForWrite
                                );

                        // Rather than add the entities to the database directly,
                        // gather them in a collection as we'll check their extents
                        // and transform them when we add them

                        var ents = new List <Entity>();

                        // Create our nodes

                        foreach (var kvnode in nodes)
                        {
                            var node = kvnode.Value;

                            // A node is a circle with some text

                            ents.Add(new Circle(node.Position, Vector3d.ZAxis, rad));
                            ents.Add(CreateText(node.Position, txtHeight, node.Name));
                        }

                        // Create our edges

                        foreach (var kvedge in edges)
                        {
                            var edge = kvedge.Value;

                            // Edges that go both ways will be arcs

                            bool createArc = edges.ContainsKey(ReverseEdge(kvedge.Key));

                            // An edge is a curve with an arrowhead and some text

                            var c = CreateEdge(rad, edge, createArc);
                            ents.Add(c);
                            ents.Add(CreateArrowhead(txtHeight, c));
                            ents.Add(CreateText(c.MidPoint(), txtHeight, edge.Name));
                        }

                        // Collect the extents of our entities

                        var ext = new Extents3d();
                        foreach (var ent in ents)
                        {
                            if (ent.Bounds.HasValue)
                            {
                                ext.AddExtents(ent.Bounds.Value);
                            }
                        }

                        // We'll displace them to start at the origin (as they're
                        // created in negative space - as we negate the Y value -
                        // we can assume the MaxPoint is going to be the origin)

                        var m = Matrix3d.Displacement(-ext.MinPoint.GetAsVector());
                        foreach (var ent in ents)
                        {
                            ent.TransformBy(m);
                            btr.AppendEntity(ent);
                            tr.AddNewlyCreatedDBObject(ent, true);
                        }

                        // Commit the transaction before we finish

                        tr.Commit();
                    }

                    // Zoom to the extents of our map

                    doc.SendStringToExecute("_.ZOOM _E ", false, false, false);
                }
            }

            return("");
        }
Example #29
0
        public void iterateEntInBlock(BlockTableRecord btr, bool _deleteWaste = true)
        {
            var tilesDict = new Dictionary <Extents3d, Tuple <ObjectId, Extents3d> >();

            _extentsByTile = new Extents3d();
            foreach (ObjectId idEnt in btr)
            {
                if (!idEnt.IsValidEx())
                {
                    continue;
                }
                using (var ent = idEnt.GetObject(OpenMode.ForRead) as Entity)
                {
                    EntInfos.Add(new EntityInfo(ent));

                    // Если это подпись Марки (на слое Марок)
                    if (ent is DBText && string.Equals(ent.Layer, Settings.Default.LayerMarks, StringComparison.CurrentCultureIgnoreCase))
                    {
                        // Как определить - это текст Марки или Покраски - сейчас Покраска в скобках (). Но вдруг будет без скобок.
                        var textCaption = (DBText)ent;
                        if (textCaption.TextString.StartsWith("("))
                        {
                            CaptionPaint   = textCaption.TextString;
                            IdCaptionPaint = idEnt;
                        }
                        else
                        {
                            CaptionMarkSb   = textCaption.TextString;
                            IdCaptionMarkSb = idEnt;
                            CaptionLayerId  = textCaption.LayerId;
                        }
                        continue;
                    }
                    // Если блок - плитка или окно
                    else if (ent is BlockReference)
                    {
                        var blRef  = ent as BlockReference;
                        var blName = blRef.GetEffectiveName();
                        if (blName.Equals(Settings.Default.BlockTileName, StringComparison.CurrentCultureIgnoreCase))
                        {
                            var ext = blRef.GeometricExtentsСlean();
                            _extentsByTile.AddExtents(ext);

                            try
                            {
                                tilesDict.Add(ext, new Tuple <ObjectId, Extents3d>(blRef.Id, ext));
                            }
                            catch (ArgumentException)
                            {
                                // Ошибка - плитка с такими границами уже есть
                                ErrMsg += "Наложение плиток. ";
                            }
                            catch (Exception ex)
                            {
                                Logger.Log.Error(ex, "iterateEntInBlock - tilesDict.Add(ent.GeometricExtents, ent.GeometricExtents);");
                            }
                            continue;
                        }
                        else if (blName.StartsWith(Settings.Default.BlockWindowName, StringComparison.OrdinalIgnoreCase))
                        {
                            // Окно оставляем
                            continue;
                        }
                    }

                    //// Удаление лишних объектов (мусора)
                    //if (_deleteWaste && deleteWaste(ent)) continue; // Если объект удален, то переход к новому объекту в блоке

                    if (_deleteWaste &&
                        (string.Equals(ent.Layer, Settings.Default.LayerDimensionFacade, StringComparison.CurrentCultureIgnoreCase) ||
                         string.Equals(ent.Layer, Settings.Default.LayerDimensionForm, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        ent.UpgradeOpen();
                        ent.Erase();
                    }
                }
            }

            Tiles = tilesDict.Values.ToList();
            // Проверка
            if (string.IsNullOrEmpty(CaptionMarkSb))
            {
                ErrMsg += "Не наден текст подписи марки панели. ";
            }
            if (string.IsNullOrEmpty(CaptionPaint))
            {
                ErrMsg += "Не наден текст подписи марки покраски панели. ";
            }
            if (ExtentsByTile.Diagonal() < 100)
            {
                ErrMsg += string.Format("Не определены габариты панели по плиткам - диагональ панели = {0}", ExtentsByTile.Diagonal());
            }

            // Определение высоты панели
            HeightByTile = ExtentsByTile.MaxPoint.Y - ExtentsByTile.MinPoint.Y;
        }
Example #30
0
        // Zooms to given objects
        public static void ZoomToObjects(IEnumerable<ObjectId> ids)
        {
            Autodesk.AutoCAD.EditorInput.Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            Extents3d outerext = new Extents3d();
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    foreach (ObjectId id in ids)
                    {
                        Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                        Extents3d ext = ent.GeometricExtents;
                        outerext.AddExtents(ext);
                    }
                }
                catch
                {
                    ;
                }
            }

            outerext.TransformBy(ed.CurrentUserCoordinateSystem.Inverse());
            Point2d min2d = new Point2d(outerext.MinPoint.X, outerext.MinPoint.Y);
            Point2d max2d = new Point2d(outerext.MaxPoint.X, outerext.MaxPoint.Y);

            ViewTableRecord view = new ViewTableRecord();

            view.CenterPoint = min2d + ((max2d - min2d) / 2.0);
            view.Height = max2d.Y - min2d.Y;
            view.Width = max2d.X - min2d.X;

            ed.SetCurrentView(view);
        }
Example #31
0
        /// <summary>
        /// Определение границ блока панели для вида формы или фасада
        /// </summary>            
        private Extents3d getPanelExt(BlockReference blRef, bool isFacadeView)
        {
            Extents3d resVal = new Extents3d();
            string ignoreLayer = isFacadeView ? Settings.Default.LayerDimensionForm : Settings.Default.LayerDimensionFacade;

            var btr = blRef.DynamicBlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;
            foreach (ObjectId idEnt in btr)
            {
                var ent = idEnt.GetObject(OpenMode.ForRead, false, true) as Entity;
                if (ent.Layer.Equals(ignoreLayer, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                try
                {
                    var curExt = ent.GeometricExtents;
                    if (!IsEmptyExt(ref curExt))
                    {
                        resVal.AddExtents(curExt);
                    }
                }
                catch { }
            }
            resVal.TransformBy(blRef.BlockTransform);
            return resVal;
        }
Example #32
0
        public override void Check(IEnumerable <Autodesk.AutoCAD.DatabaseServices.ObjectId> selectedObjectIds)
        {
            if (!selectedObjectIds.Any())
            {
                return;
            }

            var precision = 0.000001;
            // First we need to make sure all intersections are vertices of polygon
            var missingVertexSearcher = new MissingVertexSearcherQuadTree(Editor);

            missingVertexSearcher.Check(selectedObjectIds);
            if (missingVertexSearcher.MissingVertexInfos.Any())
            {
                missingVertexSearcher.FixAll();
            }

            // Use clipper to search holes
            var subject = new List <List <IntPoint> >(1);
            var clipper = new List <List <IntPoint> >(1);

            var       database = Editor.Document.Database;
            Extents3d extents  = new Extents3d(new Point3d(0, 0, 0), new Point3d(1, 1, 0));
            bool      first    = true;

            // Use all polygons to make up clipper.
            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var objId in selectedObjectIds)
                {
                    var curve = transaction.GetObject(objId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }
                    if (!IsCurveClosed(curve))
                    {
                        continue;
                    }

                    // Calculate its extents.
                    if (first)
                    {
                        extents = curve.GeometricExtents;
                        first   = false;
                    }
                    else
                    {
                        extents.AddExtents(curve.GeometricExtents);
                    }

                    // Add it to the clipper.
                    var vertices = CurveUtils.GetDistinctVertices2D(curve, transaction);
                    // Only for polygon.
                    if (vertices.Count() < 3)
                    {
                        continue;
                    }

                    // That has the same vertex for the first and last array members.
                    if (vertices[0] != vertices[vertices.Count - 1])
                    {
                        vertices.Add(vertices[0]);
                    }
                    var clockwise = ComputerGraphics.ClockWise2(vertices.ToArray());
                    if (!clockwise)
                    {
                        vertices.Reverse();
                    }
                    if (vertices[0] == vertices[vertices.Count - 1])
                    {
                        vertices.RemoveAt(vertices.Count - 1);
                    }

                    clipper.Add(vertices.Select(it => new IntPoint(it.X / precision, it.Y / precision)).ToList());
                }
                transaction.Commit();
            }

            // Create subject rectangle.

            var vector   = (extents.MaxPoint - extents.MinPoint) * 0.1;
            var minPoint = extents.MinPoint - vector;
            var maxPoint = extents.MaxPoint + vector;

            subject.Add(new List <IntPoint>()
            {
                new IntPoint(minPoint.X / precision, minPoint.Y / precision),
                new IntPoint(minPoint.X / precision, maxPoint.Y / precision),
                new IntPoint(maxPoint.X / precision, maxPoint.Y / precision),
                new IntPoint(maxPoint.X / precision, minPoint.Y / precision)
            });


            var result = new List <List <IntPoint> >();
            var cpr    = new Clipper();

            cpr.AddPaths(subject, PolyType.ptSubject, true);
            cpr.AddPaths(clipper, PolyType.ptClip, true);
            cpr.Execute(ClipType.ctXor, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
            if (result.Count <= 0)
            {
                return;
            }

            foreach (var path in result)
            {
                // Ignore the outmost loop.
                if (path.Contains(new IntPoint(minPoint.X / precision, minPoint.Y / precision)))
                {
                    continue;
                }

                var points = path.Select(it => new Point2d(it.X * precision, it.Y * precision)).ToList();
                if (points[0] != points[points.Count - 1])
                {
                    points.Add(points[0]);
                }
                var array = points.ToArray();
                if (ComputerGraphics.ClockWise2(array))
                {
                    continue;
                }

                var polyline = CreatePolygon(array);
                if (polyline.Area.Smaller(0.001))
                {
                    polyline.Dispose();
                    continue;
                }

                _holes.Add(polyline);
            }
        }