среда, 11 апреля 2012 г.

Изучение Blender API Часть 3

Подумав по поводу дальнейших действий, пришел к выводу, что модель, мне потребуется делить на части. Я это сделаю, создав функцию Slider:
Входные параметры:
  • Высота среза (координата по оси Z)
Выходные параметры:
  • Матрица координат, по которым поочередно пройдется фреза
Как получим достигнутое:
  1. Создаем списки:
    1. Вершин, которые расположены выше, плоскости среза.
    2. Ребер, которые пересекают, плоскость среза, либо, чтобы нижняя точка лежала на плоскости среза.
    3. Граней, которые пересекают, плоскость среза (они помогут составить список граней, которые в дальнейшем будут разбиты в нужном месте для получения координаты для станка)
    4. Составляем список ребер (listofFaces), имеющий следующий формат:
      [[2, 4], [4, 6], [6, 7], [2, 7]] где каждая пара внутренних квадратных скобок отвечают за грань, а цифры внутри, ребра входящие в состав.
    5. Данный двумерный список необходимо рассортировать, так, чтобы он себя представлял следующий вид:
      [[2, 4], [4, 6], [6, 7], [7, 2]]
  2. Составляем список ребер для разбиения, имеющий следующий формат
    [1 2 3 4 1 5 6 7 8 5]
    Цифра, которая повторяется означает конец контура. Фреза выводится за пределы заготовки и в холостом ходе переходит к обработке следующего контура.
  3. После получения списка, считываем число повторений и заносим в счетчик контуров.
  4. Создаем список, содержащий по отдельному списку, для каждого контура, имеющий следующий формат: [[1 2 3 4 1] [5 6 7 8 5]]
  5. Создается список координат [X, Y], в результате прохода через все ребра контура, следующего формата:
    [[[X1 Y1] [X2 Y2] [X3 Y3] [X4 Y4] [X1 Y1]] [[X5 Y5] [X6 Y6] [X7 Y7] [X8 Y8] [X5 Y5]]]
  6. Благодаря дальнейшему анализу координат, определяем зоны внутри, и зоны снаружи.
  7. (Данный пункт добавлен) Необходимо провести анализ, внешний это контур или нет.
  8. Создаем внешние контуры (по ним будет двигаться фреза, и данные контуры будут построены на расстоянии равном половине диаметра фрезы).
  9. Производим анализ, внешних контуров, если они пересекаются, выдать предупреждение, на усмотрение пользователя. (Данное предупреждение означает, что фреза не может пройти по заданной траектории без порчи, первоначальной затеи фрезеровщика)
Алгоритм был изменен и первичный алгоритм, канул в лета, так как начал, писать код в голову пришел другой алгоритм, который я считаю более оптимальным.
На данный момент, почти выполнил первый пункт, просто поленился его доделать.
***
В результате очередного тестирования скрипта выявились, проблемы, функция slider исправно сортирует список (пункт 1.4), но неисправно составляет, список listofFaces при условии, что в сцене несколько объектов.
Однако, если на сцене один объект (производим операцию boolean union). Даже для объектов находящихся в разных местах. Скрипт правильно выполнит поставленную перед ним задачу.
Такое объединение объектов в один считается изначально заданным. Так как у разных объектов может совпадать нумерация вершин, граней и фасок.
***
На данный момент 13.04.2012 пункт 1 полностью выполнен.
***
15.04.2012 Добрая половина уже сделана, но в дальнейшем, самым сложным является анализ зон. К сожалению, пока скрипт не оптимизирован. Но в дальнейшем после, того, как доведу работу до конца, планирую, оптимизировать выполнение скрипта. На данный момент, он содержит, слишком большое количество циклов.
***
18.04.2012 К сожалению, учеба отнимает сильно много времени, и у нас еще как назло конференции. Но от них есть и плюсы. Так из всех докладчиков меня интересовал лишь один доклад, то вовремя остальных докладов, я писал свой алгоритм и теперь осталось только создание внешнего контура. И анализ, на наличие пересечений. Два пункта, но самые сложные на мой взгляд в плане программной реализации.
***
В тот же день заметил, еще одну неурядицу, лучше нарисую ее.
Черной линией я нарисовал внешние контуры, красной линией внутренний.
То есть может быть потребуется начертить именно внутренний контур, а не внешний! Следовательно, перед пунктом 7 необходим, дополнительный пункт 7'. Который бы определял, внешний это контур или внутренний.
***
30.04.2012 Долго мучился с созданием внешнего/внутреннего контуров
В итоге выяснил, что на предыдущих этапах происходит плохая обработка данных, потому что на вход для испытаний мне попали данные с повторными элементами, что не соответствует заданному формату. Поэтому поставлю дополнительный фильтр, для чистки от повторных элементов.
Теперь осталось только научить, свой постпроцессор анализировать. Под анализом в данном случае, я имею ввиду умение определять по какому контуру должна идти фреза, дабы не нарушить замысел моделиста. И умение определять подойдет ли диаметр фрезы или нет. Фреза может оказаться сильно большой, и не сможет отработать заданную траекторию.
Основные задачи на ближайшее будущее:
  1. Написать фильтр значений, дабы формат входных параметров соответствовал требуемому формату.
  2. Написать анализатор вложенности контуров.
  3. Написать анализатор наличия пересечений.

    воскресенье, 8 апреля 2012 г.

    Изучение Blender API Часть 2

    Когда я писал прошлую, статью, ко мне в голову пришла одна гениальная мысль. Которую я почти сразу оформил в виде скрипта на Python. Данный скрипт выводит мне координаты вращения в углах Эйлера, местоположение объекта, данные о его масштабировании и соответственно сами координаты. Теперь вспомним намеченный план из прошлой статьи:

    1. Получить информацию об углах поворота объекта
    2. С учетом углов поворота, изменить координаты точек
    3. Получить информацию о масштабе, данной фигуры
    4. С учетом масштаба, увеличить/уменьшить координаты.
    5. Получить данные о положении объекта
    6. Все полученные на предыдущих шагах координаты переместить в место их реального положения (слава богу все координаты объекта изначально указаны относительно, геометрического, а может и просто программного центра фигуры, главное, что центра!)
    Т.е. пункты 1, 3  и 5 выполнены. Необходимо приступить к пункту 2. С учетом углов поворота, изменить координаты точек.
    Напишем алгоритм преобразования:
    1. Определить под каким углом расположен вектор из начала координат (в нашем случае он совпадает с центром фигуры) до вершины.
    2. Вычислить длину, этого вектора с учетом заданного поворота.
    3. Прибавить угол вращения
    4. Вычислить новые координаты.
    Главное не забывать, что в программировании также, как в механике используется радианная мера углов. 
    Рассмотрим преобразования для оси X, для этого потребуется рисунок:
    Зеленая стрелка это ось Y, синяя стрелка ось Z.
    1. Соответственно для оси X длина вектора от начала координат, до точки равна: modul = sqrt(Y^2+Z^2).
    2. Угол поворота определяем с помощью функции phiX = atan2(Z,Y).
    3. Далее к phiX прибавляем нужный угол поворота. phiX = phiX + angelX.
    4. Вычисляем новые координаты newY = modul*cos(phiX); newZ = modul*sin(phiX);
    Теперь рассмотрим преобразования для оси Y:
    Красная стрелка это ось X, синяя стрелка ось Z.
    1. Соответственно для оси Y длина вектора от начала координат, до точки равна: modul = sqrt(X^2+Z^2).
    2. Угол поворота определяем с помощью функции phiY = atan2(X,Z).
    3. Далее к phiX прибавляем нужный угол поворота. phiY = phiY + angelY.
    4. Вычисляем новые координаты newX = modul*sin(phiY); newZ = modul*cos(phiY);
    Ну и остался угол для последней оси Z:
    Зеленая стрелка ось Y, красная ось X
    1. Соответственно для оси Z длина вектора от начала координат, до точки равна: modul = sqrt(X^2+Y^2).
    2. Угол поворота определяем с помощью функции phiZ = atan2(Y,X).
    3. Далее к phiX прибавляем нужный угол поворота. phiZ = phiZ + angelZ.
    4. Вычисляем новые координаты newX = modul*cos(phiZ); newY = modul*sin(phiZ);
    Теперь дело за проверкой, ведь согласитесь, я мог и ошибиться в понимании углов Эйлера.
    Программу протестировал в самом Blender'е скрипт оказался вполне исправно работающим и как итог мое понимание оказалось верным. То как я тестировал скрипт описывать не буду. Скрипт тестировал отдельно для каждой оси.
    Теперь пора перейти к шагу 4. С учетом масштаба, увеличить/уменьшить координаты.
    Здесь все просто.

    1. x = x*scaleX
    2. y = y*scaleY
    3. z = z*scaleZ
    Ну и как итог, последний шаг все полученные на предыдущих шагах координаты переместить в место их реального положения:
    1. x = x + locationX
    2. y = y + locationY
    3. z = z + locationZ
    Ну вот и все, скрипт, который правильно выводит координаты для фигур написан. Следующая задача, написать скрипт, который все эти координаты преобразует в G/M коды, пускай даже по началу без особых оптимизаций (в конце концов я только учусь). Но это уже в следующем посте.

    понедельник, 2 апреля 2012 г.

    Изучение Blender API. Часть 1.

    Введение

    В предыдущем сообщении, я поставил перед собой цели. Одной из которых является изучение Blender API, чтобы вывести координаты каждой точки 3D модели во внешний текстовый файл.
    В своем изучении Blender API я не соблюдал никаких последовательностей, возможно в этом моя ошибка. В этой теме хочу по пунктам изучить Blender API.
    Начнем с нуля, или как на официальном сайте Blender осуществим быстрый старт.
    Blender/Python API позволяет:
    • Редактировать любые данные пользовательского интерфейса
    • Изменять настройки пользователя, раскладки и темы
    • Запускать инструменты со своими настройками
    • Создавать элементы пользовательского интерфейса, такие как меню, заголовки и панели.
    • Создавать новые инструменты
    • Создавать интерактивные инструменты
    • Создавать новые движки для рендеринга, которые будут совместимы с Blender
    • Создавать новые настройки для имеющихся в Blender данных
    • Рисовать 3D изображения используя команды OpenGL

    Ключевые концепции

    Перед началом любых действий лучше сразу импортировать библиотек Blender API с помощью команды:
    >>> import bpy

    Доступ к данным

    Доступ к данным, может быть получен, прямо из консоли Python. Данная операция осуществляется с помощью модуля bpy.data. Он дает доступ к библиотеке данных. Рассмотрим пример:
    >>> bpy.data.objects
    <bpy_collection[3], BlendDataObjects>
    
    >>> bpy.data.scenes
    <bpy_collection[1], BlendDataScenes>
    
    >>> bpy.data.materials
    <bpy_collection[1], BlendDataMaterials>

    О коллекциях

    Вы наверняка заметили, что индекс, также как в строке, может быть использован для доступа к членам коллекции.
    Для доступа к членам коллекции используется два метода, но надо учитывать, что индекс может быть изменен при очередном запуске Blender.
    >>> list(bpy.data.objects)
    [bpy.data.objects["Camera"], bpy.data.objects["Cube"], bpy.data.objects["Lamp"]]
    
    >>> bpy.data.objects['Cube']
    bpy.data.objects["Cube"]
    
    >>> bpy.data.objects[1]
    bpy.data.objects["Cube"]

    Доступ к аттрибутам

    Создав блоки данных, такие как материалы, объекты, группы и др. необходимо изменить их свойства, используя интерфейс пользователя. Эти же возможности доступны и с помощью Blender API.
    >>> bpy.data.objects[0].name'Camera'
    
    >>> bpy.data.scenes["Scene"]
    bpy.data.scenes["Scene"]
    
    >>> bpy.data.materials.new("MyMaterial")
    bpy.data.materials["MyMaterial"]
    Для проверки, что данные доступны, и могут использоваться из консоли воспользуемся следующим примером:
    >>> bpy.data.scenes[0].render.resolution_percentage
    50
    
    >>> bpy.data.scenes[0].objects["Cube"].data.vertices[0].co.x
    1.0
    Казалось, бы вот он ответ, на мучающий меня вопрос, но увы не тут то было. Координаты, которые получаем при выводе таким методом, скажем так, весьма относительны. Почему? Потому, что те координаты, что он дает, это координаты при условии, что моделька, один к одному, да и при всем при этом не масштабирована, не повернута, в разных направлениях и ее центр совпадает с центром начала координат.
    Как с этим бороться?
    1. Получить информацию об углах поворота объекта
    2. С учетом углов поворота, изменить координаты точек
    3. Получить информацию о масштабе, данной фигуры
    4. С учетом масштаба, увеличить/уменьшить координаты.
    5. Получить данные о положении объекта
    6. Все полученные на предыдущих шагах координаты переместить в место их реального положения (слава богу все координаты объекта изначально указаны относительно, геометрического, а может и просто программного центра фигуры, главное, что центра!)
    Из этого алгоритма, на данный момент, я не знаю, как выполнить первый пункт (получение углов вращения). Остальные пункты, по крайней мере все, что связано с Blender'ом я могу выполнить, а то что с ним не связано, могу вывести и написать алгоритм.
    Главное, что я верю, что это реально сделать! И пускай и не сразу, но я сделаю это, ибо у меня есть, тайный стимул, но об этом я расскажу позже.

    Постановка задачи на создание алгоритма постпроцессора для преобразования 3D модели в G/M коды


    Введение

    Требуется создать программу, для работы со станками ЧПУ при использовании СПО. Данный проект будет являться свободным аналогом ArtCAM работающим под ОС Linux.

    Что такое ArtCAM?

    ArtCAM Pro - программный пакет для пространственного моделирования/механообработки, который позволяет автоматически генерировать пространственные модели из плоского рисунка и получать по ним изделия на станках с ЧПУ. ArtCAM Pro предлагает мощный, легкий в использовании набор средств моделирования, который предоставляет дизайнеру свободу при создании сложных пространственных рельефов.

    Техническое задание

    Необходимо:

    • Создать постпроцессор для переработки 3D моделей в редакторе Blender в G/M коды, являющиеся мировым стандартом в станкостроении.
    Возможности постпроцессора:
    • Создание исходного файла с G/М кодами для работы на ЧПУ станке
    • Умение распознавать 3D модели, правильное расположение элементов, и частей будущего изделия
    • Возможность построения 3D модели на базе 2D изображения в форматах BMP, JPG, DXF, SVG
    • Назначение режимов резания для станка в зависимости от материала и размера фрезы (эти параметры будут задаватся в 3D редакторе Blender)
    • Выбор механообработки
      • Черновая
      • Чистовая
    • Определение точности изготовления детали и шероховатости поверхности (с учетом погрешности станка, и неточности в процессе дискретного перемещения инструмента)
    На данный момент программно-техническое обеспечение содержит следующие компоненты:
    • Blender —  свободный пакет для создания трёхмерной компьютерной графики, включающий в себя средства моделирования, анимации, рендеринга, постобработки видео, а также создания интерактивных игр.
    • Blender API(англ. application programming interface, API [эй-пи-ай]) интерфейс прикладного программирования: набор готовых классов, процедур, функций, структур и констант, предоставляемых приложением Blender для использования во внешних программных продуктах.
    • Python (англ. python — питон, произносится [ˈpaɪθ⟨ə⟩n] — па́йтон, также, широко используется русскоязычное произношение пито́н) —высокоуровневый язык программирования общего назначения с акцентом на производительность разработчика и читаемость кода. Синтаксис ядра Python минималистичен. В то же время стандартная библиотека включает большой объём полезных функций.
    Поэтапные шаги создания данного проекта:
    1. Изучить Blender API, с той целью, чтобы выяснить, как вывести координаты каждой точки 3D модели во внешний текстовый файл.
    2. Разбить полученные координаты по уровням, вдоль оси Z сверху в них в зависимости от требуемой точности изготовления станка.
    3. Описать алгоритм создания G/M кодов, для каждого уровня в отдельности, с использованием всевозможной оптимизации учетом ограничений по механообработке.
    4. Запись полученного алгоритма механообработки в G/M кодах во внешний текстовый файл.