diff --git a/src/Mod/Path/App/Area.cpp b/src/Mod/Path/App/Area.cpp index 84d735df33..a27db4bb88 100644 --- a/src/Mod/Path/App/Area.cpp +++ b/src/Mod/Path/App/Area.cpp @@ -30,7 +30,6 @@ # include "boost_fix/intrusive/detail/memory_util.hpp" # include "boost_fix/container/detail/memory_util.hpp" # endif -# include # include # include # include @@ -85,6 +84,10 @@ # include #endif +// TODO: remove omp and console +#include +#include +#include #include #include @@ -1480,29 +1483,51 @@ std::vector > Area::makeSections( area->setPlane(face.Moved(locInverse)); if(project) { - #pragma omp parallel - { - int thread_count = omp_get_num_threads(); - int thread_num = omp_get_thread_num(); - size_t chunk_size= projectedShapes.size() / thread_count; - auto begin = projectedShapes.begin(); - std::advance(begin, thread_num * chunk_size); - auto end = begin; - if(thread_num == thread_count - 1) // last thread iterates the remaining sequence - end = projectedShapes.end(); - else - std::advance(end, chunk_size); - #pragma omp barrier - for(auto s = begin; s != end; ++s) { + typedef std::list container; + typedef container::iterator iter; + std::mutex m; + + unsigned int n = std::thread::hardware_concurrency(); + Base::Console().Error("makeSections Threads: %d Shapes: %d\n", n, projectedShapes.size()); + auto worker = [&m, &d, &area, &locInverse] (iter begin, iter end) { + Base::Console().Error("In worker (# items: %d)\n", std::distance(begin, end)); + for (auto it = begin; it != end; it++) { gp_Trsf t; t.SetTranslation(gp_Vec(0,0,-d)); TopLoc_Location wloc(t); - area->add(s->shape.Moved(wloc).Moved(locInverse),s->op); + { + std::lock_guard lockGuard(m); + area->add(it->shape.Moved(wloc).Moved(locInverse),it->op); + } } + }; + if(projectedShapes.size() < n) + { + worker(projectedShapes.begin(), projectedShapes.end()); + } else { + std::vector threads(n); + const size_t chunk_size = projectedShapes.size() / n; + + size_t thread_num = 1; + for(auto it = std::begin(threads); it != std::end(threads) -1; ++it) + { + auto begin = projectedShapes.begin(); + std::advance(begin, thread_num * chunk_size); + auto end = begin; + if(thread_num == n - 1) // last thread iterates the remaining sequence + end = projectedShapes.end(); + else + std::advance(end, chunk_size); + *it = std::thread(worker, begin, end); + thread_num++; + } + for (auto&& i : threads) + i.join(); } sections.push_back(area); break; } + for(auto it=myShapes.begin();it!=myShapes.end();++it) { const auto &s = *it; BRep_Builder builder; @@ -1615,32 +1640,55 @@ std::list Area::getProjectedShapes(const gp_Trsf &trsf, bool invers TopLoc_Location loc(trsf); TopLoc_Location locInverse(loc.Inverted()); - #pragma omp parallel - { - int thread_count = omp_get_num_threads(); - int thread_num = omp_get_thread_num(); - size_t chunk_size= myShapes.size() / thread_count; - auto begin = myShapes.begin(); - std::advance(begin, thread_num * chunk_size); - auto end = begin; - if(thread_num == thread_count - 1) // last thread iterates the remaining sequence - end = myShapes.end(); - else - std::advance(end, chunk_size); - #pragma omp barrier - for(auto s = begin; s != end; ++s){ + typedef std::list container; + typedef container::const_iterator iter; + std::mutex m; + int mySkippedShapes = 0; + + unsigned int n = std::thread::hardware_concurrency(); + Base::Console().Error("getProjectedShapes Threads: %d Shapes: %d\n", n, myShapes.size()); + auto worker = [&m, &inverse, &loc, &ret, &locInverse, &mySkippedShapes] (iter begin,iter end, const AreaParams& myParams) { + Base::Console().Error("In worker (# items: %d)\n", std::distance(begin, end)); + for (auto it = begin; it != end; it++) { TopoDS_Shape out; - int skipped = Area::project(out,s->shape.Moved(loc),&myParams); - if(skipped < 0) { - ++mySkippedShapes; - continue; - }else - mySkippedShapes += skipped; - if(!out.IsNull()) - ret.emplace_back(s->op,inverse?out.Moved(locInverse):out); + int skipped = Area::project(out,it->shape.Moved(loc), &myParams); + { + std::lock_guard lockGuard(m); + if(skipped < 0) { + ++mySkippedShapes; + continue; + }else + mySkippedShapes += skipped; + if(!out.IsNull()) + ret.emplace_back(it->op,inverse?out.Moved(locInverse):out); + } + } + }; + if(myShapes.size() < n) + { + worker(myShapes.begin(), myShapes.end(), myParams); + } else { + std::vector threads(n); + const size_t chunk_size = myShapes.size() / n; + + size_t thread_num = 1; + for(auto it = std::begin(threads); it != std::end(threads) -1; ++it) + { + auto begin = myShapes.begin(); + std::advance(begin, thread_num * chunk_size); + auto end = begin; + if(thread_num == n - 1) // last thread iterates the remaining sequence + end = myShapes.end(); + else + std::advance(end, chunk_size); + *it = std::thread(worker, begin, end, myParams); + thread_num++; + } + for (auto&& i : threads) + i.join(); } - + if(mySkippedShapes) AREA_WARN("skipped " << mySkippedShapes << " sub shapes during projection"); return ret; diff --git a/src/Mod/Path/App/CMakeLists.txt b/src/Mod/Path/App/CMakeLists.txt index ec50f473ab..69a260d61b 100644 --- a/src/Mod/Path/App/CMakeLists.txt +++ b/src/Mod/Path/App/CMakeLists.txt @@ -118,9 +118,10 @@ SOURCE_GROUP("Module" FILES ${Mod_SRCS}) # SOURCE_GROUP("KDL" FILES ${KDL_SRCS} ${KDL_HPPS} ${UTIL_SRCS} ${UTIL_HPPS} ) #endif(WIN32) -find_package(OpenMP REQUIRED) +find_package(Threads REQUIRED) + add_library(Path SHARED ${Path_SRCS}) -target_link_libraries(Path ${Path_LIBS} OpenMP::OpenMP_CXX) +target_link_libraries(Path ${Path_LIBS} Threads::Threads) if(FREECAD_USE_PCH) add_definitions(-D_PreComp_)