Это старая версия документа.
Программный комплекс Топоматик Робур предоставляет пользователю возможность экспортировать плоские чертежи, а также генерировать сводную информационную модель (ИМ). В этом примере мы сформируем примитивы на основе данных нашей модели и поместим их в экспортируемый плоский чертёж. Также мы сформируем объекты на основе данных нашей модели и поместим их в экспортируемую сводную ИМ.
Создайте и настройте новый модуль для подключения к программному комплексу Топоматик Робур. С помощью диалогового окна Менеджер ссылок добавьте ссылки на следующие библиотеки:
Для экспорта элементов пользовательской модели в плоский чертёж необходимы следующий действия:
Команда должна вызвать метод принимающий в качестве аргумента объект типа GeneratePlanchetEventArgs.
Свойство GeneratePlanchetEventArgs.Layer возвращает текущий экспортируемый слой типа CadViewLayer. С помощью этого свойства убедимся, что слой является слоем нашей модели.
Свойство GeneratePlanchetEventArgs.Model возвращает корневую область модели чертежа типа DwgBlock, в которую следует добавить необходимые примитивы (подклассы DwgEntity).
Модель чертежа можно получить с помощью свойства DwgBlock.Drawing. Прежде чем вносить изменения в чертёж мы зафиксируем его настройки методом Drawing.PushState() и выполним их сброс до состояния по умолчанию методом Drawing.ResetStateDefault(). Далее в блоке try внесём необходимые изменения в чертёж и в блоке finally вернём настройки чертежа в прежнее состояние методом Drawing.PopState().
В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd».
//функция срабатывающая при обявлении бродкаста "generate_planchet" //подписка на бродкаст осудествляется в plugin-файле в разделе "broadcasts" [cmd("tutorial_generate_planchet")] private void GeneratePlanchet(GeneratePlanchetEventArgs e) { // проверяем принадлежит ли слой нашей модели if (e.Layer is ModelLayer) { // отрисовываем примитивы GenerateModelPlanchet(e); e.Handled = true; } } /// <summary> /// Формирование примитивов на основе данных полученных из модели /// и добавление примитивов в чертёж /// </summary> /// <param name="e"></param> private void GenerateModelPlanchet(GeneratePlanchetEventArgs e) { if (e.Layer is ModelLayer layer) { // определяем префикс имени слоя var path = e.Path; if (e.SaveFullPath) { path += "."; } else { path = string.Empty; } // если слой включен и относится к нашему типу модели // делаем активным необходимый слой чертежа и добавляем примитивы в чертёж if (layer.Visible && layer.Model is Model model) { var modelSpace = e.Model; var drawing = modelSpace.Drawing; // запоминаем настройки чертежа и сбрасываем к значениям по умолчанию drawing.PushState(); try { drawing.ResetStateDefault(); var layerName = path + layer.Name; var dwgLayer = drawing.Layers[layerName] ?? drawing.Layers.Add(layerName); drawing.ActiveLayer = dwgLayer; for (int i = 0; i < model.Count; i++) { var points = model[i]; var vertices = new List<Vector2D>(); for (int j = 0; j < points.Count; j++) { var point = points[j]; var text = modelSpace.AddText(j.ToString(), point, 2, 1, 0, 0); text.Color = new CadColor(Color.Orange); vertices.Add(point); } var pline = modelSpace.AddPolyline(vertices); pline.Color = CadColor.Yellow; } } finally { // восстанавливаем предыдущие настройки чертежа drawing.PopState(); } } } }
Команда «tutorial_generate_planchet» должна выполняться в момент создания планшета или экспорта ситуации. Для этого добавим соответствующую запись в plugin-файл в секции «broadcast»
"broadcasts": { "generate_planchet": "tutorial_generate_planchet" }
В результате работы команды «tutorial_generate_planchet» в экспортированном файле плоского чертежа появятся примитивы нашей модели.
Для экспорта объектов пользовательской модели в сводную ИМ необходимы следующий действия:
Команда должна вызвать метод принимающий в качестве аргумента объект типа CreateVisualizationEventArgs.
Наша модель содержит в себе линейные объекты. В качестве примера для отображения на сводной модели примем, что линейный объект нашей модели это забор (Fence) с фиксированной высотой 3 метра.
Свойство CreateVisualizationEventArgs.Layer возвращает текущий экспортируемый слой типа CadViewLayer. С помощью этого свойства убедимся, что слой является слоем нашей модели.
Свойство CreateVisualizationEventArgs.Map возвращает сводную ИМ типа VisualizationMap, в которую следует добавить необходимые группы объектов (VisualizationGroup).
Объекты ИМ объединяются в группы (VisualizationGroup). Группы так же являются объектами ИМ и могут содержать в себе другие группы. Новая группа создаётся методом VisualizationMap.BeginGroup(). После этого в блоке try в группу добавляются необходимые объекты и в блоке finally группа закрывается методом VisualizationGroup.EndGroup().
В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd».
//функция срабатывающая при обявлении бродкаста "generate_visualization_map" //подписка на бродкаст осудествляется в plugin-файле в разделе "broadcasts" [cmd("tutorial_generate_visualization")] private void GenerateVisualization(CreateVisualizationEventArgs args) { // проверяем слой на соответствие типу слоя нашей модели if (args.Layer is ModelLayer) { GenerateModelVisualization(args); args.Handled = true; } } /// <summary> /// Формирование элементов информационной модели на основе данных полученных из модели /// и добавление их в информационную модель /// </summary> /// <param name="args"></param> private void GenerateModelVisualization(CreateVisualizationEventArgs args) { var fenceHeight = 3.0; var desc = "fence"; var map = args.Map; var layer = args.Layer as ModelLayer; // проверяем слой на видимость и наличием нашей модели if (layer.Visible && layer.Model is Model model) { // собираем поверхности для определения высотного положения забора var project = ApplicationHost.Current.ActiveProject as ModelProject; var items = project.Model.GetChilds(); var surfaces = new List<ISurface>(); foreach (var item in items) { if (item.ModelType.Equals("dtm", StringComparison.OrdinalIgnoreCase) && item.Model is TerrainModel dtm) { var sfc = args.FetchSurfaces(dtm); surfaces.Add(sfc); } } map.BeginGroup("CustomModel", false); try { for (int i = 0; i < model.Count; i++) { // генерируем имя и создаём 3D-модель var meshName = map.GenMeshName("custom_mesh"); var geometry = new GeometryModel3D(); // добавляем материал 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 points = model[i]; for (int j = 0; j < points.Count; j++) { var point = points[j]; var elevation = 0.0; foreach (var sfc in surfaces) { var z = sfc.GetElevation(point); if (z.HasValue && ValueConverter.CompValues(z.Value, elevation) == 1) { elevation = z.Value; } } mesh.Positions.Add(new Vector3F(new Vector3D(point, elevation))); mesh.Positions.Add(new Vector3F(new Vector3D(point, elevation + fenceHeight))); if (j < points.Count - 1) { var nextPoint = points[j + 1]; var delta = nextPoint - point; length += delta.Length; 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); group.AddIndex(TrimShort(mesh.TriangleIndices.Count)); mesh.TriangleIndices.Add(face1); group.AddIndex(TrimShort(mesh.TriangleIndices.Count)); mesh.TriangleIndices.Add(face2); } } // добавляем сеть в 3D-модель, вставляем её в информационную модель, // назначаем ей тип и необходимые свойства map.AddMesh(meshName, geometry); map.BeginGroup("Fence", false); try { map.AddInsertion(meshName, new Vector3D(0, 0, 0)); var type = map.FindType("SmdxCustomFence"); if (type == null) { var parent = map.FindType("SmdxElement"); var typeDesc = new ImTypeDescriptor("SmdxCustomFence", "Пользовательский забор", parent); type = map.CreateType(typeDesc); } map.Group.Type = type; map.Group.Properties.Add(new ImProperty("points", "Количество узлов", points.Count)); map.Group.Properties.Add(new ImProperty("length", "Длина", length)); } finally { map.EndGroup(); } } } finally { map.EndGroup(); } } } private static ushort TrimShort(int value) { Debug.Assert(value <= ushort.MaxValue); return value > ushort.MaxValue ? ushort.MaxValue : (ushort)value; }
Команда «tutorial_generate_visualization» должна выполняться в момент создания сводной модели. Для этого добавим соответствующую запись в plugin-файл в секции «broadcast»
"broadcasts": { "generate_visualization_map": "tutorial_generate_visualization" }
В результате работы команды «tutorial_generate_visualization» в экспортированной сводной модели появятся объекты нашей модели.