trying to difference text block from cube

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

trying to difference text block from cube

jordanthompson
Total nube trying to get started with OpenSCAD...

I have the following code that is partially working the way I'd hoped. If I run only companyName(), I get what I want (an indented area with raised letters).

When I try to difference it from a cube, it becomes letters etched into a two dimensional rectangle positioned away from the cube.

My goal is to be able to create a reusable text block that I can imprint on my parts. I want this to be raised text in a recessed rectangle.

Any help would be most appreciated!


use <fontmetrics.scad>;

module companyName(x, y, z,height) {
    textDepth=1;
    border=1;
    textSpacing=.5;
    usableHeight=height-2*border-3*textSpacing;
    topTextHeight=usableHeight/2;
    bottomTextHeight=usableHeight/3;
    font = "Arial";
    topText = "Top Text";
    bottomText = "Bottom Text";
    topTextLength = measureText(topText, font=font, size=topTextHeight);
    bottomTextLength = measureText(bottomText, font=font, size=bottomTextHeight);
    echo("topTextLength", topTextLength);
    echo("bottomTextLength", bottomTextLength);
    
    translate([x-2*textDepth,y,z]) {

        difference() {
            if (topTextLength > bottomTextLength) {
                cube([2*textDepth, topTextLength+2*border+3*textSpacing, height]);
            } else {
                echo("here");
                cube([2*textDepth, bottomTextLength+2*border+3*textSpacing, height]);
            }
            translate([textDepth,border, border]) {
                if (topTextLength > bottomTextLength) {
                    cube([2*textDepth, topTextLength+border+textSpacing, height-2*border]);
                } else {
                    cube([2*textDepth, bottomTextLength+border+textSpacing, height-2*border]);
                }

            }
        }
        translate([textDepth, border+textSpacing, height-border-topTextHeight-textSpacing]) {
            rotate([90,0,90]) {
                linear_extrude(textDepth)
                drawWrappedText(topText,font=font,size=topTextHeight,halign="justify");
                //text(text, size=topTextHeight);
            }
        }
        translate([textDepth, border+textSpacing, border+textSpacing]) {
            rotate([90,0,90]) {
                linear_extrude(textDepth)
                text(bottomText, size=bottomTextHeight);
            }
        }
    }
}

module notWorking() {
    difference() {
       cube([4, 50, 50]);
       companyName(4, 0, 0, height=10);
    }
}

module working() {
    companyName(4, 0, 0, height=10);
}




	
	
	


Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: trying to difference text block from cube

JordanBrown
On 7/6/2020 1:34 AM, jordanthompson wrote:
Total nube trying to get started with OpenSCAD...

I have the following code that is partially working the way I'd hoped. If I run only companyName(), I get what I want (an indented area with raised letters).

When I try to difference it from a cube, it becomes letters etched into a two dimensional rectangle positioned away from the cube.

My goal is to be able to create a reusable text block that I can imprint on my parts. I want this to be raised text in a recessed rectangle.

Any help would be most appreciated!


You have two things going on.

The first is easy.  It's a preview rendering problem called Z-fighting.  When you difference two objects that share a face, the renderer can't figure out whether the face is there or not.  The solution is to ensure that the thing that you are subtracting, the negative space, extends past the boundary of the thing you're subtracting from. In this particular case, the easy thing to do is to offset the companyName() by just a little, perhaps:
module notWorking() {
    difference() {
       cube([4, 50, 50]);
       translate([0.01,-0.01,-0.01])
           companyName(4, 0, 0, height=10);
    }
}
Z-fighting most obviously affects F5 previews rather than F6 renders, because of the algorithms used.  However, F6 can be vulnerable to similar effects when the locations of the surfaces involved are derived from math that can yield imprecise results.


The second and harder, and what I think you're asking about, is that you aren't thinking of difference() correctly.  Remember what your companyName() looks like.  You are *removing* that material from the cube, so the result is the negative of it.  It sounds like you're thinking that in
difference() {
    A();
    B();
}
that B will somehow replace a part of A.  (But how could it?  B is an object and an infinite amount of empty space; how much of that empty space would replace part of A?)

If you want it to behave the way you're thinking, you have to arrange that B is the negative of what you want to remain.

That requires a little rearranging.

Simplifying, your current notWorking() is:
difference() {
    cube();        // big cube
    difference() {
        cube();    // A
        cube();    // B
    }
    linear_extrude() text();
}
That is, you are taking a cube A, removing another cube B to form an inset, and then adding some text, and then subtracting the result from the big cube.

In arithmetic notation, you've got (bigcube - ((A - B) + text)).  You want ((bigcube - B) + text), that you're going to take your object, subtract away an inset, and then put some text into that inset.  That expression doesn't work for you, because you want the B and "text" to come together in one module, so you want to algebraically transform it to (bigcube - (negative - text)).

It doesn't quite work like arithmetic, but it's close.  In arithmetic, a double negative is a positive.  A-(A-B) is equal to B.  In OpenSCAD CSG, a result can never be negative, so A-B can be anything from zero to A and A-(A-B) can't be more than A.  Strictly, it's set differencing rather than arithmetic differencing.

You need to be subtracting the inset, except the text, like so:
difference() {
    cube();    // big cube
    difference() {
        cube();   // negative
        linear_extrude() text();
    }
}
Note that your first cube, the one I labelled "positive", is not required.  It's material that you expect to remain from the object being imprinted; it isn't part of the "negative space".

Here's what you want companyName() to produce:




Note that this scheme is based solely on differencing - you cannot use it to make text that will extend outside the original "big cube".  Doing that would require removing the inset as one step, and then adding the text.

Here's what you need.  All I've done is to remove cube A and move the text inside the difference() so that it's being subtracted from cube B.  Oh, and I renamed "notWorking" to "nowWorking" :-)

use <fontmetrics.scad>;

module companyName(x, y, z,height) {
    textDepth=1;
    border=1;
    textSpacing=.5;
    usableHeight=height-2*border-3*textSpacing;
    topTextHeight=usableHeight/2;
    bottomTextHeight=usableHeight/3;
    font = "Arial";
    topText = "Top Text";
    bottomText = "Bottom Text";
    topTextLength = measureText(topText, font=font, size=topTextHeight);
    bottomTextLength = measureText(bottomText, font=font, size=bottomTextHeight);
    echo("topTextLength", topTextLength);
    echo("bottomTextLength", bottomTextLength);
    
    translate([x-2*textDepth,y,z]) {

        difference() {
            translate([textDepth,border, border]) {
                if (topTextLength > bottomTextLength) {
                    cube([2*textDepth, topTextLength+border+textSpacing, height-2*border]);
                } else {
                    cube([2*textDepth, bottomTextLength+border+textSpacing, height-2*border]);
                }

            }
            
            translate([textDepth, border+textSpacing, height-border-topTextHeight-textSpacing]) {
                rotate([90,0,90]) {
                    linear_extrude(textDepth)
                    drawWrappedText(topText,font=font,size=topTextHeight,halign="justify");
                    //text(text, size=topTextHeight);
                }
            }
            translate([textDepth, border+textSpacing, border+textSpacing]) {
                rotate([90,0,90]) {
                    linear_extrude(textDepth)
                    text(bottomText, size=bottomTextHeight);
                }
            }

        }
    }
}

module nowWorking() {
    difference() {
       cube([4, 50, 50]);
       translate([0.01,-0.01,-0.01]) companyName(4, 0, 0, height=10);
    }
}

module working() {
    companyName(4, 0, 0, height=10);
}

nowWorking();


Like so:



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: trying to difference text block from cube

JordanBrown
On 7/6/2020 8:49 AM, Jordan Brown wrote:
On 7/6/2020 1:34 AM, jordanthompson wrote:
Total nube trying to get started with OpenSCAD...

I have the following code that is partially working the way I'd hoped. If I run only companyName(), I get what I want (an indented area with raised letters).

When I try to difference it from a cube, it becomes letters etched into a two dimensional rectangle positioned away from the cube.

My goal is to be able to create a reusable text block that I can imprint on my parts. I want this to be raised text in a recessed rectangle.

Any help would be most appreciated!


You have two things going on.

The first is easy.  It's a preview rendering problem called Z-fighting.  When you difference two objects that share a face, the renderer can't figure out whether the face is there or not.  The solution is to ensure that the thing that you are subtracting, the negative space, extends past the boundary of the thing you're subtracting from. In this particular case, the easy thing to do is to offset the companyName() by just a little, perhaps:
module notWorking() {
    difference() {
       cube([4, 50, 50]);
       translate([0.01,-0.01,-0.01])
           companyName(4, 0, 0, height=10);
    }
}
Z-fighting most obviously affects F5 previews rather than F6 renders, because of the algorithms used.  However, F6 can be vulnerable to similar effects when the locations of the surfaces involved are derived from math that can yield imprecise results.


The second and harder, and what I think you're asking about, is that you aren't thinking of difference() correctly.  Remember what your companyName() looks like.  You are *removing* that material from the cube, so the result is the negative of it.  It sounds like you're thinking that in
difference() {
    A();
    B();
}
that B will somehow replace a part of A.  (But how could it?  B is an object and an infinite amount of empty space; how much of that empty space would replace part of A?)

If you want it to behave the way you're thinking, you have to arrange that B is the negative of what you want to remain.

That requires a little rearranging.

Simplifying, your current notWorking() is:
difference() {
    cube();        // big cube
    difference() {
        cube();    // A
        cube();    // B
    }
    linear_extrude() text();
}
That is, you are taking a cube A, removing another cube B to form an inset, and then adding some text, and then subtracting the result from the big cube.

In arithmetic notation, you've got (bigcube - ((A - B) + text)).  You want ((bigcube - B) + text), that you're going to take your object, subtract away an inset, and then put some text into that inset.  That expression doesn't work for you, because you want the B and "text" to come together in one module, so you want to algebraically transform it to (bigcube - (negative - text)).

It doesn't quite work like arithmetic, but it's close.  In arithmetic, a double negative is a positive.  A-(A-B) is equal to B.  In OpenSCAD CSG, a result can never be negative, so A-B can be anything from zero to A and A-(A-B) can't be more than A.  Strictly, it's set differencing rather than arithmetic differencing.

You need to be subtracting the inset, except the text, like so:
difference() {
    cube();    // big cube
    difference() {
        cube();   // negative
        linear_extrude() text();
    }
}
Note that your first cube, the one I labelled "positive", is not required.  It's material that you expect to remain from the object being imprinted; it isn't part of the "negative space".

Sigh.  I changed the labels as I wrote the message, and missed one.  Should be "Note that your first cube, the one I labelled A, is not required".


Here's what you want companyName() to produce:




Note that this scheme is based solely on differencing - you cannot use it to make text that will extend outside the original "big cube".  Doing that would require removing the inset as one step, and then adding the text.

Here's what you need.  All I've done is to remove cube A and move the text inside the difference() so that it's being subtracted from cube B.  Oh, and I renamed "notWorking" to "nowWorking" :-)

use <fontmetrics.scad>;

module companyName(x, y, z,height) {
    textDepth=1;
    border=1;
    textSpacing=.5;
    usableHeight=height-2*border-3*textSpacing;
    topTextHeight=usableHeight/2;
    bottomTextHeight=usableHeight/3;
    font = "Arial";
    topText = "Top Text";
    bottomText = "Bottom Text";
    topTextLength = measureText(topText, font=font, size=topTextHeight);
    bottomTextLength = measureText(bottomText, font=font, size=bottomTextHeight);
    echo("topTextLength", topTextLength);
    echo("bottomTextLength", bottomTextLength);
    
    translate([x-2*textDepth,y,z]) {

        difference() {
            translate([textDepth,border, border]) {
                if (topTextLength > bottomTextLength) {
                    cube([2*textDepth, topTextLength+border+textSpacing, height-2*border]);
                } else {
                    cube([2*textDepth, bottomTextLength+border+textSpacing, height-2*border]);
                }

            }
            
            translate([textDepth, border+textSpacing, height-border-topTextHeight-textSpacing]) {
                rotate([90,0,90]) {
                    linear_extrude(textDepth)
                    drawWrappedText(topText,font=font,size=topTextHeight,halign="justify");
                    //text(text, size=topTextHeight);
                }
            }
            translate([textDepth, border+textSpacing, border+textSpacing]) {
                rotate([90,0,90]) {
                    linear_extrude(textDepth)
                    text(bottomText, size=bottomTextHeight);
                }
            }

        }
    }
}

module nowWorking() {
    difference() {
       cube([4, 50, 50]);
       translate([0.01,-0.01,-0.01]) companyName(4, 0, 0, height=10);
    }
}

module working() {
    companyName(4, 0, 0, height=10);
}

nowWorking();


Like so:



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: trying to difference text block from cube

jordanthompson
In reply to this post by jordanthompson
Genius!!!  Thanks very much for your help and spoon-feeding (we Jordan's have
to help each other out :-).)



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org