| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Готовые программы > Blender 2.80 / Python. Аддоны экспорта сетки в FEA-проект Stark / TXT-файл Scad

Blender 2.80 / Python. Аддоны экспорта сетки в FEA-проект Stark / TXT-файл Scad

Ответ
Поиск в этой теме
Непрочитано 20.10.2019, 07:41 4 | #1
Blender 2.80 / Python. Аддоны экспорта сетки в FEA-проект Stark / TXT-файл Scad
Нубий-IV
 
Инженер-философ
 
Хабаровск
Регистрация: 24.04.2019
Сообщений: 331

Экспорт в Stark ES:
Код:
[Выделить все]
# Аддон для Blender 2.80
# Экспорт в формат FEA-файлов Stark ES
# Экспортируются сетки, и объекты, конвертирующиеся в сетки (сплайны, NURBS, матаболы, тексты)
# Трех- и четырехугольные элементы сетки преобразуются в оболочки
# Ребра, не связанные с гранями, преобразуются в стержни
# Различные материалы преобразуются в различные материалы в проекте Stark


# Стандартное описание аддона
# Используется для отображения в интерфейсе
bl_info = {
    "name": "Stark ES FEA format",
    "author": "Newbie-IV",
    "version": (2, 0, 0),
    "blender": (2, 80, 0),
    "location": "File > Export",
    "description": "Export Stark ES FEA project",
    "warning": "",
    "wiki_url": "",
    "support": 'COMMUNITY',
    "category": "Import-Export"}


# Подключение стандартных модулей
import bpy
import bmesh

from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator
from mathutils import Matrix


# FEM - проект
# Накопление узлов, элементов и материалов
# Запись в файл
class fem_project:
    # Конструктор
    def __init__(self):
        # Списки узлов, элементов и материалов, в виде строк, готовых для записи в файл
        self.nodes = []
        self.elements = []
        self.materials = []

        # Словарь использованных материалов в виде "Материал : Номер_Материала"
        # Для элементов с незаданным материалом зарезервировано пустое значение
        self.materials_dict = {None : 0}


    # Возвращает для указанной грани номер материала из словаря
    def get_material_number(self, mesh, face):
        if len(mesh.materials):
            return self.materials_dict[mesh.materials[face.material_index]]
        else:
            return self.materials_dict[None]


    # Добавляет объект сетки в проект
    def add_mesh(self, mesh):
        # Поиск и добавление новых материалов в словарь и в список материалов
        for material in mesh.materials:
            if material not in self.materials_dict:
                material_number = len(self.materials_dict)
                self.materials_dict[material] = material_number
                self.materials += "10 0 " + str(material_number) + " 0 0 0 0 0 0 0 0 0 0 0\n"

        # Чтение данных сетки
        bmsh = bmesh.new()
        bmsh.from_mesh(mesh)

        # Определение количества ранее добавленных узлов
        num_nodes = len(self.nodes)

        # Добавление элементов оболочек
        for face in bmsh.faces:
            nverts = len(face.verts)

            # Четырехугольные элементы
            if nverts == 4:
                v1 = str(face.verts[0].index + num_nodes + 1)
                v2 = str(face.verts[1].index + num_nodes + 1)
                v3 = str(face.verts[2].index + num_nodes + 1)
                v4 = str(face.verts[3].index + num_nodes + 1)
                mn = str(self.get_material_number(mesh, face))
                self.elements.append("8 " + mn + " 0 " + v1 + " " + v2 + " " + v3 + " " + v4 + " 0\n")

            # Треугольные элементы
            elif nverts == 3:
                v1 = str(face.verts[0].index + num_nodes + 1)
                v2 = str(face.verts[1].index + num_nodes + 1)
                v3 = str(face.verts[2].index + num_nodes + 1)
                mn = str(self.get_material_number(mesh, face))
                self.elements.append("7 " + mn + " 0 " + v1 + " " + v2 + " " + v3 + " 0 0\n")

        # Добавление элементов стержней
        for edge in bmsh.edges:
            if len(edge.link_faces) == 0:
                v1 = str(edge.verts[0].index + num_nodes + 1)
                v2 = str(edge.verts[1].index + num_nodes + 1)
                self.elements.append("2 0 0 " + v1 + " " + v2 + " 0 0 0\n")

        # Добавление узлов
        for vert in bmsh.verts:
            x = str(vert.co.x)
            y = str(vert.co.y)
            z = str(vert.co.z)
            self.nodes.append(x + " " + y + " " + z + "\n")

        # Освобождение ресурсов
        bmsh.free()


    # Записывает файл
    def write(self, filepath):
        file = open(filepath, 'w', encoding='utf-8')

        # Запись заголовка
        file.write("\n\n\nVERSION 1.1.0\n")

        # Запись узлов
        file.write("KNOT " + str(len(self.nodes)) + "\n")
        for node in self.nodes:
            file.write(node)

        # Запись элементов
        file.write("ELEM " + str(len(self.elements)) + "\n")
        for element in self.elements:
            file.write(element)

        # Запись материалов
        if len(self.materials):
            file.write("MATE " + str(len(self.materials)) + "\n")
            for material in self.materials:
                file.write(material)

        file.close()


# Вспомогательный объект
# Обертка для нескольких промежуточных переменных
# Операции по чтению и добавлению выбранных объектов в проект
class object_exporter:
    # Конструктор
    def __init__(self, context, filepath):
        self.context = context
        self.filepath = filepath
        self.depsgraph = context.evaluated_depsgraph_get()
        self.global_matrix = Matrix()
        self.fem = fem_project()


    # Добавляет все выбранные объекты в проект
    def read_objects(self):
        for object in self.context.selected_objects:
            # Список объектов и их матриц для обработки
            objects = [(object, object.matrix_world)]

            # Если объект - экземпляр коллекции, добавить вложенные объекты в список для обработки
            if object.is_instancer:
                objects += [
                    (instance.instance_object.original, instance.matrix_world.copy())
                    for instance in self.depsgraph.object_instances
                    if instance.parent and instance.parent.original == object]

            # Добавление в проект объектов списка
            for object, matrix in objects:
                # Применение модификаторов
                try:
                    mesh = object.evaluated_get(self.depsgraph).to_mesh()
                except RuntimeError:
                    continue

                # Применение масштаба объекта
                mesh.transform(self.global_matrix @ matrix)

                # Добавление объекта в проект
                self.fem.add_mesh(mesh)


    # Экспортирует готовый проект в файл
    def export(self):
        self.fem.write(self.filepath)


# Оператор экспорта
class fem_export(Operator, ExportHelper):
    '''Save a Stark ES FEA File'''

    # Информация для отображения в интерфейсе
    bl_idname = "export_scene.stark_fea"
    bl_label = "Export FEA"

    filename_ext = ".fea"

    filter_glob: StringProperty(
        default="*.fea",
        options={'HIDDEN'},
        maxlen=255
    )

    # Главная функция оператора
    def execute(self, context):
        # Предупреждение если ничего не выбрано
        if len(context.selected_objects) == 0:
            self.report({'WARNING'}, "Select objects to export")
            return {'CANCELLED'}

        # Экспорт
        exporter = object_exporter(context, self.filepath)
        exporter.read_objects()
        exporter.export()

        return {'FINISHED'}


# Регистрация в меню
def menu_export(self, context):
    self.layout.operator(fem_export.bl_idname, text="Stark FEA project (.fea)")


# При включении аддона
def register():
    bpy.utils.register_class(fem_export)
    bpy.types.TOPBAR_MT_file_export.append(menu_export)


# При отключении аддона
def unregister():
    bpy.utils.unregister_class(fem_export)
    bpy.types.TOPBAR_MT_file_export.remove(menu_export)


# Регистрация при запуске скрипта из редактора
if __name__ == "__main__":
    register()
Экспорт в Scad:

Код:
[Выделить все]
# Аддон для Blender 2.80
# Экспорт в формат TXT-файлов SCAD
# Экспортируются сетки, и объекты, конвертирующиеся в сетки (сплайны, NURBS, матаболы, тексты)
# Трех- и четырехугольные элементы сетки преобразуются в оболочки
# Ребра, не связанные с гранями, преобразуются в стержни
# Различные материалы преобразуются в различные материалы в проекте Scad


# Стандартное описание аддона
# Используется для отображения в интерфейсе
bl_info = {
    "name": "Scad TXT format",
    "author": "Newbie-IV",
    "version": (2, 0, 0),
    "blender": (2, 80, 0),
    "location": "File > Export",
    "description": "Export Scad TXT project",
    "warning": "",
    "wiki_url": "",
    "support": 'COMMUNITY',
    "category": "Import-Export"}


# Подключение стандартных модулей
import bpy
import bmesh

from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator
from mathutils import Matrix


# FEM - проект
# Накопление узлов, элементов и материалов
# Запись в файл
class fem_project:
    # Конструктор
    def __init__(self):
        # Списки узлов, элементов и материалов, в виде строк, готовых для записи в файл
        self.nodes = []
        self.elements = []
        self.materials = []

        # Словарь использованных материалов в виде "Материал : Номер_Материала"
        # Для элементов с незаданным материалом зарезервировано пустое значение
        self.materials_dict = {None : 0}


    # Возвращает для указанной грани номер материала из словаря
    def get_material_number(self, mesh, face):
        if len(mesh.materials):
            return self.materials_dict[mesh.materials[face.material_index]]
        else:
            return self.materials_dict[None]


    # Добавляет объект сетки в проект
    def add_mesh(self, mesh):
        # Поиск и добавление новых материалов в словарь и в список материалов
        for material in mesh.materials:
            if material not in self.materials_dict:
                material_number = len(self.materials_dict)
                self.materials_dict[material] = material_number
                self.materials += str(material_number) + " GE " + str(material_number) + " 0 0 RO 0 TMP 0 0/\n"

        # Чтение данных сетки
        bmsh = bmesh.new()
        bmsh.from_mesh(mesh)

        # Определение количества ранее добавленных узлов
        num_nodes = len(self.nodes)

        # Добавление элементов оболочек
        for face in bmsh.faces:
            nverts = len(face.verts)

            # Четырехугольные элементы
            if nverts == 4:
                v1 = str(face.verts[0].index + num_nodes + 1)
                v2 = str(face.verts[1].index + num_nodes + 1)
                v3 = str(face.verts[2].index + num_nodes + 1)
                v4 = str(face.verts[3].index + num_nodes + 1)
                mn = str(self.get_material_number(mesh, face))
                self.elements.append("44 " + mn + " " +  v1 + " " + v2 + " " + v4 + " " + v3 + "/\n")

            # Треугольные элементы
            elif nverts == 3:
                v1 = str(face.verts[0].index + num_nodes + 1)
                v2 = str(face.verts[1].index + num_nodes + 1)
                v3 = str(face.verts[2].index + num_nodes + 1)
                mn = str(self.get_material_number(mesh, face))
                self.elements.append("42 " + mn + " " + v1 + " " + v2 + " " + v3 + "/\n")

        # Добавление элементов стержней
        for edge in bmsh.edges:
            if len(edge.link_faces) == 0:
                v1 = str(edge.verts[0].index + num_nodes + 1)
                v2 = str(edge.verts[1].index + num_nodes + 1)
                self.elements.append("5 0 " + v1 + " " + v2 + "/\n")

        # Добавление узлов
        for vert in bmsh.verts:
            x = str(vert.co.x)
            y = str(vert.co.y)
            z = str(vert.co.z)
            self.nodes.append(x + " " + y + " " + z + "/\n")

        # Освобождение ресурсов
        bmsh.free()


    # Записывает файл
    def write(self, filepath):
        file = open(filepath, 'w', encoding='utf-8')

        # Запись заголовка
        #file.write("\n\n\nVERSION 1.1.0\n")

        # Запись элементов
        file.write("(1/\n")
        for element in self.elements:
            file.write(element)
        file.write(")\n")

        # Запись материалов
        file.write("(3/\n")
        for material in self.materials:
            file.write(material)
        file.write(")\n")

        # Запись узлов
        file.write("(4/\n")
        for node in self.nodes:
            file.write(node)
        file.write(")\n")

        file.close()


# Вспомогательный объект
# Обертка для нескольких промежуточных переменных
# Операции по чтению и добавлению выбранных объектов в проект
class object_exporter:
    # Конструктор
    def __init__(self, context, filepath):
        self.context = context
        self.filepath = filepath
        self.depsgraph = context.evaluated_depsgraph_get()
        self.global_matrix = Matrix()
        self.fem = fem_project()


    # Добавляет все выбранные объекты в проект
    def read_objects(self):
        for object in self.context.selected_objects:
            # Список объектов и их матриц для обработки
            objects = [(object, object.matrix_world)]

            # Если объект - экземпляр коллекции, добавить вложенные объекты в список для обработки
            if object.is_instancer:
                objects += [
                    (instance.instance_object.original, instance.matrix_world.copy())
                    for instance in self.depsgraph.object_instances
                    if instance.parent and instance.parent.original == object]

            # Добавление в проект объектов списка
            for object, matrix in objects:
                # Применение модификаторов
                try:
                    mesh = object.evaluated_get(self.depsgraph).to_mesh()
                except RuntimeError:
                    continue

                # Применение масштаба объекта
                mesh.transform(self.global_matrix @ matrix)

                # Добавление объекта в проект
                self.fem.add_mesh(mesh)


    # Экспортирует готовый проект в файл
    def export(self):
        self.fem.write(self.filepath)


# Оператор экспорта
class fem_export(Operator, ExportHelper):
    '''Save a Scad TXT file'''

    # Информация для отображения в интерфейсе
    bl_idname = "export_scene.scad_txt"
    bl_label = "Export Scad TXT"

    filename_ext = ".txt"

    filter_glob: StringProperty(
        default="*.txt",
        options={'HIDDEN'},
        maxlen=255
    )

    # Главная функция оператора
    def execute(self, context):
        # Предупреждение если ничего не выбрано
        if len(context.selected_objects) == 0:
            self.report({'WARNING'}, "Select objects to export")
            return {'CANCELLED'}

        # Экспорт
        exporter = object_exporter(context, self.filepath)
        exporter.read_objects()
        exporter.export()

        return {'FINISHED'}


# Регистрация в меню
def menu_export(self, context):
    self.layout.operator(fem_export.bl_idname, text="Scad TXT file (.txt)")


# При включении аддона
def register():
    bpy.utils.register_class(fem_export)
    bpy.types.TOPBAR_MT_file_export.append(menu_export)


# При отключении аддона
def unregister():
    bpy.utils.unregister_class(fem_export)
    bpy.types.TOPBAR_MT_file_export.remove(menu_export)


# Регистрация при запуске скрипта из редактора
if __name__ == "__main__":
    register()
Для установки сохранить в папку аддонов в кодировке UTF-8 и активировать через Edit/Preferences/Add-ons/Import-Export

Миниатюры
Нажмите на изображение для увеличения
Название: Blender.png
Просмотров: 52
Размер:	343.8 Кб
ID:	219967  Нажмите на изображение для увеличения
Название: Stark.png
Просмотров: 48
Размер:	43.6 Кб
ID:	219968  Нажмите на изображение для увеличения
Название: Scad.png
Просмотров: 46
Размер:	66.9 Кб
ID:	219969  

__________________
Учись долго, умри дураком

Последний раз редактировалось Нубий-IV, 13.11.2019 в 13:47. Причина: Обновление программы
Просмотров: 503
 
Автор темы   Непрочитано 13.11.2019, 13:52
3 | #2
Нубий-IV

Инженер-философ
 
Регистрация: 24.04.2019
Хабаровск
Сообщений: 331


Обновление
  • Экспортируются все выбранные объекты
  • Поддерживаются сетки, сплайны, NURBSы
  • Поддерживаются экземпляры коллекций
  • Учитываются модификаторы
  • Учитываются масштабы объектов
  • Добавлен экспорт в Скад
__________________
Учись долго, умри дураком
Нубий-IV на форуме  
 
Непрочитано вчера, 00:17
#3
Ayvengo

Что посеет человек, то и пожнет
 
Регистрация: 31.01.2012
Электросталь
Сообщений: 1,986
<phrase 1= Отправить сообщение для Ayvengo с помощью Skype™


Класс!!
Ayvengo вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Готовые программы > Blender 2.80 / Python. Аддоны экспорта сетки в FEA-проект Stark / TXT-файл Scad

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
В каких случаях необходимо разрабатывать ППиМ (проект планировки и межевания) @ndrey Прочее. Архитектура и строительство 6 20.11.2017 11:42
одностадийный или двустадийный проект? ask7777 Прочее. Архитектура и строительство 34 02.09.2010 06:23
Проект КТПП - замена силового трансформатора larpa Инженерные сети 13 01.07.2010 11:13
нужно ли составлять отдельный проект? Irina K. Инженерные сети 4 11.05.2010 21:18
Типовой проект 264-13-82 zebrik Поиск литературы, чертежей, моделей и прочих материалов 0 20.01.2010 22:27