我必须从doc中的每个边缘检索端点,但是由于必须遍历每个元素,检索边缘的过程花费了太多时间。 我目前的做法是
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;
}
我无法按边缘过滤,因为Edge不是Element的子项而是GeometryObject的子项
如何在不迭代每个元素的情况下获得边缘,或者如何加快过程?
答案 0 :(得分:1)
您可以从迭代中消除很多元素。
为什么要迭代符合ElementIsElementTypeFilter( true )
的元素?
项目中不存在;它们只是模板,类型,符号。只有实例存在于项目模型空间中。
此外,在每次迭代中,您在循环内调用ToElements
。这是每次创建所有元素的新集合。这是浪费时间和空间的巨大浪费。
根本不需要拨打ToElements
!查看FindElement
and Collector Optimisation的讨论。
您也可以消除许多其他元素。例如,您感兴趣的元素几乎肯定会有一个有效的类别。
The Building Coder探讨了Retrieve Model Elements or Visible 3D Elements的几种不同方法。
如果需要,可以将非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 );
}
}
}
}
}
}
}
答案 1 :(得分:0)
如果您确实需要所有几何元素,一种避免一一检查的方法是实施custom exporter。这将为您提供零麻烦的3D视图中所有可见元素的所有几何形状。如果您只需要墙壁,则设置一个合适的3D视图,使其仅显示那些墙壁。