فهرست منبع

- Ifc: improve heuristic to detect unwanted crossing lines by not running it when the window is not the result of arbitrary boolean ops on rectangles.

Alexander Gessler 12 سال پیش
والد
کامیت
8b823bd631
1فایلهای تغییر یافته به همراه19 افزوده شده و 3 حذف شده
  1. 19 3
      code/IFCGeometry.cpp

+ 19 - 3
code/IFCGeometry.cpp

@@ -963,11 +963,13 @@ struct ProjectedWindowContour
 	Contour contour;
 	Contour contour;
 	BoundingBox bb;
 	BoundingBox bb;
 	SkipList skiplist;
 	SkipList skiplist;
+	bool is_rectangular;
 
 
 
 
-	ProjectedWindowContour(const Contour& contour, const BoundingBox& bb)
+	ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
 		: contour(contour)
 		: contour(contour)
 		, bb(bb)
 		, bb(bb)
+		, is_rectangular(is_rectangular)
 	{}
 	{}
 
 
 
 
@@ -1662,7 +1664,15 @@ void CloseWindows(ContourVector& contours,
 
 
 		FindAdjacentContours(it, contours);
 		FindAdjacentContours(it, contours);
 		FindBorderContours(it);
 		FindBorderContours(it);
-		FindLikelyCrossingLines(it);
+
+		// if the window is the result of a finite union or intersection of rectangles,
+		// there shouldn't be any crossing or diagonal lines in it. Such lines would
+		// be artifacts caused by numerical inaccuracies or other bugs in polyclipper
+		// and our own code. Since rectangular openings are by far the most frequent
+		// case, it is worth filtering for this corner case.
+		if((*it).is_rectangular) {
+			FindLikelyCrossingLines(it);
+		}
 
 
 		ai_assert((*it).skiplist.size() == (*it).contour.size());
 		ai_assert((*it).skiplist.size() == (*it).contour.size());
 
 
@@ -2013,12 +2023,18 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
 		}
 		}
 		std::vector<TempOpening*> joined_openings(1, &opening);
 		std::vector<TempOpening*> joined_openings(1, &opening);
 
 
+		bool is_rectangle = temp_contour.size() == 4;
+
 		// See if this BB intersects or is in close adjacency to any other BB we have so far.
 		// See if this BB intersects or is in close adjacency to any other BB we have so far.
 		for (ContourVector::iterator it = contours.begin(); it != contours.end(); ) {
 		for (ContourVector::iterator it = contours.begin(); it != contours.end(); ) {
 			const BoundingBox& ibb = (*it).bb;
 			const BoundingBox& ibb = (*it).bb;
 
 
 			if (BoundingBoxesOverlapping(ibb, bb)) {
 			if (BoundingBoxesOverlapping(ibb, bb)) {
 
 
+				if (!(*it).is_rectangular) {
+					is_rectangle = false;
+				}
+
 				const std::vector<IfcVector2>& other = (*it).contour;
 				const std::vector<IfcVector2>& other = (*it).contour;
 				ClipperLib::ExPolygons poly;
 				ClipperLib::ExPolygons poly;
 
 
@@ -2086,7 +2102,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
 					joined_openings.end()));
 					joined_openings.end()));
 			}
 			}
 
 
-			contours.push_back(ProjectedWindowContour(temp_contour, bb));
+			contours.push_back(ProjectedWindowContour(temp_contour, bb, is_rectangle));
 		}
 		}
 	}
 	}