zoukankan      html  css  js  c++  java
  • 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, 
    640640);
                    }
                }

                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(001* dHeigh / 2 / 304.8;
                    pt1 
    = pt1 + wallVector.Normalize() * dWidth / 2 / 304.8;
                    
    //交点向下向墙线反方向移动160(风管宽高320)
                    XYZ pt2 = xyz + new XYZ(00-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
  • 相关阅读:
    Android清单文件详解(四) ---- backupAgent的用法
    Android清单文件详解(一) ---- 一切从<manifest>开始
    Android OpenGL ES(九)----构建几何物体
    Android OpenGL ES(八)----纹理编程框架
    Android OpenGL ES(七)----理解纹理与纹理过滤
    Android OpenGL ES(六)----进入三维在代码中创建投影矩阵和旋转矩阵
    Android OpenGL ES(五)----进入三维正交投影和透视投影推导
    Android OpenGL ES(四)----调整屏幕的宽高比
    获取验证码按钮点击后,一分钟内不可继续点击
    选择本地图片后,上传前显示在界面上,实现实时预览
  • 原文地址:https://www.cnblogs.com/greatverve/p/api-duct-wall-opening.html
Copyright © 2011-2022 走看看