General Polygon Clipper
Так уж сложилось, что я достаточно часто сталкиваюсь с проблемой проведения логических операций над контурами в среде Microstation и вместе с этим у меня иногда возникает проблема, когда Microstation наотрез отказывается объединять (или обрезать) нужные мне контуры.
При этом стоит отметить, что если вы используете самую последнюю версию Microstation (SS3 или же Connect), то вы можете подобных проблем и не испытывать (хотя и последние версии этой среды не лишены проблем в решении подобных задач). Но что же делать, если требуется использовать более старую версию (Microstation v8)?
Существует несколько решений:
- Использовать Microstation SS3 или Connect, но как я и говорил – на 100% это проблемы не решает, да и постоянно переключаться из одной среды в другую не самое приятное занятие;
- Использовать стороннее программное обеспечение (ArcGis, AutoCAD и другие), но это как минимум не удобно, хотя для разового решения проблемы может и подойти;
- Устранить проблему, из-за которой логическая операция не выполняется, и позже вручную провести подгон результирующего контура (добавить нужные вершины и т.п.);
- Создать свой собственный инструмент на основе алгоритмов, для которых не существует проблем проведения подобных операций.
Вот о последнем решении мы немного и поговорим.
В качестве подобного алгоритма мы будем использовать алгоритм Ватти и его конкретную реализацию в библиотеке General Polygon Clipper (далее GPC).
Как вы уже поняли самим реализовывать этот алгоритм не нужно – за нас уже все сделали, а требуется лишь подключить данную библиотеку к нашей любимой Microstation (тут вы вольны делать так как вам захочется – писать нативный инструмент на C++ или же создать макрос на VBA).
Сама библиотека доступна в нескольких реализациях:
- .NET wrapper
- .ActionScript 3 port
- .C# wrapper
- .Cocoa/NSBezier wrapper
- .COM wrapper
- .Delphi/Pascal port (GPC v2.30)
- .Delphi/Pascal port (GPC v2.32)
- .haXe port
- .Haskell port
- .Java port
- .Javascript port
- .Lua binding
- .Objective-C wrapper
- .OCaml binding
- .Octave binding
- .Perl binding
- .Python bindings
- .VB.NET wrapper
А вот исходники библиотеки доступны в двух версиях:
- GPC v2.32 – стабильный релиз;
- GPC v2.33 – экспериментальный релиз (май 2014 года).
Имеется также и полная документация, которая поясняет основные моменты работы алгоритма, а также описывает те структуры данных, которые используются для работы (это конечно обязательно пригодится вам, если вы будете писать собственную обертку над самой библиотекой).
Хоть сам я и не являюсь профессиональным программистом, но мне все-таки пришлось писать собственную DLL, которая имеет лишь одну внешнюю функцию, использующуюся для взаимодействия с Microstation через макрос, написанный на VBA. Зачем подобные сложности, когда есть COM wrapper – это уже другой вопрос, на который сложно ответить, но как минимум собственная библиотека дает возможность в будущем развивать ее, добавляя различные дополнения (никто не мешает вам реализовать в ней и другие алгоритмы).
В конечном итоге я написал на VBA макрос, который реализует все доступные в библиотеке GPC операции и внешне напоминает родной инструмент Microstation.
А вот и небольшой пример:
- Зеленый контур: ComplexShape, 17837 вершин;
- Красный контур: ComplexShape, 16930 вершин;
- Верхнее меню: родной инструмент Microstation;
- Нижнее меню: мой макрос, который создан на VBA.
Результат операции Union, проведенной с помощью Microstation:
Результат операции Union, проведенной с помощью GPC:
В общем пример, на мой взгляд, достаточно показателен – Microstation объединение не провел, а вот GPC провел успешно!