revit 2020 二次开发——在楼板上挖圆形洞(Create circle openning in floor)
程序员文章站
2022-07-12 14:57:36
...
一、思路
1)先创建圆形楼板(source floor),获取楼板的轮廓,根据轮廓在目标楼板上开洞。
2)删掉圆形楼板。
注意:创建目标楼板 和 在目标楼板上开圆形洞,尽量不要在一个事务中
二、图示
三、代码
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
try {
UIDocument uiDoc = commandData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
Selection sel = uiDoc.Selection;
Autodesk.Revit.Creation.Application acreation = commandData.Application.Application.Create;
Autodesk.Revit.Creation.Document dcreation = doc.Create;
double l = 5;
double w = 10;
double x0 = 0;
double y0 = 0;
double z0 = 1;
XYZ p_s0 = new XYZ(x0, y0, z0);
XYZ p_s1 = new XYZ(x0, y0 + w, z0);
XYZ p_s2 = new XYZ(x0 + l, y0 + w, z0);
XYZ p_s3 = new XYZ(x0 + l, y0, z0);
Line l_s0 = Line.CreateBound(p_s0, p_s1);
Line l_s1 = Line.CreateBound(p_s1, p_s2);
Line l_s2 = Line.CreateBound(p_s2, p_s3);
Line l_s3 = Line.CreateBound(p_s3, p_s0);
CurveArray fProfile = new CurveArray();
fProfile.Append(l_s0);
fProfile.Append(l_s1);
fProfile.Append(l_s2);
fProfile.Append(l_s3);
//1)创建目标楼板
Floor targetfloor = CreateTargetFloor(doc, fProfile);
Transaction ts = new Transaction(doc, "createopenning");
ts.Start();
//2)创建圆形楼板
XYZ center = new XYZ(2.5, 5, z0);
Floor ciclefloor = CreateCircleFloor(doc, z0, center);
//3)获取圆形楼板轮廓,并开洞
CreateOpening(doc, ciclefloor, targetfloor);
ts.Commit();
return Result.Succeeded;
} catch (Exception ex) {
var r = 0;
return Result.Succeeded;
}
}
private Floor CreateTargetFloor(Document doc, CurveArray fProfile)
{
Transaction ts = new Transaction(doc, "createfloor");
ts.Start();
var floor = doc.Create.NewFloor(fProfile, true);
ts.Commit();
return floor;
}
private Floor CreateCircleFloor(Document doc,double z,XYZ center)
{
double radius = 2;
Arc arc1 = Arc.Create(Plane.CreateByNormalAndOrigin(new XYZ(0, 0, 1), new XYZ(0, 0, 0)), radius, 0, Math.PI);
Arc arc2 = Arc.Create(Plane.CreateByNormalAndOrigin(new XYZ(0, 0, 1), new XYZ(0, 0, 0)), radius, Math.PI, Math.PI * 2);
CurveArray profile = new CurveArray();
profile.Append(arc1);
profile.Append(arc2);
var floor = doc.Create.NewFloor(profile, false);
//创建的圆弧位于原点,需要移动到开洞中心
ElementTransformUtils.MoveElement(doc, floor.Id, center);
return floor;
}
private void CreateOpening(Document doc, Floor sourceFloor, Floor destFloor)
{
var floorGeometryElement = sourceFloor.get_Geometry(new Options());
foreach (var geometryObject in floorGeometryElement) {
var floorSolid = geometryObject as Solid;
if (floorSolid == null)
continue;
var topFace = GetTopFace(floorSolid);
if (topFace == null)
throw new NotSupportedException(
"Floor does not have top face");
if (topFace.EdgeLoops.IsEmpty)
throw new NotSupportedException(
"Floor top face does not have edges");
//圆形楼板的外轮廓
EdgeArray ea = topFace.EdgeLoops.get_Item(0);
CurveArray openingCurveArray = new CurveArray();
foreach (Edge edge in ea) {
var edgeCurve = edge.AsCurve();
openingCurveArray.Append(edgeCurve);
}
var opening = sourceFloor.Document.Create.NewOpening(destFloor, openingCurveArray, true);
destFloor.Document.Delete(sourceFloor.Id);
}
}
const double _eps = 1.0e-9;
private static PlanarFace GetTopFace(Solid solid)
{
PlanarFace topFace = null;
FaceArray faces = solid.Faces;
foreach (Face f in faces) {
PlanarFace pf = f as PlanarFace;
if (null != pf && (Math.Abs(pf.FaceNormal.X - 0) < _eps && Math.Abs(pf.FaceNormal.Y - 0) < _eps)) {
if ((null == topFace)|| (topFace.Origin.Z < pf.Origin.Z)) {
topFace = pf;
}
}
}
return topFace;
}
四、参考文献
上一篇: 基于Spring AOP的用户日志实现
下一篇: Week2 实验