RapCAD printer interface

I have been starting to think about how to integrate the controls for my Reprap Mendel into RapCAD. I was inspired by Kliments pronterface console which as well as being colorful also looks very intuitive and clutter free. So far all I have done is added a simple prototype GUI interface which can be accessed via the print button from the RapCAD main toolbar. This will allow basic integration and testing with the libreprap library.

Ideally of course I also need to finish off the remaining electronics on my Reprap Mendel so that the integration can be tested properly. So in many ways I want the features that I am developing now to motivate me to finish of my Mendel, which after an initial bout of progress has been sitting on the shelf and collecting dust for a year. The reason it has been so long is that I got distracted writing RapCAD. For some reason I thought that I would have enough time to spend on both projects, but as always I am going to have to manage my spare time more carefully.


Version 0.5.0 is available this month. See the Download Page for details.

Advertisements

RapCAD dynamic arrays.

Just a short post this month. I just wanted to give an example of dynamic arrays which are available in RapCAD version 0.4.0. The screenshot shows what I came up with. Not very exciting, but hoping that this will help William Adams to realise some ideas that he has had regarding this. The thing that makes dynamic arrays work is the concatenation operator ~ and the append operator ~=. The operators were influenced by thier counterparts in the d programming language. On another note I have been talking again with Marius who has been looking at the RapCAD back-end code, he seems quite interested in collaborating on a shared back-end library. At this stage he is working to get his visitor branch into OpenSCAD master. When this is done and stable we would like to put some of RapCAD’s features such as this one into OpenSCAD.


Version 0.4.0 is available this month and supports Dynamic Arrays. See the Download Page for details.

RapCAD imports

The syntax for importing modules into rapcad is quite different from the legacy way of doing it. I decided to break compatibility because of a number of problems with the old syntax, that arise when you want to quickly scan for dependencies. Lets first consider a valid example using the old syntax.

module foo(){
  module bar(){
    import_stl(str("file","name",".stl"));
  }
  bar();
}
foo();

The first problem with this is that the filename argument is actually an expression. If you were parsing this script to find its dependencies, the parser would have to be able to partially evaluate the script, turning str("file","name",".stl") into the string literal filename.stl. The second problem is that the import statements are nested in several sub constructs, meaning that the parser has to understand these constructs in order to extract the import module statements. Last of all the legacy way of importing seems to be inconsistent with the way ‘use‘ and ‘include‘ statements work.

My solution was to add an import statement which works as follows

import <triceratops.off> as dino;

dino();

The import statement appears at the top of the file and it doesn’t take an expression, only a string literal. It cannot be nested, and it fits with the use and include statements. The statement is followed by an ‘as‘ clause and the identifier following the ‘as‘ clause provides a name which can be used to instantiate the imported module. The module can be instantiated any number of times, just as you would any other built-in or user defined module. The module instances can of course be nested in any other construct as required, but the import declaration remains at the top of the file, and so one can easily glean which files the script depends on.


Version 0.3.0 is available this month and is capable of importing OFF files. See the Download Page for details.

How RapCAD will do CAM.

The intention of RapCAD is to provide a programmers IDE that will allow the user to not only model their ideas, but also prototype and manufacture those ideas. Initially the focus is to support additive machines like Reprap and Makerbot. However maybe people will want to use it one day for controlling subtractive machines such as CNC routers, or Laser cutters. To support this I wanted to add as much flexibility as I could to the process of converting the description of the model into GCODE instructions that will create the model.

The idea is to use a special type of RapCAD script called an .rcam script that will perform the slicing dicing and generate paths that will be used by the GCODE generation code.

/* Manufacture module called by RapCAD.
* RapCAD will measure the bounds of the
* final model and pass the model to the
* manufacture module. The size of the
* model is made available via the $bounds
* vector. The manufacture module will be
* called for each layer, the output should
* be a 2D path.
*/
module manufacture(){
   echo("Printing object of size: ",$bounds);
   echo("Printing layer: ",$layer," of ",layers());
   infill(0.4) {
     inset(0.4) {
      slice(h=0.4,cut=$layer*0.4) {
       child(0);
      }
     }
   }
}

/* Layers function called by RapCAD.
* RapCAD will call this function to determine
* the number of layers in the model
*/
function layers() = $bounds.z/0.4;

Apart from the file name extention this script is only different from a standard RapCAD script by the definition of a module which must be called manufacture(), and a function which must be called layers(). The idea is that RapCAD will have all the modules needed for turning a primitive into a set of paths. The paths will then be sent to the GCODE generation routines. The most important module needed for turning a primitive into a path is the offset() module. In Fused Filament Fabrication, we have to shrink the shape by half the thickness of the filament, so that when the model is constructed it fills out to the correct size. A more obvious module is the slice() module, which is responsible for turning the three dimensional form into the two dimensional slices that are build up on top of each other during the printing process. In addition to others there will be an infill() module that given a two dimensional offset polygon will turn it into path roads ready for conversion to GCODE.

When RapCAD is asked to generate GCODE for the given design it first compiles and renders the description into a primitive and adds the result to a cache. The bounding box of the primitive is calculated and then the layers() function within the .rcam script is called to determine how many manufacturing cycles will need to be made. Then the manufacture module is called for each cycle, each time passing the full cached primitive and an incremented value accessible via the $layer variable.

RapCAD will come installed with a standard .rcam script designed for a reprap machine, but I hope that by giving people the flexibility to tweak the scripts, new and better ones will be written.

That’s the plan, now I just have to implement it!


As promised there is a new release of RapCAD available. This months release of RapCAD can be installed by following the instructions on the new download page

For those who want to know what has been added please see the release notes

RapCAD preview release

I decided to build a binary release of RapCAD so that people can have a look at how things are coming along without having to compile it. Its very much in a pre-alpha state so don’t expect to be able to just try out your latest greatest design and just expect it to work. Furthermore it can’t currently create any output in the form of an STL file or GCode, so it really is just a release that will let you preview a design. That said there are some nice features that I would like people to try out and see what they think. Language features such as true variables and functions with bodies seem redundant now when other projects such as openscadpy are boasting full python language integration. Having said that RapCAD scripts and OpenSCAD scripts are a DSL which is nice to use and since it has no general purpose language features such as reading or writing files, network access, etc. The scene descriptions are inherently more secure. While the authors of the software RapCAD, OpenSCAD and openscadpy are known and trusted, the authors of scene description scripts uploaded to to Thingiverse may or may not be trusted. By limiting the language features to the domain of scene description this mitigates any risk.

The features that I am developing now could go into openscad eventually, although some of the things that I am doing would require a substantial re-write of the openscad backend, such as dropping openscads 2D subsystem. (It turns out that the entire 2D subsystem can actually be done using 3D shells that have no internal volume, including boolean set operations) For those who want to try out this release instructions for installation on three popular operating systems; Windows, Ubuntu and MacOSX, can be found in the Download Page

I intend to create binary releases about once a month from now on. Next month I hope to have a release with OFF file export (Its supported natively by CGAL so should be easy to implement) and maybe native support for Bezier surfaces since I have been very interested in the work done by WilliamAAdams here is a sneak peak:

The linear_extrude is not quite working the way I would like yet, as currently it evaluates it by creating a volume for each facet and doing a union of all of these volumes. With it taking 2 seconds for each volume union, the total rendering time is a completely unacceptable 39 minutes! I would like it to work by just creating one volume, but I haven’t worked out how to find the perimeter of the Bezier surface yet.

On the other hand creating a convex hull of two Bezier surfaces works at a comparatively much more acceptable speed, about 18 seconds.

RapCAD is Rendering!

Last month I was saying I was going to hook the OpenSCAD back-end into RapCAD. It turned out to be simpler to just implement a backend myself. I started off implementing the GLView widget. I would have had to have done this anyway, since I didn’t want to hook any of OpenSCADs GUI code. I learned a lot doing this, and I think my version has better performance than OpenSCADs version so I will be proposing some performance enhancements to be backported into OpenSCAD at some point, as well as completing a feature request in the TODO list which is to have ruler ticks on the axis. I implemented something similar for RapCAD which is the outline of the 200x200mm printable area, so it should be quite easy. The next thing I put together was a CGALRenderer class, which converts CGAL primitives into openGL. The design is based on the Strategy Pattern rather than OpenSCAD’s messy rendering function pointer callback, I think this is something that could potentially benefit OpenSCAD as well, so I have already started to backport these changes in a cgal-renderer-refactor branch.

Once these two things were implemented everything seemed to come together quite quickly. So recently I have been adding all the bells and whistles and fun features like “ThingDoc” style code comments. Convex Hull for 2D & 3D primitives, and Minkowski that works with mixed 2D and 3D primitives.

Talk with Marius

I have been trying to understand and document the windows build process for OpenSCAD so that Marius and Clifford might soon be able to publish a new release.

While doing this Marius and I got talking. Specifically he wanted to know whether the work I had done for RapCAD on variables would work in the OpenSCAD back end. I told him a bit about the parser I had implemented, and how I thought that a strong concept of Statements within the language syntax would be needed to support this. We agreed that (like many projects) the OpenSCAD language has evolved over time, and its evolution had led the design to a more Declarative syntax rather than a Procedural one.

Marius also asked me whether it makes sense to write my own language or rather use an existing one. I explained that my main motivation for re-writing alot of what already exists in OpenSCAD was

  1. I was finding it fun
  2. I can understand things much easier if its my own work.
  3. Its easier to do research in a new project, than try and modify some existing codebase.

l like to think of RapCAD as my own research experiment, into an ‘Openscad 2.0’ language spec, and other potential re-factorings that might someday be applied. Marius added that in many ways that was what Clifford had done, when he took MetaCAD, and re-wrote it in C over a summer holiday.

Another thing we talked about is the possibility that some day OpenSCAD might drop CGAL as its back end rendering subsystem, and perhaps adopt something like OpenCASCADE. It makes sense to try and integrate RapCAD’s scripting engine with the OpenSCAD rendering engine in much the same way as efforts like pySCAD have done.

One idea that Marius presented to me was that of a low level API that projects like pySCAD and RapCAD could use. The API might be text based vastly simplified to a description/modeling language that only supports the basic primitives such as polyhedrons, which all other shapes can be defined in terms of, as well as csg operation nodes, and transformations which can all be defined in terms of multmatrix.

In summary I am focusing my efforts on connecting up my existing code to just the rendering functions of OpenSCAD, and modifying OpenSCAD so that it has a generic API for projects like pySCAD, SolidPython and CloudSCAD can use as well.