OpenSCAD(R面取り)

OpenSCADでR面取りの方法を考えたのでメモしておきます。

OpenSCADでは2次元のR面取りはoffsetを組み合わせによって実現できますが、立方体のR面取りは、今のところ標準では関数が準備されていないようです。

en.wikibooks.org

scrapbox.io

少し調べてみると自作関数が公開されているのですが、うまく動かなかったり、動作が重くて多用出来なかったりしたので、関数を自作しました。

単純に、立方体に対して円柱を使って辺を丸くし、球を使って角を丸くしています。

f:id:ArtificialArts:20200221074141p:plain
roundedCube([15,20,10],2, 50);

roundedCube([15,20,10],3, 50);

module roundedCube(size=[15,15,15],radius=3, fragments=30)
{
    $fn=fragments;

    translate([radius,radius,0])
    cube([size[0]-radius*2,size[1]-radius*2,size[2]]);
    translate([radius,0,radius])
    cube([size[0]-radius*2,size[1],size[2]-radius*2]);
    translate([0,radius,radius])
    cube([size[0],size[1]-radius*2,size[2]-radius*2]);

    //Pillar
    translate([radius,radius,radius])
    cylinder(h=size[2]-radius*2, r=radius);
    translate([size[0]-radius,radius,radius])
    cylinder(h=size[2]-radius*2, r=radius);
    translate([radius,size[1]-radius,radius])
    cylinder(h=size[2]-radius*2, r=radius);
    translate([size[0]-radius,size[1]-radius,radius])
    cylinder(h=size[2]-radius*2, r=radius);
    
    //Side
    translate([0,0,size[2]-radius])
    {
        translate([radius,radius,0])
        rotate([0,90,0])
        cylinder(h = size[0]-radius*2, r=radius);
        translate([radius,size[1]-radius,0])
        rotate([0,90,0])
        cylinder(h = size[0]-radius*2, r=radius);
        translate([radius,radius,0])
        rotate([-90,0,0])
        cylinder(h = size[1]-radius*2, r=radius);
        translate([size[0]-radius,radius,0])
        rotate([-90,0,0])
        cylinder(h = size[1]-radius*2, r=radius);
    }
    translate([0,0,radius])
    {
        translate([radius,radius,0])
        rotate([0,90,0])
        cylinder(h = size[0]-radius*2, r=radius);
        translate([radius,size[1]-radius,0])
        rotate([0,90,0])
        cylinder(h = size[0]-radius*2, r=radius);
        translate([radius,radius,0])
        rotate([-90,0,0])
        cylinder(h = size[1]-radius*2, r=radius);
        translate([size[0]-radius,radius,0])
        rotate([-90,0,0])
        cylinder(h = size[1]-radius*2, r=radius);
    }
        
    //Corner
    translate([radius,radius,size[2]-radius])
    sphere(r=radius);
    translate([size[0]-radius,radius,size[2]-radius])
    sphere(r=radius);
    translate([radius,size[1]-radius,size[2]-radius])
    sphere(r=radius);
    translate([size[0]-radius,size[1]-radius,size[2]-radius])
    sphere(r=radius);
    
    translate([radius,radius,radius])
    sphere(r=radius);
    translate([size[0]-radius,radius,radius])
    sphere(r=radius);
    translate([radius,size[1]-radius,radius])
    sphere(r=radius);
    translate([size[0]-radius,size[1]-radius,radius])
    sphere(r=radius);
}

自分で使う都合上、底面以外を面取りするmoduleも作成しました。

f:id:ArtificialArts:20200210075056p:plain
topRoundedCube([15,20,10],3, 50);

module roundedCubeWithoutBottom(size=[15,15,15],radius=3, fragments=30)
{
    $fn=fragments;

    translate([radius,radius,0])
    cube([size[0]-radius*2,size[1]-radius*2,size[2]]);
    translate([radius,0,0])
    cube([size[0]-radius*2,size[1],size[2]-radius]);
    translate([0,radius,0])
    cube([size[0],size[1]-radius*2,size[2]-radius]);

    //Pillar
    translate([radius,radius,0])
    cylinder(h=size[2]-radius, r=radius);
    translate([size[0]-radius,radius,0])
    cylinder(h=size[2]-radius, r=radius);
    translate([radius,size[1]-radius,0])
    cylinder(h=size[2]-radius, r=radius);
    translate([size[0]-radius,size[1]-radius,0])
    cylinder(h=size[2]-radius, r=radius);
    
    //Side
    translate([0,0,size[2]-radius])
    union()
    {
        translate([radius,radius,0])
        rotate([0,90,0])
        cylinder(h = size[0]-radius*2, r=radius);
        translate([radius,size[1]-radius,0])
        rotate([0,90,0])
        cylinder(h = size[0]-radius*2, r=radius);
        translate([radius,radius,0])
        rotate([-90,0,0])
        cylinder(h = size[1]-radius*2, r=radius);
        translate([size[0]-radius,radius,0])
        rotate([-90,0,0])
        cylinder(h = size[1]-radius*2, r=radius);
    }
    
    //Corner
    translate([radius,radius,size[2]-radius])
    sphere(r=radius);
    translate([size[0]-radius,radius,size[2]-radius])
    sphere(r=radius);
    translate([radius,size[1]-radius,size[2]-radius])
    sphere(r=radius);
    translate([size[0]-radius,size[1]-radius,size[2]-radius])
    sphere(r=radius);
}

逆に、上面のみ面取りしないものも作成しました。

f:id:ArtificialArts:20200221080021p:plain
roundedCubeWithoutTop([15,20,10],2, 50);

module roundedCubeWithoutTop(size=[15,15,15],radius=3,fragments=30)
{
    $fn=fragments;
    
    translate([radius,radius,0])
    cube([size[0]-radius*2,size[1]-radius*2,size[2]]);
    translate([radius,0,radius])
    cube([size[0]-radius*2,size[1],size[2]-radius]);
    translate([0,radius,radius])
    cube([size[0],size[1]-radius*2,size[2]-radius]);
    
    //Pillar
    translate([radius,radius,radius])
    cylinder(h=size[2]-radius, d=radius*2);
    translate([size[0]-radius,radius,radius])
    cylinder(h=size[2]-radius, d=radius*2);
    translate([radius,size[1]-radius,radius])
    cylinder(h=size[2]-radius, d=radius*2);
    translate([size[0]-radius,size[1]-radius,radius])
    cylinder(h=size[2]-radius, d=radius*2);
    
    //Side
    translate([0,0,radius/2])
    union()
    {
        translate([radius,radius,radius/2])
        rotate([0,90,0])
        cylinder(h=size[0]-radius*2,d=radius*2);
        translate([radius,size[1]-radius,radius/2])
        rotate([0,90,0])
        cylinder(h = size[0]-radius*2, d=radius*2);
        translate([radius,radius,radius/2])
        rotate([-90,0,0])
        cylinder(h = size[1]-radius*2, d=radius*2);
        translate([size[0]-radius,radius,radius/2])
        rotate([-90,0,0])
        cylinder(h = size[1]-radius*2, d=radius*2);
    }
    //corner
    translate([radius,radius,radius])
    sphere(d=radius*2);
    translate([size[0]-radius,radius,radius])
    sphere(d=radius*2);
    translate([radius,size[1]-radius,radius])
    sphere(d=radius*2);
    translate([size[0]-radius,size[1]-radius,radius])
    sphere(d=radius*2);
}