Quantcast
Channel: All Revit API Forum posts
Viewing all articles
Browse latest Browse all 66683

Collect Eleemnts that are NOT inside any room

$
0
0

I have a very huge model with hundreds of rooms. I want to collect elements that DO NOT belong to (or inside) any room. I have tried extracting room solids and check with each element using ElementIntersectsSolidFilter. I know this is extremely slow process. Here is the code;

public async Task<List<ElementId>> CollectElementsOutsideAsync(Phase phase, IProgress<double> progress) { Debris.Clear(); // Step 1: Collect valid rooms (Main Thread) List<Room> validRooms = new FilteredElementCollector(doc) .WhereElementIsNotElementType() .OfCategory(BuiltInCategory.OST_Rooms) .Cast<Room>() .Where(r => r.Area > 0 && r.Location != null) .ToList(); List<Solid> roomSolids = new List<Solid>(); SpatialElementBoundaryOptions sebOptions = new SpatialElementBoundaryOptions { SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center, StoreFreeBoundaryFaces = true }; for (int i = 0; i < validRooms.Count; i++) { Room room = validRooms[i]; Debug.Print($"Processing Room {i + 1} of {validRooms.Count}"); try { SpatialElementGeometryCalculator cal = new SpatialElementGeometryCalculator(doc, sebOptions); SpatialElementGeometryResults results = cal.CalculateSpatialElementGeometry(room); Solid roomSolid = results.GetGeometry(); roomSolids.Add(roomSolid); } catch { try { sebOptions.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; SpatialElementGeometryCalculator cal = new SpatialElementGeometryCalculator(doc, sebOptions); SpatialElementGeometryResults results = cal.CalculateSpatialElementGeometry(room); Solid roomSolid = results.GetGeometry(); roomSolids.Add(roomSolid); } catch (Exception e) { Debug.Print($"...No solid found!!"); } } await Task.Delay(50); Debug.Print($"...Done"); progress.Report((i + 1) / (double)validRooms.Count * 50); // Report progress for room processing await Task.Yield(); // Ensure the UI updates the progress bar during the loop } Debug.Print($"...Done"); List<ElementId> all3DElements = doc.GetAll3DElements().Select(e => e.Id).ToList(); List<ElementId> elementsInsideRooms = new List<ElementId>(); int totalSolids = roomSolids.Count; foreach (Solid roomSolid in roomSolids) { ElementIntersectsSolidFilter elementIntersectsSolidFilter = new ElementIntersectsSolidFilter(roomSolid); FilteredElementCollector collector = new FilteredElementCollector(doc, all3DElements); ICollection<ElementId> elementsInThisRoom = collector.WherePasses(elementIntersectsSolidFilter).ToElementIds(); elementsInsideRooms.AddRange(elementsInThisRoom); await Task.Delay(50); progress.Report(75 + (roomSolids.IndexOf(roomSolid) / (double)totalSolids * 25)); // Report progress for filtering elements await Task.Yield(); } progress.Report(100); // Report progress for completion return all3DElements.ToList().Where(e => elementsInsideRooms.Contains(e) == false).ToList(); }

 

The line;

 

ElementIntersectsSolidFilter elementIntersectsSolidFilter = new ElementIntersectsSolidFilter(roomSolid);

 

 

throws error saying;
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

Another question; Is there any better approach than to make Revit do this heavy lift?


Viewing all articles
Browse latest Browse all 66683

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>