Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
developers:tutorial:modelviewexport [2022/12/13 14:44] proxor [Создание команды добавления объектов в сводную ИМ] |
developers:tutorial:modelviewexport [2023/01/10 11:12] proxor [Экспорт объектов в сводную ИМ] |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
====== Экспорт чертежа и объектов информационной модели ====== | ====== Экспорт чертежа и объектов информационной модели ====== | ||
- | Программный комплекс Топоматик Робур предоставляет пользователю возможность экспортировать плоские чертежи, а также генерировать сводную информационную модель (ИМ). В этом примере мы сформируем примитивы на основе данных нашей модели и поместим их в экспортируемый плоский чертёж. Также мы сформируем объекты на основе данных нашей модели и поместим их в экспортируемую сводную ИМ. | + | Программный комплекс Топоматик Робур предоставляет пользователю возможность управления формированием чертежей плана и сводной модели. Для этого необходимо реализовать поддержку бродкастов: |
+ | - "generate_planchet" - для формирования чертежа плана | ||
+ | - "generate_visualization_map" - для формирования сводной модели | ||
+ | В этом примере мы сформируем примитивы на основе данных нашей модели и поместим их в экспортируемый плоский чертёж. Также мы сформируем объекты на основе данных нашей модели и поместим их в экспортируемую сводную ИМ. | ||
==== Подготовка модуля ==== | ==== Подготовка модуля ==== | ||
Строка 15: | Строка 18: | ||
==== Подготовка проекта ==== | ==== Подготовка проекта ==== | ||
Добавим элементы нашей модели на план. В нашем случае это будет выглядеть так: | Добавим элементы нашей модели на план. В нашем случае это будет выглядеть так: | ||
- | {{ :developers:tutorial:createmodel:tut_export_model_views_1.png?nolink |}} | + | |
+ | {{ :developers:tutorial:createmodel:tut_export_model_views_1.png?direct |}} | ||
==== Экспорт элементов модели в плоский чертёж ==== | ==== Экспорт элементов модели в плоский чертёж ==== | ||
Для экспорта элементов пользовательской модели в плоский чертёж необходимы следующий действия: | Для экспорта элементов пользовательской модели в плоский чертёж необходимы следующий действия: | ||
- | - Создание команды добавления примитивов на чертёж | + | - Создать команду для добавления примитивов на чертёж |
- | - Подписаться на бродкаст "generate_planchet" в plugin-файле с помощью команды из пункта 1 | + | - Зарегистрировать вызов команды через бродкаст «generate_planchet» в plugin-файле |
==== Создание команды добавления примитивов на чертёж ==== | ==== Создание команды добавления примитивов на чертёж ==== | ||
Команда должна вызвать метод принимающий в качестве аргумента объект типа **GeneratePlanchetEventArgs**. | Команда должна вызвать метод принимающий в качестве аргумента объект типа **GeneratePlanchetEventArgs**. | ||
Строка 122: | Строка 125: | ||
В результате работы команды "**tutorial_generate_planchet**" в экспортированном файле плоского чертежа появятся примитивы нашей модели. | В результате работы команды "**tutorial_generate_planchet**" в экспортированном файле плоского чертежа появятся примитивы нашей модели. | ||
- | {{ :developers:tutorial:createmodel:tut_export_model_views_3.png?nolink |}} | + | {{ :developers:tutorial:createmodel:tut_export_model_views_3.png?direct |}} |
==== Экспорт объектов в сводную ИМ ==== | ==== Экспорт объектов в сводную ИМ ==== | ||
Для экспорта объектов пользовательской модели в сводную ИМ необходимы следующий действия: | Для экспорта объектов пользовательской модели в сводную ИМ необходимы следующий действия: | ||
- | - Создание команды добавления объектов в сводную ИМ | + | - Создать команду для добавления объектов в сводную ИМ |
- | - Подписаться на бродкаст "generate_visualization_map" в plugin-файле с помощью команды из пункта 1 | + | - Зарегистрировать вызов команды через бродкаст «generate_visualization_map» в plugin-файле |
==== Создание команды добавления объектов в сводную ИМ ==== | ==== Создание команды добавления объектов в сводную ИМ ==== | ||
- | Команда должна вызвать метод принимающий в качестве аргумента объект типа **CreateVisualizationEventArgs**. | + | Команда должна вызвать метод принимающий в качестве аргумента объект типа **CreateVisualizationEventArgs**. |
- | Свойство **CreateVisualizationEventArgs.Layer** возвращает текущий экспортируемый слой типа **CadViewLayer**. С помощью этого свойства убедимся, что слой является слоем нашей модели. | + | Свойство **CreateVisualizationEventArgs.Layer** возвращает текущий экспортируемый слой типа **CadViewLayer**. По свойству Layer можно определить, какая именно модель в данный момент экспортируется. |
- | Свойство **CreateVisualizationEventArgs.Map** возвращает сводную ИМ типа **VisualizationMap**, в которую следует добавить необходимые объекты (**GeometryInsertion**). | + | Свойство **CreateVisualizationEventArgs.Map** возвращает сводную ИМ типа **VisualizationMap**, в которую следует добавить необходимые объекты. |
- | Модель чертежа можно получить с помощью свойства **DwgBlock.Drawing**. Прежде чем вносить изменения в чертёж мы зафиксируем его настройки методом **Drawing.PushState()** и выполним их сброс до состояния по умолчанию методом **Drawing.ResetStateDefault()**. Далее в блоке **try** внесём необходимые изменения в чертёж и в блоке **finally** вернём настройки чертежа в прежнее состояние методом **Drawing.PopState()**. | + | Объекты ИМ объединяются в группы (**VisualizationGroup**). Каждая группа - это узел в дереве сводной модели. Текущую группу можно получить через свойство **VisualizationMap.Group**, и при необходимости переопределить её свойства через метод **VisualizationGroup.ApplayOverridedProperties()** или тип. Группы так же могут содержать в себе другие группы. Новая группа создаётся методом **VisualizationMap.BeginGroup()** и становится текущей. Метод **VisualizationGroup.EndGroup()** заканчивает работу с текущей группой и возвращает группу уровнем выше. |
+ | |||
+ | <note>Связку **BeginGroup() => EndGroup()** следует использовать в сочетании с блоком **try/finally**. | ||
+ | <code csharp> | ||
+ | # args - аргументы типа CreateVisualizationEventArgs | ||
+ | VisualizationMap map = args.Map; | ||
+ | map.BeginGroup("GroupName", false); | ||
+ | try | ||
+ | { | ||
+ | VisualizationGroup group = map.Group; | ||
+ | # пользовательские действия | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | map.BeginGroup("GroupName", false); | ||
+ | } | ||
+ | </code> | ||
+ | </note> | ||
+ | |||
+ | Для добавления моделей в сводную ИМ используется метод **VisualizationMap.AddMesh()**, а для размещения добавленной модели в пространстве метод **VisualizationMap.AddInsertion()**. | ||
+ | |||
+ | === Добавление объекта в сводную модель === | ||
+ | |||
+ | Наша модель содержит в себе линейные объекты. В качестве примера для отображения на сводной модели примем, что линейный объект нашей модели это забор (**Fence**) с фиксированной высотой 3 метра. | ||
+ | |||
+ | Для каждого участка забора создадим полигональную сеть (**MeshGeometry3D**). | ||
+ | |||
+ | Через свойство **MeshGeometry3D.Groups** получим коллекцию групп сети (**MaterialGroupsCollection**) и добавим в неё группу с материалом (**MaterialGroup**). | ||
+ | |||
+ | Определим координаты вершин (**Vector3F**) и добавим их в коллекцию вершин (**Vector3dCollection**) через свойство **MeshGeometry3D.Positions**. | ||
+ | |||
+ | Определим грани (**Face**) опирающиеся на индексы вершин полигональной сети. Для каждой грани добавим в группу сети новый индекс методом **MaterialGroup.AddIndex()**. Через свойство **MeshGeometry3D.TriangleIndices** получим коллекцию треугольников (**TrianglesCollection**) и добавим в неё грани. | ||
+ | |||
+ | Создадим трёхмерную модель (**GeometryModel3D**). Получим словарь с материалами через свойство **GeometryModel3D.Materials** и добавим в него материал (**PhongMaterial**). Через свойство **GeometryModel3D.Meshes** получим словарь полигональных сетей и добавим в него вышеописанную сеть. | ||
+ | |||
+ | Сгенерируем новое имя для нашей 3D-модели методом **VisualizationMap.GenMeshName()**. Добавим нашу 3D-модель с новым именем в коллекцию моделей сводной ИМ методом **VisualizationMap.AddMesh**. | ||
+ | |||
+ | Создадим новую группу методом **VisualizationMap.BeginGroup()**. В блоке **try** добавим вставку (**GeometryInsertion**) ранее добавленной 3D-модели методом **VisualizationMap.AddInsertion**. Через свойство **VisualizationMap.Group** получим текущую группу (**VisualizationGroup**). Назначим ей тип через свойство **VisualizationGroup.Type**. Через свойство **VisualizationGroup.Properties** получим коллекцию свойств (**ImProperties**) и добавим в неё новые свойства (**ImProperty**) "Количество узлов" и "Длина". | ||
+ | |||
+ | В блоке **finally** закроем группу методом **VisualizationMap.EndGroup()**. | ||
В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». | ||
<file csharp Module.cs> | <file csharp Module.cs> | ||
- | //функция срабатывающая при обявлении бродкаста "generate_visualization_map" | + | //функция срабатывающая при объявлении бродкаста "generate_visualization_map" |
- | //подписка на бродкаст осудествляется в plugin-файле в разделе "broadcasts" | + | //подписка на бродкаст осуществляется в plugin-файле в разделе "broadcasts" |
[cmd("tutorial_generate_visualization")] | [cmd("tutorial_generate_visualization")] | ||
private void GenerateVisualization(CreateVisualizationEventArgs args) | private void GenerateVisualization(CreateVisualizationEventArgs args) | ||
Строка 161: | Строка 202: | ||
private void GenerateModelVisualization(CreateVisualizationEventArgs args) | private void GenerateModelVisualization(CreateVisualizationEventArgs args) | ||
{ | { | ||
- | var fenceHeight = 3.0; | + | var fenceHeight = 3.0; // высота забора |
- | var desc = "fence"; | + | var map = args.Map; // сводная модель |
- | var map = args.Map; | + | |
var layer = args.Layer as ModelLayer; | var layer = args.Layer as ModelLayer; | ||
| | ||
Строка 169: | Строка 209: | ||
if (layer.Visible && layer.Model is Model model) | if (layer.Visible && layer.Model is Model model) | ||
{ | { | ||
- | // собираем поверхности | + | // собираем поверхности для определения высотного положения забора |
var project = ApplicationHost.Current.ActiveProject as ModelProject; | var project = ApplicationHost.Current.ActiveProject as ModelProject; | ||
var items = project.Model.GetChilds(); | var items = project.Model.GetChilds(); | ||
Строка 187: | Строка 227: | ||
for (int i = 0; i < model.Count; i++) | for (int i = 0; i < model.Count; i++) | ||
{ | { | ||
- | // генерируем имя и создаём 3D-модель | + | // создаём полигональную сеть и добавляем в неё группу материалов |
- | var meshName = map.GenMeshName("custom_mesh"); | + | var mesh = new MeshGeometry3D(); |
- | var geometry = new GeometryModel3D(); | + | var materialGroup = new MaterialGroup { Material = "Fence_Material" }; |
- | + | mesh.Groups.Add(materialGroup); | |
- | // добавляем материал | + | |
- | if (!geometry.Materials.ContainsKey(desc)) | + | |
- | { | + | |
- | var material = new PhongMaterial(); | + | |
- | material.Diffuse = new Vector3F(0.6, 0.6, 0.6); | + | |
- | material.Shininess = 0.8f; | + | |
- | material.SpecularLevel = 0.8f; | + | |
- | geometry.Materials[desc] = material; | + | |
- | } | + | |
- | + | ||
- | // создаём сеть и добавляем в неё группу | + | |
- | geometry.Meshes[desc] = new MeshGeometry3D(); | + | |
- | var mesh = geometry.Meshes[desc]; | + | |
- | var group = new MaterialGroup(); | + | |
- | group.Material = desc; | + | |
- | mesh.Groups.Add(group); | + | |
| | ||
- | // наполняем сеть точками и определяем треугольники опирающиеся на эти точки | + | // наполняем сеть вершинами и определяем грани опирающиеся на эти точки |
- | var length = 0.0; | + | var length = 0.0; //длина участка забора |
var points = model[i]; | var points = model[i]; | ||
for (int j = 0; j < points.Count; j++) | for (int j = 0; j < points.Count; j++) | ||
Строка 234: | Строка 258: | ||
var face1 = new Face(j * 2, (j + 1) * 2, j * 2 + 1); | var face1 = new Face(j * 2, (j + 1) * 2, j * 2 + 1); | ||
var face2 = new Face((j + 1) * 2, (j + 1) * 2 + 1, j * 2 + 1); | var face2 = new Face((j + 1) * 2, (j + 1) * 2 + 1, j * 2 + 1); | ||
- | group.AddIndex(TrimShort(mesh.TriangleIndices.Count)); | + | materialGroup.AddIndex(TrimShort(mesh.TriangleIndices.Count)); |
mesh.TriangleIndices.Add(face1); | mesh.TriangleIndices.Add(face1); | ||
- | group.AddIndex(TrimShort(mesh.TriangleIndices.Count)); | + | materialGroup.AddIndex(TrimShort(mesh.TriangleIndices.Count)); |
mesh.TriangleIndices.Add(face2); | mesh.TriangleIndices.Add(face2); | ||
} | } | ||
} | } | ||
- | // добавляем сеть в 3D-модель, вставляем её в информационную модель, | + | // создаём 3D-модель и добавляем в неё материал |
+ | // добавляем сеть в 3D-модель | ||
+ | var geometry = new GeometryModel3D(); | ||
+ | if (!geometry.Materials.ContainsKey("Custom_Material")) | ||
+ | { | ||
+ | var material = new PhongMaterial(); | ||
+ | material.Diffuse = new Vector3F(0.6, 0.6, 0.6); | ||
+ | material.Shininess = 0.8f; | ||
+ | material.SpecularLevel = 0.8f; | ||
+ | geometry.Materials["Custom_Material"] = material; | ||
+ | } | ||
+ | geometry.Meshes["Fence_Mesh"] = mesh; | ||
+ | |||
+ | // добавляем 3D-модель в сводную модель, | ||
// назначаем ей тип и необходимые свойства | // назначаем ей тип и необходимые свойства | ||
+ | var meshName = map.GenMeshName("custom_mesh"); | ||
map.AddMesh(meshName, geometry); | map.AddMesh(meshName, geometry); | ||
map.BeginGroup("Fence", false); | map.BeginGroup("Fence", false); |