/** This makes a special mysterious Christmas tree ornament. It looks like a featureless sphere but if you put a light inside, it displays an image! */ // Resolution of the model in voxels/inch res = 254/inch // Outer radius of main sphere r = 1 inch // Deepest depth to emboss deepestEmboss = 2 mm // Thinnest depth of outer shell (should be a multiple of nozzle width) thinnest = .4 mm // Inner diameter of hole to feed light through innerCylinderDiam = 10 mm // Thickness of cylinder walls cylinderThickness = 1.2 mm // Load an image. This one is blurred to give depth. // It can be obtained remotely by the following: // img = new image["https://frinklang.org/frinksamp/MischaBrightFaceBlackbgblur.png"] img = new image["file:MischaBrightFaceBlackbgblur.png"] // Radius of inner sphere r1 = r - thinnest - deepestEmboss // The main outer sphere outerSphere= callJava["frink.graphics.VoxelArray", "makeSphere", [r res]] // Inner sphere used for embossing sphere1 = callJava["frink.graphics.VoxelArray", "makeSphere", [r1 res]] // 2-pixel cube tool for embossing pixelTool = newJava["frink.graphics.VoxelArray", [0,2,0,2,0,2,true]] // Create an embossed pattern from the image. emboss = sphere1.sphericalEmboss[img, 0,0,0, 180 deg, 2 radian, 0, .7 pi radian, 10, 255, 0, 0, 0, -deepestEmboss res, pixelTool, 0, 0, 0] // Inner sphere plus embossing to be removed from outer sphere. scombined = sphere1.union[emboss] // Outer cylinder of ornament hanger outerCylinder = callJava["frink.graphics.VoxelArray", "makeCylinder", [0, 0, (r + .3 cm) res, 0, 0, (r - .3 cm) res, (innerCylinderDiam/2 + cylinderThickness) res]] // Union of outer sphere and outer cylinder. outerObj = outerSphere.union[outerCylinder] // Remove the inner sphere and embossing from the outer sphere. outerObj.remove[scombined] // Now remove a cylinder for the light to feed in innerCylinder = callJava["frink.graphics.VoxelArray", "makeCylinder", [0, 0, (r + .3 cm) res, 0, 0, (r - .3 cm) res, (innerCylinderDiam/2) res]] // Cut the mounting/light hole through into the object. outerObj.remove[innerCylinder] v = outerObj v.projectX[undef].show["X"] v.projectY[undef].show["Y"] v.projectZ[undef].show["Z"] filename = "MischaOrnamentBright.obj" print["Writing $filename..."] w = new Writer[filename] w.println[v.toObjFormat["v", 1/(res mm)]] w.close[] println["done."]