Для работы с Python в Blender существует Python консоль для ввода команд. Данная консоль может быть вызвана с помощью комбинации shift+F4. В данной консоли можно вводить команды в интерактивном и последовательном режиме. После ввода комманды, результат выполнения будет выведен сразу после окончания ввода команды. Примечание: Перед выполнением задания, необходимо знать точный и полный путь до файла с данными. |
Пример программы# Считываем бибилиотеки относящиеся к маетматическим функциям и процедурам import itertools import math # Очищаем пространственную сцену от объектов for mesh in bpy.data.meshes: bpy.data.meshes.remove(mesh) # Очищаем пространственную сцену от камер for cam in bpy.data.cameras: bpy.data.cameras.remove(cam) # Sourcing data_file_path = "data/c20.txt" # Путь до файла с данными data_array = [] with open(data_file_path) as data_file: # Считываем данные из файла for line in data_file: data_array.append([float(number) for number in line.split()]) # Filtering filtered_data_array = data_array # Filtering пуст # Mapping sphere_radius = 0.1 # Задаем радиус сфер minimal_distance = 1.5 # Задаем минимальное расстояние для цилиндров sphere_material = bpy.data.materials.new(name="SphereMaterial") sphere_material.diffuse_color = [0.5, 0.9, 0.3, 1] # Задаем цвет сфер for point in filtered_data_array: # Создаем сферу bpy.ops.mesh.primitive_uv_sphere_add(radius=sphere_radius, location=point) sphere = bpy.context.object # Добавляем материал для сферы sphere.data.materials.append(sphere_material) cylinder_radius = sphere_radius / 2 # Задаем радиус цилиндра cylinder_material = bpy.data.materials.new(name="SphereMaterial") cylinder_material.diffuse_color = [1, 1, 1, 1] # Задаем цвет цилиндров for start, end in itertools.combinations(filtered_data_array, 2): # Считаем расстояние между точками distance = math.dist(start, end) if distance < minimal_distance: diff = [start[i] - end[i] for i in range(3)] middle = [(start[i] + end[i]) / 2 for i in range(3)] # Создаем цилиндр bpy.ops.mesh.primitive_cylinder_add( radius=cylinder_radius, depth=distance, location=middle ) cylinder = bpy.context.object # Поварачиваем цилиндр cylinder.rotation_euler[1] = math.acos(diff[2] / distance) cylinder.rotation_euler[2] = math.atan2(diff[1], diff[0]) cylinder.data.materials.append(cylinder_material) # Rendering camera_location = [5, 5, 5] camera_target = [0, 0, 0] # Задаем ветор для камеры camera_view_vector = [camera_target[i] - camera_location[i] for i in range(3)] # Создаем камеру camera = bpy.data.objects.new("Camera", bpy.data.cameras.new("Camera")) # Помещаем и поварачиваем камеру camera.location = camera_location camera.rotation_euler = Vector(camera_view_vector).to_track_quat('-Z', 'Y').to_euler() # Помещаем камеру на сцену и выбираем её в качестве активной камеры bpy.context.scene.collection.objects.link(camera) bpy.context.scene.camera = camera for area in bpy.context.screen.areas: if area.type == "VIEW_3D": area.spaces.active.region_3d.view_perspective = "CAMERA" break |
Программа вводится и выполняется по частям. |
Часть 1 SourcingВводим текст отвечающий за Sourcing. Большая часть команд в Python не возвращает результатов, видимых в консоли. Если ввести в консоли переменную, содержащую данные, то можно увидеть следующее: >>> data_array [[-1.219094, -0.6134905, 1.568064], [-1.219048, 0.7947012, 1.568227], [0.1202303, 1.229807, 1.568158], [0.9479346, 0.09052898, 1.567944], [0.1201712, -1.048725, 1.567888], [-1.818241, -1.048416, 0.3701912], [-2.188474, 0.09094238, -0.369963], [-1.818136, 1.23007, 0.3704882], [-0.8492718, -1.752463, -0.3703749], [0.3487037, -1.752652, 0.3698422], [-0.8491096, 1.934269, -0.3698732], [0.3488672, 1.934088, 0.3703492], [1.317876, 1.230073, -0.370188], [1.688112, 0.09069566, 0.3699504], [1.317813, -1.048485, -0.3704498], [-1.448331, 0.091057, -1.567983], [-0.6205603, 1.230299, -1.567894], [0.7187238, 0.7951232, -1.568042], [0.7187231, -0.6130653, -1.568167], [-0.620568, -1.048182, -1.568168]] Что означает что данные были успешно считаны из файла |
Часть 2 FilteringПостольку поскольку filtering пуст, данная часть не меняет данные. Если ввести в консоли переменную, отвечающую за отфильтрованные данные, чтобы убедится что ничего не изменилось: >>> filtered_data_array [[-1.219094, -0.6134905, 1.568064], [-1.219048, 0.7947012, 1.568227], [0.1202303, 1.229807, 1.568158], [0.9479346, 0.09052898, 1.567944], [0.1201712, -1.048725, 1.567888], [-1.818241, -1.048416, 0.3701912], [-2.188474, 0.09094238, -0.369963], [-1.818136, 1.23007, 0.3704882], [-0.8492718, -1.752463, -0.3703749], [0.3487037, -1.752652, 0.3698422], [-0.8491096, 1.934269, -0.3698732], [0.3488672, 1.934088, 0.3703492], [1.317876, 1.230073, -0.370188], [1.688112, 0.09069566, 0.3699504], [1.317813, -1.048485, -0.3704498], [-1.448331, 0.091057, -1.567983], [-0.6205603, 1.230299, -1.567894], [0.7187238, 0.7951232, -1.568042], [0.7187231, -0.6130653, -1.568167], [-0.620568, -1.048182, -1.568168]] |
Часть 3 MappingЗапускаем часть отвечаю за Mapping. После создания каждой сферы и каждого цилиндра, Blender выведет следующее сообщение в консоль: {'FINISHED'} В окне отвечающем за пространственную сцену, мы видим текующее проекционное изображение пространстенной сцены с созданными сферами и цилиндрами. |
Часть 4 RenderingЗапускаем часть отвечаю за Rendering. После задания и активации камеры, мы видим проекционное графическое изображение, полученное с помощью созданной нами камеры. |
Часть 5 BackloopЕсли аналитик хочет поменять цвет цилиндров, можно ввести следующую команду для изменения цвета цилиндров с белого на красный и сделать их слегка прозрачными: cylinder_material.diffuse_color = [0.9,0,0,0.8] |
Мы рекомендуем ознакомится с основами Python на официальном сайте, а так же с основами использования Blender библиотек. |