Auto-joining floors and walls

[Similar problem in Dynamo has been presented in another post]

When modelling, Revit automatically joins geometries of intersecting walls – making drafting process a lot faster. It does not happen however for wall and floor pairs. Which results in some extra work while creating sections and can cause errors in schedules. Fortunately it can be easily automated by using Revit API.

At the beginning we have to find all the walls and floors (separately) in the model. We need to skip element type objects.

FilteredElementCollector walls = new FilteredElementCollector(doc)
				.OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType();
FilteredElementCollector floors = new FilteredElementCollector(doc)
				.OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType();

Next, ensuring we work inside a transaction, we are going to check each wall-floor pair whether they overlap. In order to run the script efficiently we are not going to test actual geometry but objects’ bounding boxes.

In order to avoid run-time errors, for each element we check if it produces a valid (non-null) bounding box. Intersection of the boxes is tested by using a simple helper-function, which I am not going to describe in detail. Its code is included however in the final script at the bottom.

foreach(Wall w in walls) {					
  BoundingBoxXYZ wBB = w.get_BoundingBox(null);						
  if(wBB!=null) foreach(Floor f in floors) {			
    BoundingBoxXYZ fBB = f.get_BoundingBox(null);														
    if(fBB!=null) if(bbIntersect(wBB,fBB)) {		
    }
  }
}

When we find a floor-wall pair that (we suspect) can be joined, we have to check if those elements are not already joined. If not we join them. To avoid crashing the script by a single pair error, we wrap everything in try…catch statement.

if(!JoinGeometryUtils.AreElementsJoined(doc,w,f)) {
  try {							
    JoinGeometryUtils.JoinGeometry(doc, w, f);
  }	
  catch(Autodesk.Revit.Exceptions.ApplicationException)   
  {									
  }
}

The entire code could look like so:

		private bool overlap1D(double a1, double a2, double b1, double b2) {
			
			if(a2>=b1 && b2>=a1) return true;
			
			return false;
			
		}
		
		private bool bbIntersect(BoundingBoxXYZ A, BoundingBoxXYZ B) {
						
			return overlap1D(A.Min.X,A.Max.X,B.Min.X,B.Max.X) &&
				overlap1D(A.Min.Y,A.Max.Y,B.Min.Y,B.Max.Y) &&
				overlap1D(A.Min.Z,A.Max.Z,B.Min.Z,B.Max.Z);
			
		}
		
		public void joinFloorWall() {
			
			Document doc = this.ActiveUIDocument.Document;
			UIDocument uiDoc = new UIDocument(doc);
						
			FilteredElementCollector walls = new FilteredElementCollector(doc)
				.OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType();
			FilteredElementCollector floors = new FilteredElementCollector(doc)
				.OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType();
			

			using(Transaction t = new Transaction(doc,"Join walls to floors")) {
				
				t.Start();				

				foreach(Wall w in walls) {	
				
				BoundingBoxXYZ wBB = w.get_BoundingBox(null);	
					
				if(wBB!=null) foreach(Floor f in floors) {					
								
						BoundingBoxXYZ fBB = f.get_BoundingBox(null);
									
						if(fBB!=null) if(bbIntersect(wBB,fBB)) {							
									
							if(!JoinGeometryUtils.AreElementsJoined(doc,w,f)) {
								try {							
									JoinGeometryUtils.JoinGeometry(doc, w, f);
								}
								catch(Autodesk.Revit.Exceptions.ApplicationException) 
								{									
								}
							}			   
								
						}
					}
			    }					
				
				t.Commit();				
				
			}			
			
		}
Posts created 30

Leave a Reply

Your email address will not be published.

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top