Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

color() does not "inherit" as expected #4057

Closed
andysc opened this issue Jan 19, 2022 · 10 comments
Closed

color() does not "inherit" as expected #4057

andysc opened this issue Jan 19, 2022 · 10 comments

Comments

@andysc
Copy link

andysc commented Jan 19, 2022

I want to set an overall colour for a composite object, but colour sub-parts of it differently.

A simple example (the real one has modules to draw the sub-components):

color("white") {
    cube([10,10,10]);
 
    color("green")
        cylinder(d=10, h=15, $fn=150);
}

I would expect the cube to be white, and the cylinder to be green, but it comes out all white, i.e. it's ignoring the closer-binding green color instruction.

I can't see anything in the manual which suggests this shouldn't work as I expect, so suspect it's a bug?

OpenSCAD version 2021.01 on Mac

@andysc andysc changed the title color() does "inherit" as expected color() does not "inherit" as expected Jan 19, 2022
@nophead
Copy link
Member

nophead commented Jan 19, 2022

It isn't a bug. Modules always affect all their children and the cube and cylinder are implicitly unioned into one object that then gets coloured white.

I make complex assemblies with different coloured parts without any problems. You just need to put the color statements in the right places.

image

@UBaer21
Copy link
Contributor

UBaer21 commented Jan 19, 2022

the sequence is other way around the outer will supersede the inner - like an outer transformation is added to the inner

union(){
  color("white") 
      cube([10,10,10]);
  color("green")
      cylinder(d=10, h=15, $fn=150);
}

@t-paul t-paul closed this as completed Jan 19, 2022
@andysc
Copy link
Author

andysc commented Jan 19, 2022

@UBaer21 yes, as I mentioned, that trivial example didn't have the nesting that my real example does, otherwise I could have done what you proposed there.

@nophead I guess I was expecting color to bind more tightly than it does. Effectively, any "inner" color is ignored in favour of an outer one. All the other functions (e.g. translate, mirror, etc) have local effect, even if it's additive to the outer transformation matrix, so maybe the equivalent for colours would be colour addition? Adding green to white would have no effect, but maybe if my outer colour was blue, I'd get yellow when I added green to it?

It was just (to me) an unexpected effect, when the inner color function is just ignored.

But thank you both for your explanations :)

@andysc
Copy link
Author

andysc commented Jan 19, 2022

Perhaps the documentation could be updated to note that color statements can not be nested ?

@nophead
Copy link
Member

nophead commented Jan 19, 2022

I just depends on your mental model. The inner color does bind tightly to its children and colours them but the outer color does the same and overrides it. Yes colours could combine like paint but then I don't think that would be very useful.

When you have a single solid object, like a union, it doesn't make a lot of sense for it to have more than one colour unless you have a colour 3D printer, but even then it can be ambiguous when faces are shared. I apply a single colour to my objects that become STL files and are 3D printed. If they touch other 3D printed parts I use another colour so I can see the boundaries.

Other items like fasteners are coloured realistically and are just placed into or around the printed parts, so they never end up under the same color statement.

The documentation is a wiki, so feel free to add to it.

@UBaer21
Copy link
Contributor

UBaer21 commented Jan 19, 2022

what you try with nesting is apply a color twice

color("blue")color("red")cube();
which ends in a CSG tree

color([0, 0, 1, 1]) {
  color([1, 0, 0, 1]) {
    cube(size = [1, 1, 1], center = false);
  }
}

So think of it as you painted the cube red and then you paint over it in blue .. mixing colors would require to think of additive or subtractive and as white already is 1.1.1 you can't add anything however color are not part of the geometry and only visible in preview and png exports at the moment.

Also colors are always altered to give a 3D illusion / shading - so an object always has multiple colors. If you want mixing you probably could make this happens with special variables in multiple modules.

$c=[0,0,0.0];
A(c=[.2,0.5,0.3])translate([10,10])A(c=[.1,.1,.5]);

module A(c=[0,0,0]){
$c=$c+c;
 color($c)cube(5);
 children();
 }

@andysc
Copy link
Author

andysc commented Jan 19, 2022

Thanks both - that helps a lot - you're right: it just depends on your mental model.
I like the "apply it twice" explanation - that helps me a lot.
(and I wasn't seriously suggestion colour addition - I can't think of any use for that :))

I'll suggest a small change to the docs so future me doesn't trip over this again.

Thanks again

@UBaer21
Copy link
Contributor

UBaer21 commented Jan 19, 2022

color addition is possible like this to ensure you don't end up adding more than 1

$c=[0,0,0,1];
A(c=[.2,0.5,0.4,0])translate([10,10])A(c=[.1,.1,.5,0]);

module A(c=[0,0,0,0]){
$c=[min(1,$c[0]+c[0]),min(1,$c[1]+c[1]),min(1,$c[2]+c[2]),min(1,$c[3]+c[3])];
 color($c)cube(5);
 children();
 }

@andysc
Copy link
Author

andysc commented Jan 19, 2022

added
If colors are nested, the outer-most color "wins" and over-rides any lower-level color() statements.
here: https://en.wikibooks.org/w/index.php?title=OpenSCAD_User_Manual/First_Steps/Changing_the_color_of_an_object&stable=0
I hope that's OK.

@jordanbrown0
Copy link
Contributor

Not directly this topic: note that some color behaviors are somewhat deliberately not documented, because they are likely to change if we ever get multi-material multi-color support. Currently colors are applied only to faces and it is possible for an object to have different colors on different faces. With multi-color support color would have to be volumetric, and apply to the entire object. Different faces could not be different colors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants