Revit二次开发之CAD线的翻模--梁的翻模

最近开始翻模旅程,根据跟群友讨论和网上的搜寻。初步方法为先拾取CAD梁的线段,根据线段所在图层,取得所有梁的最长的那2段线。这样情况下,一条梁仅有2段相等的且平行的直线(不在是一个矩形),具体如图1-1所示!。

                                                             图 1- 1  测试模型中对于梁的整图

这里要感谢一下CSDN niuge8905版主 https://blog.csdn.net/niuge8905/article/details/77160646  和 JohnnyWu0918 https://me.csdn.net/mye918 从他们的文章中找到了读取CAD线段的一些方法。

接下来上代码。

 

using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Structure;

 

[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    class ReadCadCommand : IExternalCommand
    {
        Application app;
        Document doc;
        UIDocument uidoc;
        /// <summary>
        /// 正常梁宽度
        /// </summary>
       const double NormBeamWidth = 1000;//1000mm


        /// <summary>
        /// 所有正常梁宽度集合
        /// </summary>
        List<double> WidthList = new List<double>();

        

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            uidoc = commandData.Application.ActiveUIDocument;
            app = commandData.Application.Application;
            doc = uidoc.Document;


            Reference r;
            try
            {
                 r = uidoc.Selection.PickObject(ObjectType.PointOnElement,“选择梁的一边”);//选择一个元素
            }
            catch(Exception ex)
            {
                message = "您取消了本次操作!";
                return Result.Failed;
            }
            
            //Reference r = uidoc.Selection.PickObject(ObjectType.PointOnElement);//选择一个元素
            string ss = r.ConvertToStableRepresentation(doc);

            Element elem = doc.GetElement(r);
            GeometryElement geoElem = elem.get_Geometry(new Options());
            GeometryObject geoObj = elem.GetGeometryObjectFromReference(r);


            //获取选中的cad图层
            Category targetCategory = null;
            ElementId graphicsStyleId = null;


            if (geoObj.GraphicsStyleId != ElementId.InvalidElementId)
            {
                graphicsStyleId = geoObj.GraphicsStyleId;
                GraphicsStyle gs = doc.GetElement(geoObj.GraphicsStyleId) as GraphicsStyle;
                if (gs != null)
                {
                    targetCategory = gs.GraphicsStyleCategory;
                    var name = gs.GraphicsStyleCategory.Name;
                }
            }
            //隐藏选中的cad图层
            Transaction trans = new Transaction(doc, "隐藏图层");
            trans.Start();
            if (targetCategory != null)
                doc.ActiveView.SetCategoryHidden(targetCategory.Id, false);


            trans.Commit();

            if (geoElem == null || graphicsStyleId == null)
            {
                message = "几何元素或ID不存在!";
                return Result.Failed;
            }
            
            List<CADModel> curveArray_List = getCurveArray( doc,geoElem,graphicsStyleId);
            List<CADModel> curveArray_List_copy = new List<CADModel>();//复制得到的模型
            foreach (var OrginCADModle in curveArray_List)
            {
                curveArray_List_copy.Add(OrginCADModle);
            }


            //取得的模型的线的总数量
            int LineNumber = curveArray_List.Count();

           
          

            //存放不匹配的梁的相关线
            List<CADModel> NotMatchCadModel = new List<CADModel>();
            //存放模型数组的数组
            List<List<CADModel>> CADModelList_List = new List<List<CADModel>>();
            //int i = 0;

            //筛选模型
            while (curveArray_List.Count() > 0)
            {      

               //存放距离
                List<double> distanceList = new List<double>();
                //存放对应距离的CADModel
                List<CADModel> cADModel_B_List = new List<CADModel>();

                var CadModel_A = curveArray_List[0];
                curveArray_List.Remove(CadModel_A);//去除取出的梁的二段线段之一

                if (curveArray_List.Count() >= 1)
                {
                    foreach (var CadModel_B in curveArray_List)
                    {
                        //梁的2个段线非同一长度最大误差为50mm,方向为绝对值(然而sin120°=sin60°)
                        if ((float)Math.Abs(CadModel_A.rotation) == (float)Math.Abs(CadModel_B.rotation) && Math.Abs(CadModel_A.length - CadModel_B.length)<0.164)
                        {
                            double distance = CadModel_A.location.DistanceTo(CadModel_B.location);
                            distanceList.Add(distance);
                            cADModel_B_List.Add(CadModel_B);
                        }
                    }


                    if (distanceList.Count() != 0 && cADModel_B_List.Count != 0)
                    {
                        double distanceTwoLine = distanceList.Min();
                        //筛选不正常的宽度,如发现不正常,将CadModel_B继续放入数组
                        if (distanceTwoLine * 304.8 < NormBeamWidth && distanceTwoLine>0)
                        {
                            //TaskDialog.Show("1", (distanceTwoLine * 304.8).ToString());

                            var CadModel_shortDistance = cADModel_B_List[distanceList.IndexOf(distanceTwoLine)];
                            curveArray_List.Remove(CadModel_shortDistance);
                            //1对梁的模型装入数组
                            List<CADModel> cADModels = new List<CADModel>();
                            cADModels.Add(CadModel_A);
                            cADModels.Add(CadModel_shortDistance);
                            CADModelList_List.Add(cADModels);
                            //TaskDialog.Show("1", CadModel_A.location.ToString() + "\n" + CadModel_shortDistance.location.ToString());

                        }
                    }
                    else
                    {
                        NotMatchCadModel.Add(CadModel_A);
                    }
                   
                }          
                else
                {
                    NotMatchCadModel.Add(CadModel_A);
                }
                
            }

            TaskDialog.Show("1","未匹配的线有:"+ NotMatchCadModel.Count().ToString()+" 条!\n"+"匹配上的有:"+ CADModelList_List.Count().ToString()+" 对!\n"+"丢失:"+ (LineNumber- NotMatchCadModel.Count()- CADModelList_List.Count()*2).ToString()+" 条!\n");
            //梁类别
            FamilySymbol BeamTypeName = doc.GetElement(new ElementId(342873)) as FamilySymbol;
            //默认标高2
            Level level = LevelFilter(doc);
            int tranNumber = 0;//用于改变事务的ID
            //生成梁
            foreach (var cadModelList in CADModelList_List)
            {
                    CADModel cADModel_A = cadModelList[0];
                    CADModel cADModel_B = cadModelList[1];

                    //TaskDialog.Show("1", cADModel_A.location.ToString() + "\n" + cADModel_B.location.ToString());

                    var cADModel_A_StratPoint = cADModel_A.curveArray.get_Item(0).GetEndPoint(0);
                    var cADModel_A_EndPoint = cADModel_A.curveArray.get_Item(0).GetEndPoint(1);
                    var cADModel_B_StratPoint = cADModel_B.curveArray.get_Item(0).GetEndPoint(0);
                    var cADModel_B_EndPoint = cADModel_B.curveArray.get_Item(0).GetEndPoint(1);

                XYZ ChangeXYZ = new XYZ();
                
                var LineLength = (GetMiddlePoint(cADModel_A_StratPoint, cADModel_B_StratPoint)).DistanceTo(GetMiddlePoint(cADModel_A_EndPoint, cADModel_B_EndPoint));
                if (LineLength <0.00328)//梁的2段线起点非同一端。2段线非同一长度,又非同一端的,中间点的误差选择为1mm
                {
                    ChangeXYZ = cADModel_B_StratPoint;
                    cADModel_B_StratPoint = cADModel_B_EndPoint;
                    cADModel_B_EndPoint = ChangeXYZ;
                }
                Curve curve = Line.CreateBound((GetMiddlePoint(cADModel_A_StratPoint, cADModel_B_StratPoint)), GetMiddlePoint(cADModel_A_EndPoint, cADModel_B_EndPoint));

                    double distance = cADModel_A.location.DistanceTo(cADModel_B.location);
                    
                    distance = Math.Round(distance * 304.8, 1);//作为梁_b的参数
                     WidthList.Add(distance);//梁宽度集合

                string beamName = "ZBIM矩形梁 " + (float)(distance) + "*" + (float)(600) + "mm";//类型名 宽度*高度
                    if (!familSymbol_exists(beamName, "ZBIM - 矩形梁", doc))
                    {
                        MakeBeamType(beamName, "ZBIM - 矩形梁");
                        EditBeamType(beamName, (float)(distance), (float)(600));
                    }

                //用于数据显示和选择,已注释
                #region
                //List<string> columnTypes = new List<string>();
                //columnTypes = getBeamTypes(doc);
                //bool repeat = false;
                //foreach (string context in columnTypes)
                //{
                //    if (context == beamName)
                //    {
                //        repeat = true;
                //        break;
                //    }
                //}
                //if (!repeat)
                //{
                //    columnTypes.Add(beamName);
                //}
                #endregion

                using (Transaction transaction = new Transaction(doc))
                {
                    transaction.Start("Beadm Strart Bulid" + tranNumber.ToString());
                    FilteredElementCollector collector = new FilteredElementCollector(doc);
                    collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralFraming);


                    foreach (FamilySymbol beamType in collector)
                    {
                        if (beamType.Name == beamName)
                        {
                            if (!beamType.IsActive)
                            {
                                beamType.Activate();
                            }
                            FamilyInstance beamInstance = doc.Create.NewFamilyInstance(curve, beamType, level, StructuralType.Beam);
                            var Elevation = beamInstance.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM);

                            break;
                        }
                    }

 

                    transaction.Commit();
                }
 

            }


            

            //取得未匹配的和丢失的CADModel
            foreach (var cadModelList in CADModelList_List)
            {
                CADModel cADModel_A = cadModelList[0];
                CADModel cADModel_B = cadModelList[1];
                curveArray_List_copy.Remove(cADModel_A);
                curveArray_List_copy.Remove(cADModel_B);
            }
            //一个方向的梁
            List<CADModel> UpBeamCAdModel = new List<CADModel>();
            //一个方向的梁
            List<CADModel> CrossBeamCAdModel = new List<CADModel>();

            //最大梁宽度
            double MaxBeamWidth;
            if (WidthList.Count() == 0)
            {
                MaxBeamWidth = 1000;//1000mm
            }
            else
            {
                MaxBeamWidth = WidthList.Max();
            }
            //判断是否位空
            if (curveArray_List_copy.Count() > 1)
            {
                var OrginRotation = Math.Abs(curveArray_List_copy[0].rotation);
                //分流,横在一起,竖在一起
                foreach (var cadModle in curveArray_List_copy)
                {
                    if (Math.Abs(cadModle.rotation) == OrginRotation)
                    {
                        CrossBeamCAdModel.Add(cadModle);
                    }
                    else
                    {
                        UpBeamCAdModel.Add(cadModle);
                    }
                }

  • 17
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值