Инструменты пользователя

Инструменты сайта


Боковая панель

developers:tutorial:sfcedit

Это старая версия документа.


Добавление и редактирование элементов поверхности

Добавление и редактирование точек поверхности

Одним из основных элементов поверхности является съёмочная точка типа SurfacePoint. Так как SurfacePoint является структурой, а не классом, редактирование SurfacePoint напрямую не приведёт к желаемому результату. Добавления новых и редактирование существующих точек осуществляется с помощью специального класса PointEditor.

PointEditor позволяет осуществлять следующие операции с точками поверхности:

Добавление и редактирование структурных линий

Для добавления структурных линий помощи специальных классов не требуется. Их можно добавлять напрямую в коллекцию структурных линий (Surface.StructureLines) нужной поверхности. Аналогично с PointEditor, методы StructureLines.Add() и StructureLines.Remove() дают возможность добавить или удалить структурную линию соответственно. Для удаления структурной линии по её индексу, можно воспользоваться методом StructureLines.RemoveAt().

Редактировать структурные линии следует напрямую. Например, если мы хотим добавить существующую точку поверхности в структурную линию, нужно именно у неё вызвать метод Add().

Структурная линия всегда опирается на точки поверхности и не может существовать без них.

Настройка проекта Visual Studio

Прежде чем приступить работе с элементами поверхности, создайте и настройте новый модуль для подключения к программному комплексу Топоматик Робур.

С помощью диалогового окна Менеджер ссылок добавьте ссылки на следующие библиотеки:

В следующих примерах используются классы и методы предыдущего урока, в котором рассматривается процесс выделения элементов поверхности.

Добавление элементов поверхности

В этом примере мы выберем замкнутую структурную линию и на указанном расстоянии от неё построим новую с учётом приращения высоты.

Для этого нам потребуются координаты точек эквидистанты существующей структурной линии. Далее мы рассчитаем новое значение высоты этих точек и на основе полученных координат создадим новые точки поверхности. Вновь созданные точки поверхности станут основой для создания новой структурной линии.

Эквидистанта для новой структурной линии должна рассчитываться относительно удалённости курсора от выбранной структурной линии. Чтобы получить это значение, необходимо воспользоваться методом CadLibrary.PosToPolylineStaOffset(). В качестве аргументов, метод принимает список координат полилинии типа Vector2D, координаты курсора типа Vector2D и записывает рассчитанные значения в принимаемые переменные offset и station типа double с модификатором out. offset - кратчайшее расстояние от курсора до полилинии, а station - длина части полилинии от её первой точки до точки в которой был определён offset.

Для наглядности будущего положения новой структурной линии мы воспользуемся динамической отрисовкой примитива.

В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «create_hill_or_pit» предложит пользователю выбрать замкнутую структурную линию и приращение высоты. Результатом действия станет сооружение насыпи или котлована в зависимости от значений указанных пользователем.

{
...
    [cmd("create_hill_or_pit")]
    private void CreateHillOrPit()
    {
        //Находим активный SurfaceLayer
        var cadview = CadView;
        if (cadview == null) return;
 
        var layer = SurfaceLayer.GetSurfaceLayer(cadview);
        if (layer == null) return;
        var sfc = layer.Surface;
 
        //Выбираем структурную линию и получаем список её двумерных координат
        var strLine = layer.SelectOneStructureLine(i => sfc.StructureLines[i].IsClosed,
            "Выберите замкнутую структурную линию:");
        if (strLine == null) return;
 
        var poly = new List<Vector3D>();
        strLine.ToPolyline(poly);
        var poly2d = poly.Select(v => v.Pos).ToList();
 
        //Делегат для динамической отрисовки контура будущей структурной линии
        DrawCursorEvent ondraw = delegate (CadPen pen, Vector3D vertex)
        {
            double s, o;
            //находим смещение точки по линии
            if (CadLibrary.PosToPolylineStaOffset(poly2d, vertex.Pos, out o, out s))
            {
                var offs_line = new List<Vector3D>();
                poly.Offset(o, offs_line);
 
                //Создаём примитив и рисуем его
                var entity = new DwgPolyline();
                entity.Prepare(sfc.Situation);
                foreach (var v in offs_line)
                {
                    entity.Add(new BugleVector2D(v.Pos));
                }
 
                entity.Color = CadColor.Green;
                PaintEntityEventArgs.PaintEntity(entity, pen);
            }
        };
 
        //Подписываемся на событие динамической отрисовки примитивов
        cadview.DynamicDraw += ondraw;
 
        Vector3D point;
        GetPointResult res;
        try
        {
            //Указываем курсором точку на плане определяющую сторону и величину смещения
            //и закладываем возможность задать смещение с клавиатуры
            res = CadCursors.GetPoint(cadview, out point, "Укажите смещение или:", "Задать величину смещения");
 
        }
        finally
        {
            //Отписываемся от события, так как динамическая отрисовка нам больше не требуется
            cadview.DynamicDraw -= ondraw;
        }
 
 
        double sta;
        var off = 0.0;
        if (res == GetPointResult.Accept)
        {
            CadLibrary.PosToPolylineStaOffset(poly2d, point.Pos, out off, out sta);
        }
        else if (res == GetPointResult.UserCmd)
        {
            if (CadCursors.GetDouble(cadview, ref off, "Задайте смещение:") == GetPointResult.Cancel) return;
        }
        else if (res == GetPointResult.Cancel) return;
 
        var delta = 0.0;
        var incline = 0.0;
 
        //Указываем величину приращения отметок смещённой структурной линии
        //и закладываем возможность задать уклон откоса
        //В случае если пользователь просто нажмёт Enter то функция вернёт UserCmd
        res = CadCursors.GetDouble(cadview, ref delta, "Укажите разницу высот или:", "Задать уклон");
 
        if (res == GetPointResult.UserCmd && cadview.LastUserCmd != "")
        {
            if (CadCursors.GetDouble(cadview, ref incline, "Укажите уклон:") == GetPointResult.Cancel) return;
            delta = incline * Math.Abs(off);
        }
        else if (res == GetPointResult.Cancel) return;
 
        //Определяем эквидистанту в соответствии с параметрами указанными пользователем
        var offsetPoly = new List<Vector3D>();
        poly.Offset(off, offsetPoly);
        offsetPoly.Remove(offsetPoly[offsetPoly.Count - 1]);
 
        //Фиксируем момент начала внесения изменений в поверхность
        sfc.BeginUpdate("Построить насыпь или котлован");
 
        //Создаём точки поверхности и добавляем их в структурную линию
        try
        {
            var offsetStrLine = new StructureLine();
            var editor = new PointEditor(sfc);
            foreach (var polylinePoint in offsetPoly)
            {
                var sfcPoint = new SurfacePoint(polylinePoint + new Vector3D(0.0, 0.0, delta));
                sfcPoint.IsSituation = false;
                var sfcPointIndex = editor.Add(sfcPoint);
                offsetStrLine.Add(sfcPointIndex);
            }
 
            offsetStrLine.IsClosed = true;
            sfc.StructureLines.Add(offsetStrLine);
        }
        finally
        {
            //Фиксируем окончание внесения изменений в поверхность
            sfc.EndUpdate();
        }
 
        //Очищаем список выбранных элементов поверхности
        //и сообщаем CadView о необходиомсти обновить отображение его содержимого
        layer.SelectionSet.Clear();
        cadview.Unlock();
        cadview.Invalidate();
    }
...
}

Редактирование элементов поверхности

В этом примере мы рассмотрим процесс замены точечного объекта у точки поверхности

developers/tutorial/sfcedit.1649520331.txt.gz · Последние изменения: 2022/04/09 16:05 — proxor