avatar_ArtDen

Программы для OpenSCAD - различные модели для 3D-печати

Автор ArtDen, 08 Янв. 2019 в 11:19

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

ArtDen

OpenSCAD - это бесплатная (и открытая) программа для создания 3D-моделей. Отличается от других подобных программ тем, что модель рисуется не мышкой на экране (или планшете), а путём написания программы, которая создаёт 3D-модель. Т.е. вы пишите программу (или используете уже готовую), создаёте модель, а затем её распечатываете на 3D-принтере.

Какие это даёт преимущества? Если программа написана правильно, то можно будет с лёгкостью настроить её на свои параметры. К примеру, я собираю батарею на элементах 18650 для самодельного самоката. Меняя параметры программы, я могу подобрать параметры так, чтобы аккумуляторы плотно сидели в узлах решётки и не шатались, а прочность всей конструкции была достаточной для моих целей.

Выкладываю на суд общественности своё "творчество" - программу для генерации модели держателей аккумуляторов 18650 (или любого другого диаметра) в батарее, которую я написал с нуля для освоения OpenSCAD :ah:
Спойлер
/////////////////////////////////////////////////////

d           = 18.5; // (мм) диаметр аккумулятора
l           = 1;    // (мм) расстояние между акумуляторами (чем больше, тем больше прочность конструкции)
h           = 10;   // (мм) Толщина держателя
h2          = 2;    // (мм) Глубина выемки под ленту
w           = 8.3;  // (мм) Ширина выемки под ленту
ch          = 2;    // (мм) высота цилиндрической части сверху
h3          = 1;    // (мм) высота дополнительного выреза под ленту
xcnt        = 4;    // (int) Количество аккумуляторов по горизонтали
ycnt        = 5;    // (int) Количество аккумуляторов по вертикали
cellular    = true; // (true,false) Располагать аккумуляторы как в пчелиных сотах
top_z       = true; // (true,false) Зацепка в верхней части
bottom_z    = true; // (true,false) Зацепка в нижней части
left_lenta  = true; // (true,false) дополнительная выемка под ленту справа
right_lenta = true; // (true,false) дополнительная выемка под ленту слева

/////////////////////////////////////////////////////

DL = 0.01;
$fn = 64;

XCellSize = cellular ? d * cos(30) + l : d + l;
YCellSize = d + l;
ZacepkaSize = cellular ? d/9 : d/11;

x_len = (xcnt-1)*XCellSize+d+2*l;
y_len = ycnt*YCellSize+l + (cellular ? YCellSize/2 : 0);

zac_shift = cellular ? (w/2+ZacepkaSize) : ((d-w/2)/2);

difference ()
{
    union()
    {
        cube([x_len, y_len, h]);
       
        for (x = [0:xcnt-1]) for (y = [0:ycnt-1])
        {
            crd = item_crd(x, y);
            translate([crd[0], crd[1], 0])
                cylinder(h = h+h2+ch, d = d+l*2);
        }
       
        for (x = [0:xcnt-1])
        {
            crd = item_crd(x, 0);
           
            even_x = (x % 2) == 0;
           
            if (even_x && bottom_z)
            {
                translate([crd[0]+zac_shift, 0, 0])
                    rotate([0, 0, 180])
                        zacepka(ds = -0.1);
                   
                translate([crd[0]-zac_shift, 0, 0])
                    rotate([0, 0, 180])
                        zacepka(ds = -0.1);
            }
            else if (!even_x && top_z)
            {
                translate([crd[0]+zac_shift, y_len, 0])
                    zacepka(ds = -0.1);

                translate([crd[0]-zac_shift, y_len, 0])
                    zacepka(ds = -0.1);
            }
        }
    }
   
    for (x = [0:xcnt-1]) for (y = [0:ycnt-1])
    {
        crd = item_crd(x, y);
        translate([crd[0], crd[1], h2])
            cylinder(h = h+ch+DL, d = d);
       
        if (right_lenta || (x != (xcnt-1)))
            lenta(crd, item_crd(x+1, y));
       
        lenta(crd, item_crd(x, y+1));
       
        if (left_lenta && (x == 0))
            lenta(crd, item_crd(-1, y));
       
        if (y == 0)
            lenta(crd, item_crd(x, -1));
    }
   
    for (x = [0:xcnt-1])
    {
        crd = item_crd(x, y);
       
       
        even_x = (x % 2) == 0;
       
        if (!even_x && bottom_z)
        {
            translate([crd[0]+zac_shift, -DL, -DL])
                zacepka(dh = 2*DL);

            translate([crd[0]-zac_shift, -DL, -DL])
                zacepka(dh = 2*DL);
        }
        else if (even_x && top_z)
        {
            translate([crd[0]+zac_shift, y_len+DL, -DL])
                rotate([0, 0, 180])
                        zacepka(dh = 2*DL);

            translate([crd[0]-zac_shift, y_len+DL, -DL])
                rotate([0, 0, 180])
                    zacepka(dh = 2*DL);
        }
    }
}


function item_crd(x, y) =
    let (xtest = min(max(x, 0), xcnt-1))
    [
        x*XCellSize+l+d/2,
        y*YCellSize+l+d/2 + (cellular && ((xtest % 2) == 1) ? YCellSize/2 : 0)
    ];


module lenta(crd1, crd2)
{
    x1 = crd1[0];
    x2 = crd2[0];
    y1 = crd1[1];
    y2 = crd2[1];
   
    u = atan2(y2-y1, x2-x1);
    ln = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
   
    translate([x1, y1, -DL])
        rotate([0, 0, u])
            linear_extrude(height=h2+h3)
                offset(r = w/2)
                    square([ln, DL]);
}


module zacepka(dh = 0, ds = 0)
{
    h = h + dh;
    linear_extrude(h)
    polygon([
        [-0.6 * ZacepkaSize-ds, 0],
        [-ZacepkaSize-ds, ZacepkaSize+ds],
        [ZacepkaSize+ds, ZacepkaSize+ds],
        [0.6*ZacepkaSize+ds, 0]
    ]);
}

Все настройки, которые используются в программе, вынесены в самое начало. Можно даже настраивать тип ячеек - квадратные или в виде пчелиных сот:
d           = 18.5; // (мм) диаметр аккумулятора
l           = 1;    // (мм) расстояние между акумуляторами (чем больше, тем больше прочность конструкции)
h           = 10;   // (мм) Толщина держателя
h2          = 2;    // (мм) Глубина выемки под ленту
w           = 8.3;  // (мм) Ширина выемки под ленту
ch          = 2;    // (мм) высота цилиндрической части сверху
h3          = 1;    // (мм) высота дополнительного выреза под ленту
xcnt        = 4;    // (int) Количество аккумуляторов по горизонтали
ycnt        = 5;    // (int) Количество аккумуляторов по вертикали
cellular    = true; // (true,false) Располагать аккумуляторы как в пчелиных сотах
top_z       = true; // (true,false) Зацепка в верхней части
bottom_z    = true; // (true,false) Зацепка в нижней части
left_lenta  = true; // (true,false) дополнительная выемка под ленту справа
right_lenta = true; // (true,false) дополнительная выемка под ленту слева


Модель, которую строит скрипт получается примерно такая:


... или для квадратных ячеек:


Как выгладит сам процесс работы в OpenSCAD:


Буду рад любым замечаниям.

PS: брать OpenSCAD можно отсюда: http://www.openscad.org/downloads.html . Как работать с OpenSCAD есть много уроков для новичков в youtube

ArtDen

А вот фактический результат работы этой программы. Аккумуляторы ждут сварки в распечатанных держателях:


В планах сделать программу для генерации модели сборных крыльев для колёс самоката.

ArtDen

Обещанное крыло для самоката. Сам ещё не печатал, т.к. принтер сломался. Жду комплектующих с али.
Спойлер
/////////////////////////////////////////////////////////////////

height        = 20;  // (мм) Высота
width         = 70;  // (мм) Ширина (ширина колеса + зазор)
s             = 4;   // (мм) Толщина
angle         = 45;  // (°) Угол
radius        = 140; // (мм) Радиус (радиус колеса + зазор)
stiffener_cnt = 3;   // Количество рёбер жёсткости
stiffener_len = 4;   // (мм) Высота ребра жёсткости
kr_cnt        = 4;   // Количество креплений
kr_diam       = 3;   // (мм) Диаметр креплени
kr_w          = 3;   // (мм) Толщина крепления

/////////////////////////////////////////////////////////////////

$fn = 64;
DL = 0.01;

b = width/2;
a = height;
c = (b*b - a*a)/(2*a);
r = c + a;
alpha = atan2(b, c);

rotate_extrude(angle=angle, $fn = 180)
    translate([radius-r, 0, 0])
    {
        fender_2d();
        stiffener_2d();
    }

kr_angle = atan2(kr_w, radius);

rotate([0, 0, 0])
    rotate_extrude(angle=kr_angle, $fn = 180)
        translate([radius-r, 0, 0])
            kr_2d();

rotate([0, 0, angle-kr_angle])
    rotate_extrude(angle=kr_angle, $fn = 180)
        translate([radius-r, 0, 0])
            kr_2d();

module fender_2d()
{
    alpha_step = alpha/32;
    for (an = [-alpha:alpha_step:alpha-alpha_step])
    {
        a1 = an;
        a2 = an+alpha_step;
        y1 = r * sin(a1);
        x1 = r * cos(a1);
        y2 = r * sin(a2);
        x2 = r * cos(a2);
        line2d([x1, y1], [x2, y2], s);
    }
}

module stiffener_2d()
{
    for (ai = [0:stiffener_cnt-1])
    {
        a = 2*ai*alpha/(stiffener_cnt-1) - alpha;
        y1 = r * sin(a);
        x1 = r * cos(a);
        y2 = (r+stiffener_len) * sin(a);
        x2 = (r+stiffener_len) * cos(a);
        line2d([x1, y1], [x2, y2], s);
     }
}


module kr_2d()
{
    kr_size = kr_diam*3;
    kr_alpha = alpha - atan2(kr_size/2+s, r);
   
    for (ai = [0:kr_cnt-1])
    {
        a = 2*ai*kr_alpha/(kr_cnt-1) - kr_alpha;
       
        rotate ([0, 0, a])
        {
            difference()
            {
                union()
                {
                    translate([r+kr_size/4+s/3, 0, 0])
                        square(size = [kr_size/2+s/3, kr_size], center = true);

                    translate([r+kr_size/2+s/2, 0, 0])
                        circle(d = kr_size);

                }
                translate([r+kr_size/2+s/2, 0, 0])
                    circle(d = 7*kr_diam/6);
            }
        }
    }
}


module line2d(crd1, crd2, width)
{
    x1 = crd1[0];
    x2 = crd2[0];
    y1 = crd1[1];
    y2 = crd2[1];

    u = atan2(y2-y1, x2-x1);
    ln = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));

    translate([x1, y1])
        rotate([0, 0, u])
                offset(r = width/2)
                    square([ln, DL]);
}
Как и в прошлой программе все настройки вынесены в начало. Настройка "Угол" нужна для того, чтобы печатать крыло по частям, если принтер не может напечатать его целиком. В моём случае эта настройка стоит 45 градусов. Соответственно для одного крыла надо распечатать 4 такие части и скрепить винтиками.

Вот как выглядит модель с моими настройками:


В ней 3 ребра жёсткости и 4 крепления на каждом конце. Если же задать угол в 180 градусов, то модель будет выглядеть так:


PS: чтобы программа работала, надо скачать последний OpenSCAD из раздела Development Snapshots.

ArtDen

Напечатал для проверки, что всё печатается без проблем:


Потом перепечатаю с правильными размерам ))

ArtDen

Разломал крыло о большой бордюр? Ничего страшного просто заново распечатываешь разломанные секции  ;-)