discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Specification of CSG file format?

CA
Carsten Arnholm
Sun, May 17, 2015 10:11 PM

Hi,

The following is an attempt to understand exactly the nature and formal
definition of *.csg files, formulated through a few questions.

Background: In OpenSCAD we have a capability to export a design to a
*.csg file. OpenSCAD can also open such files via File -> Open ... or
via a command line parameter.

My first question is whether *.csg files are specific to OpenSCAD or
whether they represent some kind of universal standardised CSG tree
representation. I have not found a clear answer, but when I inspect the
OpenSCAD-generated *.csg files, it seems to me they are is OpenSCAD
specific. Is this a correct understanding? I know other programs have
made import filters for such files, but then the only "contract" is
OpenSCAD documentation, right?

Second, is it correct to say that the contents of a *.csg file generated
or read by OpenSCAD is a subset of the *.scad language, where only
literal values exist and transformations are expressed as 4x4
homogeneous transformation matrices only ("multmatrix")? If this is
correct, is the subset language used in *.csg files documented anywhere?

Third, there also seems to be an extension "group()" to the *.scad
language. Is it correct to say that "group()" in *.csg is a direct 1:1
unnamed equivalent to a "module" in *.scad? And, is there any difference
at all between "group()" and "union()" in *.csg files? It seems to me
the answer is no, apart from "group()" indicating what used to be a module?

Carsten Arnholm

Hi, The following is an attempt to understand exactly the nature and formal definition of *.csg files, formulated through a few questions. Background: In OpenSCAD we have a capability to export a design to a *.csg file. OpenSCAD can also open such files via File -> Open ... or via a command line parameter. My first question is whether *.csg files are specific to OpenSCAD or whether they represent some kind of universal standardised CSG tree representation. I have not found a clear answer, but when I inspect the OpenSCAD-generated *.csg files, it seems to me they are is OpenSCAD specific. Is this a correct understanding? I know other programs have made import filters for such files, but then the only "contract" is OpenSCAD documentation, right? Second, is it correct to say that the contents of a *.csg file generated or read by OpenSCAD is a subset of the *.scad language, where only literal values exist and transformations are expressed as 4x4 homogeneous transformation matrices *only* ("multmatrix")? If this is correct, is the subset language used in *.csg files documented anywhere? Third, there also seems to be an extension "group()" to the *.scad language. Is it correct to say that "group()" in *.csg is a direct 1:1 unnamed equivalent to a "module" in *.scad? And, is there any difference at all between "group()" and "union()" in *.csg files? It seems to me the answer is no, apart from "group()" indicating what used to be a module? Carsten Arnholm
TP
Torsten Paul
Sun, May 17, 2015 10:28 PM

On 05/18/2015 12:11 AM, Carsten Arnholm wrote:

My first question is whether *.csg files are specific to OpenSCAD

Yes, they are OpenSCAD specific. I don't think there's a clear
documentation for the file content.

Second, is it correct to say that the contents of a *.csg file
generated or read by OpenSCAD is a subset of the *.scad language

Yes, actually the test framework now validates that. There are
some corner cases that do not work though (mainly inf/nan
values).
I think it would make the format even more useful to define
some additional 2D modules so things like text() and the
upcoming trace() could be resolved. Right now the program
reading *.csg would need to render text or trace bitmaps
itself.

Third, there also seems to be an extension "group()" to the
*.scad language. Is it correct to say that "group()" in *.csg
is a direct 1:1 unnamed equivalent to a "module" in *.scad?
And, is there any difference at all between "group()" and
"union()" in *.csg files? It seems to me the answer is no,
apart from "group()" indicating what used to be a module?

I'm not sure about that one, I think currently group() does
behave like union() due to the implicit union happening
automatically. That might change with the removal of implicit
unions (https://github.com/openscad/openscad/issues/350).

ciao,
Torsten.

On 05/18/2015 12:11 AM, Carsten Arnholm wrote: > My first question is whether *.csg files are specific to OpenSCAD > Yes, they are OpenSCAD specific. I don't think there's a clear documentation for the file content. > Second, is it correct to say that the contents of a *.csg file > generated or read by OpenSCAD is a subset of the *.scad language > Yes, actually the test framework now validates that. There are some corner cases that do not work though (mainly inf/nan values). I think it would make the format even more useful to define some additional 2D modules so things like text() and the upcoming trace() could be resolved. Right now the program reading *.csg would need to render text or trace bitmaps itself. > Third, there also seems to be an extension "group()" to the > *.scad language. Is it correct to say that "group()" in *.csg > is a direct 1:1 unnamed equivalent to a "module" in *.scad? > And, is there any difference at all between "group()" and > "union()" in *.csg files? It seems to me the answer is no, > apart from "group()" indicating what used to be a module? > I'm not sure about that one, I think currently group() does behave like union() due to the implicit union happening automatically. That might change with the removal of implicit unions (https://github.com/openscad/openscad/issues/350). ciao, Torsten.
DM
doug moen
Sun, May 17, 2015 10:50 PM

A group is a list of shapes and groups. 'group' is an undocumented,
built-in OpenSCAD module that returns a group.

A module is a function with two argument lists. The inner argument list is
a list of values, while the outer argument list is either a primitive
shape, or a group of shapes. In the case of a user-defined module, the
outer argument list is always converted to a group, this group is what
children() returns.

The result returned by a module is either a shape or a group. Currently,
only built-in modules like 'cube' and 'scale' return shapes; user defined
modules return a group.

The behaviour of user-defined modules may change in the future, especially
if some of the ideas in OpenSCAD2 are implemented. It will be possible for
a user-defined module to return a single shape, instead of a group. Also,
the current behaviour of the builtin module 'for()' is to always return a
group, but Marius and I would like to change that. So the CSG tree might be
flatter in the future, due to fewer intermediate groups being generated.

On 17 May 2015 at 18:11, Carsten Arnholm arnholm@arnholm.org wrote:

Hi,

The following is an attempt to understand exactly the nature and formal
definition of *.csg files, formulated through a few questions.

Background: In OpenSCAD we have a capability to export a design to a *.csg
file. OpenSCAD can also open such files via File -> Open ... or via a
command line parameter.

My first question is whether *.csg files are specific to OpenSCAD or
whether they represent some kind of universal standardised CSG tree
representation. I have not found a clear answer, but when I inspect the
OpenSCAD-generated *.csg files, it seems to me they are is OpenSCAD
specific. Is this a correct understanding? I know other programs have made
import filters for such files, but then the only "contract" is OpenSCAD
documentation, right?

Second, is it correct to say that the contents of a *.csg file generated
or read by OpenSCAD is a subset of the *.scad language, where only literal
values exist and transformations are expressed as 4x4 homogeneous
transformation matrices only ("multmatrix")? If this is correct, is the
subset language used in *.csg files documented anywhere?

Third, there also seems to be an extension "group()" to the *.scad
language. Is it correct to say that "group()" in *.csg is a direct 1:1
unnamed equivalent to a "module" in *.scad? And, is there any difference at
all between "group()" and "union()" in *.csg files? It seems to me the
answer is no, apart from "group()" indicating what used to be a module?

Carsten Arnholm


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

A group is a list of shapes and groups. 'group' is an undocumented, built-in OpenSCAD module that returns a group. A module is a function with two argument lists. The inner argument list is a list of values, while the outer argument list is either a primitive shape, or a group of shapes. In the case of a user-defined module, the outer argument list is always converted to a group, this group is what children() returns. The result returned by a module is either a shape or a group. Currently, only built-in modules like 'cube' and 'scale' return shapes; user defined modules return a group. The behaviour of user-defined modules may change in the future, especially if some of the ideas in OpenSCAD2 are implemented. It will be possible for a user-defined module to return a single shape, instead of a group. Also, the current behaviour of the builtin module 'for()' is to always return a group, but Marius and I would like to change that. So the CSG tree might be flatter in the future, due to fewer intermediate groups being generated. On 17 May 2015 at 18:11, Carsten Arnholm <arnholm@arnholm.org> wrote: > Hi, > > The following is an attempt to understand exactly the nature and formal > definition of *.csg files, formulated through a few questions. > > Background: In OpenSCAD we have a capability to export a design to a *.csg > file. OpenSCAD can also open such files via File -> Open ... or via a > command line parameter. > > My first question is whether *.csg files are specific to OpenSCAD or > whether they represent some kind of universal standardised CSG tree > representation. I have not found a clear answer, but when I inspect the > OpenSCAD-generated *.csg files, it seems to me they are is OpenSCAD > specific. Is this a correct understanding? I know other programs have made > import filters for such files, but then the only "contract" is OpenSCAD > documentation, right? > > Second, is it correct to say that the contents of a *.csg file generated > or read by OpenSCAD is a subset of the *.scad language, where only literal > values exist and transformations are expressed as 4x4 homogeneous > transformation matrices *only* ("multmatrix")? If this is correct, is the > subset language used in *.csg files documented anywhere? > > Third, there also seems to be an extension "group()" to the *.scad > language. Is it correct to say that "group()" in *.csg is a direct 1:1 > unnamed equivalent to a "module" in *.scad? And, is there any difference at > all between "group()" and "union()" in *.csg files? It seems to me the > answer is no, apart from "group()" indicating what used to be a module? > > Carsten Arnholm > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
B
bobc
Sun, May 17, 2015 10:53 PM

I am interested in this too, I am just thinking of writing a parser, so a
grammar would be useful. If there is nothing already, I will try to put one
together.

bob

--
View this message in context: http://forum.openscad.org/Specification-of-CSG-file-format-tp12676p12681.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I am interested in this too, I am just thinking of writing a parser, so a grammar would be useful. If there is nothing already, I will try to put one together. bob -- View this message in context: http://forum.openscad.org/Specification-of-CSG-file-format-tp12676p12681.html Sent from the OpenSCAD mailing list archive at Nabble.com.
MK
Marius Kintel
Mon, May 18, 2015 7:56 AM

On May 17, 2015, at 18:11 PM, Carsten Arnholm arnholm@arnholm.org wrote:

I know other programs have made import filters for such files, but then the only "contract" is OpenSCAD documentation, right?

.csg export was added specifically to support some research being done in the RepRap project on inlining CSG operation with slicing for 3D printing.
Since then, people have started to use it as some sort of interoperability format (e.g. FreeCAD has a .csg parser for importing static OpenSCAD content).
There has been discussions on changing some aspects of .csg output; replacing multmatrix with logical transformations, replacing import() with polygon()/polyhedron(), or even replacing more advanced built-in modules like hull() and minkowski() with their results, making it easier to read or import such files.

-Marius

On May 17, 2015, at 18:11 PM, Carsten Arnholm <arnholm@arnholm.org> wrote: > I know other programs have made import filters for such files, but then the only "contract" is OpenSCAD documentation, right? > .csg export was added specifically to support some research being done in the RepRap project on inlining CSG operation with slicing for 3D printing. Since then, people have started to use it as some sort of interoperability format (e.g. FreeCAD has a .csg parser for importing static OpenSCAD content). There has been discussions on changing some aspects of .csg output; replacing multmatrix with logical transformations, replacing import() with polygon()/polyhedron(), or even replacing more advanced built-in modules like hull() and minkowski() with their results, making it easier to read or import such files. -Marius
A
arnholm@arnholm.org
Mon, May 18, 2015 9:04 AM

On 2015-05-18 09:56, Marius Kintel wrote:

On May 17, 2015, at 18:11 PM, Carsten Arnholm arnholm@arnholm.org
wrote:

I know other programs have made import filters for such files, but
then the only "contract" is OpenSCAD documentation, right?

.csg export was added specifically to support some research being done
in the RepRap project on inlining CSG operation with slicing for 3D
printing.
Since then, people have started to use it as some sort of
interoperability format (e.g. FreeCAD has a .csg parser for importing
static OpenSCAD content).
There has been discussions on changing some aspects of .csg output;
replacing multmatrix with logical transformations, replacing import()
with polygon()/polyhedron(), or even replacing more advanced built-in
modules like hull() and minkowski() with their results, making it
easier to read or import such files.

Thanks for the input!

It matches more or less what I thought. My personal recommendation would
be to keep multmatrix as is, this is by far the most general way of
handling transformations on this level. Similarly, I think it would
definitely make sense to optionally do

  • expand import() with polygon()/polyhedron()
  • expand hull() and minkowski() to basic primitives
  • expand text() to basic 3d primitives

In summary, it would be very useful to optionally expand all high level
objects to their basic primitives when exporting to .csg. For
transformations, the basic primitive is the 4x4 matrix already
implemented as multmatrix, so I would keep that.

With such options, OpenSCAD models could be more easily exchanged with
e.g. FreeCAD. I tested FreeCAD .csg import yesterday and it failed on a
very simple model because I had used hull() in OpenSCAD.

The way I look at this is that OpenSCAD provides a "user interface"
language with some primitives (cube,cylinder etc.) and some high level
features (hull() and minkowski() are 2 examples). The high level
features are very useful "user interface" idioms, but not suitable for
reliable interoperability of model data between applications. To make
interoperability more reliable, it would make sense to (optionally!)
store only basic model primitives on the .csg file together with only
basic transformation primitives (i.e. multimatrix).

You could then change the language in any way you like, plus add more
primitives without compromising data exchange with other applications.
The contract would be the set of primitives only.

Carsten Arnholm

On 2015-05-18 09:56, Marius Kintel wrote: > On May 17, 2015, at 18:11 PM, Carsten Arnholm <arnholm@arnholm.org> > wrote: > >> I know other programs have made import filters for such files, but >> then the only "contract" is OpenSCAD documentation, right? >> > .csg export was added specifically to support some research being done > in the RepRap project on inlining CSG operation with slicing for 3D > printing. > Since then, people have started to use it as some sort of > interoperability format (e.g. FreeCAD has a .csg parser for importing > static OpenSCAD content). > There has been discussions on changing some aspects of .csg output; > replacing multmatrix with logical transformations, replacing import() > with polygon()/polyhedron(), or even replacing more advanced built-in > modules like hull() and minkowski() with their results, making it > easier to read or import such files. Thanks for the input! It matches more or less what I thought. My personal recommendation would be to keep multmatrix as is, this is by far the most general way of handling transformations on this level. Similarly, I think it would definitely make sense to optionally do - expand import() with polygon()/polyhedron() - expand hull() and minkowski() to basic primitives - expand text() to basic 3d primitives In summary, it would be very useful to optionally expand all high level objects to their basic primitives when exporting to .csg. For transformations, the basic primitive is the 4x4 matrix already implemented as multmatrix, so I would keep that. With such options, OpenSCAD models could be more easily exchanged with e.g. FreeCAD. I tested FreeCAD .csg import yesterday and it failed on a very simple model because I had used hull() in OpenSCAD. The way I look at this is that OpenSCAD provides a "user interface" language with some primitives (cube,cylinder etc.) and some high level features (hull() and minkowski() are 2 examples). The high level features are very useful "user interface" idioms, but not suitable for reliable interoperability of model data between applications. To make interoperability more reliable, it would make sense to (optionally!) store *only basic model primitives* on the .csg file together with only basic transformation primitives (i.e. multimatrix). You could then change the language in any way you like, plus add more primitives without compromising data exchange with other applications. The contract would be the set of primitives only. Carsten Arnholm
MK
Marius Kintel
Mon, May 18, 2015 3:51 PM

On May 18, 2015, at 05:04 AM, arnholm@arnholm.org wrote:

With such options, OpenSCAD models could be more easily exchanged with e.g. FreeCAD. I tested FreeCAD .csg import yesterday and it failed on a very simple model because I had used hull() in OpenSCAD.

The challenge is that such a model might not be very useful - you’ve effectively stripped away most of the value OpenSCAD provides, and it might end up being marginally better than STL.
..then comes the challenge that lots of CAD tools don’t even support importing meshes, and would need higher level shapes and their relationships (e.g. STEP).

Anyway, one step at a time. We usually add features where it hurts the most. If you have cool ideas, you can always give implementing it a shot - having examples and someone willing to write code greatly improves the chances of it happening.

-Marius

On May 18, 2015, at 05:04 AM, arnholm@arnholm.org wrote: > > With such options, OpenSCAD models could be more easily exchanged with e.g. FreeCAD. I tested FreeCAD .csg import yesterday and it failed on a very simple model because I had used hull() in OpenSCAD. > The challenge is that such a model might not be very useful - you’ve effectively stripped away most of the value OpenSCAD provides, and it might end up being marginally better than STL. ..then comes the challenge that lots of CAD tools don’t even support importing meshes, and would need higher level shapes and their relationships (e.g. STEP). Anyway, one step at a time. We usually add features where it hurts the most. If you have cool ideas, you can always give implementing it a shot - having examples and someone willing to write code greatly improves the chances of it happening. -Marius
A
arnholm@arnholm.org
Mon, May 18, 2015 5:52 PM

On 2015-05-18 17:51, Marius Kintel wrote:

Anyway, one step at a time. We usually add features where it hurts the
most. If you have cool ideas, you can always give implementing it a
shot - having examples and someone willing to write code greatly
improves the chances of it happening.

I do have some very concrete ideas, even if it is possible that I am
alone thinking they are cool. I hope to realise them over a couple of
months, some time is needed. I will report when there is something
implemented.

Carsten Arnholm

On 2015-05-18 17:51, Marius Kintel wrote: > Anyway, one step at a time. We usually add features where it hurts the > most. If you have cool ideas, you can always give implementing it a > shot - having examples and someone willing to write code greatly > improves the chances of it happening. I do have some very concrete ideas, even if it is possible that I am alone thinking they are cool. I hope to realise them over a couple of months, some time is needed. I will report when there is something implemented. Carsten Arnholm
A
arnholm@arnholm.org
Mon, May 18, 2015 5:54 PM

On 2015-05-18 00:50, doug moen wrote:

'group' is an undocumented,
built-in OpenSCAD module that returns a group.

Okay :-)

On 2015-05-18 00:50, doug moen wrote: > 'group' is an undocumented, > built-in OpenSCAD module that returns a group. Okay :-)
CA
Carsten Arnholm
Mon, May 18, 2015 6:38 PM

On 2015-05-18 17:51, Marius Kintel wrote:

On May 18, 2015, at 05:04 AM, arnholm@arnholm.org wrote:

With such options, OpenSCAD models could be more easily exchanged
with e.g. FreeCAD. I tested FreeCAD .csg import yesterday and it
failed on a very simple model because I had used hull() in OpenSCAD.

The challenge is that such a model might not be very useful

Notice I emphasized such features to be entirely optional.

The current model failed for what I tried, it had to be discarded.
Interoperability is useful, the way I see it. That was for the most part
the motivation behind my suggested improvements.

Carsten Arnholm

On 2015-05-18 17:51, Marius Kintel wrote: > On May 18, 2015, at 05:04 AM, arnholm@arnholm.org wrote: >> >> With such options, OpenSCAD models could be more easily exchanged >> with e.g. FreeCAD. I tested FreeCAD .csg import yesterday and it >> failed on a very simple model because I had used hull() in OpenSCAD. >> > The challenge is that such a model might not be very useful Notice I emphasized such features to be entirely optional. The current model failed for what I tried, it had to be discarded. Interoperability is useful, the way I see it. That was for the most part the motivation behind my suggested improvements. Carsten Arnholm