• Revit API改变风管及管件尺寸


    start
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using WinForm = System.Windows.Forms;

    using Autodesk.Revit.UI;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.Attributes;

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

    using Autodesk.Revit.DB.Structure;
    using Autodesk.Revit.DB.ExtensibleStorage;
    using Autodesk.Revit.DB.Plumbing;
    using Autodesk.Revit.DB.Architecture;

    using System.Xml;
    using SelSet = HongYe.Revit.Public.SelectSet;
    using Autodesk.Revit.DB.Electrical;
    using System.Diagnostics;
    using System.Security.Cryptography;
    using System.IO;

    namespace RevitCodes
    {
        /// <summary>
        
    /// 工具类
        
    /// </summary>
        public class RevitTool
        {
            /// <summary>
            
    /// 管件是否连接风管,如果什么也没连接也返回true
            
    /// </summary>
            
    /// <returns></returns>
            public static bool IsConnectToDuct(FamilyInstance fi)
            {
                bool bResult = true;
                ConnectorSetIterator csi = fi.MEPModel.ConnectorManager.Connectors.ForwardIterator();
                while (csi.MoveNext())
                {
                    Connector conn = csi.Current as Connector;
                    if (conn.IsConnected == true)//是否有连接
                    {
                        ConnectorSet connectorSet = conn.AllRefs;//找到所有连接器连接的连接器
                        ConnectorSetIterator csiChild = connectorSet.ForwardIterator();
                        while (csiChild.MoveNext())
                        {
                            Connector connected = csiChild.Current as Connector;
                            if (null != connected && connected.Owner.UniqueId != conn.Owner.UniqueId)
                            {
                                //TaskDialog.Show("conn", conn.Width + "|" + connected.Width + ",");
                                
    // look for physical connections 
                                if (connected.ConnectorType == ConnectorType.End ||
                                    connected.ConnectorType == ConnectorType.Curve ||
                                    connected.ConnectorType == ConnectorType.Physical)
                                {
                                    //判断是不是管件,只要有一头连接的不是风管就返回false
                                    if (connected.Owner is Duct)
                                    {
                                        Duct duct = connected.Owner as Duct;
                                        Parameter pWidth = duct.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
                                        Parameter pHeight = duct.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
                                        //TaskDialog.Show("width", pWidth.AsValueString());
                                    }
                                    else
                                    {
                                        bResult = false;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                return bResult;
            }
            /// <summary>
            
    /// 改变风管尺寸
            
    /// </summary>
            
    /// <param name="duct"></param>
            
    /// <param name="sWidth"></param>
            
    /// <param name="sHeight"></param>
            public static void ChangeDuctSize(Duct duct, string sWidth, string sHeight)
            {
                Parameter pWidth = duct.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
                Parameter pHeight = duct.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
                pWidth.SetValueString(sWidth);
                pHeight.SetValueString(sHeight);
            }
            /// <summary>
            
    /// 改变管件尺寸
            
    /// </summary>
            
    /// <param name="fi"></param>
            
    /// <param name="dWidth"></param>
            
    /// <param name="dHeight"></param>
            public static void ChangeFittingSize(FamilyInstance fi, double dWidth, double dHeight)
            {
                ConnectorSetIterator csi = fi.MEPModel.ConnectorManager.Connectors.ForwardIterator();
                while (csi.MoveNext())
                {
                    Connector conn = csi.Current as Connector;
                    conn.Width = dWidth / 304.8;
                    conn.Height = dHeight / 304.8;
                }
            }

            /// <summary>
            
    /// 是否需要变换
            
    /// </summary>
            
    /// <param name="fi"></param>
            
    /// <returns></returns>
            public static bool isChange(FamilyInstance fi)
            {
                bool bChange = true;//是否需要变换宽高
                XYZ xyzFace = GetFittingSolid(fi).Normal;
                //正面朝上或者朝下,不需要变换
                if (xyzFace.AngleTo(new XYZ(001)) < 0.001 || xyzFace.AngleTo(new XYZ(00, -1)) < 0.001)
                {
                    bChange = false;
                }
                return bChange;
            }
            /// <summary>
            
    /// 取得管件的几何体的方向面,管件族的几何体,有三个。
            
    /// </summary>
            
    /// <param name="fi"></param>
            
    /// <returns></returns>
            public static PlanarFace GetFittingSolid(FamilyInstance fi)
            {
                //得到管件尺寸
                double dWidth = 0, dHeight = 0;
                ConnectorSetIterator csi = fi.MEPModel.ConnectorManager.Connectors.ForwardIterator();
                while (csi.MoveNext())
                {
                    Connector conn = csi.Current as Connector;
                    dWidth = conn.Width;
                    dHeight = conn.Height;
                }
                //
                PlanarFace resultFace = null;
                Solid resultSolid = null;
                //
                Options opt = new Options();
                opt.ComputeReferences = true;
                opt.DetailLevel = Autodesk.Revit.DB.DetailLevels.Medium;
                //
                GeometryElement e = fi.get_Geometry(opt);
                foreach (GeometryObject obj in e.Objects)
                {
                    GeometryInstance gi = obj as GeometryInstance;
                    if (gi != null)
                    {
                        GeometryElement ge = gi.GetInstanceGeometry();
                        foreach (GeometryObject go in ge.Objects)
                        {
                            Solid solid = go as Solid;
                            if (solid != null && solid.Faces.Size > 0)
                            {
                                bool isSolid = true;
                                foreach (Face face in solid.Faces)
                                {
                                    PlanarFace pf = face as PlanarFace;
                                    if (pf != null)
                                    {
                                        if (pf.Area < 0.02)//如果有一个面积特别小,这个截面体。角度为1度也大于0.02
                                        {
                                            isSolid = false;
                                        }
                                    }
                                }
                                if (isSolid)
                                {
                                    resultSolid = solid;
                                }
                            }
                        }
                    }
                }
                //找到截面
                double dArea = dWidth * dHeight;
                PlanarFace sectionFace = null;
                foreach (Face face in resultSolid.Faces)
                {
                    if (Math.Abs(face.Area - dArea) < 0.001)//面积近似
                    {
                        sectionFace = face as PlanarFace;
                        break;
                    }
                }
                //找到与截面垂直的管件正面
                foreach (Face face in resultSolid.Faces)
                {
                    PlanarFace pFace = face as PlanarFace;
                    if (pFace != null)
                    {
                        //面积相同的排除
                        if (Math.Abs(face.Area - dArea) < 0.001)//面积近似
                        {
                            continue;
                        }
                        else
                        {
                            double dAngle = pFace.Normal.AngleTo(sectionFace.Normal);
                            if (Math.Abs(dAngle - Math.PI / 2) < 0.001)//与截面垂直的面
                            {
                                resultFace = pFace;
                            }
                        }
                    }
                }
                //
                return resultFace;
            }

            /// <summary>
            
    /// 从框选元素中过滤出风管
            
    /// </summary>
            
    /// <param name="listElement"></param>
            
    /// <returns></returns>
            public static List<Duct> GetDuctsFromElements(IList<Element> listElement)
            {
                List<Duct> listDuct = new List<Duct>();
                foreach (Element el in listElement)
                {
                    if (el is Duct)
                    {
                        Duct duct = el as Duct;
                        listDuct.Add(duct);
                    }
                }
                return listDuct;
            }
            /// <summary>
            
    /// 从框选元素中过滤出管件
            
    /// </summary>
            
    /// <param name="listElement"></param>
            
    /// <returns></returns>
            public static List<FamilyInstance> GetFittingsFromElements(IList<Element> listElement)
            {
                List<FamilyInstance> listFitting = new List<FamilyInstance>();
                foreach (Element el in listElement)
                {
                    if (el is FamilyInstance)
                    {
                        FamilyInstance fi = el as FamilyInstance;
                        listFitting.Add(fi);
                    }
                }
                return listFitting;
            }
        }
        //改变尺寸方法一
        [TransactionAttribute(Autodesk.Revit.Attributes.TransactionMode.Manual)]
        public class cmdChangeSize1 : IExternalCommand
        {
            public Result Execute(ExternalCommandData commandData, ref string messages, ElementSet elements)
            {
                UIApplication app = commandData.Application;
                Document doc = app.ActiveUIDocument.Document;
                Selection sel = app.ActiveUIDocument.Selection;

                Transaction ts = new Transaction(doc, "hongye");
                //
                double dWidth = 800;
                double dHeight = 400;
                IList<Element> listElement = sel.PickElementsByRectangle("框选一个弯头及相连的两根风管");
                List<Duct> listDuct = RevitTool.GetDuctsFromElements(listElement);
                List<FamilyInstance> listFi = RevitTool.GetFittingsFromElements(listElement);
                //第一步,改变管件尺寸,改变后,肯定会增加变径。
                ts.Start();
                foreach (FamilyInstance fi in listFi)
                {
                    RevitTool.ChangeFittingSize(fi, dWidth, dHeight);
                }
                ts.Commit();
                //第二步,改变风管尺寸,如果不需要变换,变径会自动消失。
                ts.Start();
                foreach (Duct duct in listDuct)
                {
                    RevitTool.ChangeDuctSize(duct, dWidth.ToString(), dHeight.ToString());
                }
                ts.Commit();
                //第三步,判断风管与管件之间是否仍然存在变径,如果存在则宽度互换,再次改变风管尺寸。
                ts.Start();
                foreach (FamilyInstance fi in listFi)
                {
                    if (!RevitTool.IsConnectToDuct(fi))//如果连接的是变径
                    {
                        foreach (Duct duct in listDuct)
                        {
                            RevitTool.ChangeDuctSize(duct, dHeight.ToString(), dWidth.ToString());
                        }
                    }
                }
                ts.Commit();
                //////pf.Normal.AngleTo

                return Result.Succeeded;
            }
        }

        //改变尺寸方法二
        [TransactionAttribute(Autodesk.Revit.Attributes.TransactionMode.Manual)]
        public class cmdChangeSize2 : IExternalCommand
        {
            public Result Execute(ExternalCommandData commandData, ref string messages, ElementSet elements)
            {
                UIApplication app = commandData.Application;
                Document doc = app.ActiveUIDocument.Document;
                Selection sel = app.ActiveUIDocument.Selection;

                Transaction ts = new Transaction(doc, "hongye");
                ts.Start();
                //
                double dWidth = 800;
                double dHeight = 400;
                IList<Element> listElement = sel.PickElementsByRectangle("框选一个弯头及相连的两根风管");
                List<Duct> listDuct = RevitTool.GetDuctsFromElements(listElement);
                List<FamilyInstance> listFi = RevitTool.GetFittingsFromElements(listElement);
                //
                foreach (FamilyInstance fi in listFi)
                {
                    RevitTool.ChangeFittingSize(fi, dWidth, dHeight);
                    if (RevitTool.isChange(fi))
                    {
                        foreach (Duct duct in listDuct)
                        {
                            RevitTool.ChangeDuctSize(duct, dHeight.ToString(), dWidth.ToString());
                        }
                    }
                    else
                    {
                        foreach (Duct duct in listDuct)
                        {
                            RevitTool.ChangeDuctSize(duct, dWidth.ToString(), dHeight.ToString());
                        }
                    }
                }
                ts.Commit();

                return Result.Succeeded;
            }

        }
    }
    url:http://greatverve.cnblogs.com/p/duct-fitting-change-size.html
  • 相关阅读:
    Snmpwalk
    本地使用PostMan测试接口没有问题,但是线上直接进不了接口
    redis使用注意事项
    线程笔记
    springboot笔记
    springboot中多个地址指向同一个方法
    开发过程中遇到的注解
    使用maven时用到的一些问题
    遇到线程安全问题的案例
    mongodb
  • 原文地址:https://www.cnblogs.com/greatverve/p/duct-fitting-change-size.html
Copyright © 2020-2023  润新知