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
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
iirc, I used cadquery editor version3, the following code and others,
runs in that
import cadquery as cq
d = 50.0 # Diameter of the toroid
t = 10.0 # Thickness of the toroid
dm = d-t
wp = cq.Workplane("XY")
rect = wp.rect(dm*.9999999999999,t)
circle1 = cq.Workplane("XY").move(dm/2).circle(t / 2)
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
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
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.
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
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.
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.