涉及向量计算,求相交等相关技术。

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, , );
                }
            }             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(, , ) * dHeigh /  / 304.8;
                pt1 = pt1 + wallVector.Normalize() * dWidth /  / 304.8;
                //交点向下向墙线反方向移动160(风管宽高320)
                XYZ pt2 = xyz + new XYZ(, , -) * dHeigh /  / 304.8;
                pt2 = pt2 - wallVector.Normalize() * dWidth /  / 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() - lCurve.Curve.get_EndPoint();
            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().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(), list.ElementAt()) 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 > )
                {
                    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

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

  1. Revit API通过相交过滤器找到与风管相交的对象。

    相交过滤器的应用,比几何相交法简便.Excluding剔除 //找到与风管相交的对象,通过相交过滤器. [TransactionAttribute(Autodesk.Revit.Attributes. ...

  2. Revit API判断直线相交关系移动风管

    start )             );         )) )) );         XYZ xyz12 = lCurve1.Curve.get_EndPoint();         XY ...

  3. Revit API遍历系统族布置喷头

    系统族可以通过内参遍历,遍历出来是个FamilySymbol喷头属于系统族,但不能通过NewDuct();类似这样的方法布置.必须使用 NewFamilyInstance() );           ...

  4. Revit API找到风管穿过的墙(当前文档和链接文档)

    start [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class c ...

  5. Revit API画垂直于风管的风管

    start /// <summary> /// 选择风管与风管外一点,画与风管垂直的风管. /// </summary> [Transaction(TransactionMod ...

  6. 【Revit API】梁构件支座检查算法

    一.前言         应该是第二次写关于Revit API的博文了.虽然在BIM企业中工作,从事桌面BIM软件开发,但是我是不怎么喜欢写Revit API相关的代码.平时更多的是在写界面展示,架构 ...

  7. Revit API 判断一个构件在某个视图中的可见性

    查看 Revit API.发现有Element::IsHidden这个方法.通过UI创建一个element,注意要使得这个element在某些视图可见,但是在另一些视图不可见.运行下面的方法,你会发现 ...

  8. Revit API 操作共享参数和项目参数

    1.获取共享参数 private string GetSharInfo(Autodesk.Revit.ApplicationServices.Application revitApp) { Strin ...

  9. revit API 生成墙图元

    由于Revit的版本问题,在网上找的生成墙图元的代码,在我机器上的Revit 2016中编译不能通过,通过多次调试,终于找到在revit 2016中使用API生成墙图元的代码,现在贴出来. 下面的代码 ...

随机推荐

  1. 【SVN】SVN的trunk、branches、tag的使用以及分支的概念

    SVN命令参考:   https://www.cnblogs.com/wlsxmhz/p/5775393.html svn的存储结构一般建议在根目录下建立trunk.branches.tags这三个文 ...

  2. CEO、COO、CFO、CTO、CXO

    CEO:Chief Executive Officer 首席执行官——类似总经理.总裁,是企业的法人代表 COO:Chief Operating Officer 首席营运官——类似常务总经理 CFO: ...

  3. ioctl函数详细说明(网络)

    ioctl 函数 本函数影响由fd 参数引用的一个打开的文件. #include<unistd.h> int ioctl( int fd, int request, .../* void ...

  4. Memcached实战之复制----基于repcached的主从【转】

    由于 Memcached 自己没有防止单点的措施,因为为了保障 Memcached 服务的高可用,我们需要借助外部的工具来实现高可用的功能.本文引入 Repcached 这个工具,通过使用该工具我们可 ...

  5. 【LOJ】#2496. 「AHOI / HNOI2018」毒瘤

    题面 还有这么诚实的出题人! 我们最多影响20个点,然后把这20个点的虚树建出来,并且枚举每个点的选举状态,如果一个点选或不选可以通过改\(dp[u][0] = 0\)或\(dp[u][1] = 0\ ...

  6. linux设置最大打开文件数

    一.查看当前用户对进程打开文件最大数的限制 $ ulimit -a | grep open 二.系统对进程打开文件最大数是如何限制的 先来看man的一段解析: /proc/sys/fs/file-ma ...

  7. 最受欢迎编程语言又是谁?C语言居首,大数据赢了

    C语言占据榜首,但大数据类是最大赢家. IEEE Spectrum的第三次“最受欢迎编程语言”交互式排行榜新鲜出炉.因为不可能顾及到每一个程序员的想法,Spectrum使用多样化.可交互的的指标权重来 ...

  8. canvas入门级小游戏《开关灯》思路讲解

    游戏很简单,10行10列布局,每行每列各10盏灯,游戏初始化时随机点亮其中一些灯,点击某盏灯,其上下左右的灯及本身状态反转,如果点击前是灭着的,点击后即点亮,将所有灯全部点亮才算过关.游戏试玩: 下面 ...

  9. CSS3实现原腾讯视频透明边框,多重边框等(关于边框那些不为人知的事情)

    1.hsla或rgba实现半透明边框. rgba在rgb的基础上增加了透明通道,就不详细说了,下面重点说下hsla: 说明: HSLA(H,S,L,A) 取值: H:Hue(色调).0(或360)表示 ...

  10. 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem J. Joke 水题

    Problem J. Joke 题目连接: http://codeforces.com/gym/100714 Description The problem is to cut the largest ...