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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值