Pull to refresh

Comments 5

Спс, улыбнуло) Ждем когда ИИ всех нас заменит и начнет прокладывать такие трубы

Почему вам в голову пришла использовать чат-бота для генерации трёхмерных моделей вместо специализированных на этой задаче моделей?

Есть целый ряд причин.

Во-первых, эта штука не написала в ответ, что, мол, "вижу, тут требуется 3D-объект, но я всего лишь чат-бот - обратитесь к специализированной системе". Напротив - оно прямо и уверенно пишет, что точно умеет в OpenSCAD, знает все детали, приводит примеры (я спрашивал), а также предлагает проверить, что всё в коде корректно и верно при помощи рендеринга в OpenSCAD (да, такой вот "напор" демонстрирует). Опять же - что такое "чат-бот"? Если это средство занять назойливых клиентов в чате технической поддержки пустопорожним переливанием запроса в ответ - ну, да, тогда с OpenSCAD лучше не подходить. Но позиционируется-то этот инструмент явно иначе.

Во-вторых, не то чтобы была у меня какая-то уверенность, но я предположил, что в эту систему, - возможно! - уже успели-таки встроить "специализированное решение для 3D". Это разумное предположение: такая возможность, без сомнения, полезна, системы постоянно обновляют, ждут в этом году "универсальный ИИ", то и дело утверждается, что оно успешно решает задачи по геометрии на уровне "продвинутого старшеклассника". Вот и проверили. Если бы оно справилось, это бы не сделало его интеллектом, но результат бы порадовал.

В-третьих, программное, процедурное задание простейших 3D-объектов - вообще-то не сложнее, скажем, реализации алгоритмов быстрой сортировки больших массивов, алгоритмов обработки графов, алгоритмов балансировки параллельной работы с данными и т.д., и т.п. В компьютерной геометрии есть свои сложности, но они точно не в генерировании описания трёх цлиндрических трубочек и параллелепипеда (предположим). Вся такая простая 3D-геометрия - выписывается в векторах, если хотите. С этой геометрией в видеоиграх справляются те же видеокарты, на которых запускают эти же LLM. Задача процедурного определения простейшего 3D-объекта, между прочим, не сложнее и поиска "уязвимостей в ПО". И уж тем более теряется сложность на фоне разговоров о генерировании видео по текстовому описанию. Конечно, всё это верно только в том случае, если там настоящий интеллект, который именно решает задачу, а не синонимайзер, замещающий решение сгенерированным текстом (или иерархией кластеров пикселей - не важно). Собственно, поэтому-то тут и возможны специализированные решения.

В-четвёртых, постоянно вижу и слышу, как LLM типа "чат-бот" используют для генерации программного кода - для этого ведь даже есть плагины в средах разработки. Код OpenSCAD - это чисто программный код, я же не просил рисовать чертёж в изометрии. Всё подходит.

Наконец, в-пятых: в качестве специализированной системы - я бы всё же предпочёл использовать тот или иной готовый инструмент для параметрического задания типовых объектов в OpenSCAD (Y-образный адаптер к ним тоже относится). Такие инструменты есть. Они детерминированы. Они проще. Натыкать в интерфейсе размеры - быстро. Но они - не LLM, на которых обещают "универсальный интеллект". Собственно, есть ведь и немало инструментов "визуального программирования". Даже для специальных систем, типа GNU Radio, но почему-то сейчас про них вообще забыли, а рассказывают именно про генерирование кода LLM, на которые всех заменят.

Ну, все-таки, результат сильно зависит от зравомыслия промпта. Вот без усложнений, вполне реализуется:

Скрытый текст

Напиши код OpenSCAD для разветвителя гибких шлангов, для воды. Это разветвитель один-в-два, то есть, одна входная трубка и две выходных, т.е. форма изделия Y-образная. Диаметр 35 мм, толщина стенки 2мм. Должно быть цельное изделие, напоминающее рогатку. Внутренний объем всех трех трубок должен быть свободен для протекания воды.

$fn = 100; // Качество рендеринга

// Основные параметры
diameter = 35;         // Внешний диаметр трубок
wall = 2;              // Толщина стенок
length = 100;          // Длина каждой ветви
angle = 45;            // Угол разветвления (градусы)
ridge_height = 3;      // Высота ограничительного бортика
ridge_width = 2;       // Выступ бортика

// Рассчитанные параметры
inner_dia = diameter - 2*wall; // Внутренний диаметр
transition_dia = diameter*1.5; // Диаметр центрального узла

// Параметры отображения
alpha = 0.7; // Прозрачность (0-1, где 1 - полностью непрозрачный)

module hollow_tube(l, d) {
    difference() {
        cylinder(h=l, d=d);
        translate([0, 0, -0.1])
            cylinder(h=l+0.2, d=inner_dia);
    }
}

module end_ridge() {
    difference() {
        cylinder(h=ridge_height, d=diameter + 2*ridge_width);
        translate([0, 0, -0.1])
            cylinder(h=ridge_height+0.2, d=diameter);
    }
}

module y_connector() {
    union() {
        // Центральный переходный узел
        hull() {
            sphere(d=transition_dia);
            
            // Основание входной трубки
            translate([0, 0, -diameter/2])
                sphere(d=diameter);
            
            // Основания выходных трубок
            for(a = [angle, -angle]) {
                rotate([0, a, 0])
                translate([0, 0, diameter/2])
                    sphere(d=diameter);
            }
        }
        
        // Входная трубка
        translate([0, 0, -length])
        union() {
            hollow_tube(length, diameter);
            translate([0, 0, length-ridge_height])
                end_ridge();
        }
        
        // Выходные трубки
        for(a = [angle, -angle]) {
            rotate([0, a, 0])
            translate([0, 0, diameter/2])
            union() {
                hollow_tube(length, diameter);
                translate([0, 0, length-ridge_height])
                    end_ridge();
            }
        }
    }
}

// Основная модель с прозрачностью
module y_splitter() {
    color("LightBlue", alpha) { // Голубой цвет с прозрачностью
        difference() {
            y_connector();
            
            // Внутренние полости (для гарантии протока)
            // Центральная полость
            sphere(d=inner_dia);
            
            // Входная полость
            translate([0, 0, -length-0.1])
                cylinder(h=length+0.1, d=inner_dia);
            
            // Выходные полости
            for(a = [angle, -angle]) {
                rotate([0, a, 0])
                translate([0, 0, -0.1])
                    cylinder(h=length+0.1, d=inner_dia);
            }
        }
    }
    
    // Визуализация внутренних полостей (красный цвет)
    %color("red", 0.3) {
        // Центральная полость
        sphere(d=inner_dia);
        
        // Входная полость
        translate([0, 0, -length-0.1])
            cylinder(h=length+0.1, d=inner_dia);
        
        // Выходные полости
        for(a = [angle, -angle]) {
            rotate([0, a, 0])
            translate([0, 0, -0.1])
                cylinder(h=length+0.1, d=inner_dia);
        }
    }
}

y_splitter();

Ну, все-таки, результат сильно зависит от зравомыслия промпта.

Это да. Но более простые - дают результат хуже.

Вот без усложнений, вполне реализуется:

Вообще, тут утрачены параллельные выводные трубки, но откуда-то взяты буртики (их нет в промпте). Но дело даже в не в этом - вот результат, который мне выдёт GPT-4o по этому же промпту:

Трубки
Трубки
Скрытый текст

Напиши код OpenSCAD для разветвителя гибких шлангов, для воды. Это разветвитель один-в-два, то есть, одна входная трубка и две выходных, т.е. форма изделия Y-образная. Диаметр 35 мм, толщина стенки 2мм. Должно быть цельное изделие, напоминающее рогатку. Внутренний объем всех трех трубок должен быть свободен для протекания воды.

$fn = 100; // сглаживание округлостей

// Параметры
outer_diameter = 35;
wall_thickness = 2;
inner_diameter = outer_diameter - 2 * wall_thickness;
length = 50; // длина каждого ответвления

// Создание одной трубки с внутренним отверстием
module pipe_segment(len) {
    difference() {
        cylinder(h = len, d = outer_diameter, center = false);
        translate([0, 0, -1])
            cylinder(h = len + 2, d = inner_diameter, center = false);
    }
}

// Поворот и размещение боковых трубок
module y_splitter() {
    union() {
        // Центральная (входная) трубка
        translate([0, 0, 0])
            pipe_segment(length);

        // Левая выходная трубка, под углом 45°
        translate([0, 0, length])
            rotate([45, 0, -45])
                pipe_segment(length);

        // Правая выходная трубка, под углом 45°
        translate([0, 0, length])
            rotate([45, 0, 45])
                pipe_segment(length);
    }
}

y_splitter();
Sign up to leave a comment.

Articles