From b208cd8cae138bfc84809704093c715e4d7bc506 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sun, 6 Sep 2020 10:39:37 -0400 Subject: [PATCH] NFC, Performance: Use OpenMP for boolean function MakeItersectionCurvesAgainst. This is the last long-running single-threaded part of the boolean code. On one test model this took Regenerate form 27 seconds down to 18s. The critical sections needed a name (into) because that object must not be modified while in use in different places. --- src/srf/boolean.cpp | 6 ++++-- src/srf/surfinter.cpp | 35 ++++++++++++++++++++++------------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/srf/boolean.cpp b/src/srf/boolean.cpp index 6c2443e1..b0b175da 100644 --- a/src/srf/boolean.cpp +++ b/src/srf/boolean.cpp @@ -640,8 +640,10 @@ void SShell::CopySurfacesTrimAgainst(SShell *sha, SShell *shb, SShell *into, SSu } void SShell::MakeIntersectionCurvesAgainst(SShell *agnst, SShell *into) { - SSurface *sa; - for(sa = surface.First(); sa; sa = surface.NextAfter(sa)) { +#pragma omp parallel for + for(int i = 0; i< surface.n; i++) { + SSurface *sa = &surface[i]; + SSurface *sb; for(sb = agnst->surface.First(); sb; sb = agnst->surface.NextAfter(sb)){ // Intersect every surface from our shell against every surface diff --git a/src/srf/surfinter.cpp b/src/srf/surfinter.cpp index 0a2f09c0..ddcbad23 100644 --- a/src/srf/surfinter.cpp +++ b/src/srf/surfinter.cpp @@ -27,19 +27,22 @@ void SSurface::AddExactIntersectionCurve(SBezier *sb, SSurface *srfB, SBezier sbrev = *sb; sbrev.Reverse(); bool backwards = false; - for(se = into->curve.First(); se; se = into->curve.NextAfter(se)) { - if(se->isExact) { - if(sb->Equals(&(se->exact))) { - existing = se; - break; - } - if(sbrev.Equals(&(se->exact))) { - existing = se; - backwards = true; - break; +#pragma omp critical(into) + { + for(se = into->curve.First(); se; se = into->curve.NextAfter(se)) { + if(se->isExact) { + if(sb->Equals(&(se->exact))) { + existing = se; + break; + } + if(sbrev.Equals(&(se->exact))) { + existing = se; + backwards = true; + break; + } } } - } + }// end omp critical if(existing) { SCurvePt *v; for(v = existing->pts.First(); v; v = existing->pts.NextAfter(v)) { @@ -101,7 +104,10 @@ void SSurface::AddExactIntersectionCurve(SBezier *sb, SSurface *srfB, "Unexpected zero-length edge"); split.source = SCurve::Source::INTERSECTION; - into->curve.AddAndAssignId(&split); +#pragma omp critical(into) + { + into->curve.AddAndAssignId(&split); + } } void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, @@ -456,7 +462,10 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, // And now we split and insert the curve SCurve split = sc.MakeCopySplitAgainst(agnstA, agnstB, this, b); sc.Clear(); - into->curve.AddAndAssignId(&split); +#pragma omp critical(into) + { + into->curve.AddAndAssignId(&split); + } } spl.Clear(); }