[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class cmdFloorOpening : IExternalCommand
{
public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elements)
{
UIDocument uiDoc = cmdData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
Selection sel = uiDoc.Selection;
Autodesk.Revit.Creation.Application aCreate = cmdData.Application.Application.Create;
Transaction ts = new Transaction(doc, " www ");
ts.Start();
// 楼板
Reference refFloor = sel.PickObject(ObjectType.Element, " floor ");
Floor floor = doc.GetElement(refFloor) as Floor;
Face face = FindFloorFace(floor);
CurveArray curves = aCreate.NewCurveArray();
// 风管
Reference refDuct = sel.PickObject(ObjectType.Element, " duct ");
Duct duct = doc.GetElement(refDuct) as Duct;
Curve curve = FindDuctCurve(duct);
// 求交点
XYZ xyz = FindFaceCurve(face, curve);
/* 开矩形洞 */
XYZ xyz1 = xyz + new XYZ( 1, 1, 0) * 200 / 304.8;
XYZ xyz2 = xyz + new XYZ( 1, - 1, 0) * 200 / 304.8;
XYZ xyz3 = xyz + new XYZ(- 1, - 1, 0) * 200 / 304.8;
XYZ xyz4 = xyz + new XYZ(- 1, 1, 0) * 200 / 304.8;
Curve c1 = aCreate.NewLine(xyz1, xyz2, true);
Curve c2 = aCreate.NewLine(xyz2, xyz3, true);
Curve c3 = aCreate.NewLine(xyz3, xyz4, true);
Curve c4 = aCreate.NewLine(xyz4, xyz1, true);
curves.Append(c1);
curves.Append(c2);
curves.Append(c3);
curves.Append(c4);
/* 开圆形洞
double startAngle = 0;
double midAngle = Math.PI;
double endAngle = 2 * Math.PI;
XYZ xAxis = XYZ.BasisX;
XYZ yAxis = XYZ.BasisY;
double radius = 180 / 304.8;
Arc arc1 = aCreate.NewArc(xyz, radius, startAngle, midAngle, xAxis, yAxis);
Arc arc2 = aCreate.NewArc(xyz, radius, midAngle, endAngle, xAxis, yAxis);
curves.Append(arc1);
curves.Append(arc2); */
doc.Create.NewOpening(floor, curves, true);
ts.Commit();
return Result.Succeeded;
}
// 求线和面的交点
public 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;
}
// 找到风管对应的曲线
public 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;
curve.MakeUnbound();
return curve;
}
// 找到楼板的面
public Face FindFloorFace(Floor floor)
{
Face normalFace = null;
//
Options opt = new Options();
opt.ComputeReferences = true;
opt.DetailLevel = Autodesk.Revit.DB.DetailLevels.Medium;
//
GeometryElement e = floor.get_Geometry(opt);
/* 下版改进
IEnumerator<GeometryObject> enm = e.GetEnumerator();
while (enm.MoveNext())
{
Solid solid = enm.Current as Solid;
} */
foreach (GeometryObject obj in e.Objects) // 待改2013
{
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( new XYZ( 0, 0, - 1)) < 0.01) // 数值在0到PI之间
{
normalFace = face;
}
}
}
}
}
return normalFace;
}
}
[Regeneration(RegenerationOption.Manual)]
public class cmdFloorOpening : IExternalCommand
{
public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elements)
{
UIDocument uiDoc = cmdData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
Selection sel = uiDoc.Selection;
Autodesk.Revit.Creation.Application aCreate = cmdData.Application.Application.Create;
Transaction ts = new Transaction(doc, " www ");
ts.Start();
// 楼板
Reference refFloor = sel.PickObject(ObjectType.Element, " floor ");
Floor floor = doc.GetElement(refFloor) as Floor;
Face face = FindFloorFace(floor);
CurveArray curves = aCreate.NewCurveArray();
// 风管
Reference refDuct = sel.PickObject(ObjectType.Element, " duct ");
Duct duct = doc.GetElement(refDuct) as Duct;
Curve curve = FindDuctCurve(duct);
// 求交点
XYZ xyz = FindFaceCurve(face, curve);
/* 开矩形洞 */
XYZ xyz1 = xyz + new XYZ( 1, 1, 0) * 200 / 304.8;
XYZ xyz2 = xyz + new XYZ( 1, - 1, 0) * 200 / 304.8;
XYZ xyz3 = xyz + new XYZ(- 1, - 1, 0) * 200 / 304.8;
XYZ xyz4 = xyz + new XYZ(- 1, 1, 0) * 200 / 304.8;
Curve c1 = aCreate.NewLine(xyz1, xyz2, true);
Curve c2 = aCreate.NewLine(xyz2, xyz3, true);
Curve c3 = aCreate.NewLine(xyz3, xyz4, true);
Curve c4 = aCreate.NewLine(xyz4, xyz1, true);
curves.Append(c1);
curves.Append(c2);
curves.Append(c3);
curves.Append(c4);
/* 开圆形洞
double startAngle = 0;
double midAngle = Math.PI;
double endAngle = 2 * Math.PI;
XYZ xAxis = XYZ.BasisX;
XYZ yAxis = XYZ.BasisY;
double radius = 180 / 304.8;
Arc arc1 = aCreate.NewArc(xyz, radius, startAngle, midAngle, xAxis, yAxis);
Arc arc2 = aCreate.NewArc(xyz, radius, midAngle, endAngle, xAxis, yAxis);
curves.Append(arc1);
curves.Append(arc2); */
doc.Create.NewOpening(floor, curves, true);
ts.Commit();
return Result.Succeeded;
}
// 求线和面的交点
public 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;
}
// 找到风管对应的曲线
public 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;
curve.MakeUnbound();
return curve;
}
// 找到楼板的面
public Face FindFloorFace(Floor floor)
{
Face normalFace = null;
//
Options opt = new Options();
opt.ComputeReferences = true;
opt.DetailLevel = Autodesk.Revit.DB.DetailLevels.Medium;
//
GeometryElement e = floor.get_Geometry(opt);
/* 下版改进
IEnumerator<GeometryObject> enm = e.GetEnumerator();
while (enm.MoveNext())
{
Solid solid = enm.Current as Solid;
} */
foreach (GeometryObject obj in e.Objects) // 待改2013
{
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( new XYZ( 0, 0, - 1)) < 0.01) // 数值在0到PI之间
{
normalFace = face;
}
}
}
}
}
return normalFace;
}
}
url: http://greatverve.cnblogs.com/p/revit-api-FloorOpening.html