Revit API在风管与墙相交处开洞

几何元素练习Solid,Edge,Face,
GeometryObject 
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 System.Xml;

namespace RevitCodes
{
    [TransactionAttribute(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    
public class cmdOpening : IExternalCommand
    {
        
public Result Execute(ExternalCommandData commandData, ref string messages, ElementSet elements)
        {
            UIApplication uiApp 
= commandData.Application;
            Document doc 
= uiApp.ActiveUIDocument.Document;
            Selection sel 
= uiApp.ActiveUIDocument.Selection;

            Transaction ts 
= new Transaction(doc, "http://revit.5d6d.com");
            ts.Start();
            
//
            Face face = null;
            
//选择一面墙
            Reference ref1 = uiApp.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "选择一面墙");
            Element elem1 
= doc.GetElement(ref1);
            Wall wall 
= elem1 as Wall;
            
//选择一个风管
            Reference ref2 = uiApp.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "选择一个风管");
            Element elem2 
= doc.GetElement(ref2);
            Duct duct 
= elem2 as 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;

            Options opt 
= new Options();
            opt.ComputeReferences 
= true;
            opt.DetailLevel 
= Autodesk.Revit.DB.DetailLevels.Medium;
            
//取得风管边线
            GeometryElement eDuct = duct.get_Geometry(opt);
            
int i = 0;
            Curve curveOne 
= null;
            Curve curveTwo 
= null;
            
foreach (GeometryObject obj in eDuct.Objects)
            {
                Solid solid 
= obj as Solid;
                
foreach (Edge edge in solid.Edges)
                {
                    Curve curveEdge 
= edge.AsCurve();
                    Curve curveDuct 
= curve;
                    XYZ xyz1 
= GetVector(curveEdge);
                    XYZ xyz2 
= GetVector(curveDuct);
                    
if (IsParallel(xyz1, xyz2))//与风管curve平行
                    {
                        
if (i == 0)//求对角线
                            curveOne = curveEdge;
                        
if (i == 2)
                            curveTwo 
= curveEdge;
                        i 
+= 1;
                    }
                }
            }
            
//取得墙曲线
            GeometryElement e = wall.get_Geometry(opt);
            
foreach (GeometryObject obj in e.Objects)
            {
                Solid solid 
= obj as Solid;
                
if (solid != null && solid.Faces.Size > 0)
                {
                    face 
= FindBigFace(solid);//面积最大的面作为墙的主面吧。
                }
            }

            
//求交点1
            IntersectionResultArray intersectionR = new IntersectionResultArray();//交点集合
            SetComparisonResult comparisonR;//Comparison比较
            comparisonR = face.Intersect(curveOne, out intersectionR);
            XYZ intersectionResult 
= null;//交点坐标
            if (SetComparisonResult.Disjoint != comparisonR)//Disjoint不交
            {
                
if (!intersectionR.IsEmpty)
                {
                    intersectionResult 
= intersectionR.get_Item(0).XYZPoint;
                }
            }
            
//求交点2
            IntersectionResultArray intersectionR1 = new IntersectionResultArray();//交点集合
            SetComparisonResult comparisonR1;//Comparison比较
            comparisonR1 = face.Intersect(curveTwo, out intersectionR1);
            XYZ intersectionResult1 
= null;//交点坐标
            if (SetComparisonResult.Disjoint != comparisonR1)//Disjoint不交
            {
                
if (!intersectionR1.IsEmpty)
                {
                    intersectionResult1 
= intersectionR1.get_Item(0).XYZPoint;
                }
            }
            doc.Create.NewOpening(wall, intersectionResult, intersectionResult1);

            ts.Commit();

            
return Result.Succeeded;
        }

        
//判断向量是否平行
        public bool IsParallel(XYZ firstVec, XYZ secondVec)
        {
            
return (IsSameDirection(firstVec, secondVec) || IsOppositeDirection(firstVec, secondVec));
        }

        
//求曲线向量
        public XYZ GetVector(Line line) { return line.get_EndPoint(1- line.get_EndPoint(0); }
        
public XYZ GetVector(Curve line) { return line.get_EndPoint(1- line.get_EndPoint(0); }

        
/// <summary>
        
/// 判断两向量是否同向
        
/// </summary>
        
/// <param name="firstVec"></param>
        
/// <param name="secondVec"></param>
        
/// <returns></returns>
        public bool IsSameDirection(XYZ firstVec, XYZ secondVec)
        {
            XYZ first 
= firstVec.Normalize();
            XYZ second 
= secondVec.Normalize();

            
double dot = first.DotProduct(second);
            
return (IsEqual(dot, 1));
        }

        
const double precision = 0.00001;    // 精度

        
/// <summary>
        
/// 判断两double数值是否相等
        
/// </summary>
        
/// <param name="d1"></param>
        
/// <param name="d2"></param>
        
/// <returns></returns>
        public static bool IsEqual(double d1, double d2)
        {
            
double diff = Math.Abs(d1 - d2);
            
return diff < precision;
        }

        
/// <summary>
        
/// 判断两向量是否反向
        
/// </summary>
        
/// <param name="firstVec"></param>
        
/// <param name="secondVec"></param>
        
/// <returns></returns>
        public static bool IsOppositeDirection(XYZ firstVec, XYZ secondVec)
        {
            XYZ first 
= firstVec.Normalize();
            XYZ second 
= secondVec.Normalize();

            
double dot = first.DotProduct(second);
            
return (IsEqual(dot, -1));
        }
        
//求交点
        void FindInterFace(Solid solid, Curve curve)
        {
            
foreach (Face face in solid.Faces)
            {
                
//求交点
                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;
                    }
                }
                
if (intersectionResult != null)
                {
                    TaskDialog.Show(
"inter", intersectionResult.X + "," + intersectionResult.Y + "," + intersectionResult.Z);
                }
            }
        }
        
//找到面积最大的面
        Face FindBigFace(Solid solid)
        {
            
double maxArea = 0;
            Face maxFace 
= null;
            
foreach (Face face in solid.Faces)
            {
                
if (face.Area > maxArea)
                {
                    maxArea 
= face.Area;
                    maxFace 
= face;
                }
            }
            
return maxFace;
        }
        
//找到墙的下底面
        Face FindBottomFace(Solid solid)
        {
            PlanarFace pf 
= null;
            
foreach (Face face in solid.Faces)
            {
                pf 
= face as PlanarFace;
                
if (null != pf)
                {
                    
if (Math.Abs(pf.Normal.X) < 0.01 && Math.Abs(pf.Normal.Y) < 0.01 && pf.Normal.Z < 0)
                    {
                        TaskDialog.Show(
"Wall Bottom Face""Area is " + pf.Area.ToString() + "; Origin = (" + pf.Origin.X.ToString() + "  " + pf.Origin.Y.ToString() + "  " + pf.Origin.Z.ToString() + ")");

                        
break;
                    }
                }
            }
            
return pf;
        }
    }

}
from:http://revit.5d6d.com/thread-1296-1-1.html
posted @ 2011-10-24 09:05  大气象  阅读(2166)  评论(0编辑  收藏  举报
http://www.tianqiweiqi.com