I haven’t done a lot with RapCAD recently, and its time for my monthly post. What I thought I would write about is my reaction to posts on the OpenSCAD mailing list regarding turning it into a Python language library. First and foremost I think the idea is a great way to provide extensibility.

As Tony Buser says:

Access to such features would be potentially very powerful to do unforeseen things… then there’s string processing – that could be very handy with parametric scripts (look at what I had to do to handle strings in my bitmap text module) Filesystem access would be really nice for loading external data. Interesting things could be done in terms of dynamic objects if the script could call webservices…

For the power user these sorts of things are great. However I wonder if the desire to have Python support is driven by the lack of some features in OpenSCAD, such as:

  • True variables.
  • Functions with bodies.
  • Working scope blocks.
  • Statements allowed inside For and If
  • Determine how many elements are in an array or characters in a string.
  • Get the nth character of a string, and get it’s ASCII code.
  • Vector operations.

(Credit to Leemon Baird who suggested some of these)

My reaction is that we can have both a domain specific language, which is nice for the end user, and a set of language bindings to allow the power user to do advanced things, with their general purpose language of choice. I am currently trying to work out how this could be done in RapCAD, and making the RapCAD scripting language itself just one of the bindings.

With respect to the RapCAD scripting language itself, I also want to add support for the features as described above. RapCAD is not just a GUI thing. I have actually been writing an improved grammar, which I turned into a bison parser. I have also applied some Design Patterns such as Builder and Visitor to my code which may allow easier integration with external languages. Finally as mentioned before I have implemented True Variables, Functions with bodies, and some support for Vector operations.

On the face of it RapCAD just looks like a GUI front end to OpenSCAD, but that’s not actually what it is please feel free to look at the code and post any comments.

I have implemented syntax highlighting in RapCAD using the same lexical analysis engine as the script parser and evaluator uses.

I wanted to do this for two reasons, firstly flex is comparatively faster than the example QT SyntaxHighlighter implementation which uses QRegExp’s. This is partly because the lexer is built at compile time, where as QRegExp’s are compiled at runtime. The second reason for using flex as the backend to the highlighter was to ensure that there are no ambiguities between the syntax highlighter and the language definition.

I have also started to look at how to make the scripts output 3D shapes using CGAL. Its certainly not a trivial task, but I am starting to understand things.

RapCAD has now got to the point where scripts can be evaluated at a text level. What I mean by this is that modules functions statements and expressions can be evaluated and the results of those evaluations can be output to stdout using the echo module. There is no 3D output yet, so most of this is pretty trivial, but it has been fun for me to learn how to write code in C++. I still need to improve usage of ‘const correctness’ and consider using references instead of pointers, but on the whole I am happy with what I have managed so far. It might be of interest to mention at this stage that I have implemented “Variables that will” and Functions with function bodies are coming along. is implemented.

In the meantime as I have discovered how to do things by implementing them in RapCAD, I have been able to supply similar fixes to OpenSCAD, the most notable being support for nested includes.

After completing implementation of the RapCAD parser I decided to give it a thorough test against as many files as possible. I created a script that scoured thingiverse and created a list of thingiverse scad asset urls.

I then ran the RapCAD parser against all of the downloaded scad scripts to see how it fared. The test includes 515 scad scripts, of these 380 seem to parse without problems, and 135 throw up syntax errors.
I have been investigating these errors. I found that 60 of the errors are accounted for by the fact that I am not supporting implicit includes (a deprecated feature in OpenSCAD). The remaining 75 are caused by the fact that I have created a more strict grammar for RapCAD. Hopefully this will mean my RapCAD parser is a more robust and less ambiguous. I will attempt to justify all of the syntax “improvements” and suggest changes that the OpenSCAD developers can consider.

Here is a list of those syntax errors:
Read on »

For the purpose of understanding tools like Bison and Flex, I have been building a parser for RapCAD despite the fact that it will probably one day use a library version of OpenSCAD as the back end. My reasons for doing this are two fold, firstly I have never writtern a parser in Bison or a Lexer in Flex before, I have only writtern a trivial Recursive Decent Parser using .NET and Its something I have wanted to try for a while. Secondly I am interested to see how to implement such things as “variables that will”, and functions with function bodies, so that I might sometime provide a patch for OpenSCAD so that it can also do these things.

Things are moving steadily along, and I am now able to parse a simple test file containing the following:

module foo(a,b=1+2,c=1-2,d=1/2,e=1%2,f=1<2,g=1>2,h=1*2)
{
}

The parser then reads the text and turns it into an abstract syntax tree representation, which is stored in various objects. The objects all have a toString() method which when called produces following text dump:

Module: foo
Parameters: Param: a Param: b Expression: (Literal: 1 Operator: + Literal: 2 ) Param: c Expression: (Literal: 1 Operator: - Literal: 2 ) Param: d Expression: (Literal: 1 Operator: / Literal: 2 ) Param: e Expression: (Literal: 1 Operator: % Literal: 2 ) Param: f Expression: (Literal: 1 Operator: < Literal: 2 ) Param: g Expression: (Literal: 1 Operator: > Literal: 2 ) Param: h Expression: (Literal: 1 Operator: * Literal: 2 )
Done.

So, I am thinking about the parsing of functions now, and its got me wondering about function bodies. There is a problem which I am not sure the best way to resolve. I would like to allow a function to have a function body consisting of statements. It would be meaningless however to have a module instance inside a function body, but for the current grammar to work a module instance is a type of statement. I have two options, either re-write my grammar to make a module instance inside a function body as a syntax error, or the other option which would simply be to make the syntax acceptable, but when it comes to evaluate it it will be a compile error.

All this talk of RapCAD hasn’t gone un-noticed by the OpenSCAD maintainer(s). Recently on the OpenSCAD mailing list Marius Kintel has stepped forward and stated that he is now the core maintainer of OpenSCAD. He has also outlined his goals which are similar in essence to my own. Opening up development and try to build a better developer community, as well as hosting better forums/mailing lists bugtrackers and source code management. Based on this and other feedback, I have decided to change my approach somewhat. It doesn’t make all that much sense to duplicate the work of a project that is being actively developed and Marius has agreed that an OpenSCAD evaluation library could benefit multiple projects currently under development. So I will be offering any contributions I can that help OpenSCAD take this direction, and focus on developing RapCAD as a front-end thin wrapper application around this library.

Another motivation for writing RapCAD is to provide a complimentary back end tool for CloudsCAD. As I understand, a number of features have been requested by Tony Buser and the CloudsCAD community and which the OpenSCAD community has been unable to address. I am hoping to build a stronger community by setting up rapcad.org and hosting state of the art bugtracking and source code management tools.

RapCAD is a new script based CAD IDE especially for RepRap printers. It will be a written from scratch based mostly on OpenSCAD and hopefully scad scripts will just work inside RapCAD. Ultimately however I would like to add new features to the script language, so that RapCAD files will be a superset of scad files. The IDE will contain project management tools, to allow more than one script to be grouped into a project. Another planned feature is a fully syntax hi-lighted script editor, as well as a 3D visualisation window reminiscent of OpenSCAD. The IDE will also contain gcode visualisation and generation tools as can be found in the esteemed Repsnapper. I am hoping to reap the benefits of combining these two applications into one and allow them to share code, for example slice and dice might be performed using CGAL. But more generally my motivation for doing this is because I would like a one stop app that can be both the design tool, and printing tool without having to go through the intermediary step of having to convert to and from STL. Support for importing from existing STL files will still be available facilitated by an import_stl() function in the script or by some other means.

Registered the domain rapcad.org