changed some for loops to list comprehensions, added openmp for area to make two loops parallel, changed a fuse to a compound

This commit is contained in:
Eric Trombly
2020-03-26 19:02:25 -05:00
parent 5f648aa2c1
commit 651c383925
3 changed files with 65 additions and 70 deletions

View File

@@ -30,6 +30,7 @@
# include "boost_fix/intrusive/detail/memory_util.hpp"
# include "boost_fix/container/detail/memory_util.hpp"
# endif
# include <omp.h>
# include <boost/geometry.hpp>
# include <boost/geometry/index/rtree.hpp>
# include <boost/geometry/geometries/geometries.hpp>
@@ -1290,8 +1291,10 @@ int Area::project(TopoDS_Shape &shape_out,
showShape(joiner.comp,"pre_project");
Area area(params);
auto new_params = params;
Area area(new_params);
area.myParams.SectionCount = 0;
area.myParams.Offset = 0.0;
area.myParams.PocketMode = 0;
area.myParams.Explode = false;
@@ -1302,8 +1305,7 @@ int Area::project(TopoDS_Shape &shape_out,
area.myParams.Coplanar = CoplanarNone;
area.myProjecting = true;
area.add(joiner.comp, OperationUnion);
const TopoDS_Shape &shape = area.getShape();
const TopoDS_Shape shape = area.getShape();
area.myParams.dump("project");
showShape(shape,"projected");
@@ -1478,16 +1480,29 @@ std::vector<shared_ptr<Area> > Area::makeSections(
area->setPlane(face.Moved(locInverse));
if(project) {
for(const auto &s : projectedShapes) {
gp_Trsf t;
t.SetTranslation(gp_Vec(0,0,-d));
TopLoc_Location wloc(t);
area->add(s.shape.Moved(wloc).Moved(locInverse),s.op);
#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) {
gp_Trsf t;
t.SetTranslation(gp_Vec(0,0,-d));
TopLoc_Location wloc(t);
area->add(s->shape.Moved(wloc).Moved(locInverse),s->op);
}
}
sections.push_back(area);
break;
}
for(auto it=myShapes.begin();it!=myShapes.end();++it) {
const auto &s = *it;
BRep_Builder builder;
@@ -1600,18 +1615,32 @@ std::list<Area::Shape> Area::getProjectedShapes(const gp_Trsf &trsf, bool invers
TopLoc_Location loc(trsf);
TopLoc_Location locInverse(loc.Inverted());
mySkippedShapes = 0;
for(auto &s : myShapes) {
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);
#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){
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);
}
}
if(mySkippedShapes)
AREA_WARN("skipped " << mySkippedShapes << " sub shapes during projection");
return ret;

View File

@@ -118,8 +118,9 @@ SOURCE_GROUP("Module" FILES ${Mod_SRCS})
# SOURCE_GROUP("KDL" FILES ${KDL_SRCS} ${KDL_HPPS} ${UTIL_SRCS} ${UTIL_HPPS} )
#endif(WIN32)
find_package(OpenMP REQUIRED)
add_library(Path SHARED ${Path_SRCS})
target_link_libraries(Path ${Path_LIBS})
target_link_libraries(Path ${Path_LIBS} OpenMP::OpenMP_CXX)
if(FREECAD_USE_PCH)
add_definitions(-D_PreComp_)

View File

@@ -365,9 +365,9 @@ class ObjectSurface(PathOp.ObjectOp):
def opExecute(self, obj):
'''opExecute(obj) ... process surface operation'''
PathLog.track()
import cProfile
pr = cProfile.Profile()
pr.enable()
#import cProfile
#pr = cProfile.Profile()
#pr.enable()
self.modelSTLs = list()
self.safeSTLs = list()
@@ -606,8 +606,8 @@ class ObjectSurface(PathOp.ObjectOp):
del self.deflection
execTime = time.time() - startTime
pr.disable()
pr.dump_stats("/mnt/files/profile.cprof")
#pr.disable()
#pr.dump_stats("/mnt/files/profile.cprof")
PathLog.info('Operation time: {} sec.'.format(execTime))
return True
@@ -1492,7 +1492,6 @@ class ObjectSurface(PathOp.ObjectOp):
else:
PathLog.warning('Path transitions might not avoid the model. Verify paths.')
#time.sleep(0.3)
else:
# If boundbox is Job.Stock, add hidden pad under stock as base plate
toolDiam = self.cutter.getDiameter()
@@ -1511,11 +1510,7 @@ class ObjectSurface(PathOp.ObjectOp):
voidEnv = PathUtils.getEnvelope(partshape=voidComp, depthparams=self.depthParams) # Produces .Shape
fuseShapes.append(voidEnv)
f0 = fuseShapes.pop(0)
if len(fuseShapes) > 0:
fused = f0.fuse(fuseShapes)
else:
fused = f0
fused = Part.makeCompound(fuseShapes)
if self.showDebugObjects is True:
T = FreeCAD.ActiveDocument.addObject('Part::Feature', 'safeSTLShape')
@@ -2585,44 +2580,14 @@ class ObjectSurface(PathOp.ObjectOp):
return GCODE
def _planarSinglepassProcess(self, obj, PNTS):
output = []
optimize = obj.OptimizeLinearPaths
lenPNTS = len(PNTS)
lstIdx = lenPNTS - 1
lop = None
onLine = False
# Initialize first three points
nxt = None
pnt = PNTS[0]
prev = FreeCAD.Vector(-442064564.6, 258539656553.27, 3538553425.847)
# Add temp end point
PNTS.append(FreeCAD.Vector(-4895747464.6, -25855763553.2, 35865763425))
# Begin processing ocl points list into gcode
for i in range(0, lenPNTS):
# Calculate next point for consideration with current point
nxt = PNTS[i + 1]
# Process point
if optimize is True:
iPOL = prev.isOnLine(nxt, pnt)
if iPOL is True:
onLine = True
else:
onLine = False
output.append(Path.Command('G1', {'X': pnt.x, 'Y': pnt.y, 'Z': pnt.z, 'F': self.horizFeed}))
else:
output.append(Path.Command('G1', {'X': pnt.x, 'Y': pnt.y, 'Z': pnt.z, 'F': self.horizFeed}))
# Rotate point data
if onLine is False:
prev = pnt
pnt = nxt
# Efor
temp = PNTS.pop() # Remove temp end point
if obj.OptimizeLinearPaths:
# first item will be compared to the last point, but I think that should work
output = [Path.Command('G1', {'X': PNTS[i].x, 'Y': PNTS[i].y, 'Z': PNTS[i].z, 'F': self.horizFeed})
for i in range(0, len(PNTS) - 1)
if not PNTS[i].isOnLine(PNTS[i -1],PNTS[i + 1])]
output.append(Path.Command('G1', {'X': PNTS[-1].x, 'Y': PNTS[-1].y, 'Z': PNTS[-1].z, 'F': self.horizFeed}))
else:
output = [Path.Command('G1', {'X': pnt.x, 'Y': pnt.y, 'Z': pnt.z, 'F': self.horizFeed}) for pnt in PNTS]
return output