在一个项目中,我需要将墙的原始几何图形导出到 IFC 文件。所谓原始几何就是墙体的几何形状,没有被墙上的门窗切割,没有与屋顶、地板、梁、柱等连接。我想要的原始几何通常应该是一个像盒子一样的形状.
不幸的是,没有直接的 Revit API 可以为我提供墙的原始几何图形。element.get_Geometry 方法返回由门、窗和连接的地板、屋顶等切割的最终几何图形。
获得墙的原始几何图形的一种可能方法是我自己根据墙的参数重建几何图形,但我懒惰的方法是让 Revit 完成这项工作。我的方法有以下五个步骤:
步骤 1:启动 Revit 事务。
第 2 步:在调用 element.get_Geometry 之前,从 Revit 文档中临时删除墙中承载的门窗,以及与墙相连的屋顶和地板。
第 3 步:调用 document.Regenerate 方法来更新文档中的元素。当然,墙的几何形状也应该更新。
第 4 步:调用 element.get_Geometry 以获取我想要的原始几何图形。
第 5 步:回滚事务以使 Revit 文档保持不变。
问题出现在第 2 步。即使我删除了门窗,返回的几何图形中仍然存在开口。
我的问题是,如何删除与墙相关的所有元素?
我的 Revit 版本是 2013。我使用的 .rvt 文件是 Revit 附带的 rac_basic_sample_project.rvt。我要导出的墙是 id 为 117698 或 117654 的墙。
我的项目基于 Revit IFC 导出器源代码。
以下是我用来获取原始几何图形的代码段:
private GeometryElement GetOriginalWallGeometry2(Element element)
{
Document doc = element.Document;
GeometryElement geomElem = null;
//Step 1
using (Transaction t = new Transaction(doc))
{
//Step 2:
//delete wall joins
Autodesk.Revit.DB.Wall wall = element as Autodesk.Revit.DB.Wall;
//assert element is a wall
//the joined floors or roofs can be deleted as expected.
if (null != wall)
{
while (Autodesk.Revit.DB.WallUtils.IsWallJoinAllowedAtEnd(wall, 0))
{
Autodesk.Revit.DB.WallUtils.DisallowWallJoinAtEnd(wall, 0);
}
while (Autodesk.Revit.DB.WallUtils.IsWallJoinAllowedAtEnd(wall, 1))
{
Autodesk.Revit.DB.WallUtils.DisallowWallJoinAtEnd(wall, 1);
}
}
//The following code of deleting doors doesn't work as expected.
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> elementsList = collector.OfCategory(BuiltInCategory.OST_Doors).ToElements(); //here should be OST_Doors or others?
foreach (Element elem in elementsList)
{
try
{
doc.Delete(elem);
}
catch (System.Exception ex)
{
}
}
}
//The following code of deleting windows doesn't work as expected.
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> elementsList = collector.OfCategory(BuiltInCategory.OST_Windows).ToElements();//here should be OST_Windows or others?
foreach (Element elem in elementsList)
{
try
{
doc.Delete(elem);
}
catch (System.Exception ex)
{
}
}
}
//The following code also doesn't work as expected.
Autodesk.Revit.DB.HostObject hostObj = element as Autodesk.Revit.DB.HostObject;
if (hostObj != null)
{
IList<ElementId> idlist = hostObj.FindInserts(true, true, true, true);
foreach (ElementId id in idlist)
{
try
{
doc.Delete(id);
}
catch (System.Exception ex)
{
}
}
}
//Floors can be deteled as expected.
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> linkList = collector.OfCategory(BuiltInCategory.OST_Floors).ToElements();
foreach (Element elelink in linkList)
{
try
{
doc.Delete(elelink);
}
catch (System.Exception ex)
{
}
}
}
//Roofs can be deteled as expected.
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> linkList = collector.OfCategory(BuiltInCategory.OST_Roofs).ToElements();
foreach (Element elelink in linkList)
{
try
{
doc.Delete(elelink);
}
catch (System.Exception ex)
{
}
}
}
//Step 3
doc.Regenerate();
//Step 4
Options options;
View ownerView = element.Document.GetElement(element.OwnerViewId) as View;
if (ownerView == null)
{
options = GeometryUtil.GetIFCExportGeometryOptions();
}
else
{
options = new Options();
options.View = ownerView;
}
geomElem = element.get_Geometry(options);
//Step 5
FailureHandlingOptions failureOptions = t.GetFailureHandlingOptions();
failureOptions.SetClearAfterRollback(true);
failureOptions.SetDelayedMiniWarnings(true);
t.SetFailureHandlingOptions(failureOptions);
try
{
t.RollBack();
}
catch (System.Exception ex)
{
}
}
return geomElem;
}