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

ADN Club => ObjectARX => Тема начата: Kruvcraft от 25-08-2023, 14:10:35

Название: Разделение кривых
Отправлено: Kruvcraft от 25-08-2023, 14:10:35
Есть точки пересечения с определенной линией, хочется по этой точке разрезать объект, но после добавления сегментов в базуданных происходит зависание AutoCAD. Непонятно в чем проблема. Сообщения автокад не показывает.
(pEntity может быть полилинией или кругом)
Код - C++ [Выбрать]
  1. if (line->intersectWith(pEntity, AcDb::kOnBothOperands, arrPoint) == Acad::eOk && arrPoint.length() > 0)
  2. {
  3.         AcDbVoidPtrArray segments;
  4.         AcGeDoubleArray pointsDist{ 0 };
  5.         AcDbCurve* curve = AcDbCurve::cast(pEntity);
  6.         for (auto& point : arrPoint)
  7.         {
  8.                 AcGePoint3d p;
  9.                 curve->getClosestPointTo(point, p);
  10.                 double dist{ 0 };
  11.                 curve->getParamAtPoint(p, dist);
  12.                 pointsDist.append(dist);
  13.                 acutPrintf(_T("point dist %lf\n"), dist);
  14.         }
  15.         std::sort(pointsDist.begin(), pointsDist.end());                               
  16.         if (curve->getSplitCurves(pointsDist, segments) == Acad::eOk)
  17.         {
  18.                 acutPrintf(_T("len segments %d\n"), segments.length());
  19.                 for (int i{0}; i < segments.length(); i++)
  20.                 {
  21.                         AcDbEntity* seg = AcDbEntity::cast(static_cast<AcDbObject*>(segments[i]));
  22.                         pBlockTableRecord->appendAcDbEntity(seg);
  23.                         seg->close();
  24.                 }
  25.         }                              
  26. }
  27.  
Название: Re: Разделение кривых
Отправлено: Александр Ривилис от 25-08-2023, 15:52:49
А если вместо:
Код - C++ [Выбрать]
  1. AcDbEntity* seg = AcDbEntity::cast(static_cast<AcDbObject*>(segments[i]));
написать:
Код - C++ [Выбрать]
  1. AcDbCurve* seg = static_cast<AcDbCurve*>(segments[i]);
Ну и заодно проверяй результат:
pBlockTableRecord->appendAcDbEntity(seg);
Название: Re: Разделение кривых
Отправлено: Kruvcraft от 28-08-2023, 08:44:38
Простите за бесопокойство и за долгий ответ.
Проблема оказалась, что в это время я, с помощью итераторов, ходил по таблице. И получилось так, что я бесконечно добавлял объекты на черчеж.
Название: Re: Разделение кривых
Отправлено: Kruvcraft от 08-09-2023, 15:45:05
Еще вопрос появился.
intersectWith не выдает точки пересечения если line и pEntity находятся на разных уровнях.
При этом pEntity это AcDbLine. И Уровень у начальной точки 0.2, а у конечной 110.
Есть вариант как-то получить точки пересечения в таком случае ?
Название: Re: Разделение кривых
Отправлено: Александр Ривилис от 08-09-2023, 16:15:34
Используй этот перегружённый метод intersectWith: https://help.autodesk.com/view/OARX/2023/ENU/?guid=OARX-RefGuide-AcDbEntity__intersectWith_AcDbEntity__AcDb__Intersect_AcGePlane__AcGePoint3dArray__Adesk__GsMarker_Adesk__GsMarker_const
Название: Re: Разделение кривых
Отправлено: Kruvcraft от 08-09-2023, 16:35:48
Я попробовал, работает, но у полученной точки уровень равен 0.
Я поменял местами объекты, но результат такой же.
Название: Re: Разделение кривых
Отправлено: Александр Ривилис от 08-09-2023, 17:38:13
но у полученной точки уровень равен 0.
Ну тогда тебе придется найти еще пересечение с вертикальным отрезком (прямой) из этой точки
Или попробуй метод getClosestPointTo:
Код - C++ [Выбрать]
  1. virtual Acad::ErrorStatus getClosestPointTo(
  2.     const AcGePoint3d& givenPnt,
  3.     const AcGeVector3d& direction,
  4.     AcGePoint3d& pointOnCurve,
  5.     Adesk::Boolean extend = Adesk::kFalse
  6. ) const;
  7.  
Название: Re: Разделение кривых
Отправлено: Kruvcraft от 09-09-2023, 14:10:44
getClosestPointTo не подошла под задачу, так как она меняла все координаты.

Point x: 40.940229 y: 15.941884 z: 0.000000
Point x: 44.635119 y: 14.478405 z: 0.280236

А вот идея с тем, чтобы строить линию очень интересная, в целом, я получил результат, который был нужен.

Point x: 40.940229 y: 15.941884 z: 0.000000
Point x: 40.940229 y: 15.941884 z: 56.639827
Название: Re: Разделение кривых
Отправлено: Александр Ривилис от 10-09-2023, 20:04:19
getClosestPointTo не подошла под задачу, так как она меняла все координаты.

Point x: 40.940229 y: 15.941884 z: 0.000000
Point x: 44.635119 y: 14.478405 z: 0.280236
Это при какой direction?
Название: Re: Разделение кривых
Отправлено: Kruvcraft от 11-09-2023, 11:58:14
Я использовал перегрузку без данного параметра. Думаю будет безопаснее использовать линию, хотя с точки зрения памяти не очень получиться.
Название: Re: Разделение кривых
Отправлено: Александр Ривилис от 12-09-2023, 12:23:23
Я использовал перегрузку без данного параметра.
Ну и зачем я тогда писал конкретно этот перегруженный метод ???
Название: Re: Разделение кривых
Отправлено: Kruvcraft от 12-09-2023, 19:14:20
Просто, линии могут быть на разных уровнях в разных направлениях, можно вызвать два раза метод, с разными направлениями, но мне показалось это не совсем хорошим решением проблемы.

Появился другой вопрос, используется контур для разрезания.
Сделал два разрезания, один с помощью своей функции где используется intersectWith + getSplitCurves, другой с помощью функции MAPTRIM.
Некоторые линии различаются с точки зрения геометрии, как я понимаю это вызвано тем, что использовались разные алгоритмы поиска пересечения. Проблема в том, что оба результата отличаются от оригинала, то есть линии чуть дальше чем надо, но при этом intersectWith + getSplitCurves гораздо дальше.

На скрине зеленым MAPTRIM, красным intersectWith + getSplitCurves.
(https://i.postimg.cc/phxJz0KW/2023-09-12-211148.png) (https://postimg.cc/phxJz0KW)

Можно как-то получить результат лучше чем MAPTRIM или на том же уровне ?
Название: Re: Разделение кривых
Отправлено: Александр Ривилис от 13-09-2023, 13:22:02
Просто, линии могут быть на разных уровнях в разных направлениях
Если бы у тебя direction был равен AcGeVector3d::kZAxis, то менялась бы только координата Z - во всяком случае именно так должно работать.
Что касается точности, то ничего не скажу. Тут нужно разбираться с цифрами в каждом конкретном случае.
Название: Re: Разделение кривых
Отправлено: Kruvcraft от 13-09-2023, 16:23:06
Если бы у тебя direction был равен AcGeVector3d::kZAxis, то менялась бы только координата Z - во всяком случае именно так должно работать.
Попробовал все круто, спасибо.


Что касается точности, то ничего не скажу. Тут нужно разбираться с цифрами в каждом конкретном случае.
Точность это самое странное, так как если сравнить MAPTRIM и оригинал чертежа, то там не все гладко.
(https://i.postimg.cc/vcy4P7hT/2023-09-13-181635.png) (https://postimg.cc/vcy4P7hT)
Красным MAPTRIM, зеленым оригинал.

Поэтому хотелось бы спросить, есть более точные инструменты ObjectARX для разрезания кривых ? 
Я пока не вижу вообще рабочего варианта, кроме смирения. Можно наверное подгонять решение под конкретный случай, но это не универсальный подход.

Название: Re: Разделение кривых
Отправлено: Александр Ривилис от 14-09-2023, 22:56:28
Поэтому хотелось бы спросить, есть более точные инструменты ObjectARX для разрезания кривых ? 
А вообще что у тебя за кривые? Т.е. какой класс примитива?
Название: Re: Разделение кривых
Отправлено: Александр Ривилис от 15-09-2023, 11:01:10
Кстати, а регенерацию чертежа при приближении ты выполнял?