Сообщество программистов Autodesk в СНГ

ADN Club => ObjectARX => Тема начата: Debalance от 31-08-2017, 16:33:17

Название: "Комплексные" сплайны
Отправлено: Debalance от 31-08-2017, 16:33:17
В своей повседневной многотрудной работе со сплайнами мне часто попадаются так называемые "комплексные" сплайны - это объекты идентифицируемые как AcDbSpline, но с интересной особенностью: подрыв такого сплайна приводит к разложению последнего на ряд саб-сплайнов - в точности повторяющих контур исходного.
В связи с этим возникают вопросы:
1. Как распознавать такие сплайны без использования подрыва?
2. Как самостоятельно создавать такие сплайны?
Может кто в теме данной ситуации?

Пример комплексного сплайна прилагаю во вложении.
Название: Re: "Комплексные" сплайны
Отправлено: Александр Ривилис от 01-09-2017, 00:09:06
подрыв
Это что такое?
Название: Re: "Комплексные" сплайны
Отправлено: Алексей Кулик от 01-09-2017, 09:10:45
Я полагаю, аналог _.explode :)
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 01-09-2017, 10:20:19
Я полагаю, аналог _.explode :)
Вот-вот... Я бы даже выбросил слово "аналог".
Название: Re: "Комплексные" сплайны
Отправлено: trir от 01-09-2017, 13:00:29
Книга NURBS. Глава 5 - там даже есть алгоритм DecomposeCurve
Насколько я помню, это определяется степенью кривой. Сплайн это Nurbs-кривая и если у неё высокая степень, то её можно разделить на несколько сегментов - кривых Безье меньшей степени
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 01-09-2017, 13:38:28
Книга NURBS. Глава 5 - там даже есть алгоритм DecomposeCurve
Спасибо, дружище trir, за наводку, но мне не очень бы хотелось писать свои кастомные методы, а есть желание использовать уже готовые решения в рамках ObjectARX SDK. Тем более сам AutoCAD прекрасно определяет "высокую степень" конкретного сплайна и в состоянии запустить "алгоритм DecomposeCurve". Поэтому моя первоочередная задача добраться до этих готовых решений зашитых в лоне AutoCAD.
Название: Re: "Комплексные" сплайны
Отправлено: Александр Ривилис от 01-09-2017, 13:46:57
Ну из того, что я обнаружил:
1. Не совпадает количество управляющих точек (controlPoints) и количество узлов (knots). Видно при помощи ARXDBG
2. Совпадают некоторые управляющие точки:
(https://farm5.staticflickr.com/4369/36148180313_cbd0fb322c_o.png)
3. Отрицательная площадь:
(https://farm5.staticflickr.com/4440/36785473492_7882027ca9_o.png)



Название: Re: "Комплексные" сплайны
Отправлено: trir от 01-09-2017, 14:34:48
Цитировать
Совпадают некоторые управляющие точки
так всегда на прямых участках

Цитировать
Не совпадает количество управляющих точек (controlPoints) и количество узлов (knots).
так всегда
knots = controlPoints + degree + 1

Цитировать
Св.4.13  NURBS  кривая  без  внутренних  узлов  является  рациональной  кривой  Безье, поскольку  N_(i,p) (u)  сводятся  к  B_(i,n) (u); сравните  формулы  (4.2)  и  (4.3)  с  уравнением  (1.15). Из  этого, вместе  со  Св.4.7, следует, что  кривые  NURBS  содержат  нерациональные  B-сплайны  и  рациональные  и  нерациональные  кривые  Безье  в  качестве  частных  случаев;
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 01-09-2017, 15:01:51
так всегда
knots = controlPoints + degree + 1

Это не всегда так. Вот выдержка из Википедии:
Цитировать
A common misconception is that each knot is paired with a control point. This is true only for degree 1 NURBS (polylines). In general, the knots break the domain up into knot spans, but each control point corresponds to one basis function which spans a range of (degree+1) knot spans.
Название: Re: "Комплексные" сплайны
Отправлено: Александр Ривилис от 01-09-2017, 15:02:31
Цитировать

    Не совпадает количество управляющих точек (controlPoints) и количество узлов (knots).

так всегда
knots = controlPoints + degree + 1
Судя по всему не всегда. Во всяком случае я средствами AutoCAD нарисовал сплайн с degree - 3, controlPoints - 10 и knots - 11.
Название: Re: "Комплексные" сплайны
Отправлено: trir от 01-09-2017, 15:07:08
по этому и нужно учить теорию - когда её знаешь, этих вопросов просто не возникает
а я уже почти всё забыл... :=(
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 01-09-2017, 20:56:13
Во всей этой математической кутерьме связанной с кнотами и контрол-поинтами меня интересует практическая сторона вопроса, непосредственно касающаяся опубликованного мной чертежа. Речь идёт о создании региона (AcDbRegion). Я провёл небольшой тест:

1. Попытался создать регион из исходного сплайна (команда _REGION). В результате получается вполне себе корректный объект - даже площадь имеет адекватное значение.

2. В тулбаре AutoCAD я нажал вот на эту иконку:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F484172%2F105409719.4%2F0_172563_574e1b3c_orig.png&hash=3865d92753988d93dc8e438ffe673932)
и применив к сплайну команду _EXPLODE я расчленил его на группу примитивов. Если далее к полученной группе попытаться применить команду _REGION, то в текстовом окне мы обнаружим следующий лог:
1 loop extracted.
1 loop rejected.
    Unable to cover wire                   : 1 loop.
0 Regions created.
То же фиаско нас ожидает при использовании команды _BOUNDARY, если в качестве Object type указать Region.

Таким образом наблюдается некоторый дуализм в поведении AutoCAD'а. Что это баг?
Название: Re: "Комплексные" сплайны
Отправлено: Александр Ривилис от 01-09-2017, 21:03:57
Что это баг?
Воспринимай это как ограничение в AutoCAD. Не вижу смысла даже передавать это в ADN DevHelp.
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 01-09-2017, 21:18:33
Воспринимай это как ограничение в AutoCAD.
Что-то уж больно много ограничений набирается у меня при работе со сплайнами.

Не вижу смысла ...
Я тоже его не вижу. Просто пытаюсь самостоятельно разрулить программную реализацию создания региона для конкретной задачи. Но похоже выше головы не прыгнешь в рамках исходного SDK.
Название: Re: "Комплексные" сплайны
Отправлено: Александр Ривилис от 01-09-2017, 21:31:39
Но похоже выше головы не прыгнешь в рамках исходного SDK.
Думаю, что единственный правильный способ - аппроксимация сплайна с заданной точностью, а затем уже создание региона. Тем более, что точности Region и 3DSolid порядка 1e-6
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 01-09-2017, 21:46:27
Думаю, что единственный правильный способ - аппроксимация сплайна с заданной точностью
Вы намекаете на полилинию с миллиардом вершин? Представляете как раздуется чертёж в котором куча сплайнов?
Название: Re: "Комплексные" сплайны
Отправлено: Александр Ривилис от 01-09-2017, 22:08:51
Вы намекаете на полилинию с миллиардом вершин?
Думаю, что значительно меньше - зависит от "гладкости" сплайна и необходимой точности представления.
Представляете как раздуется чертёж в котором куча сплайнов?
А зачем добавлять его в чертеж? Ты его используешь только для создания AcDbRegion при помощи AcDbRegion::createFromCurves. Если это однократная операция, то можно в чертеж аппроксимированный сплайн не добавлять.
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 01-09-2017, 22:27:51
А зачем добавлять его в чертеж?
Нет, я не добавляю его в чертёж. Я просто сравниваю "вес" гипотетического региона созданного из полилинии с большим количеством вершин с "весом" региона на основе исходного сплайна. Последний (в моём понимании) существенно "легче".
Название: Re: "Комплексные" сплайны
Отправлено: trir от 02-09-2017, 09:35:05
Скорей всего сплайны разбегаются при усечении координат конечных точек в соответствии с текущей точность чертежа...
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 02-09-2017, 17:28:20
Скорей всего сплайны разбегаются при усечении координат конечных точек в соответствии с текущей точность чертежа...
Не понял. Поясните, что Вы имеете ввиду?
Название: Re: "Комплексные" сплайны
Отправлено: trir от 04-09-2017, 06:57:54
да нет, фигню сказал  :(
Название: Re: "Комплексные" сплайны
Отправлено: Николай Горлов от 04-09-2017, 11:01:52
Во всей этой математической кутерьме связанной с кнотами и контрол-поинтами меня интересует практическая сторона вопроса, непосредственно касающаяся опубликованного мной чертежа. Речь идёт о создании региона (AcDbRegion). Я провёл небольшой тест:

1. Попытался создать регион из исходного сплайна (команда _REGION). В результате получается вполне себе корректный объект - даже площадь имеет адекватное значение.
2. В тулбаре AutoCAD я нажал вот на эту иконку:

и применив к сплайну команду _EXPLODE я расчленил его на группу примитивов. Если далее к полученной группе попытаться применить команду _REGION, то в текстовом окне мы обнаружим следующий лог:
Код: [Выделить]
1 loop extracted.
1 loop rejected.
    Unable to cover wire                   : 1 loop.
0 Regions created.
То же фиаско нас ожидает при использовании команды _BOUNDARY, если в качестве Object type указать Region.
Таким образом наблюдается некоторый дуализм в поведении AutoCAD'а. Что это баг?

команды "_REGION" и "_BOUNDARY" требуют одновременной видимости всех объектов, которые включены в набор. проверил создание области у себя. всё прекрасно создается, если все используемые объекты видны на экране ("_REGION" и "_BOUNDARY" и для целого сплайна и для его кусков). потом зумом оставил правую часть объекта на экране и при выделении - перемещался по чертежу так, что правый  "хвост" скрылся за пределами экрана, а левый появился. всё выделил. нажал Enter - результат: 0 областей.
по поводу того, как создавать такие сплайны - есть команда "_JOIN". Не уверен, но для программной реализации можно поковырять класс AcDbJoinEntityPE
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 04-09-2017, 11:22:10
команды "_REGION" и "_BOUNDARY" требуют одновременной видимости всех объектов, которые включены в набор.
Данная теза вызывает сомнения касательно команды _REGION. Я так понимаю там тупо используется AcDbRegion::createFromCurves для объектов из "селекшн-сета" и если объект выбран - то он ВЫБРАН, причём здесь видимость? На каком Автокаде Вы производили тест?
Название: Re: "Комплексные" сплайны
Отправлено: Александр Ривилис от 04-09-2017, 11:29:01
команды "_REGION" и "_BOUNDARY" требуют одновременной видимости всех объектов, которые включены в набор.
Это условие требуется только для _BOUNDARY.
Название: Re: "Комплексные" сплайны
Отправлено: Николай Горлов от 04-09-2017, 11:41:50
Данная теза вызывает сомнения касательно команды _REGION. Я так понимаю там тупо используется AcDbRegion::createFromCurves для объектов из "селекшн-сета" и если объект выбран - то он ВЫБРАН, причём здесь видимость? На каком Автокаде Вы производили тест?
упс... да, видимость только для _BOUNDARY. _REGION отрабатывает нормально, даже если объект(ы) полностью за пределами чертежа
проверял в 2014x64 и 2017x64
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 04-09-2017, 11:49:11
_REGION отрабатывает нормально
Ещё раз, чтобы я понял, Вы делаете следующее:
1. Взорвали исходный контур.
2. Применили команду _REGION к группе полученных сплайнов.
3. Наблюдаете полученный регион.

Ну если это так, то я отказываюсь понимать моё поведение Автокада!
Название: Re: "Комплексные" сплайны
Отправлено: Николай Горлов от 04-09-2017, 12:10:16
та могу даже видео снять ))). варианты тестов с _REGION:
1. к исходному сплайну применяю _REGION (создается область с одной ручкой перемещения)

2. переоткрываю чертеж.
a)_EXPLODE для сплайна.
б)_REGION. Выбираю рамкой все 12 кусков. создается область с 12 ручками перемещения

3. переоткрываю чертеж.
а)_EXPLODE для сплайна.
б)_JOIN для кусков сплайна.
в)_REGION. создается область с 12 ручками перемещения

PS: напрягает во всём этом только то, что для указанного сплайна неверно определяется площадь (окно свойств, arxdbg, сервис->сведения->площадь). но кажись я нашел, какая команда автокада привносит эту изюминку :). Нарисовал два куска сплайна друг под другом. Есть такая команда - "соединение кривых". Воспользовался ей. Она дорисовала два куска сплайна самостоятельно, чтоб  было красивенько :) и замкнуто. Потом объединил сплайны в кучу. В результате - площадь "-1".

Ну если это так, то я отказываюсь понимать моё поведение Автокада!
:) пора переустанавливать кажись.
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 04-09-2017, 13:10:55
пора переустанавливать кажись.
Полагаю дело не в этом. Протестировал на двух машинах (Acad 2016x64), результат тот же - регион не создаётся. Программная реализация показывает, что метод AcDbRegion::createFromCurves возвращает Acad::eInvalidInput.

Подтверждаю, что использование _JOIN решает проблему - создаётся регион, но всего лишь с одной ручкой (вместо 12-ти как у Вас) . Вот скриншот:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F229553%2F105409719.8%2F0_173add_d5571096_orig.png&hash=d203b8e90143c6c5b33dc91f5837bdc6)
Название: Re: "Комплексные" сплайны
Отправлено: Николай Горлов от 04-09-2017, 15:02:24
хм... вот не зря я не люблю сплайны, и везде, где только можно, стараюсь переводить их в полилинии. ради интереса поковырялся во всех установленных автокадах. задача была просто получить из исходного замкнутого сплайна (без лишних телодвижений, только команда _REGION) область и посмотреть её площадь. Вот такая занимательная математика выходит, и сразу видно, когда кто-то ковырялся руками в исходном коде автокада :) (кстати, автокады 2012-2014 область создают, но в логе командной строки есть сообщение об ошибке)
акад2010:   87.6068
акад2011:   87.6068
акад2012:   87.6024      Ошибка операции моделирования: Замкнутое ребро в многореберном каркасе.
акад2013:   87.6022      Ошибка операции моделирования: Замкнутое ребро в многореберном каркасе.
акад2014:   87.6022      Ошибка операции моделирования: Замкнутое ребро в многореберном каркасе.
акад2015:   87.5999
акад2016:   87.5999
акад2017:   87.6024

Дальше просто ради смеха решил в 2016-м автокаде пересобрать сплайн (_EXPLODE + _JOIN), а затем сделать на его основе область. Всё получилось, только площадь стала 87.6018, хоть была 87.5999. Оно то в принципе и не критично, погрешность приблизительно 0.002%.
Затем я превратил сплайн в полилинию (получилось 646 точек). Ну и пробежал создание области уже для аппроксимированного сплайна (для полилинии, короче говоря). Так вот. Результат во всех автокадах одинаковый (в принципе как и площадь самой полилинии) 87.5352

PS: Дальше идет сугубо личное мнение. Если программа пишется за денежку, то покупатель должен получать одно и то же число в ЛЮБОМ автокаде (проблемы самого автокада покупателя как-то не сильно утешают. например, площадь здания не усыхается/разрастается сама по себе в зависимости от того, в каком автокаде печатается сопроводительная документация). Второе, исходный материал может быть в любом допустимом виде, но привести его к какому-то одному промежуточному, с которым удобно работать, намного проще, чем обрабатывать рандомный ввод пользователя. Ну и третье из собственного опыта, есть чертеж карьера, нарисованный 3D сплайнами. Еле шевелится этот чертеж на 3D орбите на стареньком компике. Перегнали в 3D полилинии без видимого ухудшения качества (вроде и точек мульйон стал :), а чертеж начал плавно вращаться).
PS2: Так что Наумович, как всегда прав :), без аппроксимации дела не будет, тем более, что как я понял, её и сохранять то в чертеже не нужно
Название: Re: "Комплексные" сплайны
Отправлено: Debalance от 04-09-2017, 16:25:50
Площадь фигуры ограниченная сплайном(ми) не может быть вычислена по формуле (т.е. с точностью до машинного эпсилон). Вероятнее всего в алгоритме подсчёта площади используется (опять же таки) предварительная аппроксимация. Именно от различного шага аппроксимации (используемого в разных версиях AutoCAD) и получаются разные величины площади. Где-то уже обсуждалось, что значение AcGeContext ::gTol менялось от версии к версии - возможно это и есть ответ на вопрос.

... вроде и точек мульйон стал , а чертеж начал плавно вращаться ...
А это как сравнение векторной и растровой графики: векторная и чётче и ярче и меньше по объёму, но зато затратнее по машинному времени.

Так что Наумович, как всегда прав
Возможно и прав. Но это своего рода решение-заглушка позволяющее экстенсивным способом разрулить актуальные трудности. Я надеюсь, что Autodesk через годы совершенствования своего Детища всё-таки отшлифует тематику сплайнов.  :D