you can use surface()
, see http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Surface. Calculate the heightmap in an external script and write the values in a file, e.g. 'surface.dat'. you can translate and rotate the resulting surface and use it in difference()
.
I tried it with this code and the 'surface.dat' from documentation
difference() {
translate([0,0,5])cube([10,10,10], center =true);
rotate([0,0,90])surface(file = "surface.dat", center = true, convexity = 5);}
edit 28.10.2014:
in another way you can use pixeldata in a matrix to place pixel by pixel on the circumference of the bracelet by a for loop and iteration over the matrix. The vectors in the matrix contain pixel(x), pixel(y) and the greyvalue/255 as dimension for depth of engraving. To reduce the number of shapes the pixels of one column can be pooled, creating a polygon representing the depth-profile of this column and linear-extrude it. In this case the vectors contain the pixel(x) and the pointmatrix of the polygon. I tried it successfully with the known graphic of Che. To generate the matrix i use python3.4, PyQt5 and Qt.QtGui.QImage. By default openscad turns off rendering at 2000 elements. You can set it to the needed number under Edit/Preferences/Advanced
the openscad-script:
include <./matrix_p.scad>;
difference() {
translate([-b,0,0]) rotate([0,90,0]) difference() {
cylinder(h = hb, r = rb, center = false);
translate([0,0,-0.5]) cylinder(h = hb+1, r = rb-tb, center = false);
}
for (val = m)
rotate([-ap*val[0],0,0]) translate([0,-rb-0.1,-ps/2]) linear_extrude(height = ps) polygon(points = val[1]);
}
parameter set in matrix_p.scad:
// userinput
rb = 50; //radius bracelet
tb = 5; //thickness of b.
hb = 80; //height of b.
b = 10; //borderwidth beside engraving
// input from Qt.QtGui.QImage
iw = 590; //imagewidth in pixel
ih = 726; //height in pixel
ps = (hb-2*b)/ih; //scaling of pixel to fill the free place
ap = (ps*180)/(PI*rb); //angle per pixel
Download all scripts