есть такой код:<br>import numpy as np<br>import pyvista as pv<br>from scipy.spatial import Voronoi<br>import matplotlib.colors as mcolors<br><br># Установка seed для воспроизводимости результатов<br>np.random.seed(14)<br># Количество генераторов<br>n_points = 10<br># Толщина стенок ячейки<br>wall_thickness = 1.0<br><br>def generate_points(n_points, cube_size=1.0):<br>"""<br> Генерация случайных точек внутри куба<br> :param n_points: количество точек<br> :param cube_size: размер куба<br> :return: массив точек размером (n_points, 3)<br> """<br>return np.random.random((n_points, 3)) * cube_size<br><br>def create_voronoi_diagram(points):<br>"""<br> Создание диаграммы Вороного<br> :param points: массив точек<br> :return: объект Voronoi<br> """<br># Добавляем далекие точки для ограничения диаграммы<br> center = np.mean(points, axis=0)<br> radius = 2.0<br> extra_points = []<br>for d in range(3):<br>for sign in [-1, 1]:<br> point = np.copy(center)<br> point[d] = center[d] + radius * sign<br> extra_points.append(point)<br><br> points_with_extras = np.vstack((points, extra_points))<br>return Voronoi(points_with_extras)<br><br>def analyze_voronoi_cells(vor):<br>"""<br> Анализ ячеек Вороного<br> :param vor: объект Voronoi<br> """<br>print("\nАнализ ячеек Вороного:")<br>for i, region in enumerate(vor.regions):<br>if len(region) > 0 and -1 not in region: # Пропускаем пустые регионы и регионы с бесконечными вершинами<br>print(f"\nЯчейка {i}:")<br>print("Вершины:")<br> vertices = vor.vertices[region]<br>for j, vertex in enumerate(vertices):<br>print(f" Вершина {j}: ({vertex[0]:.3f}, {vertex[1]:.3f}, {vertex[2]:.3f})")<br><br># Проверка пересечения с границами куба<br>if np.any(vertices < 0) or np.any(vertices > 1):<br>print(" Ячейка пересекает границы куба")<br><br>def visualize_voronoi_3d(vor, points, wall_thickness=1.0):<br>"""<br> Визуализация 3D диаграммы Вороного<br> :param vor: объект Voronoi<br> :param points: исходные точки<br> :param wall_thickness: толщина стенок ячеек (float, по умолчанию 1.0)<br> """<br># Создаем плоттер<br> plotter = pv.Plotter()<br><br># Создаем куб<br> cube = pv.Box(bounds=(0, 1, 0, 1, 0, 1))<br> plotter.add_mesh(cube, style='wireframe', color='black', line_width=2)<br><br># Добавляем исходные точки<br> point_cloud = pv.PolyData(points)<br> plotter.add_mesh(point_cloud, color='red', point_size=10, render_points_as_spheres=True)<br><br># Добавляем ячейки Вороного<br> colors = list(mcolors.TABLEAU_COLORS.values())<br>for i, region in enumerate(vor.regions):<br>if len(region) > 0 and -1 not in region: # Пропускаем пустые регионы и регионы с бесконечными вершинами<br> vertices = vor.vertices[region]<br># Создаем выпуклую оболочку для ячейки<br> cell = pv.PolyData(vertices).delaunay_3d()<br># Обрезаем ячейку по границам куба<br> cell = cell.clip_box((0, 1, 0, 1, 0, 1), invert=False)<br>if cell.n_points > 0: # Проверяем, осталась ли ячейка после обрезки<br># Добавляем ячейку с случайным цветом и прозрачностью<br> plotter.add_mesh(cell, color=colors[i % len(colors)], opacity=0.3)<br># Добавляем каркас ячейки с заданной толщиной<br> edges = cell.extract_feature_edges()<br> plotter.add_mesh(edges, color='black', line_width=wall_thickness)<br><br># Настройка камеры и отображение<br> plotter.camera_position = 'iso'<br> plotter.show()<br><br>def main():<br># Генерация точек<br> points = generate_points(n_points)<br><br># Создание диаграммы Вороного<br> vor = create_voronoi_diagram(points)<br><br># Анализ ячеек<br> analyze_voronoi_cells(vor)<br><br># Визуализация<br> visualize_voronoi_3d(vor, points, wall_thickness)<br><br>if __name__ == "__main__":<br> main()<br><br>надо сделать так чтобы визуализация этого кода была в gmsh