Revit二次开发 如何获得链接CAD中所有的多段线PolyLine?

项目场景:

        最近做的这个项目,涉及到提取链接CAD中的所有多段线,并根据这些多段线的几何信息做一些分析,但是产生了一些意想不到的问题。


问题描述

        通过网上流传的提取手段,并不能完全提取CAD中的所有多段线。有时候甚至只提取你不想要的多段线。下面的代码片段是博主helloyangkl提供的解决方案,原文链接为:(174条消息) revit二次开发——基于teigha读取CAD几何与文字(提供源码、引用包与异常解决)_helloyangkl的博客-CSDN博客        他的模型类CADGeometryModel应该是忘加了,我给他补充了下。由于我的模型类中的属性名跟他的略有不同,所以朋友们在粘贴复制做测试的时候,需要自己稍微修改下部分内容,注意甄别。

        通过这种方法,并不能得到CAD中的所有多段线,正如我前文中描述的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using CreatBridgeForRevit2018.ElementsSelect;
using CreatBridgeForRevit2018.Filter;
using Teigha.Runtime;
using Teigha.DatabaseServices;
using System.IO;
using System.Collections;
using Teigha.Geometry;
 
namespace CreatBridgeForRevit2018.ReadCAD
{
    
 
 
    class ReadCADUtils
    {
      static string dll = @"D:\Desktop\RvtToDwg\bin\Debug\TD_Mgd.dll";//手动指定引用dll路径
      Assembly a = Assembly.UnsafeLoadFrom(dll);
        
        /// 
        /// 取得CAD里的线,包括直线、多段线、圆曲线
        /// 
        /// 
        /// 
        public List GetCADCurves(string dwgFile)
        {
            List listCADModels = new List();            
            using (new Services())
            {
                using (Database database = new Database(false, false))
                {
                    database.ReadDwgFile(dwgFile, FileShare.Read, true, "");
                    using (var trans = database.TransactionManager.StartTransaction())
                    {
                        using (BlockTable table = (BlockTable)database.BlockTableId.GetObject(OpenMode.ForRead))
                        {
                            using (SymbolTableEnumerator enumerator = table.GetEnumerator())
                            {
                                StringBuilder sb = new StringBuilder();
                                while (enumerator.MoveNext())
                                {
                                    using (BlockTableRecord record = (BlockTableRecord)enumerator.Current.GetObject(OpenMode.ForRead))
                                    {
 
                                        foreach (ObjectId id in record)
                                        {
                                            Entity entity = (Entity)id.GetObject(OpenMode.ForRead, false, false);
                                            CADGeometryModel geoModel = new CADGeometryModel();
                                            switch (entity.GetRXClass().Name)
                                            {
                                                case "AcDbPolyline":
                                                    Teigha.DatabaseServices.Polyline pl = (Teigha.DatabaseServices.Polyline)entity;
                                                    IList listPoints = new List();
                                                    for (int i = 0; i < pl.NumberOfVertices; i++)
                                                    {
                                                        listPoints.Add(new XYZ(MillimetersToUnits(pl.GetPoint2dAt(i).X), MillimetersToUnits(pl.GetPoint2dAt(i).Y), 0));
                                                    }
                                                    PolyLine polyLine = PolyLine.Create(listPoints);
                                                    listCADModels.Add(new CADGeometryModel() {CadPolyLine= polyLine,LayerName=pl.Layer });
                                                    break;
                                                case "AcDbLine":
                                                    Teigha.DatabaseServices.Line line = (Teigha.DatabaseServices.Line)entity;
                                                    Autodesk.Revit.DB.Line revitLine = Autodesk.Revit.DB.Line.CreateBound(ConverCADPointToRevitPoint(line.StartPoint), ConverCADPointToRevitPoint(line.EndPoint));
                                                    listCADModels.Add(new CADGeometryModel() {CadCurve=revitLine as Autodesk.Revit.DB.Curve ,LayerName=line.Layer});
                                                    break;
                                                case "AcDbArc":
                                                    Teigha.DatabaseServices.Arc arc = (Teigha.DatabaseServices.Arc)entity;
                                                    double enda, stara;
                                                    if (arc.StartAngle> arc.EndAngle)
                                                    {
                                                        enda = arc.StartAngle;
                                                        stara = arc.EndAngle;
                                                    }
                                                    else
                                                    {
                                                        enda = arc.EndAngle;
                                                        stara = arc.StartAngle;
                                                    }
                                                    Autodesk.Revit.DB.Arc revitArc = Autodesk.Revit.DB.Arc.Create(Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(new XYZ( arc.Normal.X, arc.Normal.Y, arc.Normal.Z),
                                                        ConverCADPointToRevitPoint(arc.Center)), MillimetersToUnits(arc.Radius), stara, enda);
                                                    listCADModels.Add(new CADGeometryModel() { CadCurve = revitArc as Autodesk.Revit.DB.Curve, LayerName = arc.Layer });
                                                    break;
                                                default:
                                                    break;
                                            }
                                        }
                                    }
                                }
 
                            }
                        }
                    }
                }
            }
            return listCADModels;
        }
 
        /// 
        /// 毫米转化成英寸
        /// 
        /// 
        /// 
        private double MillimetersToUnits(double value)
        {
            return UnitUtils.ConvertToInternalUnits(value, DisplayUnitType.DUT_MILLIMETERS);
        }
 
        /// 
        /// 将CAD里的点转化为Revit里的点
        /// 
        /// 
        /// 
        private XYZ ConverCADPointToRevitPoint(Point3d point)
        {
            return new XYZ(MillimetersToUnits(point.X), MillimetersToUnits(point.Y), MillimetersToUnits(point.Z));
        }
    }
public class CADTextModel
    {
        public XYZ Location { get; set; }
        public string Text { get; set; }
        public double Angle { get; set; }
        public string Layer { get; set; }
        public CADTextModel()
        {
            Location = null;
            Text = "";
            Angle = 0;
            Layer = "";
        }       
    }
    public class CADGeometryModel
    {
        public Autodesk.Revit.DB.PolyLine revitPolyLine { get; set; }
        public Teigha.DatabaseServices.Polyline cadPolyLine { get; set; }
        public string LayerName { get; set; }
        public Autodesk.Revit.DB.Curve revitCurve { get; set; }
        public Teigha.DatabaseServices.Curve cadCurve { get; set; }

    }

}


原因分析:

        经过分析我发现,原因在于:在CAD中多段线是由三种类型组成的,即Polyline,Polyline2d,Polyline3d。而上文的代码只能提取Polyline。


解决方案:

        我们在识别到Polyline2d,Polyline3d时,可以通过polyline.ConvertFrom(entity,transferId)的方法将Polyline2d,Polyline3d转化为Polyline以后,再做处理。详细代码如下:

 

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Teigha.DatabaseServices;
using Teigha.Geometry;
using Teigha.Runtime;

namespace FamilyManagerUI.Function
{
    class ReadCADUtils
    {
        static string dll = @"E:\CSharp\BigProject\dll\TD_Mgd.dll";//手动指定引用dll路径
        Assembly a = Assembly.UnsafeLoadFrom(dll);
        /// 
        /// 取得链接cad的路径
        /// 
        /// 
        /// 
        /// 
        public string GetCADPath(ElementId cadLinkTypeID, Document revitDoc)
        {
            CADLinkType cadLinkType = revitDoc.GetElement(cadLinkTypeID) as CADLinkType;
            return ModelPathUtils.ConvertModelPathToUserVisiblePath(cadLinkType.GetExternalFileReference().GetAbsolutePath());
        }

        /// 
        /// 取得CAD的文字信息
        /// 
        /// 
        /// 
        public List GetCADTextInfo(string dwgFile)
        {
            List listCADModels = new List();
            using (var service = new Services())
            {
                using (var database = new Database(false, true))
                {
                    try
                    {
                        database.ReadDwgFile(dwgFile, FileShare.Read, true, "");
                        using (var trans = database.TransactionManager.StartTransaction())
                        {
                            using (BlockTable table = (BlockTable)database.BlockTableId.GetObject(OpenMode.ForRead))
                            {
                                using (SymbolTableEnumerator enumerator = table.GetEnumerator())
                                {
                                    StringBuilder sb = new StringBuilder();
                                    while (enumerator.MoveNext())
                                    {
                                        using (BlockTableRecord record = (BlockTableRecord)enumerator.Current.GetObject(OpenMode.ForRead))
                                        {

                                            foreach (ObjectId id in record)
                                            {
                                                Entity entity = (Entity)id.GetObject(OpenMode.ForRead, false, false);
                                                CADTextModel model = new CADTextModel();
                                                switch (entity.GetRXClass().Name)
                                                {
                                                    case "AcDbText":
                                                        Teigha.DatabaseServices.DBText text = (Teigha.DatabaseServices.DBText)entity;
                                                        model.Location = ConverCADPointToRevitPoint(text.Position);
                                                        model.Text = text.TextString;
                                                        model.Angle = text.Rotation;
                                                        model.Layer = text.Layer;
                                                        listCADModels.Add(model);
                                                        break;
                                                    case "AcDbMText":
                                                        Teigha.DatabaseServices.MText mText = (Teigha.DatabaseServices.MText)entity;
                                                        model.Location = ConverCADPointToRevitPoint(mText.Location);
                                                        model.Text = mText.Text;
                                                        model.Angle = mText.Rotation;
                                                        model.Layer = mText.Layer;
                                                        listCADModels.Add(model);
                                                        break;
                                                }
                                            }
                                        }
                                    }

                                }
                            }
                        }

                    }
                    catch (System.Exception)
                    {

                        throw;
                    }

                }
            }
            return listCADModels;
        }

        /// 
        /// 取得cad的图层名称
        /// 
        /// 
        /// 
        public IList GetLayerName(string dwgFile)
        {
            IList cadLayerNames = new List();
            using (new Services())
            {
                using (Database database = new Database(false, false))
                {
                    database.ReadDwgFile(dwgFile, FileShare.Read, true, "");
                    using (var trans = database.TransactionManager.StartTransaction())
                    {
                        using (LayerTable lt = (LayerTable)trans.GetObject(database.LayerTableId, OpenMode.ForRead))
                        {
                            foreach (ObjectId id in lt)
                            {
                                LayerTableRecord ltr = (LayerTableRecord)trans.GetObject(id, OpenMode.ForRead);
                                cadLayerNames.Add(ltr.Name);
                            }
                        }
                        trans.Commit();
                    }
                }
            }
            return cadLayerNames;
        }

        /// 
        /// 取得CAD里的线,包括直线、多段线、圆曲线
        /// 
        /// 
        /// 
        public List GetCADCurves(string dwgFile, Autodesk.Revit.ApplicationServices.Application application)
        {
            List listCADModels = new List();
            using (new Services())
            {
                using (Database database = new Database(false, false))
                {
                    database.ReadDwgFile(dwgFile, FileShare.Read, true, "");

                    using (var trans = database.TransactionManager.StartTransaction())
                    {
                        using (BlockTable table = (BlockTable)database.BlockTableId.GetObject(OpenMode.ForRead))
                        {
                            using (SymbolTableEnumerator enumerator = table.GetEnumerator())
                            {
                                StringBuilder sb = new StringBuilder();
                                while (enumerator.MoveNext())
                                {
                                    using (BlockTableRecord record = (BlockTableRecord)enumerator.Current.GetObject(OpenMode.ForRead))
                                    {

                                        foreach (ObjectId id in record)
                                        {
                                            // Entity entity = (Entity)id.GetObject(OpenMode.ForRead, false, false); // CSDN上用的entity
                                            DBObject obj= trans.GetObject(id, OpenMode.ForWrite); // G站上的大佬用的DBObject
                                            CADGeometryModel geoModel = new CADGeometryModel(); 
                                            switch (obj.GetType().Name)
                                            {
                                                case "DBPoint":
                                                    DBPoint dbpoint = (DBPoint)obj;

                                                    break;
                                                case "Line":
                                                    Teigha.DatabaseServices.Line line = (Teigha.DatabaseServices.Line)obj;
                                                    //if (line.Layer != layerName) break;
                                                    if (ConverCADPointToRevitPoint(line.StartPoint).DistanceTo(ConverCADPointToRevitPoint(line.EndPoint)) <= application.ShortCurveTolerance) break;
                                                    Autodesk.Revit.DB.Line revitLine = Autodesk.Revit.DB.Line.CreateBound(ConverCADPointToRevitPoint(line.StartPoint), ConverCADPointToRevitPoint(line.EndPoint));
                                                    listCADModels.Add(new CADGeometryModel() { revitCurve = revitLine as Autodesk.Revit.DB.Curve, LayerName = line.Layer, cadCurve = line });

                                                    break;
                                                case "Ellipse":
                                                    Teigha.DatabaseServices.Ellipse ellipse = (Teigha.DatabaseServices.Ellipse)obj;
                                                    //if (ellipse.Layer != layerName) break;
                                                    break;
                                                case "Arc":
                                                    Teigha.DatabaseServices.Arc arc = (Teigha.DatabaseServices.Arc)obj;
                                                    double enda, stara;
                                                    if (arc.StartAngle > arc.EndAngle)
                                                    {
                                                        enda = arc.StartAngle;
                                                        stara = arc.EndAngle;
                                                    }
                                                    else
                                                    {
                                                        enda = arc.EndAngle;
                                                        stara = arc.StartAngle;
                                                    }
                                                    Autodesk.Revit.DB.Arc revitArc = Autodesk.Revit.DB.Arc.Create(Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(new XYZ(arc.Normal.X, arc.Normal.Y, arc.Normal.Z),
                                                        ConverCADPointToRevitPoint(arc.Center)), MillimetersToUnits(arc.Radius), stara, enda);
                                                    listCADModels.Add(new CADGeometryModel() { revitCurve = revitArc as Autodesk.Revit.DB.Curve, LayerName = arc.Layer, cadCurve = arc });

                                                    //if (arc.Layer != layerName) break;
                                                    break;
                                                case "Circle":
                                                    Circle circle = (Circle)obj;


                                                    //if (circle.Layer != layerName) break;
                                                    break;
                                                case "Polyline":
                                                    Teigha.DatabaseServices.Polyline pl = (Teigha.DatabaseServices.Polyline)obj;
                                                    
                                                    IList listPoints = new List();
                                                    for (int i = 0; i < pl.NumberOfVertices; i++)
                                                    {
                                                        listPoints.Add(new XYZ(MillimetersToUnits(pl.GetPoint2dAt(i).X), MillimetersToUnits(pl.GetPoint2dAt(i).Y), 0));
                                                    }
                                                    PolyLine polyLine = PolyLine.Create(listPoints);
                                                    listCADModels.Add(new CADGeometryModel() { revitPolyLine = polyLine, LayerName = pl.Layer, cadPolyLine = pl });

                                                    //if (polyline.Layer != layerName) break;
                                                    break;
                                                case "Polyline2d":
                                                    Teigha.DatabaseServices.Polyline2d pl2d = (Teigha.DatabaseServices.Polyline2d)obj;
                                                    Teigha.DatabaseServices.Polyline pl2 = new Teigha.DatabaseServices.Polyline();
                                                    pl2.ConvertFrom(pl2d, false);
                                                    IList listPoints2 = new List();
                                                    for (int i = 0; i < pl2.NumberOfVertices; i++)
                                                    {
                                                        listPoints2.Add(new XYZ(MillimetersToUnits(pl2.GetPoint2dAt(i).X), MillimetersToUnits(pl2.GetPoint2dAt(i).Y), 0));
                                                    }
                                                    PolyLine polyLine2 = PolyLine.Create(listPoints2);
                                                    
                                                    listCADModels.Add(new CADGeometryModel() { revitPolyLine = polyLine2, LayerName = pl2.Layer, cadPolyLine = pl2 });

                                                    //if (polyline.Layer != layerName) break;
                                                    break;

                                                case "DBText":
                                                    DBText dBText = (DBText)obj;
                                                    //if (dBText.Layer != layerName) break;
                                                    break;
                                                case "Region":
                                                    Region region = (Region)obj;
                                                    //if (region.Layer != layerName) break;
                                                    break;
                                                default:
                                                    break;
                                            }
                                        }
                                    }
                                }

                            }
                        }
                    }
                }
            }
            return listCADModels;
        }

        /// 
        /// 毫米转化成英寸
        /// 
        /// 
        /// 
        private double MillimetersToUnits(double value)
        {
            return UnitUtils.ConvertToInternalUnits(value, DisplayUnitType.DUT_MILLIMETERS);
        }

        /// 
        /// 将CAD里的点转化为Revit里的点
        /// 
        /// 
        /// 
        private XYZ ConverCADPointToRevitPoint(Point3d point)
        {
            return new XYZ(MillimetersToUnits(point.X), MillimetersToUnits(point.Y), MillimetersToUnits(point.Z));
        }

    }
    public class CADGeometryModel
    {
        public Autodesk.Revit.DB.PolyLine revitPolyLine { get; set; }
        public Teigha.DatabaseServices.Polyline cadPolyLine { get; set; }
        public string LayerName { get; set; }
        public Autodesk.Revit.DB.Curve revitCurve { get; set; }
        public Teigha.DatabaseServices.Curve cadCurve { get; set; }

    }
    public class CADTextModel
    {
        public XYZ Location { get; set; }
        public string Text { get; set; }
        public double Angle { get; set; }
        public string Layer { get; set; }
        public CADTextModel()
        {
            Location = null;
            Text = "";
            Angle = 0;
            Layer = "";
        }
    }


}

你可能感兴趣的:(Revit,二次开发,Revit,Cad,c#,visual,studio,算法,sql,javascript)