Revit API在风管与墙相交处开洞
几何元素练习Solid,Edge,Face,GeometryObject
from:http://revit.5d6d.com/thread-1296-1-1.html
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;
}
}
}
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;
}
}
}
我这个博客废弃不用了,今天想寻找外链的时候,突然想到这个博客权重很高。
有需要免费外链的,留言即可,我准备把这个博客变成免费的友情链接站点。