CAD开发__面域重叠检查

概述

    在一些设计场景中,用户需要用到相互靠近但又不重叠的面域。但用户画图过程中,因为画图习惯或者精度问题,一些肉眼无法识别的重叠在所难免,因此需要些工具来辅助重叠判别和重叠区域识别。

原理

    用面域间的布尔运算可以判定两个面域是否重叠。为了让用户知道重叠区域在哪,需要把重叠的区域生成重来,并设置特定的图层和颜色;当面域数量比较多时,耗时比较多,还需要设置进度条;判别完后,用户想知道有没有面域重叠,有多少个面域重叠,因此还需要输出结论;用户有时只想对某个或者某些图层进行面域识别,因此还需要提供一个选择的界面。整个原理比较简单,就不提供流程图了。

代码实现

     完整业务代码(界面和ViewModel未包含)如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using CadToolset.Common;
using TimesBIM.CadToolset.App.Commands.Landscape;
using TimesBIM.CadToolset.App.Utils;
using TimesBIM.CadToolset.App.View.Landscape;
using TimesBIM.CadToolset.App.ViewModel.Landscape;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(CmdCheckRegion))]

namespace TimesBIM.CadToolset.App.Commands.Landscape
{
    public class CmdCheckRegion
    {
        private const string _regionLayerName = "00-重叠面域";

        [CommandMethod("MYJC")]
        public void CheckRegion()
        {
            var db = Application.DocumentManager.MdiActiveDocument.Database;
            using (var transaction = db.TransactionManager.StartTransaction())
            {
                var mDocumentLock = Application.DocumentManager.MdiActiveDocument.LockDocument();
                var regions = GetRegions(transaction);//获取面域
                var layerTable = transaction.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;//层表
                var layerTableRecords = GetLayerTableRecords(layerTable);//获取层表记录
                SetLayerByName(layerTable);//设置目标图层
                var regionTuples = layerTableRecords.Select(x => new Tuple<string, List<Region>>(x.Name, regions //面域按图层分组
                    .Where(y => y.LayerId.ToString() == x.Id.ToString()).ToList())).ToList();
                regionTuples = regionTuples.Where(x => x.Item2.Count > 0).ToList();

                var checkRegionVM = new CheckRegionVM(regionTuples
                    .Select(x => new CheckRegionVM.LayerForCheck { ToCheck = x.Item1.Contains("(预)"), LayerName = x.Item1 }).ToList());
                var checkRegionView = new CheckRegionView { DataContext = checkRegionVM };
                checkRegionView.ShowDialog();
                if ( !checkRegionView.ToConfirm) { transaction.Commit(); return; };//选择检查图层
                CheckRegions(transaction, layerTable[_regionLayerName], checkRegionVM, regionTuples, regions);//检查
                mDocumentLock.Dispose();
                transaction.Commit();
            }
        }

        private List<Region> GetRegions(Transaction transaction)
        {
            var regions = new List<Region>();
            var doc = Application.DocumentManager.MdiActiveDocument;
            var curBlockTb = transaction.GetObject(doc.Database.BlockTableId, OpenMode.ForWrite) as BlockTable; //当前文档块表
            if (curBlockTb == null) { transaction.Commit(); return regions; }
            var modelSpaceBlockTableRecord = (BlockTableRecord)transaction.GetObject(curBlockTb[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
            foreach (ObjectId id in modelSpaceBlockTableRecord)
            {
                var region = transaction.GetObject(id, OpenMode.ForRead);
                if (region != null && region is Region) regions.Add(region as Region);
            }
            return regions;
        }

        private List<LayerTableRecord> GetLayerTableRecords(LayerTable layerTable)
        {
            var layerTableRecords = new List<LayerTableRecord>();
            foreach (ObjectId id in layerTable)
            {
                layerTableRecords.Add((LayerTableRecord)id.GetObject(OpenMode.ForRead));
            }
            return layerTableRecords;
        }

        private void SetLayerByName(LayerTable layerTable)
        {
            using (var record = new LayerTableRecord())
            {
                record.Name = _regionLayerName;
                record.Color = Color.FromRgb(255, 0, 0);
                layerTable.UpgradeOpen();//修改图层打开方式为写
                if (!layerTable.Has(record.Name)) layerTable.Add(record);//将新图层追加到图层表
                layerTable.DowngradeOpen();
            }
        }

        private void CheckRegions(Transaction transaction,ObjectId layerId, CheckRegionVM checkRegionVM, List<Tuple<string, List<Region>>> regionTuples, List<Region> regions)
        {
            var layers = checkRegionVM.LayerForChecks.Where(x => x.ToCheck).Select(x => x.LayerName).ToList();
            regionTuples = regionTuples.Where(x => layers.Contains(x.Item1)).ToList();
            regions = regions.Where(x => regionTuples.Any(y => y.Item2.Contains(x))).ToList();
            var overlapedRegionCount = 0;
            var count = regions.Count;
            if (count < 2) { MessageBox.Show("面域数<2,不需要检查重叠");return; }
            var progressMeter = new ProgressMeter();
            progressMeter.Start("面域重叠检查进行中...");
            progressMeter.SetLimit(count*(count-1)/2);

            foreach (var region in regions)
            {
                int index = regions.IndexOf(region);
                for (int i = index + 1; i < regions.Count; i++)
                {
                    var overlapResult = RegionOverlap(region, regions[i], out var OverlapedRegion);
                    progressMeter.MeterProgress();
                    if (overlapResult)
                    {
                        OverlapedRegion.SetLayerId(layerId, true);
                        transaction.AddEntity(OverlapedRegion);//添加实体
                        overlapedRegionCount++;
                    }
                }
            }
            progressMeter.Stop();
            var message = overlapedRegionCount > 0 ? "重叠面域数为:" + overlapedRegionCount+ ",请检查图面。" : "未有发现面域重叠!";
            if (overlapedRegionCount > 0) MessageBox.Show(message);
        }

        private static bool RegionOverlap(Region bigRegion, Region regionSecond,out Region region)
        {
            var newRegion1 = (Region)bigRegion.Clone();
            region = (Region)regionSecond.Clone();
            try
            {
                region.BooleanOperation(BooleanOperationType.BoolIntersect, newRegion1);
            }
            catch
            {
                return false;
            }
            return region.Area > 0;
        }
    }
}

实现效果

在这里插入图片描述

输入文件

在这里插入图片描述

图层选择界面

进度条

进度条

在这里插入图片描述

运行完以后输出结论

在这里插入图片描述

重叠区域标识
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值