diff --git a/lib/bsp_loader/src/brush.rs b/lib/bsp_loader/src/brush.rs
index 1a0c6d9..8e53182 100644
--- a/lib/bsp_loader/src/brush.rs
+++ b/lib/bsp_loader/src/brush.rs
@@ -35,6 +35,8 @@ pub enum PlanesToFacesError{
 	InitIntersection,
 	FindNewIntersection,
 	EmptyFaces,
+	InfiniteLoop1,
+	InfiniteLoop2,
 }
 impl std::fmt::Display for PlanesToFacesError{
 	fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -69,10 +71,17 @@ fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Result<Faces,Plan
 			edge_dir.dot(p.normal)
 		}).ok_or(PlanesToFacesError::InitFace2)?;
 
+		let mut detect_loop=200u8;
+
 		let mut intersection=solve3(face0,face1,face2).ok_or(PlanesToFacesError::InitIntersection)?;
 
 		// repeatedly update face0, face1 until all faces form part of the convex solid
 		'find: loop{
+			if let Some(a)=detect_loop.checked_sub(1){
+				detect_loop=a;
+			}else{
+				return Err(PlanesToFacesError::InfiniteLoop1);
+			}
 			// test if any *other* faces occlude the intersection
 			for new_face in &face_list{
 				// new face occludes intersection point
@@ -126,6 +135,8 @@ fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Result<Faces,Plan
 		// Note that we chose face2 such that the 3 faces create a particular winding order.
 		// If we choose a consistent face to follow (face1, face2) it will always wind with a consistent chirality
 
+		let mut detect_loop=200u8;
+
 		// keep looping until we meet this face again
 		let face1=face1;
 		let mut face=Vec::new();
@@ -165,6 +176,12 @@ fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Result<Faces,Plan
 
 			face2=new_face;
 			intersection=new_intersection;
+
+			if let Some(a)=detect_loop.checked_sub(1){
+				detect_loop=a;
+			}else{
+				return Err(PlanesToFacesError::InfiniteLoop2);
+			}
 		}
 
 		faces.push(face);