void MergeAreasGenerator::MergeAreas(Progress& progress, const std::unordered_set<Id>& nodeUseMap, AreaMergeData& job) { std::unordered_map<Id,std::set<AreaRef> > idAreaMap; size_t overallCount=job.areas.size(); IndexAreasByNodeIds(nodeUseMap, job.areas, idAreaMap); progress.Info("Found "+NumberToString(idAreaMap.size())+" nodes as possible connection points for areas"); while (!job.areas.empty()) { AreaRef area; progress.SetProgress(overallCount-job.areas.size(),overallCount); // Pop a area from the list of "to be processed" areas area=job.areas.front(); job.areas.pop_front(); // This areas has already be "handled", ignore it if (job.mergedAway.find(area->GetFileOffset())!=job.mergedAway.end()) { continue; } // Delete all mentioning of this area in the idAreaMap cache EraseAreaInCache(nodeUseMap, area, idAreaMap); std::set<Id> finishedIds; // Now try to merge it against candidates that share the same ids. if (TryMerge(nodeUseMap, *area, idAreaMap, finishedIds, job.mergedAway)) { job.merges.push_back(area); while (TryMerge(nodeUseMap, *area, idAreaMap, finishedIds, job.mergedAway)) { // no code } } } }
static void MergeNodeFaces (node_t* node) { face_t* f1; for (f1 = node->faces; f1; f1 = f1->next) { face_t* f2; if (f1->merged || f1->split[0] || f1->split[1]) continue; for (f2 = node->faces; f2 != f1; f2 = f2->next) { const plane_t* plane = &mapplanes[node->planenum]; face_t* merged; face_t* end; if (f2->merged || f2->split[0] || f2->split[1]) continue; merged = TryMerge(f1, f2, plane->normal); if (!merged) continue; /* add merged to the end of the node face list * so it will be checked against all the faces again */ for (end = node->faces; end->next; end = end->next); merged->next = nullptr; end->next = merged; break; } } }
face_t *MergeFaceToList (face_t *face, face_t *list) { face_t *newf, *f; for (f=list ; f ; f=f->next) { //CheckColinear (f); if (mergedebug) { Draw_ClearWindow (); Draw_DrawFace (face); Draw_DrawFace (f); Draw_SetBlack (); } newf = TryMerge (face, f); if (!newf) continue; FreeFace (face); f->numpoints = -1; // merged out return MergeFaceToList (newf, list); } // didn't merge, so add at start face->next = list; return face; }
/* =============== MergeFaceToList =============== */ face_t *MergeFaceToList (face_t *face, face_t *list) { face_t *newf, *f; for (f=list ; f ; f=f->next) { newf = TryMerge (face, f); if (!newf) continue; FreeFace (face); ResizeFace (f, 0); f->numpoints = -1; // merged out return MergeFaceToList (newf, list); } // didn't merge, so add at start face->next = list; return face; }
/* =============== MergeFaceToList =============== */ face_t * MergeFaceToList(face_t *face, face_t *list) { face_t *newf, *f; f = list; while (f) { #ifdef PARANOID CheckColinear (f); #endif newf = TryMerge(face, f); if (newf) { FreeMem(face, FACE, 1); f->w.numpoints = -1; // merged out, remove later face = newf; f = list; } else f = f->next; } // didn't merge, so add at start face->next = list; return face; }