Revit API遍历全部风管,找到与风管相关的墙开洞

涉及向量计算,求相交等相关技术。
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;

namespace  RevitCodes
{
    
// 找洞口
    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    
public   class  cmdWallOpening : IExternalCommand
    {
        
public  Result Execute(ExternalCommandData cmdData,  ref   string  messages, ElementSet elements)
        {
            UIApplication uiApp 
=  cmdData.Application;
            Document doc 
=  uiApp.ActiveUIDocument.Document;
            Selection sel 
=  uiApp.ActiveUIDocument.Selection;

            Transaction ts 
=   new  Transaction(doc,  " revit.5d6d.com " );
            ts.Start();
            
/*
            //选择一面墙
            WallSelectionFilter fWall = new WallSelectionFilter();
            Reference ref1 = uiApp.ActiveUIDocument.Selection.PickObject(ObjectType.Element, fWall, "选择一面墙:");
            Element elem1 = doc.GetElement(ref1);
            Wall wall = elem1 as Wall;
            //选择一个风管
            DuctSelectionFilter fDuct = new DuctSelectionFilter();
            Reference ref2 = uiApp.ActiveUIDocument.Selection.PickObject(ObjectType.Element, fDuct, "选择一个风管:");
            Element elem2 = doc.GetElement(ref2);
            Duct duct = elem2 as Duct;
             
*/  
            
// 开同心洞
            
// CenterOpen(doc, wall, duct, 640, 640);
            List < Duct >  listDuct  =  FindAllDuct(doc);
            
foreach  (Duct duct  in  listDuct)
            {
                List
< Wall >  listWall  =  FindDuctWall(doc, duct);
                
foreach  (Wall wall  in  listWall)
                {
                    CenterOpen(doc, wall, duct, 
640 640 );
                }
            }

            ts.Commit();

            
return  Result.Succeeded;
        }
        
// 找到所有风管
        List < Duct >  FindAllDuct(Document doc)
        {
            List
< Duct >  listDuct  =   new  List < Duct > ();
            FilteredElementCollector collector 
=   new  FilteredElementCollector(doc);
            collector.OfClass(
typeof (Duct)).OfCategory(BuiltInCategory.OST_DuctCurves);

            
foreach  (Element el  in  collector)
            {
                Duct duct 
=  el  as  Duct;
                
if  (duct  !=   null )
                    listDuct.Add(duct);
            }
            
return  listDuct;
        }
        
// 找到与风管相交的墙
        List < Wall >  FindDuctWall(Document doc, Duct duct)
        {
            List
< Wall >  listWall  =   new  List < Wall > ();
            
// 找到outLine
            BoundingBoxXYZ bb  =  duct.get_BoundingBox(doc.ActiveView);
            Outline outline 
=   new  Outline(bb.Min, bb.Max);
            
//
            FilteredElementCollector collector  =   new  FilteredElementCollector(doc);
            BoundingBoxIntersectsFilter invertFilter 
=   new  BoundingBoxIntersectsFilter(outline,  false );
            IList
< Element >  noIntersectWalls  =  collector.OfClass( typeof (Wall)).WherePasses(invertFilter).ToElements();
            
foreach  (Element el  in  noIntersectWalls)
            {
                Wall wall 
=  el  as  Wall;
                
if  (wall  !=   null )
                    listWall.Add(wall);
            }
            
return  listWall;
        }
        
// 开同心洞
        Result CenterOpen(Document doc, Wall wall, Duct duct,  double  dWidth,  double  dHeigh)
        {
            SubTransaction subTs 
=   new  SubTransaction(doc);
            subTs.Start();
            
try
            {
                
// 求面和线的交点
                Face face  =  FindWallFace(wall);
                Curve curve 
=  FindDuctCurve(duct);
                XYZ xyz 
=  FindFaceCurve(face, curve);
                
// 墙线的向量
                XYZ wallVector  =  FindWallVector(wall);
                
// 交点向上向墙线正方向移动160(风管宽高320)
                XYZ pt1  =  xyz  +   new  XYZ( 0 0 1 *  dHeigh  /   2   /   304.8 ;
                pt1 
=  pt1  +  wallVector.Normalize()  *  dWidth  /   2   /   304.8 ;
                
// 交点向下向墙线反方向移动160(风管宽高320)
                XYZ pt2  =  xyz  +   new  XYZ( 0 0 - 1 *  dHeigh  /   2   /   304.8 ;
                pt2 
=  pt2  -  wallVector.Normalize()  *  dWidth  /   2   /   304.8 ;
                
// 开洞
                doc.Create.NewOpening(wall, pt1, pt2);

                subTs.Commit();
                
return  Result.Succeeded;
            }
            
catch
            {
                subTs.RollBack();
                
return  Result.Failed;
            }
        }
        
// 找到墙线的向量
        XYZ FindWallVector(Wall wall)
        {
            LocationCurve lCurve 
=  wall.Location  as  LocationCurve;
            XYZ xyz 
=  lCurve.Curve.get_EndPoint( 1 -  lCurve.Curve.get_EndPoint( 0 );
            
return  xyz;
        }
        
// 求线和面的交点
        XYZ FindFaceCurve(Face face, Curve curve)
        {
            
// 求交点
            IntersectionResultArray intersectionR  =   new  IntersectionResultArray(); // 交点集合
            SetComparisonResult comparisonR; // Comparison比较
            comparisonR  =  face.Intersect(curve,  out  intersectionR);
            XYZ intersectionResult 
=   null ; // 交点坐标
             if  (SetComparisonResult.Disjoint  !=  comparisonR) // Disjoint不交
            {
                
if  ( ! intersectionR.IsEmpty)
                {
                    intersectionResult 
=  intersectionR.get_Item( 0 ).XYZPoint;
                }
            }
            
return  intersectionResult;
        }
        
// 找到风管对应的曲线
        Curve FindDuctCurve(Duct duct)
        {
            
// 得到风管曲线
            IList < XYZ >  list  =   new  List < XYZ > ();
            ConnectorSetIterator csi 
=  duct.ConnectorManager.Connectors.ForwardIterator();
            
while  (csi.MoveNext())
            {
                Connector conn 
=  csi.Current  as  Connector;
                list.Add(conn.Origin);
            }
            Curve curve 
=  Line.get_Bound(list.ElementAt( 0 ), list.ElementAt( 1 ))  as  Curve;
            
return  curve;
        }
        
// 找到墙的正面
        Face FindWallFace(Wall wall)
        {
            Face normalFace 
=   null ;
            
//
            Options opt  =   new  Options();
            opt.ComputeReferences 
=   true ;
            opt.DetailLevel 
=  Autodesk.Revit.DB.DetailLevels.Medium;
            
//
            GeometryElement e  =  wall.get_Geometry(opt);
            
foreach  (GeometryObject obj  in  e.Objects)
            {
                Solid solid 
=  obj  as  Solid;
                
if  (solid  !=   null   &&  solid.Faces.Size  >   0 )
                {
                    
foreach  (Face face  in  solid.Faces)
                    {
                        PlanarFace pf 
=  face  as  PlanarFace;
                        
if  (pf  !=   null )
                        {
                            
if  (pf.Normal.AngleTo(wall.Orientation)  <   0.01 ) // 数值在0到PI之间
                            {
                                normalFace 
=  face;
                            }
                        }
                    }
                }
            }
            
return  normalFace;
        }
    }
    
// 墙的过滤条件
     class  WallSelectionFilter : ISelectionFilter
    {
        
public   bool  AllowElement(Element e)
        {
            
return  e  is  Wall;
        }

        
public   bool  AllowReference(Reference r, XYZ p)
        {
            
return   true ;
        }
    }
    
// 风管的过滤条件
     class  DuctSelectionFilter : ISelectionFilter
    {
        
public   bool  AllowElement(Element e)
        {
            
return  e  is  Duct;
        }

        
public   bool  AllowReference(Reference r, XYZ p)
        {
            
return   true ;
        }
    }
}
url: http://greatverve.cnblogs.com/p/api-duct-wall-opening.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值