discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

About Automatically Translating OpenSCAD Scripting Code into CadQuery Scripting Code (Python Code)

RW
Raymond West
Sat, Feb 8, 2025 6:50 PM

thanks, I'll see if it is better as an stl than before. I expect it is...

On 08/02/2025 15:24, 张友宝 via Discuss wrote:

Dear Raymond,

Here is my translation:

###########CadQuery code begin###############

from cadquery.func import *
from cadquery.vis import show
import math

part1 = cylinder(2 * 50, 10)
part2 = sphere(500).moved(Location(0, 0, 255))
result_part = part1 - part2

result_part.exportStep("result_part.step")

show(result_part)

###########CadQuery code end#################

The following is the CadQuery code output.

The original OpenSCAD code is here:

/OpenSCAD code begin*******/

$fn=200;
difference(){
cylinder(h=10,d=100);
translate([0,0,255])
sphere(d=500);
}

/OpenSCAD code end*******/

Best regards,

Youbao

 -----Original Messages-----
 *From:*"Raymond West via Discuss" <discuss@lists.openscad.org>
 *Sent Time:*2025-02-08 22:17:53 (Saturday)
 *To:* "张友宝 via Discuss" <discuss@lists.openscad.org>
 *Cc:* "Raymond West" <raywest@raywest.com>
 *Subject:* [OpenSCAD] Re: About Automatically Translating OpenSCAD
 Scripting Code into CadQuery Scripting Code (Python Code)

 In the few experiments I made with cadquery, some months ago, I
 had a problem with some of the results that boolean operations
 gave, due to the fact, afaik, that  in openscad code is converted
 to triangle meshes, whereas in cadquery it is a mathematical
 surface, which can have discontinuities. (A sphere is represented
 on screen as a circle with a curved line).

 I'm not sure that a simple translation will be enough, since if I
 differenced a sphere from a cylinder, say, in openscad I saw a
 good representation, but in cadquery, depending on the rotation of
 the sphere I did not.

 I can't find my test cadquery code, but here is an openscad script
 that may show the problem, if you want to translate that...

 $fn=200;
 difference(){
     cylinder(h=10,d=100);
     translate([0,0,255])
       sphere(d=500);
 }

 Iirc that the equivalent in cadquery required the sphere to be
 rotated such that its 'line' was not in the cylinder.

 I also could not find an active forum, although there were a few
 posters on reddit.


 On 08/02/2025 09:47, 张友宝 via Discuss wrote:
 Hi developers,


 With the arrival of free functions in
 CadQuery(https://github.com/CadQuery/cadquery), I believe it's
 the perfect time to bridge the OpenSCAD and CadQuery communities.


 I've tried manually translating a simple OpenSCAD script into
 CadQuery, and it is quite straightforward. To benefit both
 communities, I'm thinking about automatically translating
 OpenSCAD scripts into CadQuery scripts.

 To perform the translation, we need to parse the OpenSCAD script.
 Since the OpenSCAD source code already handles parsing, we can
 utilize the parsed AST for our translation.

 To expedite and professionalize the process, I am seeking
 opinions and suggestions.

 OpenSCAD Scripting Code:
 /***********The OpenSCAD code begin******************/
 module Flange_01() {
     difference() {
         cylinder(10, 100, 100, $fn = 30);
         r = 80;
         for (i = [0:90:359]) {
             translate([r * cos(i), r * sin(i), -1])
             cylinder(12, 10, 10, $fn = 30);
             translate([0, 0, -1])
             cylinder(12, 50, 50, $fn = 50);
         }
     }
 }
 Flange_01();
 /***********The OpenSCAD code end********************/

 Manually Translated CadQuery Scripting Code:
 ###########The CadQuery code begin###########
 from cadquery.func import *
 from cadquery.vis import show
 import math


 r1 = 100
 part1 = cylinder(2 * r1, 10)


 r2 = 80
 theta_values = [0, math.pi / 2, math.pi, 3 * math.pi / 2]
 for theta in theta_values:
     part2 = cylinder(2 * 10, 12).moved(x = r2 * math.cos(theta),
 y = r2 * math.sin(theta))
     part1 -= part2


 part2 = cylinder(2 * 50, 12).moved(x = 0, y = 0)
 part1 -= part2


 show(part1)

 ###########The CadQuery code end#############


 Best regards,

 Youbao


 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email todiscuss-leave@lists.openscad.org 

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

thanks, I'll see if it is better as an stl than before. I expect it is... On 08/02/2025 15:24, 张友宝 via Discuss wrote: > > Dear Raymond, > > > Here is my translation: > > ###########CadQuery code begin############### > > from cadquery.func import * > from cadquery.vis import show > import math > > part1 = cylinder(2 * 50, 10) > part2 = sphere(500).moved(Location(0, 0, 255)) > result_part = part1 - part2 > > result_part.exportStep("result_part.step") > > show(result_part) > > ###########CadQuery code end################# > > The following is the CadQuery code output. > > > The original OpenSCAD code is here: > > /**************OpenSCAD code begin*********************/ > > $fn=200; > difference(){ > cylinder(h=10,d=100); > translate([0,0,255]) > sphere(d=500); > } > > /**************OpenSCAD code end*********************/ > > > Best regards, > > Youbao > > > -----Original Messages----- > *From:*"Raymond West via Discuss" <discuss@lists.openscad.org> > *Sent Time:*2025-02-08 22:17:53 (Saturday) > *To:* "张友宝 via Discuss" <discuss@lists.openscad.org> > *Cc:* "Raymond West" <raywest@raywest.com> > *Subject:* [OpenSCAD] Re: About Automatically Translating OpenSCAD > Scripting Code into CadQuery Scripting Code (Python Code) > > In the few experiments I made with cadquery, some months ago, I > had a problem with some of the results that boolean operations > gave, due to the fact, afaik, that  in openscad code is converted > to triangle meshes, whereas in cadquery it is a mathematical > surface, which can have discontinuities. (A sphere is represented > on screen as a circle with a curved line). > > I'm not sure that a simple translation will be enough, since if I > differenced a sphere from a cylinder, say, in openscad I saw a > good representation, but in cadquery, depending on the rotation of > the sphere I did not. > > I can't find my test cadquery code, but here is an openscad script > that may show the problem, if you want to translate that... > > $fn=200; > difference(){ >     cylinder(h=10,d=100); >     translate([0,0,255]) >       sphere(d=500); > } > > Iirc that the equivalent in cadquery required the sphere to be > rotated such that its 'line' was not in the cylinder. > > I also could not find an active forum, although there were a few > posters on reddit. > > > On 08/02/2025 09:47, 张友宝 via Discuss wrote: >> >> Hi developers, >> >> >> With the arrival of free functions in >> CadQuery(https://github.com/CadQuery/cadquery), I believe it's >> the perfect time to bridge the OpenSCAD and CadQuery communities. >> >> >> I've tried manually translating a simple OpenSCAD script into >> CadQuery, and it is quite straightforward. To benefit both >> communities, I'm thinking about automatically translating >> OpenSCAD scripts into CadQuery scripts. >> >> To perform the translation, we need to parse the OpenSCAD script. >> Since the OpenSCAD source code already handles parsing, we can >> utilize the parsed AST for our translation. >> >> To expedite and professionalize the process, I am seeking >> opinions and suggestions. >> >> OpenSCAD Scripting Code: >> /***********The OpenSCAD code begin******************/ >> module Flange_01() { >>     difference() { >>         cylinder(10, 100, 100, $fn = 30); >>         r = 80; >>         for (i = [0:90:359]) { >>             translate([r * cos(i), r * sin(i), -1]) >>             cylinder(12, 10, 10, $fn = 30); >>             translate([0, 0, -1]) >>             cylinder(12, 50, 50, $fn = 50); >>         } >>     } >> } >> Flange_01(); >> /***********The OpenSCAD code end********************/ >> >> Manually Translated CadQuery Scripting Code: >> ###########The CadQuery code begin########### >> from cadquery.func import * >> from cadquery.vis import show >> import math >> >> >> r1 = 100 >> part1 = cylinder(2 * r1, 10) >> >> >> r2 = 80 >> theta_values = [0, math.pi / 2, math.pi, 3 * math.pi / 2] >> for theta in theta_values: >>     part2 = cylinder(2 * 10, 12).moved(x = r2 * math.cos(theta), >> y = r2 * math.sin(theta)) >>     part1 -= part2 >> >> >> part2 = cylinder(2 * 50, 12).moved(x = 0, y = 0) >> part1 -= part2 >> >> >> show(part1) >> >> ###########The CadQuery code end############# >> >> >> Best regards, >> >> Youbao >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
RW
Raymond West
Sat, Feb 8, 2025 7:28 PM

Hi Jon,

I wanted to use cadquery since it could do things like filleting,. etc
(but not as selective as in freecad). But from ChatGPT, a good summary
is below

Feature            OpenSCAD                       CadQuery
Mutability       Immutable                       Mutable
Variables         Single assignment           Reassignable
Modelling        CSG (Boolean ops)          Feature-based
Execution        Lazy evaluation               Procedural execution
Geometry       Mesh-based                     B-Rep (solid modelling)
Scripting          OpenSCAD language      Python
Extensibility    Limited                             Full Python ecosystem

You may find Python to be more easy to code than openscad script, but I
hit a problem with the geometry rendering,  and there was little help
that I could find. However, I like the limited language of openscad
script, (and dislike the structure of python, the spacing requirements
etc. - but bear in mind I started programming when punched cards were
the thing, when there were no wheels to reinvent). An important fact is
that the folk who look after openscad ensure it maintains backwards
compatibility.

(A friend of my son was working on some Cobol code. He found out that
his mother had written it, about 35 years ago. That is not what
'inheritance' means)

On 08/02/2025 15:44, Jon Bondy via Discuss wrote:

What is the big deal about CadQuery?  What does it offer that OpenSCAD
lacks?

Jon

Hi Jon, I wanted to use cadquery since it could do things like filleting,. etc (but not as selective as in freecad). But from ChatGPT, a good summary is below Feature            OpenSCAD                       CadQuery Mutability       Immutable                       Mutable Variables         Single assignment           Reassignable Modelling        CSG (Boolean ops)          Feature-based Execution        Lazy evaluation               Procedural execution Geometry       Mesh-based                     B-Rep (solid modelling) Scripting          OpenSCAD language      Python Extensibility    Limited                             Full Python ecosystem You may find Python to be more easy to code than openscad script, but I hit a problem with the geometry rendering,  and there was little help that I could find. However, I like the limited language of openscad script, (and dislike the structure of python, the spacing requirements etc. - but bear in mind I started programming when punched cards were the thing, when there were no wheels to reinvent). An important fact is that the folk who look after openscad ensure it maintains backwards compatibility. (A friend of my son was working on some Cobol code. He found out that his mother had written it, about 35 years ago. That is not what 'inheritance' means) On 08/02/2025 15:44, Jon Bondy via Discuss wrote: > What is the big deal about CadQuery?  What does it offer that OpenSCAD > lacks? > > Jon > >
RW
Raymond West
Sat, Feb 8, 2025 7:57 PM

iirc, I used cadquery editor version3,  the following code and others,
runs in that

import cadquery as cq

Parameters

d = 50.0  # Diameter of the toroid
t = 10.0  # Thickness of the toroid

dm = d-t

Create a workplane

wp = cq.Workplane("XY")

Define the profile with rounded ends

rect = wp.rect(dm*.9999999999999,t)

Semi-circles at both ends

circle1 = cq.Workplane("XY").move(dm/2).circle(t / 2)

Combine the shapes into a single profile

path = cq.Workplane("XZ").circle(dm / 2).val()

s1=circle1.sweep(path)
s2=rect.sweep(path)
shape=s1.union(s2)
show_object(shape)

cq.exporters.export(shape,'donut.stl',  exportType='STL')

###################end

Can't remember if i wrote it, or found it.

However, your example does not run for me. it gives an error in cadquery

      module not found - from cadquery.func import *

This is one of the snags I find with Python in general, if you want to
do something you have to install a number of modules.

On 08/02/2025 15:24, 张友宝 via Discuss wrote:

Dear Raymond,

Here is my translation:

###########CadQuery code begin###############

from cadquery.func import *
from cadquery.vis import show
import math

part1 = cylinder(2 * 50, 10)
part2 = sphere(500).moved(Location(0, 0, 255))
result_part = part1 - part2

result_part.exportStep("result_part.step")

show(result_part)

###########CadQuery code end#################

The following is the CadQuery code output.

The original OpenSCAD code is here:

/OpenSCAD code begin*******/

$fn=200;
difference(){
cylinder(h=10,d=100);
translate([0,0,255])
sphere(d=500);
}

/OpenSCAD code end*******/

Best regards,

Youbao

 -----Original Messages-----
 *From:*"Raymond West via Discuss" <discuss@lists.openscad.org>
 *Sent Time:*2025-02-08 22:17:53 (Saturday)
 *To:* "张友宝 via Discuss" <discuss@lists.openscad.org>
 *Cc:* "Raymond West" <raywest@raywest.com>
 *Subject:* [OpenSCAD] Re: About Automatically Translating OpenSCAD
 Scripting Code into CadQuery Scripting Code (Python Code)

 In the few experiments I made with cadquery, some months ago, I
 had a problem with some of the results that boolean operations
 gave, due to the fact, afaik, that  in openscad code is converted
 to triangle meshes, whereas in cadquery it is a mathematical
 surface, which can have discontinuities. (A sphere is represented
 on screen as a circle with a curved line).

 I'm not sure that a simple translation will be enough, since if I
 differenced a sphere from a cylinder, say, in openscad I saw a
 good representation, but in cadquery, depending on the rotation of
 the sphere I did not.

 I can't find my test cadquery code, but here is an openscad script
 that may show the problem, if you want to translate that...

 $fn=200;
 difference(){
     cylinder(h=10,d=100);
     translate([0,0,255])
       sphere(d=500);
 }

 Iirc that the equivalent in cadquery required the sphere to be
 rotated such that its 'line' was not in the cylinder.

 I also could not find an active forum, although there were a few
 posters on reddit.


 On 08/02/2025 09:47, 张友宝 via Discuss wrote:
 Hi developers,


 With the arrival of free functions in
 CadQuery(https://github.com/CadQuery/cadquery), I believe it's
 the perfect time to bridge the OpenSCAD and CadQuery communities.


 I've tried manually translating a simple OpenSCAD script into
 CadQuery, and it is quite straightforward. To benefit both
 communities, I'm thinking about automatically translating
 OpenSCAD scripts into CadQuery scripts.

 To perform the translation, we need to parse the OpenSCAD script.
 Since the OpenSCAD source code already handles parsing, we can
 utilize the parsed AST for our translation.

 To expedite and professionalize the process, I am seeking
 opinions and suggestions.

 OpenSCAD Scripting Code:
 /***********The OpenSCAD code begin******************/
 module Flange_01() {
     difference() {
         cylinder(10, 100, 100, $fn = 30);
         r = 80;
         for (i = [0:90:359]) {
             translate([r * cos(i), r * sin(i), -1])
             cylinder(12, 10, 10, $fn = 30);
             translate([0, 0, -1])
             cylinder(12, 50, 50, $fn = 50);
         }
     }
 }
 Flange_01();
 /***********The OpenSCAD code end********************/

 Manually Translated CadQuery Scripting Code:
 ###########The CadQuery code begin###########
 from cadquery.func import *
 from cadquery.vis import show
 import math


 r1 = 100
 part1 = cylinder(2 * r1, 10)


 r2 = 80
 theta_values = [0, math.pi / 2, math.pi, 3 * math.pi / 2]
 for theta in theta_values:
     part2 = cylinder(2 * 10, 12).moved(x = r2 * math.cos(theta),
 y = r2 * math.sin(theta))
     part1 -= part2


 part2 = cylinder(2 * 50, 12).moved(x = 0, y = 0)
 part1 -= part2


 show(part1)

 ###########The CadQuery code end#############


 Best regards,

 Youbao


 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email todiscuss-leave@lists.openscad.org 

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

iirc, I used cadquery editor version3,  the following code and others, runs in that import cadquery as cq # Parameters d = 50.0  # Diameter of the toroid t = 10.0  # Thickness of the toroid dm = d-t # Create a workplane wp = cq.Workplane("XY") # Define the profile with rounded ends rect = wp.rect(dm*.9999999999999,t) # Semi-circles at both ends circle1 = cq.Workplane("XY").move(dm/2).circle(t / 2) # Combine the shapes into a single profile path = cq.Workplane("XZ").circle(dm / 2).val() s1=circle1.sweep(path) s2=rect.sweep(path) shape=s1.union(s2) show_object(shape) cq.exporters.export(shape,'donut.stl',  exportType='STL') ###################end Can't remember if i wrote it, or found it. However, your example does not run for me. it gives an error in cadquery       module not found - from cadquery.func import * This is one of the snags I find with Python in general, if you want to do something you have to install a number of modules. On 08/02/2025 15:24, 张友宝 via Discuss wrote: > > Dear Raymond, > > > Here is my translation: > > ###########CadQuery code begin############### > > from cadquery.func import * > from cadquery.vis import show > import math > > part1 = cylinder(2 * 50, 10) > part2 = sphere(500).moved(Location(0, 0, 255)) > result_part = part1 - part2 > > result_part.exportStep("result_part.step") > > show(result_part) > > ###########CadQuery code end################# > > The following is the CadQuery code output. > > > The original OpenSCAD code is here: > > /**************OpenSCAD code begin*********************/ > > $fn=200; > difference(){ > cylinder(h=10,d=100); > translate([0,0,255]) > sphere(d=500); > } > > /**************OpenSCAD code end*********************/ > > > Best regards, > > Youbao > > > -----Original Messages----- > *From:*"Raymond West via Discuss" <discuss@lists.openscad.org> > *Sent Time:*2025-02-08 22:17:53 (Saturday) > *To:* "张友宝 via Discuss" <discuss@lists.openscad.org> > *Cc:* "Raymond West" <raywest@raywest.com> > *Subject:* [OpenSCAD] Re: About Automatically Translating OpenSCAD > Scripting Code into CadQuery Scripting Code (Python Code) > > In the few experiments I made with cadquery, some months ago, I > had a problem with some of the results that boolean operations > gave, due to the fact, afaik, that  in openscad code is converted > to triangle meshes, whereas in cadquery it is a mathematical > surface, which can have discontinuities. (A sphere is represented > on screen as a circle with a curved line). > > I'm not sure that a simple translation will be enough, since if I > differenced a sphere from a cylinder, say, in openscad I saw a > good representation, but in cadquery, depending on the rotation of > the sphere I did not. > > I can't find my test cadquery code, but here is an openscad script > that may show the problem, if you want to translate that... > > $fn=200; > difference(){ >     cylinder(h=10,d=100); >     translate([0,0,255]) >       sphere(d=500); > } > > Iirc that the equivalent in cadquery required the sphere to be > rotated such that its 'line' was not in the cylinder. > > I also could not find an active forum, although there were a few > posters on reddit. > > > On 08/02/2025 09:47, 张友宝 via Discuss wrote: >> >> Hi developers, >> >> >> With the arrival of free functions in >> CadQuery(https://github.com/CadQuery/cadquery), I believe it's >> the perfect time to bridge the OpenSCAD and CadQuery communities. >> >> >> I've tried manually translating a simple OpenSCAD script into >> CadQuery, and it is quite straightforward. To benefit both >> communities, I'm thinking about automatically translating >> OpenSCAD scripts into CadQuery scripts. >> >> To perform the translation, we need to parse the OpenSCAD script. >> Since the OpenSCAD source code already handles parsing, we can >> utilize the parsed AST for our translation. >> >> To expedite and professionalize the process, I am seeking >> opinions and suggestions. >> >> OpenSCAD Scripting Code: >> /***********The OpenSCAD code begin******************/ >> module Flange_01() { >>     difference() { >>         cylinder(10, 100, 100, $fn = 30); >>         r = 80; >>         for (i = [0:90:359]) { >>             translate([r * cos(i), r * sin(i), -1]) >>             cylinder(12, 10, 10, $fn = 30); >>             translate([0, 0, -1]) >>             cylinder(12, 50, 50, $fn = 50); >>         } >>     } >> } >> Flange_01(); >> /***********The OpenSCAD code end********************/ >> >> Manually Translated CadQuery Scripting Code: >> ###########The CadQuery code begin########### >> from cadquery.func import * >> from cadquery.vis import show >> import math >> >> >> r1 = 100 >> part1 = cylinder(2 * r1, 10) >> >> >> r2 = 80 >> theta_values = [0, math.pi / 2, math.pi, 3 * math.pi / 2] >> for theta in theta_values: >>     part2 = cylinder(2 * 10, 12).moved(x = r2 * math.cos(theta), >> y = r2 * math.sin(theta)) >>     part1 -= part2 >> >> >> part2 = cylinder(2 * 50, 12).moved(x = 0, y = 0) >> part1 -= part2 >> >> >> show(part1) >> >> ###########The CadQuery code end############# >> >> >> Best regards, >> >> Youbao >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
JB
Jon Bondy
Sat, Feb 8, 2025 8:36 PM

I do not know python and have no need to learn it.  I, too, grew up with
punched cards, Fortran, etc.  Then Modula, then Pascal.  I avoided Cobol.

The OpenSCAD language is ... peculiar.  But with BOSL2, I can do almost
anything I want/need, except for organic or sculptural shapes.  And the
community here is simply spectacular.

No urgent pressure on my part to jump ship.

Jon

On 2/8/2025 2:28 PM, Raymond West via Discuss wrote:

Hi Jon,

I wanted to use cadquery since it could do things like filleting,. etc
(but not as selective as in freecad). But from ChatGPT, a good summary
is below

Feature            OpenSCAD                       CadQuery
Mutability       Immutable                       Mutable
Variables         Single assignment           Reassignable
Modelling        CSG (Boolean ops)          Feature-based
Execution        Lazy evaluation               Procedural execution
Geometry       Mesh-based                     B-Rep (solid modelling)
Scripting          OpenSCAD language      Python
Extensibility    Limited                             Full Python
ecosystem

You may find Python to be more easy to code than openscad script, but
I hit a problem with the geometry rendering,  and there was little
help that I could find. However, I like the limited language of
openscad script, (and dislike the structure of python, the spacing
requirements etc. - but bear in mind I started programming when
punched cards were the thing, when there were no wheels to reinvent).
An important fact is that the folk who look after openscad ensure it
maintains backwards compatibility.

(A friend of my son was working on some Cobol code. He found out that
his mother had written it, about 35 years ago. That is not what
'inheritance' means)

On 08/02/2025 15:44, Jon Bondy via Discuss wrote:

What is the big deal about CadQuery?  What does it offer that
OpenSCAD lacks?

Jon


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

--
This email has been checked for viruses by AVG antivirus software.
www.avg.com

I do not know python and have no need to learn it.  I, too, grew up with punched cards, Fortran, etc.  Then Modula, then Pascal.  I avoided Cobol. The OpenSCAD language is ... peculiar.  But with BOSL2, I can do almost anything I want/need, except for organic or sculptural shapes.  And the community here is simply spectacular. No urgent pressure on my part to jump ship. Jon On 2/8/2025 2:28 PM, Raymond West via Discuss wrote: > Hi Jon, > > I wanted to use cadquery since it could do things like filleting,. etc > (but not as selective as in freecad). But from ChatGPT, a good summary > is below > > Feature            OpenSCAD                       CadQuery > Mutability       Immutable                       Mutable > Variables         Single assignment           Reassignable > Modelling        CSG (Boolean ops)          Feature-based > Execution        Lazy evaluation               Procedural execution > Geometry       Mesh-based                     B-Rep (solid modelling) > Scripting          OpenSCAD language      Python > Extensibility    Limited                             Full Python > ecosystem > > You may find Python to be more easy to code than openscad script, but > I hit a problem with the geometry rendering,  and there was little > help that I could find. However, I like the limited language of > openscad script, (and dislike the structure of python, the spacing > requirements etc. - but bear in mind I started programming when > punched cards were the thing, when there were no wheels to reinvent). > An important fact is that the folk who look after openscad ensure it > maintains backwards compatibility. > > (A friend of my son was working on some Cobol code. He found out that > his mother had written it, about 35 years ago. That is not what > 'inheritance' means) > > > On 08/02/2025 15:44, Jon Bondy via Discuss wrote: >> What is the big deal about CadQuery?  What does it offer that >> OpenSCAD lacks? >> >> Jon >> >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org -- This email has been checked for viruses by AVG antivirus software. www.avg.com
JB
Jordan Brown
Sun, Feb 9, 2025 2:19 AM

Continuing the conversation from the GitHub issue… lexer.l and parser.y will get you the syntax, but not the semantics.

As a trivial example, you mention cylinder(10,100,100).  What do those numbers mean? That information is in primitives.cc, in built in_cylinder().  But how many sides will the cylinder have? That’s in src/utils/calc.cc, in Calc:: get_fragments_from_r(). And which way do the vertexes point? That’s back in primitives.cc, in generate_circle().

OK, so you have to have an adequate library.  But surely the language is easy enough, right?

Consider the following.  What will it print?

a = “a1”;
$b = “b1”;
module foo() echo(a=a, $b=$b);
if (true) {
a = “a2”;
$b = “b2”;
foo();
}

Prints
a=“a1”, $b=“b2”
“a” is lexically scoped, scoped based on the textual structure of the program.  “$b”, on the other hand, is dynamically scoped, scoped by the call structure.

Or:

i = 1;
if (true) {
echo(i);
i = i + 1;
}
echo(i);

First, it will print a 2.  In a particular scope, OpenSCAD will execute all assignments and then all module invocations, and echo() is a module invocation. Then it will print a 1, because the “if” creates a new scope. In that scope the original “i” is visible until the 2 is assigned to a new “i”. At the end of the scope that new “i” disappears, revealing the original “i”.  Some of those semantics are in parser.y, in the actions, while other parts are not.

And there’s a lot more where those came from.

Do real OpenSCAD programs do this sort of thing? Depend on the orientation of a cylinder’s vertexes? Sure. Do tricks with $ variables? More than you can believe.  Do strange things with scoping and execution order? Mostly no.  But sometimes?

Implementing the lexical analysis and the parser, or extracting the AST from OpenSCAD somehow, plus obvious implementations of primitives, will get you a modest fraction of OpenSCAD programs.  Driving that fraction up will take a lot more.

—-

Marius suggests working from a CSG export. That will indeed get you past most of the semantics, since it avoids annoying stuff like variables, expressions, conditionals, modules, and so on.  However, it will lose all semantic information about how the model is constructed.

for(i = [1:10]) translate([i*10,0,0]) cube(i);

will generate ten cubes with particular size and position relationships to one another. The CSG export will have those ten cubes and their positions, of course, but will have nothing about why they are at those sizes and positions - just the positions and sizes.  Want spheres instead of cubes? A one-word change to the OpenSCAD; a ten-word change to the CSG. Want them spaced 20 apart instead of 10? Trivial in the original, less so in the CSG.

If all you want is an export of the resulting model, CSG is good.  (Give or take stuff about vertex orientation.) But if you want a program with the same inputs, algorithms, and outputs, it’s not helpful.

There are OpenSCAD models where the two are nearly the same, but my guess is very few, and rarely if ever complex ones.

Continuing the conversation from the GitHub issue… lexer.l and parser.y will get you the syntax, but not the semantics. As a trivial example, you mention cylinder(10,100,100). What do those numbers mean? That information is in primitives.cc, in built in_cylinder(). But how many sides will the cylinder have? That’s in src/utils/calc.cc, in Calc:: get_fragments_from_r(). And which way do the vertexes point? That’s back in primitives.cc, in generate_circle(). OK, so you have to have an adequate library. But surely the language is easy enough, right? Consider the following. What will it print? a = “a1”; $b = “b1”; module foo() echo(a=a, $b=$b); if (true) { a = “a2”; $b = “b2”; foo(); } Prints a=“a1”, $b=“b2” “a” is lexically scoped, scoped based on the textual structure of the program. “$b”, on the other hand, is dynamically scoped, scoped by the call structure. Or: i = 1; if (true) { echo(i); i = i + 1; } echo(i); First, it will print a 2. In a particular scope, OpenSCAD will execute all assignments and then all module invocations, and echo() is a module invocation. Then it will print a 1, because the “if” creates a new scope. In that scope the original “i” is visible until the 2 is assigned to a *new* “i”. At the end of the scope that new “i” disappears, revealing the original “i”. Some of those semantics are in parser.y, in the actions, while other parts are not. And there’s a lot more where those came from. Do real OpenSCAD programs do this sort of thing? Depend on the orientation of a cylinder’s vertexes? Sure. Do tricks with $ variables? More than you can believe. Do strange things with scoping and execution order? Mostly no. But sometimes? Implementing the lexical analysis and the parser, or extracting the AST from OpenSCAD somehow, plus obvious implementations of primitives, will get you a modest fraction of OpenSCAD programs. Driving that fraction up will take a *lot* more. —- Marius suggests working from a CSG export. That will indeed get you past most of the semantics, since it avoids annoying stuff like variables, expressions, conditionals, modules, and so on. However, it will lose all semantic information about how the model is constructed. for(i = [1:10]) translate([i*10,0,0]) cube(i); will generate ten cubes with particular size and position relationships to one another. The CSG export will have those ten cubes and their positions, of course, but will have nothing about *why* they are at those sizes and positions - just the positions and sizes. Want spheres instead of cubes? A one-word change to the OpenSCAD; a ten-word change to the CSG. Want them spaced 20 apart instead of 10? Trivial in the original, less so in the CSG. If all you want is an export of the resulting model, CSG is good. (Give or take stuff about vertex orientation.) But if you want a *program* with the same inputs, algorithms, and outputs, it’s not helpful. There are OpenSCAD models where the two are nearly the same, but my guess is very few, and rarely if ever complex ones.
Z
zhangyoubao@siom.ac.cn
Sun, Feb 9, 2025 12:26 PM

Dear Jordan,

Thank you very much for your comprehensive response.

Overall, the task of converting OpenSCAD scripts to CadQuery scripts seems quite formidable. However, considering the countless engineers who have successfully converted various languages to JavaScript or wasm, it appears that those were non-trivial tasks as well. I believe we can manually explore this further to understand the complexities involved, and then determine the best approach.

I have quoted the most relevant content below.
> Implementing the lexical analysis and the parser, or extracting the AST from OpenSCAD somehow, plus obvious implementations of primitives, > will get you a modest fraction of OpenSCAD programs.  Driving that fraction up will take a lot more.
> If all you want is an export of the resulting model, CSG is good.  (Give or take stuff about vertex orientation.) But if you want a >program with the same inputs, algorithms, and outputs, it’s not helpful.

Best regards,
Youbao

> -----Original Messages-----
> From: "Jordan Brown via Discuss" discuss@lists.openscad.org
> Sent Time: 2025-02-09 10:19:15 (Sunday)
> To: discuss@lists.openscad.org
> Cc: 张友宝 zhangyoubao@siom.ac.cn, discuss@lists.openscad.org, "Jordan Brown" openscad@jordan.maileater.net
> Subject: [OpenSCAD] Re: About Automatically Translating OpenSCAD Scripting Code into CadQuery Scripting Code (Python Code)
>
> Continuing the conversation from the GitHub issue… lexer.l and parser.y will get you the syntax, but not the semantics.
>
> As a trivial example, you mention cylinder(10,100,100).  What do those numbers mean? That information is in primitives.cc, in built in_cylinder().  But how many sides will the cylinder have? That’s in src/utils/calc.cc, in Calc:: get_fragments_from_r(). And which way do the vertexes point? That’s back in primitives.cc, in generate_circle().
>
> OK, so you have to have an adequate library.  But surely the language is easy enough, right?
>
> Consider the following.  What will it print?
>
> a = “a1”;
> $b = “b1”;
> module foo() echo(a=a, $b=$b);
> if (true) {
>    a = “a2”;
>    $b = “b2”;
>    foo();
> }
>
> Prints
>    a=“a1”, $b=“b2”
> “a” is lexically scoped, scoped based on the textual structure of the program.  “$b”, on the other hand, is dynamically scoped, scoped by the call structure.
>
> Or:
>
> i = 1;
> if (true) {
>    echo(i);
>    i = i + 1;
> }
> echo(i);
>
> First, it will print a 2.  In a particular scope, OpenSCAD will execute all assignments and then all module invocations, and echo() is a module invocation. Then it will print a 1, because the “if” creates a new scope. In that scope the original “i” is visible until the 2 is assigned to a new “i”. At the end of the scope that new “i” disappears, revealing the original “i”.  Some of those semantics are in parser.y, in the actions, while other parts are not.
>
> And there’s a lot more where those came from.
>
> Do real OpenSCAD programs do this sort of thing? Depend on the orientation of a cylinder’s vertexes? Sure. Do tricks with $ variables? More than you can believe.  Do strange things with scoping and execution order? Mostly no.  But sometimes?
>
> Implementing the lexical analysis and the parser, or extracting the AST from OpenSCAD somehow, plus obvious implementations of primitives, will get you a modest fraction of OpenSCAD programs.  Driving that fraction up will take a lot more.
>
> —-
>
> Marius suggests working from a CSG export. That will indeed get you past most of the semantics, since it avoids annoying stuff like variables, expressions, conditionals, modules, and so on.  However, it will lose all semantic information about how the model is constructed.
>
> for(i = [1:10]) translate([i*10,0,0]) cube(i);
>
> will generate ten cubes with particular size and position relationships to one another. The CSG export will have those ten cubes and their positions, of course, but will have nothing about why they are at those sizes and positions - just the positions and sizes.  Want spheres instead of cubes? A one-word change to the OpenSCAD; a ten-word change to the CSG. Want them spaced 20 apart instead of 10? Trivial in the original, less so in the CSG.
>
> If all you want is an export of the resulting model, CSG is good.  (Give or take stuff about vertex orientation.) But if you want a program with the same inputs, algorithms, and outputs, it’s not helpful.
>
> There are OpenSCAD models where the two are nearly the same, but my guess is very few, and rarely if ever complex ones.
>
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
/openscad@jordan.maileater.net/zhangyoubao@siom.ac.cn/discuss@lists.openscad.org

Dear Jordan, Thank you very much for your comprehensive response. Overall, the task of converting OpenSCAD scripts to CadQuery scripts seems quite formidable. However, considering the countless engineers who have successfully converted various languages to JavaScript or wasm, it appears that those were non-trivial tasks as well. I believe we can manually explore this further to understand the complexities involved, and then determine the best approach. I have quoted the most relevant content below. &gt; Implementing the lexical analysis and the parser, or extracting the AST from OpenSCAD somehow, plus obvious implementations of primitives, &gt; will get you a modest fraction of OpenSCAD programs. Driving that fraction up will take a *lot* more. &gt; If all you want is an export of the resulting model, CSG is good. (Give or take stuff about vertex orientation.) But if you want a &gt;*program* with the same inputs, algorithms, and outputs, it’s not helpful. Best regards, Youbao &gt; -----Original Messages----- &gt; From: "Jordan Brown via Discuss" <discuss@lists.openscad.org> &gt; Sent Time: 2025-02-09 10:19:15 (Sunday) &gt; To: discuss@lists.openscad.org &gt; Cc: 张友宝 <zhangyoubao@siom.ac.cn>, discuss@lists.openscad.org, "Jordan Brown" <openscad@jordan.maileater.net> &gt; Subject: [OpenSCAD] Re: About Automatically Translating OpenSCAD Scripting Code into CadQuery Scripting Code (Python Code) &gt; &gt; Continuing the conversation from the GitHub issue… lexer.l and parser.y will get you the syntax, but not the semantics. &gt; &gt; As a trivial example, you mention cylinder(10,100,100). What do those numbers mean? That information is in primitives.cc, in built in_cylinder(). But how many sides will the cylinder have? That’s in src/utils/calc.cc, in Calc:: get_fragments_from_r(). And which way do the vertexes point? That’s back in primitives.cc, in generate_circle(). &gt; &gt; OK, so you have to have an adequate library. But surely the language is easy enough, right? &gt; &gt; Consider the following. What will it print? &gt; &gt; a = “a1”; &gt; $b = “b1”; &gt; module foo() echo(a=a, $b=$b); &gt; if (true) { &gt; a = “a2”; &gt; $b = “b2”; &gt; foo(); &gt; } &gt; &gt; Prints &gt; a=“a1”, $b=“b2” &gt; “a” is lexically scoped, scoped based on the textual structure of the program. “$b”, on the other hand, is dynamically scoped, scoped by the call structure. &gt; &gt; Or: &gt; &gt; i = 1; &gt; if (true) { &gt; echo(i); &gt; i = i + 1; &gt; } &gt; echo(i); &gt; &gt; First, it will print a 2. In a particular scope, OpenSCAD will execute all assignments and then all module invocations, and echo() is a module invocation. Then it will print a 1, because the “if” creates a new scope. In that scope the original “i” is visible until the 2 is assigned to a *new* “i”. At the end of the scope that new “i” disappears, revealing the original “i”. Some of those semantics are in parser.y, in the actions, while other parts are not. &gt; &gt; And there’s a lot more where those came from. &gt; &gt; Do real OpenSCAD programs do this sort of thing? Depend on the orientation of a cylinder’s vertexes? Sure. Do tricks with $ variables? More than you can believe. Do strange things with scoping and execution order? Mostly no. But sometimes? &gt; &gt; Implementing the lexical analysis and the parser, or extracting the AST from OpenSCAD somehow, plus obvious implementations of primitives, will get you a modest fraction of OpenSCAD programs. Driving that fraction up will take a *lot* more. &gt; &gt; —- &gt; &gt; Marius suggests working from a CSG export. That will indeed get you past most of the semantics, since it avoids annoying stuff like variables, expressions, conditionals, modules, and so on. However, it will lose all semantic information about how the model is constructed. &gt; &gt; for(i = [1:10]) translate([i*10,0,0]) cube(i); &gt; &gt; will generate ten cubes with particular size and position relationships to one another. The CSG export will have those ten cubes and their positions, of course, but will have nothing about *why* they are at those sizes and positions - just the positions and sizes. Want spheres instead of cubes? A one-word change to the OpenSCAD; a ten-word change to the CSG. Want them spaced 20 apart instead of 10? Trivial in the original, less so in the CSG. &gt; &gt; If all you want is an export of the resulting model, CSG is good. (Give or take stuff about vertex orientation.) But if you want a *program* with the same inputs, algorithms, and outputs, it’s not helpful. &gt; &gt; There are OpenSCAD models where the two are nearly the same, but my guess is very few, and rarely if ever complex ones. &gt; &gt; &gt; _______________________________________________ &gt; OpenSCAD mailing list &gt; To unsubscribe send an email to discuss-leave@lists.openscad.org </openscad@jordan.maileater.net></zhangyoubao@siom.ac.cn></discuss@lists.openscad.org>
RW
Raymond West
Sun, Feb 9, 2025 1:50 PM

Hi Jon,

On 08/02/2025 20:36, Jon Bondy wrote:

The OpenSCAD language is ... peculiar.  But with BOSL2, I can do
almost anything I want/need, except for organic or sculptural shapes. 
And the community here is simply spectacular.

I agree with that, except I can create many organic shapes without using
BOS2L (often with extensive help from members on here). For most organic
objects, then you usually need some randomness, and bezier curves can be
useful. Hull and Minkowski are also often useful. It sometimes helps to
use shapes as outlines,* to sketch out the locations of the solid
shapes, and export an svg, and import it back in as a list of points.
(Not knowing much about the internals of openscad, I think it would  be
simple enough to have a 'shape to point' conversion built in, since it
already does that to export an svg, but it would probably break the
module/function paradigm.).

The problem with sculpting, is that difference of a tool shape works
fine, except it is tedious calculating the rotation and translation of
said tool, since openscad is not that interactive, and does not accept
input other than keyboard to create coordinates.

*e.g.

module line(p1,p2,w){
    hull(){
      translate(p1)circle(w/2);
      translate(p2)circle(w/2);
    }
}

module circlel(d,w){
     difference(){
        circle((d+w)/2);
        circle((d-w)/2);
   }
}

circlel(20,1);
line([0,5],[40,0],1) ;

similar for 3d and cube, etc.

Hi Jon, On 08/02/2025 20:36, Jon Bondy wrote: > The OpenSCAD language is ... peculiar.  But with BOSL2, I can do > almost anything I want/need, except for organic or sculptural shapes.  > And the community here is simply spectacular. I agree with that, except I can create many organic shapes without using BOS2L (often with extensive help from members on here). For most organic objects, then you usually need some randomness, and bezier curves can be useful. Hull and Minkowski are also often useful. It sometimes helps to use shapes as outlines,* to sketch out the locations of the solid shapes, and export an svg, and import it back in as a list of points. (Not knowing much about the internals of openscad, I think it would  be simple enough to have a 'shape to point' conversion built in, since it already does that to export an svg, but it would probably break the module/function paradigm.). The problem with sculpting, is that difference of a tool shape works fine, except it is tedious calculating the rotation and translation of said tool, since openscad is not that interactive, and does not accept input other than keyboard to create coordinates. *e.g. module line(p1,p2,w){     hull(){       translate(p1)circle(w/2);       translate(p2)circle(w/2);     } } module circlel(d,w){      difference(){         circle((d+w)/2);         circle((d-w)/2);    } } circlel(20,1); line([0,5],[40,0],1) ; similar for 3d and cube, etc.
JB
Jordan Brown
Sun, Feb 9, 2025 6:30 PM

Overall, the task of converting OpenSCAD scripts to CadQuery scripts seems quite formidable. However, considering the countless engineers who have successfully converted various languages to JavaScript or wasm, it appears that those were non-trivial tasks as well. I believe we can manually explore this further to understand the complexities involved, and then determine the best approach.

I’m sure it’s possible.  I just wanted you to understand that getting the AST is only the first step, and probably the easiest step.

> Overall, the task of converting OpenSCAD scripts to CadQuery scripts seems quite formidable. However, considering the countless engineers who have successfully converted various languages to JavaScript or wasm, it appears that those were non-trivial tasks as well. I believe we can manually explore this further to understand the complexities involved, and then determine the best approach. I’m sure it’s possible. I just wanted you to understand that getting the AST is only the first step, and probably the easiest step.