//=========================================================================== // Carves any intersecting solid brushes into the minimum number // of non-intersecting brushes. // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== bspbrush_t *ChopBrushes (bspbrush_t *head) { bspbrush_t *b1, *b2, *next; bspbrush_t *tail; bspbrush_t *keep; bspbrush_t *sub, *sub2; int c1, c2; int num_csg_iterations; Log_Print("-------- Brush CSG ---------\n"); Log_Print("%6d original brushes\n", CountBrushList (head)); num_csg_iterations = 0; qprintf("%6d output brushes", num_csg_iterations); #if 0 if (startbrush == 0) WriteBrushList ("before.gl", head, false); #endif keep = NULL; newlist: // find tail if (!head) return NULL; for (tail = head; tail->next; tail = tail->next) ; for (b1=head ; b1 ; b1=next) { next = b1->next; //if the conversion is cancelled if (cancelconversion) { b1->next = keep; keep = b1; continue; } //end if for (b2 = b1->next; b2; b2 = b2->next) { if (BrushesDisjoint (b1, b2)) continue; sub = NULL; sub2 = NULL; c1 = 999999; c2 = 999999; if (BrushGE (b2, b1)) { sub = SubtractBrush (b1, b2); if (sub == b1) { continue; // didn't really intersect } //end if if (!sub) { // b1 is swallowed by b2 head = CullList (b1, b1); goto newlist; } c1 = CountBrushList (sub); } if ( BrushGE (b1, b2) ) { sub2 = SubtractBrush (b2, b1); if (sub2 == b2) continue; // didn't really intersect if (!sub2) { // b2 is swallowed by b1 FreeBrushList (sub); head = CullList (b1, b2); goto newlist; } c2 = CountBrushList (sub2); } if (!sub && !sub2) continue; // neither one can bite // only accept if it didn't fragment // (commenting this out allows full fragmentation) if (c1 > 1 && c2 > 1) { if (sub2) FreeBrushList (sub2); if (sub) FreeBrushList (sub); continue; } if (c1 < c2) { if (sub2) FreeBrushList (sub2); tail = AddBrushListToTail (sub, tail); head = CullList (b1, b1); goto newlist; } //end if else { if (sub) FreeBrushList (sub); tail = AddBrushListToTail (sub2, tail); head = CullList (b1, b2); goto newlist; } //end else } //end for if (!b2) { // b1 is no longer intersecting anything, so keep it b1->next = keep; keep = b1; } //end if num_csg_iterations++; qprintf("\r%6d", num_csg_iterations); } //end for if (cancelconversion) return keep; // qprintf("\n"); Log_Write("%6d output brushes\r\n", num_csg_iterations); #if 0 { WriteBrushList ("after.gl", keep, false); WriteBrushMap ("after.map", keep); } #endif return keep; } //end of the function ChopBrushes
/* ================= ChopBrushes Carves any intersecting solid brushes into the minimum number of non-intersecting brushes. ================= */ bspbrush_t *ChopBrushes (bspbrush_t *head) { bspbrush_t *b1, *b2, *next; bspbrush_t *tail; bspbrush_t *keep; bspbrush_t *sub, *sub2; int c1, c2; Sys_FPrintf( SYS_VRB, "---- ChopBrushes ----\n"); Sys_FPrintf( SYS_VRB, "original brushes: %i\n", CountBrushList (head)); #if 0 if (startbrush == 0) WriteBrushList ("before.gl", head, false); #endif keep = NULL; newlist: // find tail if (!head) return NULL; for (tail=head ; tail->next ; tail=tail->next) ; for (b1=head ; b1 ; b1=next) { next = b1->next; for (b2=b1->next ; b2 ; b2 = b2->next) { if (BrushesDisjoint (b1, b2)) continue; sub = NULL; sub2 = NULL; c1 = 999999; c2 = 999999; if ( BrushGE (b2, b1) ) { sub = SubtractBrush (b1, b2); if (sub == b1) continue; // didn't really intersect if (!sub) { // b1 is swallowed by b2 head = CullList (b1, b1); goto newlist; } c1 = CountBrushList (sub); } if ( BrushGE (b1, b2) ) { sub2 = SubtractBrush (b2, b1); if (sub2 == b2) continue; // didn't really intersect if (!sub2) { // b2 is swallowed by b1 FreeBrushList (sub); head = CullList (b1, b2); goto newlist; } c2 = CountBrushList (sub2); } if (!sub && !sub2) continue; // neither one can bite // only accept if it didn't fragment // (commening this out allows full fragmentation) if (c1 > 1 && c2 > 1) { if (sub2) FreeBrushList (sub2); if (sub) FreeBrushList (sub); continue; } if (c1 < c2) { if (sub2) FreeBrushList (sub2); tail = AddBrushListToTail (sub, tail); head = CullList (b1, b1); goto newlist; } else { if (sub) FreeBrushList (sub); tail = AddBrushListToTail (sub2, tail); head = CullList (b1, b2); goto newlist; } } if (!b2) { // b1 is no longer intersecting anything, so keep it b1->next = keep; keep = b1; } } Sys_FPrintf( SYS_VRB, "output brushes: %i\n", CountBrushList (keep)); #if 0 { WriteBrushList ("after.gl", keep, false); WriteBrushMap ("after.map", keep); } #endif return keep; }