// general purpose vertex-drop which delegates to this->height(r) of subclass bool MillingCutter::vertexDrop(CLPoint &cl, const Triangle &t) const { bool result = false; BOOST_FOREACH( const Point& p, t.p) { // test each vertex of triangle double q = cl.xyDistance(p); // distance in XY-plane from cl to p if ( q <= radius ) { // p is inside the cutter CCPoint cc_tmp(p, VERTEX); if ( cl.liftZ( p.z - this->height(q), cc_tmp ) ) result = true; } } return result; }
/* * Copyright 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com) * * This file is part of OpenCAMlib. * * OpenCAMlib is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenCAMlib 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenCAMlib. If not, see <http://www.gnu.org/licenses/>. */ #include <iostream> #include <sstream> #include <string> #include "compositecutter.hpp" #include "numeric.hpp" #include "cylcutter.hpp" #include "ballcutter.hpp" #include "bullcutter.hpp" #include "conecutter.hpp" namespace ocl { CompositeCutter::CompositeCutter() { radiusvec = std::vector<double>(); cutter = std::vector<MillingCutter*>(); radius=0; diameter=0; } // add cutter c which is valid until radius=r and height=z with z-offset zoff void CompositeCutter::addCutter(MillingCutter& c, double r, double h, double zoff) { radiusvec.push_back(r); heightvec.push_back(h); cutter.push_back(&c); zoffset.push_back(zoff); if (r>radius) { radius = r; diameter = 2*r; } // update length also? } // this allows vertexDrop in the base-class to work as for other cutters double CompositeCutter::height(double r) const { unsigned int idx = radius_to_index(r); return cutter[idx]->height(r) + zoffset[idx]; } // return the width of the cutter at height h. double CompositeCutter::width(double h) const { unsigned int idx = height_to_index(h); // std::cout << "CompositeCutter::width( " << h << " ) idx=" << idx << " zoffset= " << zoffset[idx] << "\n"; // std::cout << " width = " << cutter[idx]->width( h - zoffset[idx] ) << "\n"; return cutter[idx]->width( h - zoffset[idx] ); } unsigned int CompositeCutter::height_to_index(double h) const { for (unsigned int n=0; n<cutter.size(); ++n) { if ( validHeight(n,h) ) return n; } // return the last cutter if we get here... return cutter.size()-1; std::cout << " Error, height= " << h << " has no index \n"; assert(0); return 0; } unsigned int CompositeCutter::radius_to_index(double r) const { for (unsigned int n=0; n<cutter.size(); ++n) { if ( validRadius(n,r) ) return n; } assert(0); return 0; } bool CompositeCutter::ccValidRadius(unsigned int n, CLPoint& cl) const { if (cl.cc->type == NONE) return false; double d = cl.xyDistance(*cl.cc); double lolimit; double hilimit; if (n==0) lolimit = - 1E-6; else lolimit = radiusvec[n-1] - 1E-6; hilimit = radiusvec[n]+1e-6; // FIXME: really ugly solution this one... if (d<lolimit) return false; else if (d>hilimit) return false; else return true; } bool CompositeCutter::ccValidHeight(unsigned int n, CCPoint& cc, const Fiber& f) const { //if ( ((cc.z-f.p1.z) >= 0.0) && (n == height_to_index(cc.z-f.p1.z)) ) if ( n == height_to_index(cc.z-f.p1.z) ) return true; else return false; } // return true if height h belongs to cutter n bool CompositeCutter::validHeight(unsigned int n, double h) const { double lolimit, hilimit; if (n==0) lolimit = -1E-6; else lolimit = heightvec[n-1] - 1E-6; hilimit = heightvec[n]+1e-6; // FIXME: really ugly solution this one... if ( (lolimit<=h) ) if (h<=hilimit) return true; return false; } bool CompositeCutter::validRadius(unsigned int n, double r) const { assert( r >= 0.0 ); double lolimit, hilimit; if (n==0) lolimit = -1E-6; else lolimit = radiusvec[n-1] - 1E-6; hilimit = radiusvec[n]+1e-6; // FIXME: really ugly solution this one... if ( (lolimit<=r) ) if (r<=hilimit) return true; return false; } //******** facetDrop ********************** */ // call facetDrop on each cutter and pick a valid cc-point bool CompositeCutter::facetDrop(CLPoint &cl, const Triangle &t) const { bool result = false; for (unsigned int n=0; n<cutter.size(); ++n) { // loop through cutters CLPoint cl_tmp = cl + CLPoint(0,0,zoffset[n]); CCPoint* cc_tmp; if ( cutter[n]->facetDrop(cl_tmp, t) ) { assert( cl_tmp.cc != 0); if ( ccValidRadius(n,cl_tmp) ) { // cc-point is valid cc_tmp = new CCPoint(*cl_tmp.cc); if (cl.liftZ( cl_tmp.z - zoffset[n] )) { // we need to lift the cutter cc_tmp->type = FACET; cl.cc = cc_tmp; result = true; } else { delete cc_tmp; } } } } return result; } //******** edge **************************************************** */ bool CompositeCutter::edgeDrop(CLPoint &cl, const Triangle &t) const { bool result = false; for (unsigned int n=0; n<cutter.size(); ++n) { // loop through cutters CLPoint cl_tmp = cl + Point(0,0,zoffset[n]); CCPoint* cc_tmp; if ( cutter[n]->edgeDrop(cl_tmp,t) ) { // drop sub-cutter against edge if ( ccValidRadius(n,cl_tmp) ) { // check if cc-point is valid cc_tmp = new CCPoint(*cl_tmp.cc); if (cl.liftZ( cl_tmp.z - zoffset[n] ) ) { // we need to lift the cutter cc_tmp->type = EDGE; cl.cc = cc_tmp; result = true; } else { delete cc_tmp; } } } } return result; }
// call facetDrop on each cutter and pick a valid cc-point bool CompositeCutter::facetDrop(CLPoint &cl, const Triangle &t) const { bool result = false; for (unsigned int n=0; n<cutter.size(); ++n) { // loop through cutters CLPoint cl_tmp = cl + CLPoint(0,0,zoffset[n]); CCPoint* cc_tmp; if ( cutter[n]->facetDrop(cl_tmp, t) ) { assert( cl_tmp.cc != 0); if ( ccValidRadius(n,cl_tmp) ) { // cc-point is valid cc_tmp = new CCPoint(*cl_tmp.cc); if (cl.liftZ( cl_tmp.z - zoffset[n] )) { // we need to lift the cutter cc_tmp->type = FACET; cl.cc = cc_tmp; result = true; } else { delete cc_tmp; } } } } return result; }