You can find the home page of the project here:
The source code can be accessed using svn:
svn checkout https://camvox.svn.sourceforge.net/svnroot/camvox/trunk camvox
I recently bought a Proxxon MF-70 CNC, with 4-axis. But I was pretty shocked at the lack of an open source CAM project for those kinds of machines.
So I decided to create a open source (GPL3) project myself, called "camvox". I am awaiting approval from sourceforge to host the project over there, otherwise I will host it at my own website.
The flow of the software is as follows:
- Describe the work-piece, material and tools using constructive solid geometry.
- Then convert the work-piece and material to high resolution voxel space.
- Remove material slice by slice without colliding the tool through the work-piece or too much material. Continue until there is no material left.
- Write the tool-path (g-code) made by the tool to disk.
The code is written in C++ for both speed and memory usage (voxel spaces tend to be memory hungry). It will be accessible through python, so one can build the CSG trees, make tool movements and write the g-code in an easier to use language.
The maximum voxel space will contain 2 billion oct tree nodes and use 68 GB of memory. If you will need all nodes of the octtree you can only go 10 deep or 1024 x 1024 x 1024 pixels. My mill can cut material of around 25 cm in length, so that is a minimum of 0.24 mm accuracy. In reality one would not use all the nodes of an octtree and the depth/accuracy should be much higher.
Right now the code can render a unit sphere at the origin into voxel space. It can also write a POV-RAY scene consisting of a bunch of oct-tree boxes.
Luckily the algorithm for rendering CSG into voxels is really simple and you can simply use characteristic functions of objects for inside-outside checking (x^2 + y^2 + z^2 + 1 is a characteristic function for a unit sphere).
So it is really easy to extend the number of primitives, or even use mathematical formulas to describe a surface. It is also possible to make a bag-of-triangles CSG object (for compatibility with CAD programs that create STL files) as long as the resulting object is a solid.
I am currently making the code ready for publishing and creating the python interface and optimising the voxel space memory usage.
I hope I will be able to get some feedback and help from everyone here.
I've been playing with a design for a 5-axis mill. There are a number of questions in my mind, but one of the main ones is SW. I've looked at this forum topic several times and it always seems like these projects get started then die befor they are productive. I'd love to see you be more sucessful.
1) What is your 4th axis? My interest is in having two rotation axis that are orthogonal to the mill centerline. A added rotary table would be a 6th axis.
2) I think you are describing voxels that are volumes whose edge planes are parallel to the xy, xz and yz planes. If that is the case how do you plan to smooth a surface that is 45 degrees asque from those planes?
3) Where do you expect to find the expertise needed to utilize normal CAD output files? I've thought about trying to apply the gridding functions are used in finite element structure analysis, but I've never see good algorithms described pubically for that process.
4) Working in C++ seems like a good idea but effective C++ design requires very creative work in defining the classes. Are you really going with a true OO design or just writing C code for the C++ compiler? I understand the difference and have written in both coding styles. (Its easy if you started coding before FORTAN had numbers after it, but that perspective also makes me think that it would be very hard to really use OO programming in a group project.)
4) What compiler are you going to use, and are you thinking about a Windows, CGYWIN, Linux or UNIX environment?
I have not looked at you code yet but will do that tomorrow. Tonight I'm ready to crash, not do a code review. I'm not sure I have the time available to write code, but maybe after I see what you have I'll get hooked.
My 4th axis is the a-axis, i.e. rotating around the x-axis. However I am trying to design the software to do continues multi-axis milling, with as many axis and in any orientation.1) What is your 4th axis? My interest is in having two rotation axis that are orthogonal to the mill centerline. A added rotary table would be a 6th axis.
In my many years of software development I found that the more generic solutions are actually simpler to implement and faster to execute (cpu time).
You are correct about the orientation shape of the voxels. I see two solutions two this problem:2) I think you are describing voxels that are volumes whose edge planes are parallel to the xy, xz and yz planes. If that is the case how do you plan to smooth a surface that is 45 degrees asque from those planes?
1) There are well known algorithms to find the normal of a voxel (by looking at its neighbours), this is normally used showing the voxels on the screen and make it look smooth instead of blocky.
2) Use the voxels for roughing and collision detection, for finishing one could follow the actual CSG model, and leave a trace of where you where in the voxel space so you know what parts you have done. I can put a pointer of the CSG subtree in the edge voxels, which makes this computational feasible.
I think working with normal CAD files would not be hard, STL output (if that is what we are talking about) is just a set of triangles describing a solid space. I only need a mathematical formula that tells me if a point is on the inside/outside/edge of the object. I would be rather surprised if there is not a paper somewhere that describes this formula.3) Where do you expect to find the expertise needed to utilize normal CAD output files? I've thought about trying to apply the gridding functions are used in finite element structure analysis, but I've never see good algorithms described pubically for that process.
I have designed a true OO design, but I am trying to keep it simple. The only place I have used inheritance is on the CSG tree because it is natural. Templates I have only used for the Vector, Matrix and Interval classes, because I needed both double and Interval Vectors.4) Working in C++ seems like a good idea but effective C++ design requires very creative work in defining the classes. Are you really going with a true OO design or just writing C code for the C++ compiler? I understand the difference and have written in both coding styles. (Its easy if you started coding before FORTAN had numbers after it, but that perspective also makes me think that it would be very hard to really use OO programming in a group project.)
I am developing on OS X, but i am keeping the code portable so it will also run on Linux. I use the autoconf/automake tools to keep everything building on all platforms. From what I understand this should also be able to run on a CYGWIN system and with the microsoft C compiler. But I never tried much programming on windows.4) What compiler are you going to use, and are you thinking about a Windows, CGYWIN, Linux or UNIX environment?
Right now it needs Python and swig to compile everything. I got rid of the boost libraries last night when I found that I couldn't do scalar multiplication with their Interval object in some cases, maybe I was using it wrong.
I hope you get hooked, there is quite a bit of work to be done yet. As for the code review, maybe I should document my files a bit better, but right now there are a lot of changes that are made.I have not looked at you code yet but will do that tomorrow. Tonight I'm ready to crash, not do a code review. I'm not sure I have the time available to write code, but maybe after I see what you have I'll get hooked.
I have been working on it quite a bit this weekend, I am pretty far along with the CSG objects, the following is now implemented:
- infinite cylinder
- infinite plane
This set will allow you to create many shapes, including a box from 6 planes, or a capped cylinder with an infinite cylinder and two planes.
I also implemented translation, scale and rotation methods on each object in the tree.
You can see the result with povray using the test.sh script in the examples directory. povray will show the scene made up of voxels, it is not yet very pretty we probably need a better voxel visualizer.
I've working toward getting an actual CSG model that can conceivably be milled on my machine and this is the result.
It is made from cylinders and planes, made into more complex shapes like boxes and capped cylinders. The new voxelization engine is quite fast, for most voxels it is only testing a single shape, such as a plane which is really quick test.
I've also started working on documenting the source code using doxygen, so that it will be easier for other people to contribute.
My next step is to also define the material to be cut, the shapes of the tools and clamps and then make an roughing algorithm that starts cutting.
I finally figured out a bit on how to do the roughing stage, and I am implementing this right now.
Basically I will do a search for low resolution voxels (1/4th the diameter of the tool) that are:
- made of the material layer to be cut.
- is not made of any other layer.
- and that has at least one side exposed to air.
These voxels would be the skin of the material to be cut and can be accessed by the tool without cutting to deep. The side that is exposed also gives is a normal, i.e. angle in which the tool may be held.
Next task would be to find alternate angles to hold the tool at to eliminate collisions for each voxel, if the original angle doesn't work. Eliminate all the voxels that could not be cut at any angle.
Last thing is to sort the voxels so that a toolpath going through all those voxels will be as short/fast as possible.
Now generate the toolpath and remove voxels from the voxel space based on the size of the tool. In this step we will also see how much volume of material will be cut and adjust the speed accordingly.
Now start the process over with the voxels that still exist. Like peeling an union.
This strategy may not be good enough for high speed machining, but I have only a low speed mill.
This looks like an interesting project.
Being public, people like me have the opportunity to comment, so of course I have some comments. (which I hope will be a good thing )
Have you looked at the other open-source CAD/CAM offerings? I don't have all the URLs, but here are a few names off the top of my head: QCad, KiCad, and GCam. I think they all do things a little differently, and your method is also different from all of those.
One question I have is why convert to voxels? You start with mathematically correct geometry (e.g. "sphere of radius 1.0"), then introduce error by converting to voxels. Once you have the not-quite-correct voxels, you approximate the toolpath based on whether the selected tool is "too big" compared to the geometry and the resolution at which it has been sampled. If you would keep the representation of the volume as CSG, and only "render" it at the needed resolution (set by the user as depth of each pass, stepover, scallop depth, etc.), then you would always have the best path possible. A straight diagonal move would be easily exported as a single G1 move, rather than stepping along the staircased result of "voxelization".
Leaving the representation as geometric entities makes the file size small, and makes it possible to redefine the operations later. This could provide the ability to have a "feature tree" - the program records the operations the user does, and can rebuild the solid if the user changes something (the size of an object, for example).
A possible memory optimization (though this would take a speed hit) would be to only voxelize in slices. That way, you only use memory in O(n^2) rather than O(N^3). If the voxel libraries only allow volumes with the same length in all dimensions, this would of course not work. It would likely extend run time since the same operations would be done more than once, but it would allow finer resolution for a similar memory footprint.
Of course, you're writing the code (so far ), and there's no definite reason why things should be done "my way" either, but I thought I'd throw out the idea (without reading the source, incidentally).
Thanks for reading
Thank you for your post. I have first looked at other offerings before I started on this project, as for your list.
- qcad is a 2D cad program, there is a closed source CAM for it. There is not much information about the CAM, but I expect it to be 2.5D for 3-axis machines.
- kicad is a electronic and printed circuit board design, pretty cool, but I don't think it works for creating 3D objects.
- gcam is a 2.5D cam for 3-axis, it looks pretty cool, but it seems it can only do simple pocketing and surfacing, not simply work with random geometry. So this is the reason I wanted to make something from scratch.
I am rendering into voxel space because it sees to me an easy way of tracking what has been cut already, and quickly determine collisions between complex 3D objects.
So during roughing I use the voxel space to peel the union of the material, until I am close to the surface of the final object. During roughing I can still use smooth paths; to increase speed. The smooth paths are just less precise, because they are based on voxels.
Then during finishing, I use the skin voxels of the final object to figure out what parts have been finished, but use the CSG object for the exact position and normal of the surface. Each skin voxel also points to the sub tree of CSG objects that are needed to be test, as a speed up. This process is almost identical to the roughing phase, except it uses the higher precision of the CSG object.
You can set the resolution of each CSG object, before you render it into voxel space, to lower the memory usage. Very useful for the tool-path which doesn't need extremely high resolution.
The voxel space is made as an oct-tree which saves memory considerably and also speeds up intersection/collision testing as well.
There is at least one thing that I keep breaking my head on. The tool length after switching tools. It seems that EMC2 can not handle those with inverse kinematics. To be honest I now not much about g-code, is it possible to generate code that has coordinates in part space and rotations to specify the angle of attack?
If g-code is machine specific, then we need an other processing step to generate g-code in machine co ordinates.
I am not so far as to say it is stable, in fact I can not say it is actually producing a toolpath yet.
But when I do, I'll add it to your page.
A new step, here is my model that consists of different parts.
- White is the skin around the object that will need to be finished.
- Underneath the white is a blue object, which you can't see of course.
- The yellow is material that needs to be cut after finishing, so that the object get loose from the clamp.
- The red are the clamps, onto which the material is mounted and may not be worked on by the tool.
Around this will be material that needs to be roughed, it will be green, but then you wouldn't see the other parts.