[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