/* $Id$
*
* Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com).
*
* This file is part of OpenCAMlib
* (see https://github.com/aewallin/opencamlib).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
#include
#ifdef _OPENMP // this should really not be a check for Windows, but a check for OpenMP
#include
#endif
#include "point.hpp"
#include "triangle.hpp"
#include "batchdropcutter.hpp"
namespace ocl
{
//******** ********************** */
BatchDropCutter::BatchDropCutter() {
clpoints = new std::vector();
nCalls = 0;
#ifdef _OPENMP
nthreads = omp_get_num_procs(); // figure out how many cores we have
#endif
cutter = NULL;
bucketSize = 1;
root = new KDTree();
}
BatchDropCutter::~BatchDropCutter() {
clpoints->clear();
delete clpoints;
delete root;
}
void BatchDropCutter::setSTL(const STLSurf &s) {
// std::cout << "bdc::setSTL()\n";
surf = &s;
root->setXYDimensions(); // we search for triangles in the XY plane, don't care about Z-coordinate
root->setBucketSize( bucketSize );
root->build(s.tris);
// std::cout << "bdc::setSTL() done.\n";
}
void BatchDropCutter::appendPoint(CLPoint& p) {
clpoints->push_back(p);
}
// drop cutter against all triangles in surface
void BatchDropCutter::dropCutter1() {
// std::cout << "dropCutterSTL1 " << clpoints->size() <<
// " cl-points and " << surf->tris.size() << " triangles...";
nCalls = 0;
BOOST_FOREACH(CLPoint &cl, *clpoints) {
BOOST_FOREACH( const Triangle& t, surf->tris) {// test against all triangles in s
cutter->dropCutter(cl,t);
++nCalls;
}
}
// std::cout << "done.\n";
return;
}
// first search for triangles under the cutter
// then only drop cutter against found triangles
void BatchDropCutter::dropCutter2() {
// std::cout << "dropCutterSTL2 " << clpoints->size() <<
// " cl-points and " << surf->tris.size() << " triangles.\n";
std::cout.flush();
nCalls = 0;
std::list *triangles_under_cutter;
BOOST_FOREACH(CLPoint &cl, *clpoints) { //loop through each CL-point
triangles_under_cutter = root->search_cutter_overlap( cutter , &cl);
BOOST_FOREACH( const Triangle& t, *triangles_under_cutter) {
cutter->dropCutter(cl,t);
++nCalls;
}
delete triangles_under_cutter;
}
// std::cout << "done. " << nCalls << " dropCutter() calls.\n";
std::cout.flush();
return;
}
// compared to dropCutter2, add an additional explicit overlap-test before testing triangle
void BatchDropCutter::dropCutter3() {
// std::cout << "dropCutterSTL3 " << clpoints->size() <<
// " cl-points and " << surf->tris.size() << " triangles.\n";
nCalls = 0;
std::list *triangles_under_cutter;
BOOST_FOREACH(CLPoint &cl, *clpoints) { //loop through each CL-point
triangles_under_cutter = root->search_cutter_overlap( cutter , &cl);
BOOST_FOREACH( const Triangle& t, *triangles_under_cutter) {
if (cutter->overlaps(cl,t)) {
if ( cl.below(t) ) {
cutter->dropCutter(cl,t);
++nCalls;
}
}
}
delete triangles_under_cutter;
}
// std::cout << "done. " << nCalls << " dropCutter() calls.\n";
return;
}
// use OpenMP to share work between threads
void BatchDropCutter::dropCutter4() {
// std::cout << "dropCutterSTL4 " << clpoints->size() <<
// " cl-points and " << surf->tris.size() << " triangles.\n";
nCalls = 0;
int calls=0;
std::list* tris;
#ifdef _WIN32 // OpenMP version 2 of VS2013 OpenMP need signed loop variable
int n; // loop variable
int Nmax = static_cast(clpoints->size());
#else
unsigned int n; // loop variable
unsigned int Nmax = clpoints->size();
#endif
std::vector& clref = *clpoints;
#ifdef _OPENMP
omp_set_num_threads(nthreads); // the constructor sets number of threads right
// or the user can explicitly specify something else
#endif
std::list::iterator it;
#pragma omp parallel for shared( calls, clref) private(n,tris,it)
for (n=0;n< Nmax ;n++) { // PARALLEL OpenMP loop!
// #ifdef _OPENMP
// if ( n== 0 ) { // first iteration
// if (omp_get_thread_num() == 0 )
// std::cout << "Number of OpenMP threads = "<< omp_get_num_threads() << "\n";// print out how many threads we are using
// }
// #endif
tris = root->search_cutter_overlap( cutter, &clref[n] );
// assert( tris->size() <= ntriangles ); // can't possibly find more triangles than in the STLSurf
for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles
if ( cutter->overlaps(clref[n],*it) ) { // cutter overlap triangle? check
if (clref[n].below(*it)) {
cutter->vertexDrop( clref[n],*it);
++calls;
}
}
}
for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles
if ( cutter->overlaps(clref[n],*it) ) { // cutter overlap triangle? check
if (clref[n].below(*it))
cutter->facetDrop( clref[n],*it);
}
}
for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles
if ( cutter->overlaps(clref[n],*it) ) { // cutter overlap triangle? check
if (clref[n].below(*it))
cutter->edgeDrop( clref[n],*it);
}
}
delete( tris );
} // end OpenMP PARALLEL for
nCalls = calls;
// std::cout << " " << nCalls << " dropCutter() calls.\n";
return;
}
// use OpenMP to share work between threads
void BatchDropCutter::dropCutter5() {
// std::cout << "dropCutterSTL5 " << clpoints->size() <<
// " cl-points and " << surf->tris.size() << " triangles.\n";
nCalls = 0;
int calls=0;
std::list* tris;
#ifdef _WIN32 // OpenMP version 2 of VS2013 OpenMP need signed loop variable
int Nmax = static_cast(clpoints->size());
int n; // loop variable
#else
unsigned int Nmax = clpoints->size();
unsigned int n; // loop variable
#endif
std::vector& clref = *clpoints;
#ifdef _OPENMP
omp_set_num_threads(nthreads); // the constructor sets number of threads right
// or the user can explicitly specify something else
#endif
std::list::iterator it;
#pragma omp parallel for schedule(dynamic) shared( calls, clref ) private(n,tris,it)
for (n=0;nsearch_cutter_overlap( cutter, &clref[n] );
assert( tris );
// assert( tris->size() <= ntriangles ); // can't possibly find more triangles than in the STLSurf
for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles
if ( cutter->overlaps(clref[n],*it) ) { // cutter overlap triangle? check
if (clref[n].below(*it)) {
cutter->dropCutter( clref[n],*it);
++calls;
}
}
}
delete( tris );
} // end OpenMP PARALLEL for
nCalls = calls;
// std::cout << "\n " << nCalls << " dropCutter() calls.\n";
return;
}
}// end namespace
// end file batchdropcutter.cpp