Today's OpenSCAD color processing does face coloring. It is perfectly
possible to have the six faces of a cube have six different colors, and
if you union two shapes of different colors there's nothing known about
the color of the overlap area.
That scheme is fine, more or less, for visualization, but it doesn't
work well for actual 3D printing where you need to know what color (or
material) the interior of a shape is to be.
What you need is volumetric color, so that there are no overlapping
shapes and you always know what color the interior of a shape is.
I mentioned this need as part of a discussion of color semantics, and
one of the responses was that we didn't know how to do volumetric
color. I'd done an OpenSCAD demonstration of volumetric color and was
pretty sure that it was straightforward to come up with appropriate
processing, so I said I'd recreate that proof-of-concept for discussion.
And here it is.
Note: this is not the most efficient possible implementation. It
re-evaluates the model many times, when it really only needs to be
evaluated once. There should probably be a few more render()s scattered
around to try to get subtrees to be cached. But it looks like it works.
Implementations of hull(), minkowski(), et cetera, and of the 2D
operations, left as an exercise for the reader.
Here's the result of this particular model, both in assembled form and
exploded by color:
// Volumetric color proof of concept
// Jordan Brown, openscad@jordan.maileater.net
// There are four relevant modules in this POC:
// col - replacement for color()
// uni - replacement for union()
// dif - replacement for difference()
// int - replacement for intersection()
// In this POC, the list of possible colors needs to be known in advance;
// in a built-in implementation it would either be collected during the
// evaluation phase or managed entirely dynamically. It would be
// straightforward to build a version of this POC that would be
// driven by an external script that would first run it in a
// "list colors" mode and would then run it once for each color.
// Similarly, in this POC the model is encapsulated in a module main(),
// while in a built-in implementation the final "step through the colors"
// loop would be implied and the model could be at the top level.
// This POC steps through the colors, generating the parts for one color,
// then the next, then the next. A built-in implementation could do
// that, or could do roughly the same operations across all colors at once.
// The model. A couple of unions, a difference, and an intersection
// to do a cutaway so that you can see the internal colors.
module main() {
int() {
uni() {
col("green") rotate([90,0,0]) cylinder(h=30, d=5, center=true);
dif() {
uni() {
col("red") cube(10);
col("blue") sphere(10);
}
cylinder(h=30, d=5, center=true);
}
}
rotate(-45) translate([0,-20,-20]) cube([40,40,40]);
}
}
// And now the infrastructure...
// Set the color of the children, like color().
// In this POC, this really operates by skipping anything that
// isn't the desired color, and then coloring during the per-color
// pass at the end, but there are other variations.
module col(c) {
union() { // work around #6456.
// $color=undef means that we want all colors - in particular,
// for the second-and-later children of dif() and int().
if (is_undef($color) || c == $color) {
children();
}
}
}
// Union the children.
// What this does is to draw the first child, then draw the second child
// less the first child, then the third less the first and second, and
// so on. Note that the negative components have $color=undef so that
// the entire subassembly, of all colors, gets subtracted out.
module uni() {
for (i=[0:1:$children-1]) {
// Add this child, less the children before it. Note that
// because of col() processing this might be only part
// of the logical subtree, but that's OK; what's important
// is that we mask it all colors of the previous children.
difference() {
children(i);
children([0:1:i-1], $color=undef);
}
}
}
// Difference the children.
// The only novel thing that this does is to set $color=undef
// for the second-and-later children, so that all colors are
// subtracted away from the first child. Again, because of
// col() processing the first child might only be a fraction of
// the logical subtree; it'll all get reassembled in the final
// multiple passes.
module dif() {
difference() {
children(0);
children([1:$children-1], $color=undef);
}
}
// Intersect the children.
// Think of this as taking the first child, and subtracting
// parts of it that are not in common with the later children.
// That neatly answers the question of what color the result
// should be, and makes everything consistent: the first child's
// color wins.
module int() {
intersection_for(i=[0:1:$children-1]) {
if (i == 0) {
children(i);
} else {
$color = undef;
children(i);
}
}
}
// As noted above, this list of colors needs to be
// known in advance; in a built-in implementation (or even
// in a script-driven userspace implementation) this list
// would be dynamically derived.
colors = [ "red", "green", "blue" ];
// Build the model.
for (c = colors) {
$color=c;
color(c) render() main();
}
// Build an exploded set so that you can see
// what the individual colored parts look like.
for (i = [ 0:len(colors)-1 ]) {
c = colors[i];
$color=c;
translate([20+i*20,0,0]) color(c) render() main();
}
On 12/23/25 20:03, Jordan Brown via Discuss wrote:
Today's OpenSCAD color processing does face coloring. It is perfectly
possible to have the six faces of a cube have six different colors, and
if you union two shapes of different colors there's nothing known about
the color of the overlap area.
That scheme is fine, more or less, for visualization, but it doesn't
work well for actual 3D printing where you need to know what color (or
material) the interior of a shape is to be.
What you need is volumetric color, so that there are no overlapping
shapes and you always know what color the interior of a shape is.
I mentioned this need as part of a discussion of color semantics, and
one of the responses was that we didn't know how to do volumetric
color. I'd done an OpenSCAD demonstration of volumetric color and was
pretty sure that it was straightforward to come up with appropriate
processing, so I said I'd recreate that proof-of-concept for discussion.
And here it is.
Note: this is not the most efficient possible implementation. It
re-evaluates the model many times, when it really only needs to be
evaluated once. There should probably be a few more render()s scattered
around to try to get subtrees to be cached. But it looks like it works.
Very impressive, and raising the priority of building a 3d printer
capable of doing that,
Currently my dream thoughts have leaned more toward switching src spools
of the
same color to make a printer capable of switching src spools to continue
the print
when the current spool runs out. To that continuous end, or for
multicolor, we'ed need to
establish a protocol we could setup in the slicer, to select which
method we have in
mind. Selectable by telling the slicer in the g-code pramble, what we
want the printer
to do. As the src of the code that winds driving the printer, it
behooves us to develop
the method, and attempt to set the industrues std way of doing this.
Otherwise we are left with everybody going off in their own direction,
diluting the
transition because every kit we might buy to build a printer, ideally
capable of
doing either according to the job at hand, and no ones product is compatible
with any other vendors hardware. That is the road block preventing me from
buying a box turtle, or any other solution. And because of this, not
one is offering
a complete, bolt it on, load it with spools of plastic and Just Run
solution.
So please, develop a std and break a few arms getting it accepted on an
industry
wide basis because it in the end, the inter-compatibility makes sense.
Now 91 yo & running out of time, its beyond my pay grade, but the
present situation
makes no sense at all. It is a huge road block to progress.
Thank you and Merry Christmas everybody.
Implementations of hull(), minkowski(), et cetera, and of the 2D
operations, left as an exercise for the reader.
Here's the result of this particular model, both in assembled form and
exploded by color:
// Volumetric color proof of concept
// Jordan Brown, openscad@jordan.maileater.net
// There are four relevant modules in this POC:
// col - replacement for color()
// uni - replacement for union()
// dif - replacement for difference()
// int - replacement for intersection()
// In this POC, the list of possible colors needs to be known in advance;
// in a built-in implementation it would either be collected during the
// evaluation phase or managed entirely dynamically. It would be
// straightforward to build a version of this POC that would be
// driven by an external script that would first run it in a
// "list colors" mode and would then run it once for each color.
// Similarly, in this POC the model is encapsulated in a module main(),
// while in a built-in implementation the final "step through the colors"
// loop would be implied and the model could be at the top level.
// This POC steps through the colors, generating the parts for one color,
// then the next, then the next. A built-in implementation could do
// that, or could do roughly the same operations across all colors at once.
// The model. A couple of unions, a difference, and an intersection
// to do a cutaway so that you can see the internal colors.
module main() {
int() {
uni() {
col("green") rotate([90,0,0]) cylinder(h=30, d=5, center=true);
dif() {
uni() {
col("red") cube(10);
col("blue") sphere(10);
}
cylinder(h=30, d=5, center=true);
}
}
rotate(-45) translate([0,-20,-20]) cube([40,40,40]);
}
}
// And now the infrastructure...
// Set the color of the children, like color().
// In this POC, this really operates by skipping anything that
// isn't the desired color, and then coloring during the per-color
// pass at the end, but there are other variations.
module col(c) {
union() { // work around #6456.
// $color=undef means that we want all colors - in particular,
// for the second-and-later children of dif() and int().
if (is_undef($color) || c == $color) {
children();
}
}
}
// Union the children.
// What this does is to draw the first child, then draw the second child
// less the first child, then the third less the first and second, and
// so on. Note that the negative components have $color=undef so that
// the entire subassembly, of all colors, gets subtracted out.
module uni() {
for (i=[0:1:$children-1]) {
// Add this child, less the children before it. Note that
// because of col() processing this might be only part
// of the logical subtree, but that's OK; what's important
// is that we mask it all colors of the previous children.
difference() {
children(i);
children([0:1:i-1], $color=undef);
}
}
}
// Difference the children.
// The only novel thing that this does is to set $color=undef
// for the second-and-later children, so that all colors are
// subtracted away from the first child. Again, because of
// col() processing the first child might only be a fraction of
// the logical subtree; it'll all get reassembled in the final
// multiple passes.
module dif() {
difference() {
children(0);
children([1:$children-1], $color=undef);
}
}
// Intersect the children.
// Think of this as taking the first child, and subtracting
// parts of it that are not in common with the later children.
// That neatly answers the question of what color the result
// should be, and makes everything consistent: the first child's
// color wins.
module int() {
intersection_for(i=[0:1:$children-1]) {
if (i == 0) {
children(i);
} else {
$color = undef;
children(i);
}
}
}
// As noted above, this list of colors needs to be
// known in advance; in a built-in implementation (or even
// in a script-driven userspace implementation) this list
// would be dynamically derived.
colors = [ "red", "green", "blue" ];
// Build the model.
for (c = colors) {
$color=c;
color(c) render() main();
}
// Build an exploded set so that you can see
// what the individual colored parts look like.
for (i = [ 0:len(colors)-1 ]) {
c = colors[i];
$color=c;
translate([20+i*20,0,0]) color(c) render() main();
}
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
Have you used PrusaSlicer or Bambu Studio or OrcaSlicer, Gene?
I think the standards for slicing have been out there for quite a while.
Jon
On 12/23/2025 8:57 PM, gene heskett via Discuss wrote:
On 12/23/25 20:03, Jordan Brown via Discuss wrote:
Today's OpenSCAD color processing does face coloring. It is perfectly
possible to have the six faces of a cube have six different colors, and
if you union two shapes of different colors there's nothing known about
the color of the overlap area.
That scheme is fine, more or less, for visualization, but it doesn't
work well for actual 3D printing where you need to know what color (or
material) the interior of a shape is to be.
What you need is volumetric color, so that there are no overlapping
shapes and you always know what color the interior of a shape is.
I mentioned this need as part of a discussion of color semantics, and
one of the responses was that we didn't know how to do volumetric
color. I'd done an OpenSCAD demonstration of volumetric color and was
pretty sure that it was straightforward to come up with appropriate
processing, so I said I'd recreate that proof-of-concept for discussion.
And here it is.
Note: this is not the most efficient possible implementation. It
re-evaluates the model many times, when it really only needs to be
evaluated once. There should probably be a few more render()s scattered
around to try to get subtrees to be cached. But it looks like it works.
Very impressive, and raising the priority of building a 3d printer
capable of doing that,
Currently my dream thoughts have leaned more toward switching src
spools of the
same color to make a printer capable of switching src spools to
continue the print
when the current spool runs out. To that continuous end, or for
multicolor, we'ed need to
establish a protocol we could setup in the slicer, to select which
method we have in
mind. Selectable by telling the slicer in the g-code pramble, what we
want the printer
to do. As the src of the code that winds driving the printer, it
behooves us to develop
the method, and attempt to set the industrues std way of doing this.
Otherwise we are left with everybody going off in their own direction,
diluting the
transition because every kit we might buy to build a printer, ideally
capable of
doing either according to the job at hand, and no ones product is
compatible
with any other vendors hardware. That is the road block preventing me
from
buying a box turtle, or any other solution. And because of this, not
one is offering
a complete, bolt it on, load it with spools of plastic and Just Run
solution.
So please, develop a std and break a few arms getting it accepted on
an industry
wide basis because it in the end, the inter-compatibility makes sense.
Now 91 yo & running out of time, its beyond my pay grade, but the
present situation
makes no sense at all. It is a huge road block to progress.
Thank you and Merry Christmas everybody.
Implementations of hull(), minkowski(), et cetera, and of the 2D
operations, left as an exercise for the reader.
Here's the result of this particular model, both in assembled form and
exploded by color:
// Volumetric color proof of concept
// Jordan Brown, openscad@jordan.maileater.net
// There are four relevant modules in this POC:
// col - replacement for color()
// uni - replacement for union()
// dif - replacement for difference()
// int - replacement for intersection()
// In this POC, the list of possible colors needs to be known in
advance;
// in a built-in implementation it would either be collected during the
// evaluation phase or managed entirely dynamically. It would be
// straightforward to build a version of this POC that would be
// driven by an external script that would first run it in a
// "list colors" mode and would then run it once for each color.
// Similarly, in this POC the model is encapsulated in a module main(),
// while in a built-in implementation the final "step through the
colors"
// loop would be implied and the model could be at the top level.
// This POC steps through the colors, generating the parts for one
color,
// then the next, then the next. A built-in implementation could do
// that, or could do roughly the same operations across all colors at
once.
// The model. A couple of unions, a difference, and an intersection
// to do a cutaway so that you can see the internal colors.
module main() {
int() {
uni() {
col("green") rotate([90,0,0]) cylinder(h=30, d=5,
center=true);
dif() {
uni() {
col("red") cube(10);
col("blue") sphere(10);
}
cylinder(h=30, d=5, center=true);
}
}
rotate(-45) translate([0,-20,-20]) cube([40,40,40]);
}
}
// And now the infrastructure...
// Set the color of the children, like color().
// In this POC, this really operates by skipping anything that
// isn't the desired color, and then coloring during the per-color
// pass at the end, but there are other variations.
module col(c) {
union() { // work around #6456.
// $color=undef means that we want all colors - in particular,
// for the second-and-later children of dif() and int().
if (is_undef($color) || c == $color) {
children();
}
}
}
// Union the children.
// What this does is to draw the first child, then draw the second child
// less the first child, then the third less the first and second, and
// so on. Note that the negative components have $color=undef so that
// the entire subassembly, of all colors, gets subtracted out.
module uni() {
for (i=[0:1:$children-1]) {
// Add this child, less the children before it. Note that
// because of col() processing this might be only part
// of the logical subtree, but that's OK; what's important
// is that we mask it all colors of the previous children.
difference() {
children(i);
children([0:1:i-1], $color=undef);
}
}
}
// Difference the children.
// The only novel thing that this does is to set $color=undef
// for the second-and-later children, so that all colors are
// subtracted away from the first child. Again, because of
// col() processing the first child might only be a fraction of
// the logical subtree; it'll all get reassembled in the final
// multiple passes.
module dif() {
difference() {
children(0);
children([1:$children-1], $color=undef);
}
}
// Intersect the children.
// Think of this as taking the first child, and subtracting
// parts of it that are not in common with the later children.
// That neatly answers the question of what color the result
// should be, and makes everything consistent: the first child's
// color wins.
module int() {
intersection_for(i=[0:1:$children-1]) {
if (i == 0) {
children(i);
} else {
$color = undef;
children(i);
}
}
}
// As noted above, this list of colors needs to be
// known in advance; in a built-in implementation (or even
// in a script-driven userspace implementation) this list
// would be dynamically derived.
colors = [ "red", "green", "blue" ];
// Build the model.
for (c = colors) {
$color=c;
color(c) render() main();
}
// Build an exploded set so that you can see
// what the individual colored parts look like.
for (i = [ 0:len(colors)-1 ]) {
c = colors[i];
$color=c;
translate([20+i*20,0,0]) color(c) render() main();
}
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Cheers, Gene Heskett, CET.
--
This email has been checked for viruses by AVG antivirus software.
www.avg.com
How do you think this improves on colorscad?
You made a number of choices regarding what
union/difference/intersection mean, but are those useful and efficient
in creating actual shapes versus i.e. BOSL2's coloring?
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently familiar with OS,
(2) relative beginner with python, and (3) working in a Windows environment (if that matters)?
Currently prusasliccer 2.8.1's AppImage, later are flatpacks which won't
run on my bookworm.
On 12/23/25 21:36, Jon Bondy wrote:
Have you used PrusaSlicer or Bambu Studio or OrcaSlicer, Gene?
yes, no-no privacy, and no. Cura for a while. prusa has more knobs.
I think the standards for slicing have been out there for quite a while.
But not for multi-color.
Jon
Merry Christmas, Jon.
On 12/23/2025 8:57 PM, gene heskett via Discuss wrote:
On 12/23/25 20:03, Jordan Brown via Discuss wrote:
Today's OpenSCAD color processing does face coloring. It is perfectly
possible to have the six faces of a cube have six different colors, and
if you union two shapes of different colors there's nothing known about
the color of the overlap area.
That scheme is fine, more or less, for visualization, but it doesn't
work well for actual 3D printing where you need to know what color (or
material) the interior of a shape is to be.
What you need is volumetric color, so that there are no overlapping
shapes and you always know what color the interior of a shape is.
I mentioned this need as part of a discussion of color semantics, and
one of the responses was that we didn't know how to do volumetric
color. I'd done an OpenSCAD demonstration of volumetric color and was
pretty sure that it was straightforward to come up with appropriate
processing, so I said I'd recreate that proof-of-concept for
discussion.
And here it is.
Note: this is not the most efficient possible implementation. It
re-evaluates the model many times, when it really only needs to be
evaluated once. There should probably be a few more render()s
scattered
around to try to get subtrees to be cached. But it looks like it
works.
Very impressive, and raising the priority of building a 3d printer
capable of doing that,
Currently my dream thoughts have leaned more toward switching src
spools of the
same color to make a printer capable of switching src spools to
continue the print
when the current spool runs out. To that continuous end, or for
multicolor, we'ed need to
establish a protocol we could setup in the slicer, to select which
method we have in
mind. Selectable by telling the slicer in the g-code pramble, what
we want the printer
to do. As the src of the code that winds driving the printer, it
behooves us to develop
the method, and attempt to set the industrues std way of doing this.
Otherwise we are left with everybody going off in their own
direction, diluting the
transition because every kit we might buy to build a printer, ideally
capable of
doing either according to the job at hand, and no ones product is
compatible
with any other vendors hardware. That is the road block preventing me
from
buying a box turtle, or any other solution. And because of this, not
one is offering
a complete, bolt it on, load it with spools of plastic and Just Run
solution.
So please, develop a std and break a few arms getting it accepted on
an industry
wide basis because it in the end, the inter-compatibility makes sense.
Now 91 yo & running out of time, its beyond my pay grade, but the
present situation
makes no sense at all. It is a huge road block to progress.
Thank you and Merry Christmas everybody.
Implementations of hull(), minkowski(), et cetera, and of the 2D
operations, left as an exercise for the reader.
Here's the result of this particular model, both in assembled form and
exploded by color:
// Volumetric color proof of concept
// Jordan Brown, openscad@jordan.maileater.net
// There are four relevant modules in this POC:
// col - replacement for color()
// uni - replacement for union()
// dif - replacement for difference()
// int - replacement for intersection()
// In this POC, the list of possible colors needs to be known in
advance;
// in a built-in implementation it would either be collected during the
// evaluation phase or managed entirely dynamically. It would be
// straightforward to build a version of this POC that would be
// driven by an external script that would first run it in a
// "list colors" mode and would then run it once for each color.
// Similarly, in this POC the model is encapsulated in a module main(),
// while in a built-in implementation the final "step through the
colors"
// loop would be implied and the model could be at the top level.
// This POC steps through the colors, generating the parts for one
color,
// then the next, then the next. A built-in implementation could do
// that, or could do roughly the same operations across all colors
at once.
// The model. A couple of unions, a difference, and an intersection
// to do a cutaway so that you can see the internal colors.
module main() {
int() {
uni() {
col("green") rotate([90,0,0]) cylinder(h=30, d=5,
center=true);
dif() {
uni() {
col("red") cube(10);
col("blue") sphere(10);
}
cylinder(h=30, d=5, center=true);
}
}
rotate(-45) translate([0,-20,-20]) cube([40,40,40]);
}
}
// And now the infrastructure...
// Set the color of the children, like color().
// In this POC, this really operates by skipping anything that
// isn't the desired color, and then coloring during the per-color
// pass at the end, but there are other variations.
module col(c) {
union() { // work around #6456.
// $color=undef means that we want all colors - in particular,
// for the second-and-later children of dif() and int().
if (is_undef($color) || c == $color) {
children();
}
}
}
// Union the children.
// What this does is to draw the first child, then draw the second
child
// less the first child, then the third less the first and second, and
// so on. Note that the negative components have $color=undef so that
// the entire subassembly, of all colors, gets subtracted out.
module uni() {
for (i=[0:1:$children-1]) {
// Add this child, less the children before it. Note that
// because of col() processing this might be only part
// of the logical subtree, but that's OK; what's important
// is that we mask it all colors of the previous children.
difference() {
children(i);
children([0:1:i-1], $color=undef);
}
}
}
// Difference the children.
// The only novel thing that this does is to set $color=undef
// for the second-and-later children, so that all colors are
// subtracted away from the first child. Again, because of
// col() processing the first child might only be a fraction of
// the logical subtree; it'll all get reassembled in the final
// multiple passes.
module dif() {
difference() {
children(0);
children([1:$children-1], $color=undef);
}
}
// Intersect the children.
// Think of this as taking the first child, and subtracting
// parts of it that are not in common with the later children.
// That neatly answers the question of what color the result
// should be, and makes everything consistent: the first child's
// color wins.
module int() {
intersection_for(i=[0:1:$children-1]) {
if (i == 0) {
children(i);
} else {
$color = undef;
children(i);
}
}
}
// As noted above, this list of colors needs to be
// known in advance; in a built-in implementation (or even
// in a script-driven userspace implementation) this list
// would be dynamically derived.
colors = [ "red", "green", "blue" ];
// Build the model.
for (c = colors) {
$color=c;
color(c) render() main();
}
// Build an exploded set so that you can see
// what the individual colored parts look like.
for (i = [ 0:len(colors)-1 ]) {
c = colors[i];
$color=c;
translate([20+i*20,0,0]) color(c) render() main();
}
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Cheers, Gene Heskett, CET.
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
On 12/24/25 13:55, gene heskett via Discuss wrote:
Currently prusasliccer 2.8.1's AppImage, later are flatpacks which
won't run on my bookworm.
On 12/23/25 21:36, Jon Bondy wrote:
Have you used PrusaSlicer or Bambu Studio or OrcaSlicer, Gene?
yes, no-no privacy, and no. Cura for a while. prusa has more knobs.
I think the standards for slicing have been out there for quite a while.
But not for multi-color.
Jon
Merry Christmas, Jon.
On 12/23/2025 8:57 PM, gene heskett via Discuss wrote:
On 12/23/25 20:03, Jordan Brown via Discuss wrote:
Today's OpenSCAD color processing does face coloring. It is perfectly
possible to have the six faces of a cube have six different colors,
and
if you union two shapes of different colors there's nothing known
about
the color of the overlap area.
That scheme is fine, more or less, for visualization, but it doesn't
work well for actual 3D printing where you need to know what color (or
material) the interior of a shape is to be.
What you need is volumetric color, so that there are no overlapping
shapes and you always know what color the interior of a shape is.
I mentioned this need as part of a discussion of color semantics, and
one of the responses was that we didn't know how to do volumetric
color. I'd done an OpenSCAD demonstration of volumetric color and was
pretty sure that it was straightforward to come up with appropriate
processing, so I said I'd recreate that proof-of-concept for
discussion.
And here it is.
Note: this is not the most efficient possible implementation. It
re-evaluates the model many times, when it really only needs to be
evaluated once. There should probably be a few more render()s
scattered
around to try to get subtrees to be cached. But it looks like it
works.
Very impressive, and raising the priority of building a 3d printer
capable of doing that,
Currently my dream thoughts have leaned more toward switching src
spools of the
same color to make a printer capable of switching src spools to
continue the print
when the current spool runs out. To that continuous end, or for
multicolor, we'ed need to
establish a protocol we could setup in the slicer, to select which
method we have in
mind. Selectable by telling the slicer in the g-code pramble, what
we want the printer
to do. As the src of the code that winds driving the printer, it
behooves us to develop
the method, and attempt to set the industrues std way of doing this.
Otherwise we are left with everybody going off in their own
direction, diluting the
transition because every kit we might buy to build a printer,
ideally capable of
doing either according to the job at hand, and no ones product is
compatible
with any other vendors hardware. That is the road block preventing
me from
buying a box turtle, or any other solution. And because of this,
not one is offering
a complete, bolt it on, load it with spools of plastic and Just Run
solution.
So please, develop a std and break a few arms getting it accepted on
an industry
wide basis because it in the end, the inter-compatibility makes sense.
Now 91 yo & running out of time, its beyond my pay grade, but the
present situation
makes no sense at all. It is a huge road block to progress.
Thank you and Merry Christmas everybody.
Implementations of hull(), minkowski(), et cetera, and of the 2D
operations, left as an exercise for the reader.
Here's the result of this particular model, both in assembled form and
exploded by color:
// Volumetric color proof of concept
// Jordan Brown, openscad@jordan.maileater.net
// There are four relevant modules in this POC:
// col - replacement for color()
// uni - replacement for union()
// dif - replacement for difference()
// int - replacement for intersection()
// In this POC, the list of possible colors needs to be known in
advance;
// in a built-in implementation it would either be collected during
the
// evaluation phase or managed entirely dynamically. It would be
// straightforward to build a version of this POC that would be
// driven by an external script that would first run it in a
// "list colors" mode and would then run it once for each color.
// Similarly, in this POC the model is encapsulated in a module
main(),
// while in a built-in implementation the final "step through the
colors"
// loop would be implied and the model could be at the top level.
// This POC steps through the colors, generating the parts for one
color,
// then the next, then the next. A built-in implementation could do
// that, or could do roughly the same operations across all colors
at once.
// The model. A couple of unions, a difference, and an intersection
// to do a cutaway so that you can see the internal colors.
module main() {
int() {
uni() {
col("green") rotate([90,0,0]) cylinder(h=30, d=5,
center=true);
dif() {
uni() {
col("red") cube(10);
col("blue") sphere(10);
}
cylinder(h=30, d=5, center=true);
}
}
rotate(-45) translate([0,-20,-20]) cube([40,40,40]);
}
}
// And now the infrastructure...
// Set the color of the children, like color().
// In this POC, this really operates by skipping anything that
// isn't the desired color, and then coloring during the per-color
// pass at the end, but there are other variations.
module col(c) {
union() { // work around #6456.
// $color=undef means that we want all colors - in
particular,
// for the second-and-later children of dif() and int().
if (is_undef($color) || c == $color) {
children();
}
}
}
// Union the children.
// What this does is to draw the first child, then draw the second
child
// less the first child, then the third less the first and second, and
// so on. Note that the negative components have $color=undef so that
// the entire subassembly, of all colors, gets subtracted out.
module uni() {
for (i=[0:1:$children-1]) {
// Add this child, less the children before it. Note that
// because of col() processing this might be only part
// of the logical subtree, but that's OK; what's important
// is that we mask it all colors of the previous children.
difference() {
children(i);
children([0:1:i-1], $color=undef);
}
}
}
// Difference the children.
// The only novel thing that this does is to set $color=undef
// for the second-and-later children, so that all colors are
// subtracted away from the first child. Again, because of
// col() processing the first child might only be a fraction of
// the logical subtree; it'll all get reassembled in the final
// multiple passes.
module dif() {
difference() {
children(0);
children([1:$children-1], $color=undef);
}
}
// Intersect the children.
// Think of this as taking the first child, and subtracting
// parts of it that are not in common with the later children.
// That neatly answers the question of what color the result
// should be, and makes everything consistent: the first child's
// color wins.
module int() {
intersection_for(i=[0:1:$children-1]) {
if (i == 0) {
children(i);
} else {
$color = undef;
children(i);
}
}
}
// As noted above, this list of colors needs to be
// known in advance; in a built-in implementation (or even
// in a script-driven userspace implementation) this list
// would be dynamically derived.
colors = [ "red", "green", "blue" ];
// Build the model.
for (c = colors) {
$color=c;
color(c) render() main();
}
// Build an exploded set so that you can see
// what the individual colored parts look like.
for (i = [ 0:len(colors)-1 ]) {
c = colors[i];
$color=c;
translate([20+i*20,0,0]) color(c) render() main();
}
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Cheers, Gene Heskett, CET.
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org
On 12/24/25 01:46, pca006132 via Discuss wrote:
I use .3mf exclusively unless the slicer objects, but have not been made
aware of that. Where can I find this documentation so I can understand
what is out there?
Thank you.
On 12/24/25 13:55, gene heskett via Discuss wrote:
Currently prusasliccer 2.8.1's AppImage, later are flatpacks which
won't run on my bookworm.
On 12/23/25 21:36, Jon Bondy wrote:
Have you used PrusaSlicer or Bambu Studio or OrcaSlicer, Gene?
yes, no-no privacy, and no. Cura for a while. prusa has more knobs.
I think the standards for slicing have been out there for quite a
while.
But not for multi-color.
[...]
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
How do you think this improves on colorscad?
I haven’t used colorscad; I’ve only just now read its README. Looking at it, it looks like it’s actually almost exactly the stuff I said you could wrap around this implementation to make it actually useful.
But it doesn’t do the stuff that I consider truly interesting. Consider this paragraph from its README:
Let's avoid weird geometry such as overlapping color volumes... Avoid using multiple colors in an intersection() or difference(), if unavoidable then just wrap it in a color() statement.
If you’re willing to live with those restrictions, well, OK, but it sure seems like the example that I gave would be much harder to build if you have to live within them. I want something where color (“red”) cube(10); color(“blue”) sphere(10); does something sensible and predictable, without me having to do the work to avoid the overlap. Similarly, I want to be able to take a multicolor object and cut it in half with a difference or intersection and have it just work. (Which I suspect it will, with colorscad, but the documentation isn’t encouraging.)
As an exercise, you could demonstrate creating my sample model using colorscad’s restrictions; it would be interesting to see the comparison. (Remember that “my sample model” is only the stuff inside the “main” module; the rest is infrastructure.)
You made a number of choices regarding what union/difference/intersection mean, but are those useful and efficient in creating actual shapes versus i.e. BOSL2's coloring?
I haven’t noticed similar support in BOSL2, but I haven’t looked. It wouldn’t surprise me if they had something similar, because what I did is a lot like what they do with their diff() operator.
But that would only make my point, which is that it is possible to define volumetric color.
Are the definitions I picked useful? I have no practical experience with them, since I don’t have a multicolor printer. However, since they’re a superset of the capabilities of colorscad’s design capabilities - if you avoid overlaps, it’ll generate the same results that colorscad produces - they’re at least as useful as it is. (Again noting that it does the automation that wraps around this geometry processing to step through the colors, which wasn’t the point of this exercise.)
I’ve been thinking about the definitions on and off for a long time. Difference is easy; the colors of the first child must remain unchanged as you cut away parts of it. Intersection and the overlapping part of union, which are in a sense the same thing, kind of need to be either first-wins or last-wins, and the two strategies seems equivalent, so I picked first-wins because that’s what difference needs. Hull and the others need some answer, but I doubt that what the answer is matters.
Are they efficient? First, I don’t care. Getting a useful and understandable result is the critical piece; a scheme that is ten times faster and requires the model to be ten times as complicated (or even twice as complicated) is in my mind a losing proposition. Second… as implemented, absolutely not. There’s at least a couple of optimizations that could be made even in an OpenSCAD-language implementation, and there’s several more that can be made if you can work directly with the CSG tree. (Geometry values from PR#4478 would help there.) Third, I expect that a multicolor scheme is always going to be slower than a single-color scheme, because there’s just more geometry processing to do.
Better than my OpenSCAD-language implementation? Absolutely! My point was only to demonstrate definitions, using operations that we already have.
Better than in a slicer? Also absolutely, for a different reason. Slicers shouldn’t be controlling the design of the piece. They are responsible for implementing the design, but the model should say unambiguously how the model is divided by color/material/whatever.
Yeah, I get the impression that that’s more or less a solved problem.
So, to start to answer my own questions and move some goalposts (maybe)...
How do you think this improves on colorscad?
Colorscad says "Let's avoid weird geometry such as overlapping color volumes... Avoid using multiple colors in an intersection() or difference(), if unavoidable then just wrap it in a color() statement."
So that's obvious.
You made a number of choices regarding what union/difference/intersection mean, but are those useful and efficient in creating actual shapes versus i.e. BOSL2's coloring?
Let's say I design a really cool eye module made of several different colored non-overlapping meshes. I then want to place it overlapping an arbitrary mesh M. With volumetric that's just a union, but I must place my eye first. Without, it's a union with the eye and the difference of M minus the eye... NO! because the difference-created faces gain the eye colors, colorscad doesn't work.
I think this can only be backward-compatible by having color take an option meaning volumetric and having union, intersection, etc use the new behaviour when any child is volumetric colored; Or have some global setting to say "color is now volumetric". Or can they coexist!?
I think the usual process in Blender etc is to build a mesh and then color faces of it, because it's more for computer graphics. If I made i.e. a flexi-dragon that way, I'd still have the problem of making it printable; either there's some foolproof limited algorithm (its volume is X color; colored faces are extruded Y deep) or you must then break it into separate meshes manually?
But that makes me think they can't simply coexist and thus there should be a flag that switches the meaning globally. Actually, especially with geometry literals, it must happen before evaluation begins, so I think that means new syntax happening at parse time. Or... they can coexist, but if any time an operation has something with volumetric color, face color becomes undefined.
OpenSCAD is going to have to maintain a map of volumetric color to mesh everywhere a mesh is currently returned, wouldn't it? And what was an i.e. intersection of two meshes is now NxN meshes, just like your POC shows.
Sorry, I answered my own questions, but took too long and then my email program ate it. I'll try to write it all again later.
My "real-world" example was an eye made of many materials and attaching it to another object. With volumetric color, all you must do is union it, with it being the first entry and the things you want to attach/embed it into being the second item. Without, you must maintain separate entries for each volumetric color on both sides manually. For simple functional things (like I make) it didn't seem useful, colorscad easy enough, but the first time you would try to operate on multiple things with multiple colors... yuck.
You could have an option to automatically "volumetrically-colorize" any shape with face coloring.
Backward-compatibility seems feasible (the operations will know if any child has volumetric color; otherwise preserve existing behaviour).
On December 24, 2025 12:28:45 AM PST, Jordan Brown via Discuss discuss@lists.openscad.org wrote:
How do you think this improves on colorscad?
I haven’t used colorscad; I’ve only just now read its README. Looking at it, it looks like it’s actually almost exactly the stuff I said you could wrap around this implementation to make it actually useful.
But it doesn’t do the stuff that I consider truly interesting. Consider this paragraph from its README:
Let's avoid weird geometry such as overlapping color volumes... Avoid using multiple colors in an intersection() or difference(), if unavoidable then just wrap it in a color() statement.
If you’re willing to live with those restrictions, well, OK, but it sure seems like the example that I gave would be much harder to build if you have to live within them. I want something where color (“red”) cube(10); color(“blue”) sphere(10); does something sensible and predictable, without me having to do the work to avoid the overlap. Similarly, I want to be able to take a multicolor object and cut it in half with a difference or intersection and have it just work. (Which I suspect it will, with colorscad, but the documentation isn’t encouraging.)
As an exercise, you could demonstrate creating my sample model using colorscad’s restrictions; it would be interesting to see the comparison. (Remember that “my sample model” is only the stuff inside the “main” module; the rest is infrastructure.)
You made a number of choices regarding what union/difference/intersection mean, but are those useful and efficient in creating actual shapes versus i.e. BOSL2's coloring?
I haven’t noticed similar support in BOSL2, but I haven’t looked. It wouldn’t surprise me if they had something similar, because what I did is a lot like what they do with their diff() operator.
But that would only make my point, which is that it is possible to define volumetric color.
Are the definitions I picked useful? I have no practical experience with them, since I don’t have a multicolor printer. However, since they’re a superset of the capabilities of colorscad’s design capabilities - if you avoid overlaps, it’ll generate the same results that colorscad produces - they’re at least as useful as it is. (Again noting that it does the automation that wraps around this geometry processing to step through the colors, which wasn’t the point of this exercise.)
I’ve been thinking about the definitions on and off for a long time. Difference is easy; the colors of the first child must remain unchanged as you cut away parts of it. Intersection and the overlapping part of union, which are in a sense the same thing, kind of need to be either first-wins or last-wins, and the two strategies seems equivalent, so I picked first-wins because that’s what difference needs. Hull and the others need some answer, but I doubt that what the answer is matters.
Are they efficient? First, I don’t care. Getting a useful and understandable result is the critical piece; a scheme that is ten times faster and requires the model to be ten times as complicated (or even twice as complicated) is in my mind a losing proposition. Second… as implemented, absolutely not. There’s at least a couple of optimizations that could be made even in an OpenSCAD-language implementation, and there’s several more that can be made if you can work directly with the CSG tree. (Geometry values from PR#4478 would help there.) Third, I expect that a multicolor scheme is always going to be slower than a single-color scheme, because there’s just more geometry processing to do.
On 12/24/25 16:18, gene heskett via Discuss wrote:
I use .3mf exclusively unless the slicer objects, but have not been
made aware of that. Where can I find this documentation so I can
understand what is out there?
Thank you.
If you look at the specification example
https://github.com/3MFConsortium/spec_core/blob/master/3MF%20Core%20Specification.md#appendix-b2-3mf-metadata-example,
you can see that it defines a basematerials with id=1, and references
that in the object with id=2 using pid="1", and the object contains a
mesh. From chapter 4, it said that the pid attribute is for "Reference
to the property group element with the matching id attribute value (e.g.
<basematerials>). It is REQUIRED if pindex is specified.". You can also
add properties per triangle (4.1.4.1). The materials extensions
(https://github.com/3MFConsortium/spec_materials/blob/master/3MF%20Materials%20Extension.md)
allows you to specify more complex properties, such as interpolation,
coordinates, display properties, etc. But i think the core spec is
enough for simple volumetric color/material.
I feel like the best way would be to have a new modifier, and not to mix
things.
On 12/24/25 18:34, Cory Cross via Discuss wrote:
Sorry, I answered my own questions, but took too long and then my
email program ate it. I'll try to write it all again later.
My "real-world" example was an eye made of many materials and
attaching it to another object. With volumetric color, all you must do
is union it, with it being the first entry and the things you want to
attach/embed it into being the second item. Without, you must maintain
separate entries for each volumetric color on both sides manually. For
simple functional things (like I make) it didn't seem useful,
colorscad easy enough, but the first time you would try to operate on
multiple things with multiple colors... yuck.
You could have an option to automatically "volumetrically-colorize"
any shape with face coloring.
Backward-compatibility seems feasible (the operations will know if any
child has volumetric color; otherwise preserve existing behaviour).
On December 24, 2025 12:28:45 AM PST, Jordan Brown via Discuss
discuss@lists.openscad.org wrote:
How do you think this improves on colorscad?
I haven’t used colorscad; I’ve only just now read its README.
Looking at it, it looks like it’s actually almost exactly the
stuff I said you could wrap around this implementation to make it
actually useful.
But it doesn’t do the stuff that I consider truly interesting.
Consider this paragraph from its README:
Let's avoid weird geometry such as overlapping color
volumes... Avoid using multiple colors in an
|intersection()|or|difference()|, if unavoidable then just
wrap it in a|color()| statement.
If you’re willing to live with those restrictions, well, OK, but
it sure seems like the example that I gave would be much harder to
build if you have to live within them. I want something where
color (“red”) cube(10); color(“blue”) sphere(10); does something
sensible and predictable, without me having to do the work to
avoid the overlap. Similarly, I want to be able to take a
multicolor object and cut it in half with a difference or
intersection and have it just work. (Which I suspect it will, with
colorscad, but the documentation isn’t encouraging.)
As an exercise, you could demonstrate creating my sample model
using colorscad’s restrictions; it would be interesting to see the
comparison. (Remember that “my sample model” is only the stuff
inside the “main” module; the rest is infrastructure.)
You made a number of choices regarding what
union/difference/intersection mean, but are those useful and
efficient in creating actual shapes versus i.e. BOSL2's coloring?
I haven’t noticed similar support in BOSL2, but I haven’t looked.
It wouldn’t surprise me if they had something similar, because
what I did is a lot like what they do with their diff() operator.
But that would only make my point, which is that it *is* possible
to define volumetric color.
Are the definitions I picked useful? I have no practical
experience with them, since I don’t have a multicolor printer.
However, since they’re a superset of the capabilities of
colorscad’s design capabilities - if you avoid overlaps, it’ll
generate the same results that colorscad produces - they’re at
least as useful as it is. (Again noting that it does the
automation that wraps around this geometry processing to step
through the colors, which wasn’t the point of this exercise.)
I’ve been thinking about the definitions on and off for a long
time. Difference is easy; the colors of the first child must
remain unchanged as you cut away parts of it. Intersection and the
overlapping part of union, which are in a sense the same thing,
kind of need to be either first-wins or last-wins, and the two
strategies seems equivalent, so I picked first-wins because that’s
what difference needs. Hull and the others need *some* answer, but
I doubt that what the answer is matters.
Are they efficient? First, I don’t care. Getting a useful and
understandable result is the critical piece; a scheme that is ten
times faster and requires the model to be ten times as complicated
(or even twice as complicated) is in my mind a losing proposition.
Second… as implemented, absolutely not. There’s at least a couple
of optimizations that could be made even in an OpenSCAD-language
implementation, and there’s several more that can be made if you
can work directly with the CSG tree. (Geometry values from PR#4478
would help there.) Third, I expect that a multicolor scheme is
always going to be slower than a single-color scheme, because
there’s just more geometry processing to do.
OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org
On 12/24/25 06:56, pca006132 via Discuss wrote:
On 12/24/25 16:18, gene heskett via Discuss wrote:
I use .3mf exclusively unless the slicer objects, but have not been
made aware of that. Where can I find this documentation so I can
understand what is out there?
Thank you.
If you look at the specification example
https://github.com/3MFConsortium/spec_core/blob/master/3MF%20Core%20Specification.md#appendix-b2-3mf-metadata-example,
you can see that it defines a basematerials with id=1, and references
that in the object with id=2 using pid="1", and the object contains a
mesh. From chapter 4, it said that the pid attribute is for "Reference
to the property group element with the matching id attribute value
(e.g. <basematerials>). It is REQUIRED if pindex is specified.". You
can also add properties per triangle (4.1.4.1). The materials
extensions
(https://github.com/3MFConsortium/spec_materials/blob/master/3MF%20Materials%20Extension.md)
allows you to specify more complex properties, such as interpolation,
coordinates, display properties, etc. But i think the core spec is
enough for simple volumetric color/material.
Just reading the disclaimer would prevent me from touching that with a
30 ft fiberglass pole. While it is probably do-able in dot mixing
formats such as a color paper printer where the exact color of the inks
is known to a fraction of a % for all inks, I don't see it as
practically applicable to a 3d printer, because it would require a
mixing device operating at lay temp to blend 2 or more of the
complimentary colors to blend to the desired color with 2 or more
filaments being fed to the nozzle, each at the flow rate desired. Just
the complexity of that isn't suitable for a mailing list.
What I had more in mind was for the plastic maker to supply an RGBA
table, available using current RF-ID tech for each spool mounted. That
would restrict the available choices to what was loaded. But could be
done in 60 days or less of coding for a POC. Hundreds of times more usable.
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
Gene:
I have not read the spec, but I believe that when a multi-color 3D model
file is loaded into a slicer, the operator of the slicer gets to assign
the model colors to the available filaments. They can assign a green
from a model to a green colored filament, but they could just as easily
assign it to a red colored filament. Mixing devices are not required.
Jon
On 12/24/2025 8:18 AM, gene heskett via Discuss wrote:
On 12/24/25 06:56, pca006132 via Discuss wrote:
On 12/24/25 16:18, gene heskett via Discuss wrote:
I use .3mf exclusively unless the slicer objects, but have not been
made aware of that. Where can I find this documentation so I can
understand what is out there?
Thank you.
If you look at the specification example
https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_3MFConsortium_spec-5Fcore_blob_master_3MF-2520Core-2520Specification.md-23appendix-2Db2-2D3mf-2Dmetadata-2Dexample&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=pIZg2czpDjuvuPC-XsRq8QI3FCn_RXY-AQy8oXHVWSnFwZudr4mhxqINwA2g1BOT&s=0pp9aMmd17NFFNK4mQ6jRdpH8CsrrD7EKbp-oVGh5L0&e=,
you can see that it defines a basematerials with id=1, and references
that in the object with id=2 using pid="1", and the object contains a
mesh. From chapter 4, it said that the pid attribute is for
"Reference to the property group element with the matching id
attribute value (e.g. <basematerials>). It is REQUIRED if pindex is
specified.". You can also add properties per triangle (4.1.4.1). The
materials extensions
(https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_3MFConsortium_spec-5Fmaterials_blob_master_3MF-2520Materials-2520Extension.md&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=pIZg2czpDjuvuPC-XsRq8QI3FCn_RXY-AQy8oXHVWSnFwZudr4mhxqINwA2g1BOT&s=ifnaGFisJXbJIoC9oXR4OqqlSQsD0kS-pBQ63JBiZLE&e=)
allows you to specify more complex properties, such as interpolation,
coordinates, display properties, etc. But i think the core spec is
enough for simple volumetric color/material.
Just reading the disclaimer would prevent me from touching that with a
30 ft fiberglass pole. While it is probably do-able in dot mixing
formats such as a color paper printer where the exact color of the
inks is known to a fraction of a % for all inks, I don't see it as
practically applicable to a 3d printer, because it would require a
mixing device operating at lay temp to blend 2 or more of the
complimentary colors to blend to the desired color with 2 or more
filaments being fed to the nozzle, each at the flow rate desired. Just
the complexity of that isn't suitable for a mailing list.
What I had more in mind was for the plastic maker to supply an RGBA
table, available using current RF-ID tech for each spool mounted. That
would restrict the available choices to what was loaded. But could be
done in 60 days or less of coding for a POC. Hundreds of times more
usable.
Cheers, Gene Heskett, CET.
--
This email has been checked for viruses by AVG antivirus software.
www.avg.com
On 12/24/25 08:52, Jon Bondy wrote:
Gene:
I have not read the spec, but I believe that when a multi-color 3D
model file is loaded into a slicer, the operator of the slicer gets to
assign the model colors to the available filaments. They can assign a
green from a model to a green colored filament, but they could just as
easily assign it to a red colored filament. Mixing devices are not
required.
Correct, Jon but what if the desired color isn't available? That .3mf
spec as I read it, would only apply to an inkjet printer. You'd have to
bend things beyond recognition to apply it to a printer incapable of
blending to get the desired color. So if I buy something like a box
turtle, it will be for mounting a 2nd spool of the same color to
automatically continue a print that has used up the current spool in
use. Most of what I've done would be continued when the existing spool
was used up. With the Soval sv08 max I could do a part that uses half a
spool per part pair, 8 up without baby sitting it to feed a new spool on
the fly, my current situation.
Jon
On 12/24/2025 8:18 AM, gene heskett via Discuss wrote:
On 12/24/25 06:56, pca006132 via Discuss wrote:
On 12/24/25 16:18, gene heskett via Discuss wrote:
I use .3mf exclusively unless the slicer objects, but have not been
made aware of that. Where can I find this documentation so I can
understand what is out there?
Thank you.
If you look at the specification example
https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_3MFConsortium_spec-5Fcore_blob_master_3MF-2520Core-2520Specification.md-23appendix-2Db2-2D3mf-2Dmetadata-2Dexample&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=pIZg2czpDjuvuPC-XsRq8QI3FCn_RXY-AQy8oXHVWSnFwZudr4mhxqINwA2g1BOT&s=0pp9aMmd17NFFNK4mQ6jRdpH8CsrrD7EKbp-oVGh5L0&e=,
you can see that it defines a basematerials with id=1, and
references that in the object with id=2 using pid="1", and the
object contains a mesh. From chapter 4, it said that the pid
attribute is for "Reference to the property group element with the
matching id attribute value (e.g. <basematerials>). It is REQUIRED
if pindex is specified.". You can also add properties per triangle
(4.1.4.1). The materials extensions
(https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_3MFConsortium_spec-5Fmaterials_blob_master_3MF-2520Materials-2520Extension.md&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=pIZg2czpDjuvuPC-XsRq8QI3FCn_RXY-AQy8oXHVWSnFwZudr4mhxqINwA2g1BOT&s=ifnaGFisJXbJIoC9oXR4OqqlSQsD0kS-pBQ63JBiZLE&e=)
allows you to specify more complex properties, such as
interpolation, coordinates, display properties, etc. But i think the
core spec is enough for simple volumetric color/material.
Just reading the disclaimer would prevent me from touching that with
a 30 ft fiberglass pole. While it is probably do-able in dot mixing
formats such as a color paper printer where the exact color of the
inks is known to a fraction of a % for all inks, I don't see it as
practically applicable to a 3d printer, because it would require a
mixing device operating at lay temp to blend 2 or more of the
complimentary colors to blend to the desired color with 2 or more
filaments being fed to the nozzle, each at the flow rate desired.
Just the complexity of that isn't suitable for a mailing list.
What I had more in mind was for the plastic maker to supply an RGBA
table, available using current RF-ID tech for each spool mounted.
That would restrict the available choices to what was loaded. But
could be done in 60 days or less of coding for a POC. Hundreds of
times more usable.
Cheers, Gene Heskett, CET.
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
The file contains all the information you want, but it does not mean
that you have to follow the information. It is designed to include
information useful for any manufacturing purposes, but it does not mean
that each manufacturing method has to support all features. And I think
slicers ignore RGB for slicing, it will just ask you to assign a
material for that color, probably.
Also, I don't think there is anything weird with their disclaimer. How
can they be responsible for any damage caused by an implementation of
the spec? This is a format specification, not about how you should
implement your slicer to be complaint to this. And even for compliant,
it is really just about reading the file, your print does not have to
adhere to the material specification because it is impossible to do so.
On 12/24/25 22:28, gene heskett via Discuss wrote:
On 12/24/25 08:52, Jon Bondy wrote:
Gene:
I have not read the spec, but I believe that when a multi-color 3D
model file is loaded into a slicer, the operator of the slicer gets
to assign the model colors to the available filaments. They can
assign a green from a model to a green colored filament, but they
could just as easily assign it to a red colored filament. Mixing
devices are not required.
Correct, Jon but what if the desired color isn't available? That .3mf
spec as I read it, would only apply to an inkjet printer. You'd have
to bend things beyond recognition to apply it to a printer incapable
of blending to get the desired color. So if I buy something like a
box turtle, it will be for mounting a 2nd spool of the same color to
automatically continue a print that has used up the current spool in
use. Most of what I've done would be continued when the existing spool
was used up. With the Soval sv08 max I could do a part that uses half
a spool per part pair, 8 up without baby sitting it to feed a new
spool on the fly, my current situation.Jon
On 12/24/2025 8:18 AM, gene heskett via Discuss wrote:
On 12/24/25 06:56, pca006132 via Discuss wrote:
On 12/24/25 16:18, gene heskett via Discuss wrote:
I use .3mf exclusively unless the slicer objects, but have not
been made aware of that. Where can I find this documentation so I
can understand what is out there?
Thank you.If you look at the specification example
https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_3MFConsortium_spec-5Fcore_blob_master_3MF-2520Core-2520Specification.md-23appendix-2Db2-2D3mf-2Dmetadata-2Dexample&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=pIZg2czpDjuvuPC-XsRq8QI3FCn_RXY-AQy8oXHVWSnFwZudr4mhxqINwA2g1BOT&s=0pp9aMmd17NFFNK4mQ6jRdpH8CsrrD7EKbp-oVGh5L0&e=,
you can see that it defines a basematerials with id=1, and
references that in the object with id=2 using pid="1", and the
object contains a mesh. From chapter 4, it said that the pid
attribute is for "Reference to the property group element with the
matching id attribute value (e.g. <basematerials>). It is REQUIRED
if pindex is specified.". You can also add properties per triangle
(4.1.4.1). The materials extensions
(https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_3MFConsortium_spec-5Fmaterials_blob_master_3MF-2520Materials-2520Extension.md&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=pIZg2czpDjuvuPC-XsRq8QI3FCn_RXY-AQy8oXHVWSnFwZudr4mhxqINwA2g1BOT&s=ifnaGFisJXbJIoC9oXR4OqqlSQsD0kS-pBQ63JBiZLE&e=)
allows you to specify more complex properties, such as
interpolation, coordinates, display properties, etc. But i think
the core spec is enough for simple volumetric color/material.
Just reading the disclaimer would prevent me from touching that with
a 30 ft fiberglass pole. While it is probably do-able in dot mixing
formats such as a color paper printer where the exact color of the
inks is known to a fraction of a % for all inks, I don't see it as
practically applicable to a 3d printer, because it would require a
mixing device operating at lay temp to blend 2 or more of the
complimentary colors to blend to the desired color with 2 or more
filaments being fed to the nozzle, each at the flow rate desired.
Just the complexity of that isn't suitable for a mailing list.What I had more in mind was for the plastic maker to supply an RGBA
table, available using current RF-ID tech for each spool mounted.
That would restrict the available choices to what was loaded. But
could be done in 60 days or less of coding for a POC. Hundreds of
times more usable.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
.Cheers, Gene Heskett, CET.
Cheers, Gene Heskett, CET.
but the first time you would try to operate on multiple things with multiple colors... yuck.
Yeah, that was what my intuition said.
Backward-compatibility seems feasible
Yes, any of a couple of ways. And there’s a question of what preview should do with volumetric color; my initial experiments years ago floundered on the fact that preview really doesn’t like coincident faces and this processing generates a lot of faces, many of them coincident.
I haven’t thought too much about the language binding, about how you would say you want volumetric color. When I first played with this years ago, it was after somebody told me not to document the existing color behavior because it was kind of an accident and maybe not the right behavior. One of my initial thoughts would be to just cut over, accepting the short term pain to get the long term simplicity. However, (a) there are a lot of people relying, for visualization and other non-3DP purposes, on the current behavior, and (b) non-3DP applications like video games probably want face coloring, so reluctantly I wouldn’t recommend that choice today.
They could be a second operator - “part”, maybe, to encompass color, material, and maybe other similar applications. There could be an option on color(). There could be a $ variable that you could set at the top level. (I see TP cringing.)
Right now I think a general purpose part() might be best, but since I come up with at least four applications for it, care would be required to ensure that it covers all of them without unduly burdening any of them.
Those four applications are:
Color
Material
“Modifier” shapes that enclose other shapes and do things like change print parameters. (Maybe transparency is one of these, or maybe it’s a color or material.)
Multiple result-shapes in one file. I often group related models together, for preview and file management reasons, but then separate them for printing. This might also tie into semi automatic mechanisms for splitting shapes larger than your print bed.
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to
learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small video
for a starting point in case you are interested:
https://youtu.be/kBshJ0CQCS0
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <
discuss@lists.openscad.org> wrote:
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently
familiar with OS,
(2) relative beginner with python, and (3) working in a Windows
environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
On Tuesday, December 23, 2025 at 10:36:24 PM EST, Lee DeRaud via Discuss discuss@lists.openscad.org wrote:
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Yes, there have been.
Any suggestions for where best to start, assuming someone (1) decently familiar with OS,
(2) relative beginner with python, and (3) working in a Windows environment (if that matters)?
I've been having good luck with:
and am especially grateful for it since persistent, mutable variables made possible my moving forward on:
https://github.com/WillAdams/gcodepreview
What sort of projects do you wish to do?
How do you wish to approach them?
Addressing what sort of manufacturing tool(s)?
William
--
Sphinx of black quartz, judge my vow.
https://designinto3d.com/
Ok, watched the video: where might ”openscad4.py” be found?
From: Sanjeev Prabhakar sprabhakar2006@gmail.com
Sent: Wednesday, December 24, 2025 7:58 AM
To: OpenSCAD general discussion Mailing-list discuss@lists.openscad.org
Cc: lee.deraud@roadrunner.com
Subject: Re: [OpenSCAD] Best starting point using Python with OpenSCAD?
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small video for a starting point in case you are interested:
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org > wrote:
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently familiar with OS,
(2) relative beginner with python, and (3) working in a Windows environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
It's mentioned in the video description
You can download it from here:
https://github.com/sprabhakar2006/openSCAD/blob/main/openscad4.py
You need to also install following libraries in python:
numpy, scipy, sympy, scikit-image
On Thu, 25 Dec, 2025, 12:56 am Lee DeRaud via Discuss, <
discuss@lists.openscad.org> wrote:
Ok, watched the video: where might ”openscad4.py” be found?
From: Sanjeev Prabhakar sprabhakar2006@gmail.com
Sent: Wednesday, December 24, 2025 7:58 AM
To: OpenSCAD general discussion Mailing-list <discuss@lists.openscad.org
Cc: lee.deraud@roadrunner.com
Subject: Re: [OpenSCAD] Best starting point using Python with OpenSCAD?
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to
learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small
video for a starting point in case you are interested:
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <
discuss@lists.openscad.org> wrote:
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently
familiar with OS,
(2) relative beginner with python, and (3) working in a Windows
environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Thanks.
I’d swear I did a search on github for ‘openscad4.py’ and got no results…maybe I really AM that lame. ☹
From: Sanjeev Prabhakar sprabhakar2006@gmail.com
Sent: Wednesday, December 24, 2025 2:03 PM
To: OpenSCAD general discussion Mailing-list discuss@lists.openscad.org
Cc: Lee DeRaud lee.deraud@roadrunner.com
Subject: Re: [OpenSCAD] Re: Best starting point using Python with OpenSCAD?
It's mentioned in the video description
You can download it from here: https://github.com/sprabhakar2006/openSCAD/blob/main/openscad4.py
You need to also install following libraries in python:
numpy, scipy, sympy, scikit-image
On Thu, 25 Dec, 2025, 12:56 am Lee DeRaud via Discuss, <discuss@lists.openscad.org mailto:discuss@lists.openscad.org > wrote:
Ok, watched the video: where might ”openscad4.py” be found?
From: Sanjeev Prabhakar <sprabhakar2006@gmail.com mailto:sprabhakar2006@gmail.com >
Sent: Wednesday, December 24, 2025 7:58 AM
To: OpenSCAD general discussion Mailing-list <discuss@lists.openscad.org mailto:discuss@lists.openscad.org >
Cc: lee.deraud@roadrunner.com mailto:lee.deraud@roadrunner.com
Subject: Re: [OpenSCAD] Best starting point using Python with OpenSCAD?
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small video for a starting point in case you are interested:
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org > wrote:
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently familiar with OS,
(2) relative beginner with python, and (3) working in a Windows environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
Oh, I have never tried searching for openscad4.py
You can download an examples file from here. Some of the definitions in the
index may be outdated, but the examples should be good:
On Thu, 25 Dec 2025 at 03:48, Lee DeRaud via Discuss <
discuss@lists.openscad.org> wrote:
Thanks.
I’d swear I did a search on github for ‘openscad4.py’ and got no
results…maybe I really AM that lame. ☹
From: Sanjeev Prabhakar sprabhakar2006@gmail.com
Sent: Wednesday, December 24, 2025 2:03 PM
To: OpenSCAD general discussion Mailing-list <discuss@lists.openscad.org
Cc: Lee DeRaud lee.deraud@roadrunner.com
Subject: Re: [OpenSCAD] Re: Best starting point using Python with
OpenSCAD?
It's mentioned in the video description
You can download it from here:
https://github.com/sprabhakar2006/openSCAD/blob/main/openscad4.py
You need to also install following libraries in python:
numpy, scipy, sympy, scikit-image
On Thu, 25 Dec, 2025, 12:56 am Lee DeRaud via Discuss, <
discuss@lists.openscad.org> wrote:
Ok, watched the video: where might ”openscad4.py” be found?
From: Sanjeev Prabhakar sprabhakar2006@gmail.com
Sent: Wednesday, December 24, 2025 7:58 AM
To: OpenSCAD general discussion Mailing-list <discuss@lists.openscad.org
Cc: lee.deraud@roadrunner.com
Subject: Re: [OpenSCAD] Best starting point using Python with OpenSCAD?
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to
learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small
video for a starting point in case you are interested:
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <
discuss@lists.openscad.org> wrote:
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently
familiar with OS,
(2) relative beginner with python, and (3) working in a Windows
environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Sanjeev:
"You need to learn first to work with points list instead of openscad
primitives."
You and I think very differently. From my perspective, the whole point
of using OpenSCAD (plus BOSL2) is to NOT have to deal with point lists.
Jon
On 12/24/2025 10:58 AM, Sanjeev Prabhakar via Discuss wrote:
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You
need to learn first to work with points list instead of openscad
primitives.
I have written various examples for this approach and here is a small
video for a starting point in case you are interested:
https://youtu.be/kBshJ0CQCS0
https://urldefense.proofpoint.com/v2/url?u=https-3A__youtu.be_kBshJ0CQCS0&d=DwMFaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=C-2LNFc4Vy8H1YpL56LCiAEPDkG3QYO27Ipyvyc0DrQ2c1gbJkY4C2Ac9G-rFCJu&s=GOkemD40ePPDy_8Nl3SyQh9B-HzV8PuteL-E8-MnCrU&e=
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss
discuss@lists.openscad.org wrote:
The whole "just do it in python" thing seems to be turning into a
meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1)
decently familiar with OS,
(2) relative beginner with python, and (3) working in a Windows
environment (if that matters)?
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org
--
This email has been checked for viruses by AVG antivirus software.
www.avg.com
Hi Jon,
I understand your point of view.
Bosl2 basically works on the points list afaik, you may not be aware about
it though.
Openscad as a software is wonderful with it's capabilities to render
objects and boolean operations especially.
Only problem i feel is with the language.
Python is far better and with a well written library probably you would not
even know that you are using python and may look very similar to openscad.
On Thu, 25 Dec, 2025, 7:41 am Jon Bondy, jon@jonbondy.com wrote:
Sanjeev:
"You need to learn first to work with points list instead of openscad
primitives."
You and I think very differently. From my perspective, the whole point of
using OpenSCAD (plus BOSL2) is to NOT have to deal with point lists.
Jon
On 12/24/2025 10:58 AM, Sanjeev Prabhakar via Discuss wrote:
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to
learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small
video for a starting point in case you are interested:
https://youtu.be/kBshJ0CQCS0
https://urldefense.proofpoint.com/v2/url?u=https-3A__youtu.be_kBshJ0CQCS0&d=DwMFaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=C-2LNFc4Vy8H1YpL56LCiAEPDkG3QYO27Ipyvyc0DrQ2c1gbJkY4C2Ac9G-rFCJu&s=GOkemD40ePPDy_8Nl3SyQh9B-HzV8PuteL-E8-MnCrU&e=
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <
discuss@lists.openscad.org> wrote:
The whole "just do it in python" thing seems to be turning into a meme.
😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently
familiar with OS,
(2) relative beginner with python, and (3) working in a Windows
environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient
Virus-free.www.avg.com
http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient
<#m_4330863540560679973_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
As it happens, most of my OS work lately involves adding shapes to imported STLs from scans
or chunks thereof: I’m designing things like fender flares for plastic car models. Seemed like a
good idea at the time...not sure what the python stuff will bring to the table, but hey, learn
something new every day.
(My wife has described the last couple of weeks as “a scavenger hunt down a rabbit hole”.
It’s rapidly changing into multiple scavenger hunts down multiple rabbit holes. So it goes.)
From: Jon Bondy via Discuss discuss@lists.openscad.org
Sent: Wednesday, December 24, 2025 6:12 PM
To: OpenSCAD general discussion Mailing-list discuss@lists.openscad.org
Cc: lee.deraud@roadrunner.com; Sanjeev Prabhakar sprabhakar2006@gmail.com; Jon Bondy jon@jonbondy.com
Subject: [OpenSCAD] Re: Best starting point using Python with OpenSCAD?
Sanjeev:
"You need to learn first to work with points list instead of openscad primitives."
You and I think very differently. From my perspective, the whole point of using OpenSCAD (plus BOSL2) is to NOT have to deal with point lists.
Jon
On 12/24/2025 10:58 AM, Sanjeev Prabhakar via Discuss wrote:
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small video for a starting point in case you are interested:
https://youtu.be/kBshJ0CQCS0 https://urldefense.proofpoint.com/v2/url?u=https-3A__youtu.be_kBshJ0CQCS0&d=DwMFaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=C-2LNFc4Vy8H1YpL56LCiAEPDkG3QYO27Ipyvyc0DrQ2c1gbJkY4C2Ac9G-rFCJu&s=GOkemD40ePPDy_8Nl3SyQh9B-HzV8PuteL-E8-MnCrU&e=
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org > wrote:
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently familiar with OS,
(2) relative beginner with python, and (3) working in a Windows environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
Virus-free. http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient www.avg.com
On Wednesday, December 24, 2025 at 09:39:16 PM EST, Lee DeRaud via Discuss discuss@lists.openscad.org wrote:
As it happens, most of my OS work lately involves adding shapes to imported STLs from scans
or chunks thereof: I’m designing things like fender flares for plastic car models. Seemed like a
good idea at the time...not sure what the python stuff will bring to the table, but hey, learn
something new every day.(My wife has described the last couple of weeks as “a scavenger hunt down a rabbit hole”.
It’s rapidly changing into multiple scavenger hunts down multiple rabbit holes. So it goes.)
Recently on HackerNews, I had a bit of a discussion where one user posted:
One annoying thing is that the default way of writing programs in OpenSCAD uses 'modules',
which are a bit limited compared to functions (you can't store them as values to to functions
or other modules). I worked around that by writing a module that interprets arrays (think S-expressions)
that representing the shape, and then just build up that S-expression-like thing with functions and whatever.
which resulted in:
An example of an OpenSCAD design written this way: https://github.com/TOGoS/OpenSCADDesigns/blob/master/2023/experimental/Threads2.scad
I wrote about the approach a little bit in this Reddit post: https://www.reddit.com/r/openscad/comments/186b54r/interpreter_pattern_to_work_around_lack_of/
The interpreter itself is just a single module: https://github.com/TOGoS/OpenSCADDesigns/blob/master/2023/lib/TOGMod1.scad
which brings us back to OpenSCAD and while another hole, maybe is one worth looking into?
William
That's "just" vnf https://github.com/BelfrySCAD/BOSL2/wiki/vnf.scad using lists instead of functions.
On December 24, 2025 6:47:12 PM PST, "William F. Adams via Discuss" discuss@lists.openscad.org wrote:
On Wednesday, December 24, 2025 at 09:39:16 PM EST, Lee DeRaud via Discuss discuss@lists.openscad.org wrote:
As it happens, most of my OS work lately involves adding shapes to imported STLs from scans
or chunks thereof: I’m designing things like fender flares for plastic car models. Seemed like a
good idea at the time...not sure what the python stuff will bring to the table, but hey, learn
something new every day.(My wife has described the last couple of weeks as “a scavenger hunt down a rabbit hole”.
It’s rapidly changing into multiple scavenger hunts down multiple rabbit holes. So it goes.)
Recently on HackerNews, I had a bit of a discussion where one user posted:
One annoying thing is that the default way of writing programs in OpenSCAD uses 'modules',
which are a bit limited compared to functions (you can't store them as values to to functions
or other modules). I worked around that by writing a module that interprets arrays (think S-expressions)
that representing the shape, and then just build up that S-expression-like thing with functions and whatever.
which resulted in:
An example of an OpenSCAD design written this way: https://github.com/TOGoS/OpenSCADDesigns/blob/master/2023/experimental/Threads2.scad
I wrote about the approach a little bit in this Reddit post: https://www.reddit.com/r/openscad/comments/186b54r/interpreter_pattern_to_work_around_lack_of/
The interpreter itself is just a single module: https://github.com/TOGoS/OpenSCADDesigns/blob/master/2023/lib/TOGMod1.scad
which brings us back to OpenSCAD and while another hole, maybe is one worth looking into?
William
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
On 12/24/2025 9:37 PM, Cory Cross via Discuss wrote:
That's "just" vnf
https://github.com/BelfrySCAD/BOSL2/wiki/vnf.scad using lists instead
of functions.
Not even a little bit. VNF is vertices-n-faces, basically the
parameters for polyhedron(). What this person has done is to represent
the CSG tree as data, and then interpret it.
Note, for instance, this snippet:
https://github.com/TOGoS/OpenSCADDesigns/blob/master/2023/experimental/Threads2.scad
["union",
["translate", [0,0,head_height/2], ["rotate", [90,0,0], headside_hole]],
["translate", [0,0,head_height/2], ["rotate", [0,90,0], headside_hole]],
];
It's an interesting technique, though I'm not immediate seeing any big
win for this particular model.
Where it would be a win:
If I get bored in a couple of days I might take this model and translate
it back to "normal" OpenSCAD, and compare.
On December 24, 2025 11:31:57 PM PST, Jordan Brown via Discuss discuss@lists.openscad.org wrote:
On 12/24/2025 9:37 PM, Cory Cross via Discuss wrote:
That's "just" vnf
https://github.com/BelfrySCAD/BOSL2/wiki/vnf.scad using lists instead
of functions.
Not even a little bit. VNF is vertices-n-faces, basically the
parameters for polyhedron().
What do you think togthreads2_make_threads( is returning if not polyhedron data?
What this person has done is to represent
the CSG tree as data, and then interpret it.
OpenSCAD does that for you, if you write union() { translate( 0,0,head_height/2)... vnf_polyhedron(the_post); } instead.
Or you write a union function which operates on vnf: https://github.com/BelfrySCAD/BOSL2/wiki/regions.scad#functionmodule-union (though this only works on 2d AFAICT, but the concept isn't so limited) and https://github.com/BelfrySCAD/BOSL2/wiki/transforms.scad#functionmodule-move (which does operate fully on 3d vnf).
That's why I say it's "just" vnf: most all of BOSL2 works on vnf and geometry.
Where it would be a win:
...
You could write defmacros which operate on this CSG, but that doesn't appear, on rough review, to be exploited; and that it would save a lot of duplication to use BOSL2 instead.
Cory
Hi Jordan,
If you do a boolean on a couple of objects, you need a 'rule' (or user
decides) to specify the final object colour, since the original objects
no longer exist. If it is the faces that are coloured, then the exposed
faces may or may not retain their original colour (user decides). There
is a bit of complexity within openscad, as to whether parts are being
considered as 3d or 2d.
Best wishes,
Ray
O, so the color parametr for themdissapearsn 24/12/2025 01:02, Jordan
Brown via Discuss wrote:
Today's OpenSCAD color processing does face coloring. It is perfectly
possible to have the six faces of a cube have six different colors,
and if you union two shapes of different colors there's nothing known
about the color of the overlap area.
That scheme is fine, more or less, for visualization, but it doesn't
work well for actual 3D printing where you need to know what color (or
material) the interior of a shape is to be.
What you need is volumetric color, so that there are no overlapping
shapes and you always know what color the interior of a shape is.
I mentioned this need as part of a discussion of color semantics, and
one of the responses was that we didn't know how to do volumetric
color. I'd done an OpenSCAD demonstration of volumetric color and was
pretty sure that it was straightforward to come up with appropriate
processing, so I said I'd recreate that proof-of-concept for discussion.
And here it is.
Note: this is not the most efficient possible implementation. It
re-evaluates the model many times, when it really only needs to be
evaluated once. There should probably be a few more render()s
scattered around to try to get subtrees to be cached. But it looks
like it works.
Implementations of hull(), minkowski(), et cetera, and of the 2D
operations, left as an exercise for the reader.
Here's the result of this particular model, both in assembled form and
exploded by color:
// Volumetric color proof of concept
// Jordan Brown,openscad@jordan.maileater.net
// There are four relevant modules in this POC:
// col - replacement for color()
// uni - replacement for union()
// dif - replacement for difference()
// int - replacement for intersection()
// In this POC, the list of possible colors needs to be known in advance;
// in a built-in implementation it would either be collected during the
// evaluation phase or managed entirely dynamically. It would be
// straightforward to build a version of this POC that would be
// driven by an external script that would first run it in a
// "list colors" mode and would then run it once for each color.
// Similarly, in this POC the model is encapsulated in a module main(),
// while in a built-in implementation the final "step through the colors"
// loop would be implied and the model could be at the top level.
// This POC steps through the colors, generating the parts for one color,
// then the next, then the next. A built-in implementation could do
// that, or could do roughly the same operations across all colors at once.
// The model. A couple of unions, a difference, and an intersection
// to do a cutaway so that you can see the internal colors.
module main() {
int() {
uni() {
col("green") rotate([90,0,0]) cylinder(h=30, d=5, center=true);
dif() {
uni() {
col("red") cube(10);
col("blue") sphere(10);
}
cylinder(h=30, d=5, center=true);
}
}
rotate(-45) translate([0,-20,-20]) cube([40,40,40]);
}
}
// And now the infrastructure...
// Set the color of the children, like color().
// In this POC, this really operates by skipping anything that
// isn't the desired color, and then coloring during the per-color
// pass at the end, but there are other variations.
module col(c) {
union() { // work around #6456.
// $color=undef means that we want all colors - in particular,
// for the second-and-later children of dif() and int().
if (is_undef($color) || c == $color) {
children();
}
}
}
// Union the children.
// What this does is to draw the first child, then draw the second child
// less the first child, then the third less the first and second, and
// so on. Note that the negative components have $color=undef so that
// the entire subassembly, of all colors, gets subtracted out.
module uni() {
for (i=[0:1:$children-1]) {
// Add this child, less the children before it. Note that
// because of col() processing this might be only part
// of the logical subtree, but that's OK; what's important
// is that we mask it all colors of the previous children.
difference() {
children(i);
children([0:1:i-1], $color=undef);
}
}
}
// Difference the children.
// The only novel thing that this does is to set $color=undef
// for the second-and-later children, so that all colors are
// subtracted away from the first child. Again, because of
// col() processing the first child might only be a fraction of
// the logical subtree; it'll all get reassembled in the final
// multiple passes.
module dif() {
difference() {
children(0);
children([1:$children-1], $color=undef);
}
}
// Intersect the children.
// Think of this as taking the first child, and subtracting
// parts of it that are not in common with the later children.
// That neatly answers the question of what color the result
// should be, and makes everything consistent: the first child's
// color wins.
module int() {
intersection_for(i=[0:1:$children-1]) {
if (i == 0) {
children(i);
} else {
$color = undef;
children(i);
}
}
}
// As noted above, this list of colors needs to be
// known in advance; in a built-in implementation (or even
// in a script-driven userspace implementation) this list
// would be dynamically derived.
colors = [ "red", "green", "blue" ];
// Build the model.
for (c = colors) {
$color=c;
color(c) render() main();
}
// Build an exploded set so that you can see
// what the individual colored parts look like.
for (i = [ 0:len(colors)-1 ]) {
c = colors[i];
$color=c;
translate([20+i*20,0,0]) color(c) render() main();
}
OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org
It’s certainly nice to not deal with point lists most of the time, but BOSL2 also has an extensive array of functions that do just that. I had a difficult task when I tackled Hirth Joints. It turned out that BOSL2s VNFs were the secret to solving it. The solution was surprisingly elegant when completed.
-Bob
Tucson AZ
On Dec 24, 2025, at 21:11, Jon Bondy via Discuss discuss@lists.openscad.org wrote:
Sanjeev:
"You need to learn first to work with points list instead of openscad primitives."
You and I think very differently. From my perspective, the whole point of using OpenSCAD (plus BOSL2) is to NOT have to deal with point lists.
Jon
On 12/24/2025 10:58 AM, Sanjeev Prabhakar via Discuss wrote:
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small video for a starting point in case you are interested:
https://youtu.be/kBshJ0CQCS0 https://urldefense.proofpoint.com/v2/url?u=https-3A__youtu.be_kBshJ0CQCS0&d=DwMFaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=C-2LNFc4Vy8H1YpL56LCiAEPDkG3QYO27Ipyvyc0DrQ2c1gbJkY4C2Ac9G-rFCJu&s=GOkemD40ePPDy_8Nl3SyQh9B-HzV8PuteL-E8-MnCrU&e=
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:
The whole "just do it in python" thing seems to be turning into a meme. 😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently familiar with OS,
(2) relative beginner with python, and (3) working in a Windows environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient Virus-free.www.avg.com http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient x-msg://31/#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
On 12/25/2025 12:09 AM, Cory Cross via Discuss wrote:
What do you think togthreads2_make_threads( is returning if not polyhedron data?
Probably. But that's not the essence of the pattern.
What this person has done is to represent
the CSG tree as data, and then interpret it.
OpenSCAD does that for you, if you write union() { translate( 0,0,head_height/2)... vnf_polyhedron(the_post); } instead.
Indeed, I'm not at all sure that this scheme helps you any, in the vast
majority of cases. But it isn't just VNF; it's representing a CSG
tree as data and then interpreting that data.
an example of creating surface with 4 lines enclosure and creating a solid
On Wed, 24 Dec 2025 at 21:28, Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:
I have been working on openscad with python for a few years now.
I use Jupyter Lab to write my python code and it is working well for me.
But simply writing openscad code in python is not very useful. You need to
learn first to work with points list instead of openscad primitives.
I have written various examples for this approach and here is a small
video for a starting point in case you are interested:
https://youtu.be/kBshJ0CQCS0
On Wed, 24 Dec 2025 at 09:06, Lee DeRaud via Discuss <
discuss@lists.openscad.org> wrote:
The whole "just do it in python" thing seems to be turning into a meme.
😊
There appear to be multiple approaches to extending OS with python...
Any suggestions for where best to start, assuming someone (1) decently
familiar with OS,
(2) relative beginner with python, and (3) working in a Windows
environment (if that matters)?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
On December 24, 2025 7:48:59 AM PST, Jordan Brown via Discuss
discuss@lists.openscad.org wrote:
I haven’t thought too much about the language binding, about how you would say you want volumetric color. When I first played with this years ago, it was after somebody told me not to document the existing color behavior because it was kind of an accident and maybe not the right behavior. One of my initial thoughts would be to just cut over, accepting the short term pain to get the long term simplicity. However, (a) there are a lot of people relying, for visualization and other non-3DP purposes, on the current behavior, and (b) non-3DP applications like video games probably want face coloring, so reluctantly I wouldn’t recommend that choice today.
Also with fdm printing, sometimes face coloring is the right thing.
Every time someone chooses "purge to infill" they've abandoned
"volumetric color" to some degree, though not one that requires the
modeling software to be involved.
Slicers already allow you to color faces of models separate from the
interior, so coloring faces and having volumetric color already has
semantic meaning:
https://wiki.snapmaker.com/en/third_party_software/orcaslicer_color_painting
Lets take the example of creating a single-piece, non-functional traffic
light (i.e. only its outward appearance matters). With volumetric color
as proposed, I must prematurely decide what every internal volume is?
even if I only care about the face. Naively lets say I model most of it
out of yellow, then volumetrically union in the lights (lights being
complicated multi-material so they sparkle). But then I go to print and
I'm low on yellow. So I want yellow faces but a different volumetric
color. I think this can be solved with a conditional volumetric color,
i.e. color("purple", prior_color="yellow", volumetric_only=true), at the
appropriate place.
color("purple", prior_color="yellow", volumetric_only=true)
difference() { // volumetric diff because body is volumetric color
body(); // Already volumetric colored in this example
lights();
}
There, now I have a model with all yellow faces and a different
volumetric color, and I can print it.
Or, prepare the whole thing as a single multi-material model:
union() { // volumetric because at least one child is volumetric
color("purple", volumetric_only=true)
color("yellow", face_only=true)
body(); // Already colored, but doesn't matter in this example
lights();
}
which mostly minimizes the amount of yellow filament needed. (Truly
minimize by recoloring all yellow volume to purple like previous
example, in case the lights contain any yellow volumetric colors).
There aren't any operations for working on mesh faces, because OpenSCAD
doesn't let you directly target faces except by polyhedron? If you
wanted to model a superman chest S logo thing, with color, I assume
you'd have to make each delineation a slightly different height of
colored, linear extruded polygons? Or use polyhedron to explicitly
create the desired faces, which could allow you to set each face color
and have the final surface be perfectly flat. I'm not sure if being able
to color a subset of geometry faces is a good idea outside polyhedron
though, just because you have so little control of them being created.
I wonder if it ever makes sense to specify the non-volumetric
difference/union/intersection algorithm for a volumetrically-colored
geometry? I thought I had use cases above, but I'm not sure yet.
difference(volumetric=true)
difference(face=true)
Default is volumetric iff the first child is volumetric? (any for
intersection or union)
-Cory
On 12/29/2025 7:36 AM, Cory Cross via Discuss wrote:
Slicers already allow you to color faces of models separate from the
interior, so coloring faces and having volumetric color already has
semantic meaning:
https://wiki.snapmaker.com/en/third_party_software/orcaslicer_color_painting
Sure. Slicers can let you do anything to the model - especially in the
absence of good support elsewhere in the toolchain. But should you
have to? My mental model is that, to the greatest extent possible,
the modeling tool (OpenSCAD) is responsible for designing the final
model, and the slicer is responsible for making that vision real.
Anything that you must control in the slicer is a functionality gap. The
ideal is a Star Trek replicator; you give it a model and it gives you a
physical object, and you don't have to worry about materials, or print
orientation, or support, or layer lines, or performance tradeoffs.
Lets take the example of creating a single-piece, non-functional
traffic light (i.e. only its outward appearance matters). With
volumetric color as proposed, I must prematurely decide what every
internal volume is?
I'd say that the word "must" is ... misleading ... there. In any
variation, if you say color("red") cube(10) you get a 100% red cube. Is
it correct to say that you "must" specify the color of the interior?
No, I'd say that you (implicitly) have specified the color of the
interior, absent explicit editing downstream.
When you bring in multiple colors, and you say color("red") cube(10);
color("blue") sphere(10), there will be infill that's either red or
blue. Probably the cube-only parts will be red and the sphere-only
parts will be blue. But what color will the overlap be? With face
coloring, it's entirely up to the slicer, and there's no way to control
it from the modeling tool. With volumetric color, it's well-defined,
and there's presumably a way to control it.
even if I only care about the face. Naively lets say I model most of
it out of yellow, then volumetrically union in the lights (lights
being complicated multi-material so they sparkle). But then I go to
print and I'm low on yellow. So I want yellow faces but a different
volumetric color. I think this can be solved with a conditional
volumetric color, i.e. color("purple", prior_color="yellow",
volumetric_only=true), at the appropriate place.
First, note that with face coloring you'd have an unspecified color in
the interior. It's not like the slicer is going to automatically
separate it into a separate part to be assigned to a different
extruder. With volumetric color indeed the interior is yellow, but that
leaves you in approximately the same position: an object with an
interior that isn't the color you need it to be.
With volumetric color you could go back to the design tool and
re-color the interior as desired.
With either face-coloring or volumetric color, you could probably go in
with the slicer and manually specify which volumes are to be what
color. (Maybe it could do that semi-automatically, by having a "set
infill to <this> color" mechanism, or maybe you'd have to "paint" on
different colors.)
color("purple", prior_color="yellow", volumetric_only=true)
difference() { // volumetric diff because body is volumetric color
body(); // Already volumetric colored in this example
lights();
}
You're editing the color, saying "change this color to that color".
While I can't give a clear reason why that bothers me, it does.
If we were to try to do this, I would think of modeling this object like so:
union() {
lights();
color(faces="yellow", interior="purple") body();
}
But... what would that really mean? In digital-land, we can have
zero-thickness yellow paint on the outside of a purple object, but in
physical reality the yellow has to have a thickness. How thick should
it be, and where should you set that thickness? It seems like you're
hinting to the slicer that the outside should be yellow, to some depth,
but without saying anything about how deep; that would have to be up to
the slicer. And if it's up to the slicer, why not make the slicer
responsible for changing the interior color, rather than hinting from
the design tool?
If you really want to control it from the design tool, you have to
specify the thickness of the yellow... that is, you have to specify it
volumetrically.
You would want something like (handwaving furiously in the vicinity of
the offset()):
union() {
lights();
color("purple") offset(-1) body();
color(yellow") body();
}
There aren't any operations for working on mesh faces, because
OpenSCAD doesn't let you directly target faces except by polyhedron?
Indeed, if we wanted to truly support face coloring then I'd say that
polyhedron() should accept a "color" parameter that is an array parallel
to the "faces" array, that specifies the color of each face. (Or, more
generally, the texture.)
We could also do that for cubes, allowing a color parameter that
specifies the colors of the +Z, -Z, +X, -X, +Y, -Y sides, in that order.
Cylinders... tough. You could separately specify top, bottom, and
sides, and with $fn specified you could specify the sides. But if the
sides are curved, there's not much you could do.
Spheres... doesn't seem practical.
If you wanted to model a superman chest S logo thing, with color, I
assume you'd have to make each delineation a slightly different height
of colored, linear extruded polygons?
Why different heights? If they're separate extrusions then they are
just differently-colored shapes subject to the rules established for
combining differently-colored shapes. But really the color should be
preserved from 2D to 3D; you should draw N different-colored polygons
(which would have rules for how they combine), and then extrude them.
I wonder if it ever makes sense to specify the non-volumetric
difference/union/intersection algorithm for a volumetrically-colored
geometry? I thought I had use cases above, but I'm not sure yet.
difference(volumetric=true)
difference(face=true)
Default is volumetric iff the first child is volumetric? (any for
intersection or union)
Note that there's not much point to face-colored union. The results
visible from the outside are the same for volumetric and face-colored
union (unless you really like Z-fighting). The differences are in the
interior, where in volumetric union the results are well-defined and in
face-colored union the results are undefined.
I haven't thought about how volumetric and non-volumetric difference and
intersection would interact. Mostly, I think the answer is that you
want to design in either volumetric color or face color, and not mix the
two - and that in the long run, you mostly want to design in volumetric
color. But how do you specify which style you want? And what happens
when you do mix them?
On 12/29/25 10:36, Cory Cross via Discuss wrote:
On December 24, 2025 7:48:59 AM PST, Jordan Brown via Discuss
discuss@lists.openscad.org wrote:
I haven’t thought too much about the language binding, about how you
would say you want volumetric color. When I first played with this
years ago, it was after somebody told me not to document the existing
color behavior because it was kind of an accident and maybe not the
right behavior. One of my initial thoughts would be to just cut over,
accepting the short term pain to get the long term simplicity.
However, (a) there are a lot of people relying, for visualization and
other non-3DP purposes, on the current behavior, and (b) non-3DP
applications like video games probably want face coloring, so
reluctantly I wouldn’t recommend that choice today.
Also with fdm printing, sometimes face coloring is the right thing.
Every time someone chooses "purge to infill" they've abandoned
"volumetric color" to some degree, though not one that requires the
modeling software to be involved.
Seems to me the modeling software. like us, must be involved. OTOH the
traffic light situation seems to be best handled after the print with paint.
The amount of time needed to withdraw the current color, and refeed a
different one, purge until, just to color a traffic light lens seems to
be a huge time killer, one that would be a wasted time multiplier to me.
Just paint it. Or fit the correct color of LED. again after the fact.
What I might buy a box turtle or similar tool, for me would be that of
using up the spool, and autochanging to a fresh spool of the same color
so it runs out mid job and continues on the job with another spool of
the same color. I would be far more likely to build for that than for
multicolor.
Slicers already allow you to color faces of models separate from the
interior, so coloring faces and having volumetric color already has
semantic meaning:
https://wiki.snapmaker.com/en/third_party_software/orcaslicer_color_painting
Lets take the example of creating a single-piece, non-functional
traffic light (i.e. only its outward appearance matters). With
volumetric color as proposed, I must prematurely decide what every
internal volume is? even if I only care about the face. Naively lets
say I model most of it out of yellow, then volumetrically union in the
lights (lights being complicated multi-material so they sparkle). But
then I go to print and I'm low on yellow. So I want yellow faces but a
different volumetric color. I think this can be solved with a
conditional volumetric color, i.e. color("purple",
prior_color="yellow", volumetric_only=true), at the appropriate place.
color("purple", prior_color="yellow", volumetric_only=true)
difference() { // volumetric diff because body is volumetric color
body(); // Already volumetric colored in this example
lights();
}
There, now I have a model with all yellow faces and a different
volumetric color, and I can print it.
Or, prepare the whole thing as a single multi-material model:
union() { // volumetric because at least one child is volumetric
color("purple", volumetric_only=true)
color("yellow", face_only=true)
body(); // Already colored, but doesn't matter in this example
lights();
}
which mostly minimizes the amount of yellow filament needed. (Truly
minimize by recoloring all yellow volume to purple like previous
example, in case the lights contain any yellow volumetric colors).
There aren't any operations for working on mesh faces, because
OpenSCAD doesn't let you directly target faces except by polyhedron?
If you wanted to model a superman chest S logo thing, with color, I
assume you'd have to make each delineation a slightly different height
of colored, linear extruded polygons? Or use polyhedron to explicitly
create the desired faces, which could allow you to set each face color
and have the final surface be perfectly flat. I'm not sure if being
able to color a subset of geometry faces is a good idea outside
polyhedron though, just because you have so little control of them
being created.
I wonder if it ever makes sense to specify the non-volumetric
difference/union/intersection algorithm for a volumetrically-colored
geometry? I thought I had use cases above, but I'm not sure yet.
difference(volumetric=true)
difference(face=true)
Default is volumetric iff the first child is volumetric? (any for
intersection or union)
-Cory
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
On Dec 29, 2025, at 10:23 AM, gene heskett via Discuss <discuss@lists.openscad.org> wrote:
The amount of time needed to withdraw the current color, and refeed a different one, purge until, just to color a traffic light lens seems to be a huge time killer, one that would be a wasted time multiplier to me.
Recently, tool changing printers like the Snapmaker U1 are emerging that mitigate a lot of that.
🤯 The Snapmaker U1 Changes Tools 👌
-Revar
On 12/29/25 15:12, Revar Desmera via Discuss wrote:
On Dec 29, 2025, at 10:23 AM, gene heskett via Discuss
discuss@lists.openscad.org wrote:
The amount of time needed to withdraw the current color, and refeed a
different one, purge until, just to color a traffic light lens seems to be a
huge time killer, one that would be a wasted time multiplier to me.
Recently, tool changing printers like the Snapmaker U1 are emerging that
mitigate a lot of that.
oardefault.jpg
🤯 The Snapmaker U1 Changes Tools 👌 <https://youtube.com/shorts/29x94q-s8m8?
si=yYiS1vbp-y8NrNqa>
youtube.com https://youtube.com/shorts/29x94q-s8m8?si=yYiS1vbp-y8NrNqa
Interesting, until you realize its a bed slinger=slow. And they don't
show a corexy which could be 10x faster w/o breaking a sweat. Combine
that with a Sovol sv08 max which I have still in parts looking for space
for it and I'll drop the card instantly. That I expect will approach the
Prusa corexy, but I've BTDT, Over $1000 for a $20 hot end with half
stripped threads in the dead soft alu hot block & zero support. Call me
Pi$$ed. I will probably put a box turtle on the sv08 Max. Unless
someone comes up with a tool changer kit for the Max. That would be my
ideal 3d printer
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
Gene:
"Unless someone comes up with a tool changer kit for the Max."
Are you aware of this effort?
https://www.youtube.com/watch?v=h7yb_HNKJVw
Jon
On 12/29/2025 8:19 PM, gene heskett via Discuss wrote:
On 12/29/25 15:12, Revar Desmera via Discuss wrote:
On Dec 29, 2025, at 10:23 AM, gene heskett via Discuss >
discuss@lists.openscad.org wrote:
The amount of time needed to withdraw the current color, and refeed
a > different one, purge until, just to color a traffic light lens
seems to be a > huge time killer, one that would be a wasted time
multiplier to me.
Recently, tool changing printers like the Snapmaker U1 are emerging that
mitigate a lot of that.
oardefault.jpg
🤯 The Snapmaker U1 Changes Tools 👌
https://urldefense.proofpoint.com/v2/url?u=https-3A__youtube.com_shorts_29x94q-2Ds8m8-3F&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=bgduDWXOLEmt7ecPXNPd2uOVjQKneAgGfgVOCuQ_UAbKI8myL6jppCClGEfbwEBM&s=lADY2XbiVtRwnLiw2Y_OUfFTqjpZUXLfE5kXnUvtl7M&e=
si=yYiS1vbp-y8NrNqa>
https://urldefense.proofpoint.com/v2/url?u=http-3A__youtube.com&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=bgduDWXOLEmt7ecPXNPd2uOVjQKneAgGfgVOCuQ_UAbKI8myL6jppCClGEfbwEBM&s=d2HNwRBVd2YE-mRFVewme6xGTIvFoJRR05rN-JJQv5I&e=
https://urldefense.proofpoint.com/v2/url?u=https-3A__youtube.com_shorts_29x94q-2Ds8m8-3Fsi-3DyYiS1vbp-2Dy8NrNqa&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=bgduDWXOLEmt7ecPXNPd2uOVjQKneAgGfgVOCuQ_UAbKI8myL6jppCClGEfbwEBM&s=U6mVB1h-m_XoFC-Xicmfg5qv1wpdgArClkAYd3qBVoc&e=
Interesting, until you realize its a bed slinger=slow. And they don't
show a corexy which could be 10x faster w/o breaking a sweat. Combine
that with a Sovol sv08 max which I have still in parts looking for
space for it and I'll drop the card instantly. That I expect will
approach the Prusa corexy, but I've BTDT, Over $1000 for a $20 hot
end with half stripped threads in the dead soft alu hot block & zero
support. Call me Pi$$ed. I will probably put a box turtle on the
sv08 Max. Unless someone comes up with a tool changer kit for the
Max. That would be my ideal 3d printer
Cheers, Gene Heskett, CET.
--
This email has been checked for viruses by AVG antivirus software.
www.avg.com
On 12/29/25 21:03, Jon Bondy via Discuss wrote:
Gene:
"Unless someone comes up with a tool changer kit for the Max."
Are you aware of this effort?
No, I was not. Thank you Jon. I traced a goodly number of the URL's
there but did not find a "one place" that sells the whole kit, plus its
made for the smaller SV08, so at least the spring would have to grow,
and maybe the head cable too. IOW not the Max which has an operating
envelope of half a meter in all directions. Truly a monster size
wise... However, just a single dual head would get me an auto switch
for filament runout mid job situations. So I am wondering if the dual
nozzle head could be adapted to the SV08 Max. None of the links I
checked offered any info about that. Any SWAG's from anyone here?
Jon
On 12/29/2025 8:19 PM, gene heskett via Discuss wrote:
On 12/29/25 15:12, Revar Desmera via Discuss wrote:
On Dec 29, 2025, at 10:23 AM, gene heskett via Discuss >
discuss@lists.openscad.org wrote:
The amount of time needed to withdraw the current color, and
refeed a > different one, purge until, just to color a traffic
light lens seems to be a > huge time killer, one that would be a
wasted time multiplier to me.
Recently, tool changing printers like the Snapmaker U1 are emerging
that
mitigate a lot of that.
oardefault.jpg
🤯 The Snapmaker U1 Changes Tools 👌
https://urldefense.proofpoint.com/v2/url?u=https-3A__youtube.com_shorts_29x94q-2Ds8m8-3F&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=bgduDWXOLEmt7ecPXNPd2uOVjQKneAgGfgVOCuQ_UAbKI8myL6jppCClGEfbwEBM&s=lADY2XbiVtRwnLiw2Y_OUfFTqjpZUXLfE5kXnUvtl7M&e=
si=yYiS1vbp-y8NrNqa>
https://urldefense.proofpoint.com/v2/url?u=http-3A__youtube.com&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=bgduDWXOLEmt7ecPXNPd2uOVjQKneAgGfgVOCuQ_UAbKI8myL6jppCClGEfbwEBM&s=d2HNwRBVd2YE-mRFVewme6xGTIvFoJRR05rN-JJQv5I&e=
https://urldefense.proofpoint.com/v2/url?u=https-3A__youtube.com_shorts_29x94q-2Ds8m8-3Fsi-3DyYiS1vbp-2Dy8NrNqa&d=DwIGaQ&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=AsrE-c7ZR7B2Kyr3qgfvvppkCEBVsNmwEMndcrRSuOI&m=bgduDWXOLEmt7ecPXNPd2uOVjQKneAgGfgVOCuQ_UAbKI8myL6jppCClGEfbwEBM&s=U6mVB1h-m_XoFC-Xicmfg5qv1wpdgArClkAYd3qBVoc&e=
Interesting, until you realize its a bed slinger=slow. And they
don't show a corexy which could be 10x faster w/o breaking a sweat.
Combine that with a Sovol sv08 max which I have still in parts
looking for space for it and I'll drop the card instantly. That I
expect will approach the Prusa corexy, but I've BTDT, Over $1000 for
a $20 hot end with half stripped threads in the dead soft alu hot
block & zero support. Call me Pi$$ed. I will probably put a box
turtle on the sv08 Max. Unless someone comes up with a tool changer
kit for the Max. That would be my ideal 3d printer
Cheers, Gene Heskett, CET.
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
This got long again so I tried to drop more stuff, but if it's getting
too confusing please ping me for clarification.
On 12/29/25 9:32 AM, Jordan Brown via Discuss wrote:
On 12/29/2025 7:36 AM, Cory Cross via Discuss wrote:
Slicers already allow you to color faces of models separate from the
interior, so coloring faces and having volumetric color already has
semantic meaning:
https://wiki.snapmaker.com/en/third_party_software/orcaslicer_color_painting
Sure. Slicers can let you do anything to the model - especially in
the absence of good support elsewhere in the toolchain. But should
you have to?
Not sure if we have the same understanding or not, but that's just my
point. I think OpenSCAD should be able to create a model with face and
volumetric color simultaneously, because that's a model you can prepare
in the slicer. It's annoying to have to go back after reloading a model
and repeat some manual operations.
Lets take the example of creating a single-piece, non-functional
traffic light (i.e. only its outward appearance matters). With
volumetric color as proposed, I must prematurely decide what every
internal volume is?
I'd say that the word "must" is ... misleading ... there. In any
variation, if you say color("red") cube(10) you get a 100% red cube.
Is it correct to say that you "must" specify the color of the
interior? No, I'd say that you (implicitly) have specified the
color of the interior, absent explicit editing downstream.
My point is that with your volumetric color POC, I can't (?) color
faces, so to make my traffic light body yellow, I must give it the
volumetric color yellow? (the question marks are intentional, because
it's not clear to me)
even if I only care about the face. Naively lets say I model most of
it out of yellow, then volumetrically union in the lights (lights
being complicated multi-material so they sparkle). But then I go to
print and I'm low on yellow. So I want yellow faces but a different
volumetric color. I think this can be solved with a conditional
volumetric color, i.e. color("purple", prior_color="yellow",
volumetric_only=true), at the appropriate place.
First, note that with face coloring you'd have an unspecified color in
the interior.
Exactly: the inside is unspecified until the point where it makes sense
for me to do so.
It's not like the slicer is going to automatically separate it into a
separate part to be assigned to a different extruder. With volumetric
color indeed the interior is yellow, but that leaves you in
approximately the same position: an object with an interior that
isn't the color you need it to be.
Volumetric uncolor can get a default color when render is complete, like
face positive/negative uncolors. Or you should be able to say "color the
uncolored stuff only".
Lets say my traffic light has a black stripe across the back of it. With
the volumetric coloring POC, I now need to know how translucent my
filament will be and must encode the thickness in the model, instead of
the slicer adapting to different filaments (e.g. black can be thinner
than white).
union() { color("black") translate([0,0,15]) linear_extrude(h=10)
polygon([[0,10],[0.5,9.5],[9.5,9.5],[10,10]]); color("yellow")
cube([10,10,40]); }
Instead, with face coloring (but we should specify what to do with
coincident faces with different colors... I don't think that came up in
our color spec conversation), I should be able to:
union() { color("yellow") cube([10,10,40]); translate([0,10,15])
color("black") cube([10,0.01,10]);
Nothing in this second example specifies the internal volume color,
because I don't (yet) care. And yet it looks exactly how I want it to
(modulo the epsilon depth). And the slicer can handle the correct
thickness of material to create that black stripe and update it if I
change to green or white.
If we were to try to do this, I would think of modeling this object
like so:
union() {
lights();
color(faces="yellow", interior="purple") body();
}
Oh, I did get union backward; this is the way it'd have to be done with
your POC. And that would be a solution, except with the black stripe
problem.
But... what would that really mean? In digital-land, we can have
zero-thickness yellow paint on the outside of a purple object, but in
physical reality the yellow has to have a thickness. How thick should
it be, and where should you set that thickness? It seems like you're
hinting to the slicer that the outside should be yellow, to some
depth, but without saying anything about how deep; that would have to
be up to the slicer.
Yes, just like it's responsible for infill variations. Rarely does
anybody model infill, and similarly you don't need to actually extrude
every face inward to full define the 3d volume.
And if it's up to the slicer, why not make the slicer responsible for
changing the interior color, rather than hinting from the design tool?
Because you sometimes do care about the interior color; the lights can
be a tendrils of translucent filament going into the depth where they're
surrounded by other interior volume colors to create an appearance of
light from reflections. And you communicate that you don't care about
the volume color by specifically choosing a unique color, and then, in
the slicer, you map that color once and it persists across model
updates. Manual operations mostly can't persist
If you really want to control it from the design tool, you have to
specify the thickness of the yellow... that is, you have to specify it
volumetrically.
You don't, simply record exactly what the slicers already do: color some
subset of faces different than the volumetric colors and let the slicer
handle it, just like it handles infill.
I specified non-functional intentionally for the example. If you had a
rubber shell that had functional purpose for e.g. absorbing shock, then
you should specify its thickness in the model properly to do its job, a
particular shell of rubber around a stiffer core, where the interior
volume of the model matters.
But why shouldn't I be able to do all these steps in OpenSCAD?:
Your proposal is to add #2, but I think #3 should be brought along.
If you wanted to model a superman chest S logo thing, with color, I
assume you'd have to make each delineation a slightly different
height of colored, linear extruded polygons?
Why different heights? If they're separate extrusions then they are
just differently-colored shapes subject to the rules established for
combining differently-colored shapes.
You're right, it would be fine (still worry about Preview and coincident
faces, but not actually an issue here for the reasons you state).
On 12/30/25 01:02, Cory Cross via Discuss wrote:
This got long again so I tried to drop more stuff, but if it's getting
too confusing please ping me for clarification.
On 12/29/25 9:32 AM, Jordan Brown via Discuss wrote:
On 12/29/2025 7:36 AM, Cory Cross via Discuss wrote:
Slicers already allow you to color faces of models separate from the
interior, so coloring faces and having volumetric color already has
semantic meaning:
https://wiki.snapmaker.com/en/third_party_software/orcaslicer_color_painting
Sure. Slicers can let you do anything to the model - especially in
the absence of good support elsewhere in the toolchain. But should
you have to?
Not sure if we have the same understanding or not, but that's just my
point. I think OpenSCAD should be able to create a model with face and
volumetric color simultaneously, because that's a model you can
prepare in the slicer. It's annoying to have to go back after
reloading a model and repeat some manual operations.
Lets take the example of creating a single-piece, non-functional
traffic light (i.e. only its outward appearance matters). With
volumetric color as proposed, I must prematurely decide what every
internal volume is?
I'd say that the word "must" is ... misleading ... there. In any
variation, if you say color("red") cube(10) you get a 100% red cube.
Is it correct to say that you "must" specify the color of the
interior? No, I'd say that you (implicitly) have specified the
color of the interior, absent explicit editing downstream.
My point is that with your volumetric color POC, I can't (?) color
faces, so to make my traffic light body yellow, I must give it the
volumetric color yellow? (the question marks are intentional, because
it's not clear to me)
even if I only care about the face. Naively lets say I model most of
it out of yellow, then volumetrically union in the lights (lights
being complicated multi-material so they sparkle). But then I go to
print and I'm low on yellow. So I want yellow faces but a different
volumetric color. I think this can be solved with a conditional
volumetric color, i.e. color("purple", prior_color="yellow",
volumetric_only=true), at the appropriate place.
First, note that with face coloring you'd have an unspecified color
in the interior.
Exactly: the inside is unspecified until the point where it makes
sense for me to do so.
It's not like the slicer is going to automatically separate it into a
separate part to be assigned to a different extruder. With
volumetric color indeed the interior is yellow, but that leaves you
in approximately the same position: an object with an interior that
isn't the color you need it to be.
Volumetric uncolor can get a default color when render is complete,
like face positive/negative uncolors. Or you should be able to say
"color the uncolored stuff only".
Lets say my traffic light has a black stripe across the back of it.
With the volumetric coloring POC, I now need to know how translucent
my filament will be and must encode the thickness in the model,
instead of the slicer adapting to different filaments (e.g. black can
be thinner than white).
union() { color("black") translate([0,0,15]) linear_extrude(h=10)
polygon([[0,10],[0.5,9.5],[9.5,9.5],[10,10]]); color("yellow")
cube([10,10,40]); }
Instead, with face coloring (but we should specify what to do with
coincident faces with different colors... I don't think that came up
in our color spec conversation), I should be able to:
union() { color("yellow") cube([10,10,40]); translate([0,10,15])
color("black") cube([10,0.01,10]);
Nothing in this second example specifies the internal volume color,
because I don't (yet) care. And yet it looks exactly how I want it to
(modulo the epsilon depth). And the slicer can handle the correct
thickness of material to create that black stripe and update it if I
change to green or white.
If we were to try to do this, I would think of modeling this object
like so:
union() {
lights();
color(faces="yellow", interior="purple") body();
}
Oh, I did get union backward; this is the way it'd have to be done
with your POC. And that would be a solution, except with the black
stripe problem.
But... what would that really mean? In digital-land, we can have
zero-thickness yellow paint on the outside of a purple object, but in
physical reality the yellow has to have a thickness. How thick
should it be, and where should you set that thickness? It seems like
you're hinting to the slicer that the outside should be yellow, to
some depth, but without saying anything about how deep; that would
have to be up to the slicer.
Yes, just like it's responsible for infill variations. Rarely does
anybody model infill, and similarly you don't need to actually extrude
every face inward to full define the 3d volume.
And if it's up to the slicer, why not make the slicer responsible for
changing the interior color, rather than hinting from the design tool?
Because you sometimes do care about the interior color; the lights
can be a tendrils of translucent filament going into the depth where
they're surrounded by other interior volume colors to create an
appearance of light from reflections. And you communicate that you
don't care about the volume color by specifically choosing a unique
color, and then, in the slicer, you map that color once and it
persists across model updates. Manual operations mostly can't persist
If you really want to control it from the design tool, you have to
specify the thickness of the yellow... that is, you have to specify
it volumetrically.
You don't, simply record exactly what the slicers already do: color
some subset of faces different than the volumetric colors and let the
slicer handle it, just like it handles infill.
I specified non-functional intentionally for the example. If you had a
rubber shell that had functional purpose for e.g. absorbing shock,
then you should specify its thickness in the model properly to do its
job, a particular shell of rubber around a stiffer core, where the
interior volume of the model matters.
But why shouldn't I be able to do all these steps in OpenSCAD?:
Your proposal is to add #2, but I think #3 should be brought along.
If you wanted to model a superman chest S logo thing, with color, I
assume you'd have to make each delineation a slightly different
height of colored, linear extruded polygons?
Why different heights? If they're separate extrusions then they are
just differently-colored shapes subject to the rules established for
combining differently-colored shapes.
You're right, it would be fine (still worry about Preview and
coincident faces, but not actually an issue here for the reasons you
state).
You, Cory, have described the problem in detail I hadn't considered,
but that is the clearest description of the problem yet. IMO this is the
direction OpenSCAD should take. Unfortunately my oar in this is a
broken toothpick and likely does not see the problems that creating the
solution will involve.
Lets hope 2026 is better than 2025 has been.
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
On 12/29/2025 10:02 PM, Cory Cross via Discuss wrote:
Sure. Slicers can let you do anything to the model - especially in
the absence of good support elsewhere in the toolchain. But should
you have to?
Not sure if we have the same understanding or not, but that's just my
point. I think OpenSCAD should be able to create a model with face and
volumetric color simultaneously, because that's a model you can
prepare in the slicer. It's annoying to have to go back after
reloading a model and repeat some manual operations.
Hmm. Do slicers really support "painting" the model? I know it looks
like that from the UI, but what does it really mean depth-wise? If you
have a cube, and paint it all blue, what does that mean for the
interior? My assumption had always been that the paint-like UI was
only an approximation, and that really it was going to take that paint
and apply it throughout the model, until it ran into some other paint.
Do they really support the concept of "just change the outermost little
bit of this shape, but leave the interior alone"?
A quick experiment later... PrusaSlicer's "multimaterial painting"
feature does indeed paint the interior. I created a cube(10);
sphere(10); and painted the cube. The resulting slice carries the
cube's color throughout the cube, though the exact boundary is ...
strange. Here's pictures taken at a couple of different layers.
Still, that does seem like a plausible feature so that's an argument for
supporting it.
My point is that with your volumetric color POC, I can't (?) color faces,
Correct. (Noting again that I don't yet have a theory on how to make
legacy face painting and new volumetric coloring peacefully coexist, and
I accept the need for some sort of coexistence.)
so to make my traffic light body yellow, I must give it the
volumetric color yellow? (the question marks are intentional, because
it's not clear to me)
I would say "to make my traffic light body yellow, I must make it
yellow", but yes. With the POC there's no way to say "make the faces
yellow but the interior purple", or equivalently "make the faces yellow
but the interior unspecified".
Can the various formats even represent that? STL is monochromatic, of
course, but even the first-level workaround of having a different STL
for each color can't represent that face-vs-interior distinction. You'd
need to have two sets of STLs - one set that represents the face colors,
and another set that represents the interior colors. I have no idea
whether 3MF can distinguish between the color of a face and the color of
the interior.
My guess (a total guess) is that they can only represent the color of a
shape, and that the slicers then interpret that as the color of the
faces, and then flood the interior with that color, using some scheme
that decides on a boundary when two faces of the same shape have
different colors.
First, note that with face coloring you'd have an unspecified color
in the interior.
Exactly: the inside is unspecified until the point where it makes
sense for me to do so.
So one of the key questions is whether the color of the interior is an
aspect of the design (and so properly controlled by the design tool), or
an implementation detail (like layer height and infill pattern) and so
properly controlled by the slicer.
Lets say my traffic light has a black stripe across the back of it.
With the volumetric coloring POC, I now need to know how translucent
my filament will be and must encode the thickness in the model,
instead of the slicer adapting to different filaments (e.g. black can
be thinner than white).
Indeed, there's an argument that a slicer could have such a "paint"
feature, and could do a better job of it than the design tool can do.
I suspect that existing slicers do not have that feature. I started
over with the cube+sphere model, and put a single dot of second-extruder
on the side of the cube; here's what I got:
Instead, with face coloring (but we should specify what to do with
coincident faces with different colors... I don't think that came up
in our color spec conversation), I should be able to:
Theoretically, I think the answer should be the same as for volumes,
which means either first-wins or last-wins, and for me that coin came
down on first-wins.
Practically, however, there are cases where faces are mathematically
coincident but in actual calculation (because of floating point error,
grid snap, et cetera) are slightly off. I think best practice, as with
difference and for exactly the same reasons, is to avoid coincident faces.
Well, sort of. Having two objects that share the same side of the
same face, bad. Having two objects that share opposite sides of the
same face, not bad. That is:
color("red") cube(10);
color("blue") cube(5);
would be bad, because it would share 5x5 squares on three sides and it's
hard to tell what color those squares should be, and you care because
they're visible. However,
color("red") cube(10);
translate([10,0,0]) color("blue") cube(5);
would be OK because although at the micro level it's not clear exactly
where the boundary is or if there's a micro gap or overlap, at the macro
level it's clear that there is a boundary and that it's red on one
side and blue on the other side, and nobody cares about micro variations
on the inside.
Yes, just like it's responsible for infill variations. Rarely does
anybody model infill, and similarly you don't need to actually extrude
every face inward to full define the 3d volume.
Ref my "key question" above, but there's an additional tidbit here.
You say "extrude every face inward" like face coloring is the natural
behavior, like cube() defines faces and only happens to define the
enclosed volume. I would say, on the other hand, that volume coloring
is the natural behavior and that cube() defines a solid cube, and that
faces are only interesting because they are the boundary between cube
and not-cube. That is, conceptually, does cube() define six squares in
a particular layout, or does it define a six-sided solid? Yes, I know
that the mesh defines the faces, but conceptually is that because the
goal is to define faces, or is it because the goal is to define the
enclosed solid?
On 12/30/2025 10:37 AM, Jordan Brown via Discuss wrote:
Can the various formats even represent that? STL is monochromatic, of
course, but even the first-level workaround of having a different STL
for each color can't represent that face-vs-interior distinction.
You'd need to have two sets of STLs - one set that represents the face
colors, and another set that represents the interior colors. I have
no idea whether 3MF can distinguish between the color of a face and
the color of the interior.
My guess (a total guess) is that they can only represent the color of
a shape, and that the slicers then interpret that as the color of the
faces, and then flood the interior with that color, using some scheme
that decides on a boundary when two faces of the same shape have
different colors.
The 3MF specification allows the identification of up to three
properties per triangle, one for each vertex. Properties refer to
materials defined under the <basematerials> section. This information
was nominally destined to inform rendering in OpenGL/Direct3D/whatever,
but effectively defines a surface (boundary) coloring.
STL doesn't even preserve topology, much less inform color, boundary or
volumetric.
https://github.com/3MFConsortium/spec_core/blob/master/3MF%20Core%20Specification.md#41-meshes
ref: I've recently been writing OBJ, STL, and 3MF I/O routines, got
tired of messing with assimp...
I mentioned earlier, the complexity of mixing 2d with 3d, which openscad
tries to do. If the surface is treated as a thin solid, then everything
is solved by dealing with colour of a solid. That applies to 3d
printing, and even a painted surface.
If you want a pattern on the surface, then that is merely individual
extruded solid tris, but too many to think about.
For objects with solid colours, they can exist and retain their
individual colours, unless unioned. You need rules for booleans and
colour. but, you can leave the result of boolean colours as neutral, and
assign a colour to the final object, if required. You cannot add
colours, not usually in practice, since more than two or three unions
will usually end up as a brown mess.
If you generate the rules, and adhere to them, anything else can adapt
to them. When rules are inconsistent, that is where the problems occur.
Consider normal? fdm printing in plastic. Most slicers allow painting of
colours onto the object, since the earlier slicers had to do something
with stl files. obj files can have an axillary colour file, but I've
never seen that used, and ply files have colour built in, but orca and
many slicers do not import that. 3mf has a colour extension, but bbl
does not always conform. It seems that slicers do their own thing wrt
colour for the current crop of multicolour fdm printers. Resin and other
printers, probably no colour involved. My opinion, is that trying to put
colour into an object, and hoping that all slicers will interpret it, is
a bit pointless, unless the user can't change it in the slicer, which
they all can. You may as well not let the user scale or rotate the
object. (If you are running a print farm, then you may want one file
that isn't modified, but that will be the gcode/sliced file unless you
have different printer types, and if it is a business, you need to pay
for your cad!).
The other aspect that crops up is the use of colour to signify the type
of line, in laser cutting, say. In most cases, a colour fill will do the
same job in 2d, as a solid colour in 3d. since openscad does not have an
effective gui interface, it is probably not the best 2d drawing package
to use.
This sort of reminds me of the 1960's when diy and black and decker
drills became popular. Folk, not knowing much about power/bearings etc.,
began attaching grinding discs, circular saws and the like to the
drills, which then began to disassemble. The solution was to develop a
range of tools to do specific jobs.
The image, the red and green cubes placed overlapping, not unioned, and
tapered hole differenced. Since the part in the middle is both red and
green, you get some 'fighting', which to my mind is exactly as it should
be. If it is unioned, then it is one object, so the colour is grey,
unless assigned to whatever.
On 12/30/25 9:37 AM, Jordan Brown via Discuss wrote:
On 12/29/2025 10:02 PM, Cory Cross via Discuss wrote:
Not sure if we have the same understanding or not, but that's just my
point. I think OpenSCAD should be able to create a model with face
and volumetric color simultaneously, because that's a model you can
prepare in the slicer. It's annoying to have to go back after
reloading a model and repeat some manual operations.
Hmm. Do slicers really support "painting" the model? ...
A quick experiment later... PrusaSlicer's "multimaterial painting"
feature does indeed paint the interior. I created a cube(10);
sphere(10); and painted the cube. The resulting slice carries the
cube's color throughout the cube, though the exact boundary is ...
strange. Here's pictures taken at a couple of different layers.
It is, but they're also continually improving and evolving. Face
painting will likely only get better as time goes on.
so to make my traffic light body yellow, I must give it the
volumetric color yellow? (the question marks are intentional, because
it's not clear to me)
I would say "to make my traffic light body yellow, I must make it
yellow", but yes. With the POC there's no way to say "make the faces
yellow but the interior purple", or equivalently "make the faces
yellow but the interior unspecified".
Can the various formats even represent that? STL is monochromatic
We shouldn't concern ourselves with STL, it's inherently broken.
I have no idea whether 3MF can distinguish between the color of a face
and the color of the interior.
It can, 3MF is hierarchical so mesh can have a material and faces
(triangles) can override:
https://learn.microsoft.com/en-us/windows/uwp/devices-sensors/3d-generate-3mf#create-materials
Furthermore, individual triangles on each mesh can specify different
materials and different materials can even be represented within a
single triangle
Examples:
https://github.com/3MFConsortium/spec_materials/blob/master/3MF%20Materials%20Extension.md#chapter-5-multiproperties
and a "different faces with different colors":
https://github.com/3MFConsortium/3mf-samples/blob/master/examples/material/sphere_logo.png
Lets say my traffic light has a black stripe across the back of it.
With the volumetric coloring POC, I now need to know how translucent
my filament will be and must encode the thickness in the model,
instead of the slicer adapting to different filaments (e.g. black can
be thinner than white).
Indeed, there's an argument that a slicer could have such a "paint"
feature, and could do a better job of it than the design tool can do.
Right, but that's why I want to export just the colored face and not
change the interior of model. Let slicer handle the realization and
don't make me recolor it every time I reload my model.
Instead, with face coloring (but we should specify what to do with
coincident faces with different colors... I don't think that came up
in our color spec conversation), I should be able to:
Theoretically, I think the answer should be the same as for volumes,
which means either first-wins or last-wins, and for me that coin came
down on first-wins.
Sadly, it does not do that. I'm, uh, not sure exactly this is. F6 w/
Manifold (duh, because color).
union() { color("white") cube(10);
translate([0,0,5]) color("black") cube(10);
}
translate([15,0,0]) union() {
translate([0,0,5]) color("black") cube(10);
color("white") cube(10);
translate([5,0,5]) rotate([-90,0,0]) color("red") cylinder(d=5,h=10);
}
Practically, however, there are cases where faces are mathematically
coincident but in actual calculation (because of floating point error,
grid snap, et cetera) are slightly off.
I don't think that's true with Manifold (and we should skate to where
the puck's going to be).
I think best practice, as with difference and for exactly the same
reasons, is to avoid coincident faces.
Well, sort of. Having two objects that share the same side of the
same face, bad. Having two objects that share opposite sides of the
same face, not bad.
That's why I'm a bit lost on how to create and color a face in
OpenSCAD, which, except for polygon/polyhedron, exposes nothing about
faces. After all, it's going for CSG.
Yes, just like it's responsible for infill variations. Rarely does
anybody model infill, and similarly you don't need to actually
extrude every face inward to full define the 3d volume.
Ref my "key question" above, but there's an additional tidbit here.
You say "extrude every face inward" like face coloring is the natural
behavior, like cube() defines faces and only happens to define the
enclosed volume. I would say, on the other hand, that volume coloring
is the natural behavior and that cube() defines a solid cube, and
that faces are only interesting because they are the boundary between
cube and not-cube. That is, conceptually, does cube() define six
squares in a particular layout, or does it define a six-sided solid?
Yes, I know that the mesh defines the faces, but conceptually is that
because the goal is to define faces, or is it because the goal is to
define the enclosed solid?
The very fact that unioning two different "colored" solids has an
indeterminate interior essentially proves that it's six squares in a
particular layout.
If we ignore all coloring, we can exported the enclosed solid for 3D
printing, but you've already applied a transform (flattening color).
Arguing the original was an enclosed solid is like arguing a cube is 2d
because you ran projection on it and got a 2d shape.
Adding volumetric color makes geometry be an enclosed solid AND six
squares in a particular layout. You can then use only part of the output
(computer graphics only needs the faces) if you want. If slicers didn't
allow coloring faces, then exporting only enclosed solids would be all
you want to do. But since they do...
On 12/30/25 11:41 AM, Raymond West via Discuss wrote:
Consider normal? fdm printing in plastic. Most slicers allow painting
of colours onto the object, since the earlier slicers had to do
something with stl files. obj files can have an axillary colour file,
but I've never seen that used, and ply files have colour built in, but
orca and many slicers do not import that. 3mf has a colour extension,
but bbl does not always conform. It seems that slicers do their own
thing wrt colour for the current crop of multicolour fdm printers.
It's also chicken-and-egg; if inputs using these features are rare, then
there's no motivation to be able to import them. If we're taking the
effort to set up volumetric color, I think it's worth going all the way
and make a chicken.