REVIT API 按边过滤元素
REVIT API Filtering Elements by Edges
我必须从文档中的每个边缘检索端点,但由于必须遍历每个元素,检索边缘的过程花费了太多时间。
我目前的做法是
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.WherePasses(new LogicalOrFilter((new ElementIsElementTypeFilter(false)), new ElementIsElementTypeFilter(true)));
List<object> coordinatelist = new List<object>();
for (int i = collector.ToElements().Count - 1; i > 0; i--)
{
Element element = collector.ToElements()[i];
GeometryElement geo = element.get_Geometry(new Options());
if (geo != null)
{
for(int j = geo.Count()-1;j>=0;j--){
Solid geosolid = geo.ElementAt(j) as Solid;
if(geosolid != null)
{
for(int k = geosolid.Edges.Size - 1; k >= 0; k--)
{
Edge edge = geosolid.Edges.get_Item(k);
Curve edgecurve = edge.AsCurve();
FillDictionary(edgecurve, element);
}
}
else continue;
}
}
else continue;
}
我无法按边过滤,因为边不是元素的子元素而是几何对象的子元素
如何在不遍历每个元素的情况下获得边缘,或者如何加快该过程?
您可以从迭代中消除很多元素。
为什么要迭代满足 ElementIsElementTypeFilter( true )
的元素?
项目中不存在;它们只是模板、类型、符号。只有实例存在于项目模型 space.
此外,您在循环中的每次迭代中调用 ToElements
。这是每次都创建一个包含所有元素的新集合。那是对时间和 space.
的巨大浪费
根本不需要调用ToElements
!查看 FindElement
and Collector Optimisation.
的讨论
您可能还可以消除许多其他元素。例如,您感兴趣的元素几乎肯定会有一个有效的类别。
The Building Coder explored several different approaches to Retrieve Model Elements or Visible 3D Elements.
如果需要,您可以将 non-void 实体的检查和实体的提取添加到 LINQ 子句中,以使您的代码更短且更易读;但是,这可能不会对性能产生太大影响。
是这样的吗?
void RetrieveEdges(
Document doc,
Dictionary<Curve, ElementId> curves )
{
FilteredElementCollector collector
= new FilteredElementCollector( doc )
.WhereElementIsNotElementType()
.WhereElementIsViewIndependent();
Options opt = new Options();
foreach( Element el in collector )
{
if( null != el.Category )
{
GeometryElement geo = el.get_Geometry( opt );
if( geo != null )
{
foreach( GeometryObject obj in geo )
{
Solid sol = obj as Solid;
if( null!= sol )
{
foreach( Edge edge in sol.Edges )
{
Curve edgecurve = edge.AsCurve();
curves.Add( edgecurve, el.Id );
}
}
}
}
}
}
}
如果您确实需要所有几何元素,避免逐个检查它们的一种方法是实现 custom exporter。这将为您提供零麻烦的 3D 视图中所有可见元素的所有几何形状。如果您只需要墙壁,请设置一个合适的 3D 视图,只显示那些墙壁。
我必须从文档中的每个边缘检索端点,但由于必须遍历每个元素,检索边缘的过程花费了太多时间。 我目前的做法是
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.WherePasses(new LogicalOrFilter((new ElementIsElementTypeFilter(false)), new ElementIsElementTypeFilter(true)));
List<object> coordinatelist = new List<object>();
for (int i = collector.ToElements().Count - 1; i > 0; i--)
{
Element element = collector.ToElements()[i];
GeometryElement geo = element.get_Geometry(new Options());
if (geo != null)
{
for(int j = geo.Count()-1;j>=0;j--){
Solid geosolid = geo.ElementAt(j) as Solid;
if(geosolid != null)
{
for(int k = geosolid.Edges.Size - 1; k >= 0; k--)
{
Edge edge = geosolid.Edges.get_Item(k);
Curve edgecurve = edge.AsCurve();
FillDictionary(edgecurve, element);
}
}
else continue;
}
}
else continue;
}
我无法按边过滤,因为边不是元素的子元素而是几何对象的子元素
如何在不遍历每个元素的情况下获得边缘,或者如何加快该过程?
您可以从迭代中消除很多元素。
为什么要迭代满足 ElementIsElementTypeFilter( true )
的元素?
项目中不存在;它们只是模板、类型、符号。只有实例存在于项目模型 space.
此外,您在循环中的每次迭代中调用 ToElements
。这是每次都创建一个包含所有元素的新集合。那是对时间和 space.
根本不需要调用ToElements
!查看 FindElement
and Collector Optimisation.
您可能还可以消除许多其他元素。例如,您感兴趣的元素几乎肯定会有一个有效的类别。
The Building Coder explored several different approaches to Retrieve Model Elements or Visible 3D Elements.
如果需要,您可以将 non-void 实体的检查和实体的提取添加到 LINQ 子句中,以使您的代码更短且更易读;但是,这可能不会对性能产生太大影响。
是这样的吗?
void RetrieveEdges(
Document doc,
Dictionary<Curve, ElementId> curves )
{
FilteredElementCollector collector
= new FilteredElementCollector( doc )
.WhereElementIsNotElementType()
.WhereElementIsViewIndependent();
Options opt = new Options();
foreach( Element el in collector )
{
if( null != el.Category )
{
GeometryElement geo = el.get_Geometry( opt );
if( geo != null )
{
foreach( GeometryObject obj in geo )
{
Solid sol = obj as Solid;
if( null!= sol )
{
foreach( Edge edge in sol.Edges )
{
Curve edgecurve = edge.AsCurve();
curves.Add( edgecurve, el.Id );
}
}
}
}
}
}
}
如果您确实需要所有几何元素,避免逐个检查它们的一种方法是实现 custom exporter。这将为您提供零麻烦的 3D 视图中所有可见元素的所有几何形状。如果您只需要墙壁,请设置一个合适的 3D 视图,只显示那些墙壁。