/* $Id$ */ /*! \mainpage OpenCAMLib manual * * \section intro_sec Introduction * OpenCAMLib is a C++ library with Python bindings under LGPL license * for creating toolpaths for cnc machines. * * - hosted at: http://code.google.com/p/opencamlib/ * - mailing-list at: http://groups.google.com/group/opencamlib * - svn-commits at: http://groups.google.com/group/opencamlib-svn * * This section describes how to obtain, build, and install OpenCAMLib. * * The \ref usr-manual section describes how to install and use OpenCAMLib. * * The \ref dev-manual section describes the CAM-algorithms in more detail. * * \section install_sec Installation * As of 2010 March there is no release yet. You have to build from source. * * \subsection source Building from source * The project is hosted at google-code: http://code.google.com/p/opencamlib/ * * To checkout the newest OpenCAMLib, run: * * svn checkout http://opencamlib.googlecode.com/svn/trunk/ opencamlib-read-only * * * Building requires the Boost libraries and a compiler that supports OpenMP. Visualizations require VTK. * It should be as simple as: * * cmake . * * make * * make install * * * all done! * * \subsubsection ubuntu Debian package On Ubuntu * As of SVN r95, OCL builds easily on Ubuntu Hardy through Karmic. * OCL will build on Lucid with some tweaks, which are not covered in these * brief instructions; proper support for Lucid is planned for the near * future. * * Use apt-get to install some software that helps build Debian packages: * * shell> apt-get install devscripts build-essential * * Use apt-get to install the packages used by OCL. The build dependencies * are listed in the debian/control file, on the "Build-Depends" line. * The following command is appropriate for SVN r95, check the source file * for current dependencies for your version: * * shell> apt-get install debhelper libboost-python-dev python-dev python-support * * Next build the OCL source tree into a debian package: * * shell> debuild -us -uc * * This will produce a Debian package (a ".deb" file) of OCL in the parent * directory "../", which can be installed with dpkg: * * shell> dpkg -i ../python-opencamlib_*.deb * * * \subsubsection windows Building On Windows * Text here on how to build on windows. * * \subsection OCL with CAD-applications * How to get opencamlib installed and working with HeeksCNC. * * How to use OCL with Blender, FreeCAD, etc. */ /*! \page usr-manual OpenCAMLib user manual * * Here text on how to use the library. * * \section Drop-Cutter * Tutorial and examples using drop-cutter. */ /*! \page dev-manual OpenCAMLib developer manual * * \section intro_dev Introduction * This section of the manual describes the computational geometry and algorithms used in OpenCAMLib. * Three-dimensional points and vectors are denoted with bold. * * \section Drop-Cutter * The drop cutter algorithm drops a cutter, positioned at a predefined (x,y) location * down along the z-axis until it makes contact with a triangle. * The algorithm is split into three parts, testing the cutter separately against the * three vertices ( vertexDrop() ), three edges ( edgeDrop() ), and the facet ( facetDrop() )of the triangle. * In general the vertex test is trivial, the facet test easy, and the edge test is the most difficult. * * \subsection dc-gen General * A cutter-location cl point is a point where the cutter tip can be located when in contact * with the surface, but without interfering with the STL-surface. * A cutter-contact (cc) point is the point where the cutter makes contact with the STL-surface. * The user specifies the (cl.x, cl.y) coordinates of the cutter, and an initial value cl.z for the cl z-coordinate. * The task for the vertex, facet, and edge tests is to update the height of the cutter cl.z. When each vertex, edge, * and facet of each triangle under the cutter positioned at (cl.x, cl.y) has been tested, the resulting cl.z is the * correct and final (maximum) height of the cutter we want. If no test finds a contact between the cutter and a triangle, then * cl.z and cc are left unmodified. * * The following milling cutters are supported by opencamlib. They all inherit from the base-class MillingCutter. * The CompoundCutter class allows specifying any shape similar to a general APT-type cutter. * * All cutters share common data-fields: * - diameter * - radius * - length * * Cutter shapes: * - Cylindrical: CylCutter * - radius = diameter/2 * - Spherical: BallCutter * - radius = diameter/2 * - Toroidal: BullCutter * - radius1 = the radius of the cylindrical middle part of the cutter. also called the torus radius * - radius2 = the tube-radius of the torus * - radius2 <= radius1 must be true (undefined behavior may occur if radius2>radius1) * - Conical: ConeCutter * - diameter = maximum diameter of the cone * - angle = half-angle of the cone, in radians. For a 90-degree cutter, set angle = pi/4 * - Compound: combinations of the above (restricted to an overall convex cutter shape). For example: * - ConeConeCutter * - BallConeCutter * - BullConeCutter * * \subsection verttest Vertex test * Milling cutters are symmetrical around their axis of rotation (the z-axis in 3-axis milling), so the vertex * test only depends on the distance between the cutter axis and the test-vertex. * Given cl and a vertex p to test, calculate the distance d in the xy-plane from cl to p: * \f[ * d = |cl - p| = \sqrt{(cl.x-p.x)^2+(cl.y-p.y)^2} * \f] * If \f$d > radius\f$ the cutter will not contact the vertex and we return without modifying cl.z. * If \f$d <= radius\f$ the cutter will make contact with the vertex. * * - Cylindrical cutters are flat we can set \f$cl.z = p.z\f$ * - For a Spherical cutter (see FigureX) \f$h = r - \sqrt{ r^2 - d^2 }\f$ and we set \f$cl.z = p.z - h\f$ * - For Toroidal cutters: * - If \f$d < r_1\f$ we are in the cylindrical part of the cutter and set \f$cl.z = p.z\f$ * - If \f$r_1 < d < r\f$ we are in the toroidal part and \f$ h = r_2 - \sqrt{ r_2^2 - (d-r_1)^2 }\f$ and then \f$cl.z = p.z - h\f$ * - For Conical cutters: * - \f$h = d/tan(angle)\f$ and set \f$cl.z = p.z - h\f$ * In all cases cc = p. (TODO: insert image of vertex test here) * * * * * \subsection facettest Facet test * Call the three vertices of the triangle p1, p2, and p3. * The facet test is really a test against the whole plane which contains the triangle facet. * First calculate the normal n of the facet, and normalize its length to one. The equation for the * plane is given by * \f[ * a*x + b*y + c*z + d = 0 * \f] * where the coefficients \f$(a, b, c) = \bar{n}\f$. The constant d can be calculated by inserting one vertex * into the formula of the plane: \f$d = -\bar{n}\cdot \bar{p_1}\f$. * * Also calculate and normalize the xy-projection of the normal \f$\bar{n_{xy}}\f$. * Note that vertical facets with n.z = 0 are a special case which are ignored in the drop-cutter algorithm. * * \subsubsection cylfacettest Cylindrical cutter facet test * The contact point with the plane will lie on the periphery of the cutter, a * distance \f$radius\f$ from \f$(cl.x, cl.y)\f$ in the direction \f$-\bar{n_{xy}}\f$, so the xy-coordinates of * the cc-point are given by: * \f[ * (cc.x, cc.y) = (cl.x, cl.y) - r*\bar{n_{xy}} * \f] * This cc-point lies on the plane, but not necessarily in the facet of the triangle. * If the cc-point is contained within the triangle (in the xy-plane), we can calculate its z-coordinate by * inserting into the equation of the plane: * \f[ * cc.z = (1/c)*(-d-a*cc.x-b*cc.y) * \f] * Since the cylindrical endmill is flat, we can also set \f$cl.z = cc.z\f$. * Note division by \f$c\f$ which requires \f$c = n.z \neq 0\f$ * * \subsubsection sphfacettest Spherical cutter facet test * The center of the sphere is located a distance \f$radius\f$ from \f$(cl.x, cl.y)\f$ in the direction of \f$-\bar{n}\f$. * We can find out the xy-compontents of the cc point with: * \f[ * \bar{cc} = \bar{cl} - r*\bar{n} * \f] * If this point lies within the facet of the triangle we locate the point on the plane by setting cc.z on the plane: * \f[ * cc.z = (1/c)*(-d-a*cc.x-b*cc.y) * \f] * The tool-tip z-coordinate is now given by \f$cl.z = cc.z + r*(n\cdot\hat{z}) - r \f$ * * * \subsubsection torfacettest Toroidal cutter facet test * Define a vector which points from the cc-point to the center of the toroid. This is a distance \f$radius2\f$ * along the surface normal \bar{n} and a distance \f$radius1\f$ along the XY-normal \bar{n_{xy}}: * \f[ * \bar{R} = r_2*\bar{n} + r_1* \bar{n_{xy}} * \f] * Now the xy-coordinates of the cc-point are given by * \f[ * \bar{cc} = \bar{cl} - \bar{R} * \f] * now check if this cc-point lies in the facet of the plane. If so, the z-coordinate of the cc-point is calculated: * \f[ * cc.z = (1/c)*(-d-a*cc.x-b*cc.y) * \f] * And the tool-tip will be located at \f$cl.z = cc.z + r_2*n.z - r_2\f$ * * \subsubsection conefacettest Conical cutter facet test * Describe ConeCutter facet test here. * * \subsection edgetest Edge test * Each test loops through all three edges of the triangle. The edge is defined by its startpoint * p1 and its endpoint p2. * * It is easier to do the tests in a translated and rotated coordinate system where the * cl-point is at (0,0) and the edge is rotated to be parallel with the X-axis. We call the * new endpoints of the edge p1u and p2u. These are found by noting that * \f[ * p1u_y = d * p2u_y = d * \f] * where d is the distance, in the XY-plane, from cl to a line through p1 and p2, * i.e. \f$d = cl.xyDistanceToLine(p1, p2) \f$. We also define, in the XY-plane, * the closest point to cl on the line as: \f$ sc = cl.xyClosestPoint( p1, p2 ) \f$. * * Now the x-coordinates of p1u and p2u are given by: * \f[ * p1u_x = (p1-sc).dot(v) * p2u_x = (p2-sc).dot(v) * \f] * where v is a normalized vector in the direction of the edge, or v=(p2-p1).xyNormalize() * * The tests find a contact between the cutter and an infinite line which contains the * edge we are testing against. Once the contact cc-point is found we check whether this cc-point is * actually in the edge. * * \subsubsection cyledge Cylindrical cutter edge test * In the XY-plane we want to find the intersection between an infinite line and a circle. * This is described e.g. here: see http://mathworld.wolfram.com/Circle-LineIntersection.html * * \subsubsection balledge Spherical cutter edge test * \subsubsection bulledge Toroidal cutter edge test * \subsubsection coneedge Conical cutter edge test * * \subsection optdc Optimizing drop-cutter * \subsubsection kdtree Using a kd-tree for finding triangles under the cutter * * * * \section Z-slice * An algorithm for 'slicing' an STL surface at a defined Z-coordinate. Produces waterline type paths. * These contours can be used as a starting point for area-clearing algorithms in roughing operations. * * * \section cutsim Cutting Simulation * Describe cutting simulation here (octree etc). * * * \section References * \subsection Books * \li O'Rourke, Computational Geometry in C. * \li deBerg, Computational Geometry: Algorithms and Applications * \li Ghali, Introduction to Geometric Computing * * \subsection Papers * \li Chuang2002 http://dx.doi.org/10.1007/PL00003965 "A Reverse Engineering Approach to Generating Interference-Free Tool * Paths in Three-Axis Machining from Scanned Data of Physical Models" * - this paper contains the basics of drop-cutter * \li Hwang1998 http://dx.doi.org/10.1016/S0010-4485(98)00021-9 * - DropCutter for flat, filleted and ball-nose cutters. Edge test with iterative solution. * \li Yau2004 http://dx.doi.org/10.1080/00207540410001671651 * - DropCutter for a general APT-style cutter. This includes cutters with pointed ends and tapered cutters. * - kd-tree for triangle search * \li Chuang2005 http://dx.doi.org/10.1016/j.cad.2004.10.005 * - presents a Push-cutter idea for calculating z-level (waterline) paths. * */