Тема: Как закрыть полилинию?
Посмотрел по форуму на тему как закрыть полилинию, предложен вариант с pedit
Мне интересно, можно ли как-то иначе программно замкнуть полилинию, чтоб акад не выбрасывал лишние строчки в командную строку
Информационный портал для профессионалов в области САПР
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Форумы CADUser → Программирование → ObjectARX → Как закрыть полилинию?
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Посмотрел по форуму на тему как закрыть полилинию, предложен вариант с pedit
Мне интересно, можно ли как-то иначе программно замкнуть полилинию, чтоб акад не выбрасывал лишние строчки в командную строку
> Николай
Конечно можно. Причем разными способами. Не указано о каком типе полилинии идет речь, что не правильно, т.к. их как минимум три типа.
1) Просто задать признак замкнутости:
AcDbPolyline::setClosed
AcDb2dPolyline::makeClosed
AcDb3dPolyline::makeClosed
2) Добавить еще одну вершину, совпадающую с первой - мене красивый способ - не рекомендую.
Это все не плохо, но такой вариант распространяется ТОЛЬКО на польлинию заданного типа. Мне необходимо закрыть AcDbCurve. Т.к. под этот тип попадает несколько больший выбор примитивов, например, окружность.
Код выглядит примерно так:
AcDbCurve* pCurve; switch( acedEntSel("\nУкажите контур: ", ent,pt) ) { case RTCAN : case RTERROR : case RTNONE : return; case RTNORM : ; } pCurve = Ccast(ent,0,0); if(pCurve == 0) { acedAlert("Объект не является кривой AutoCAD"); return; } if( !pCurve->isClosed() ) { // замкнуть контур }
> Николай
И как вы рассчитывали замкнуть AcDbCurve при помощи _PEDIT? Наивный! Это же базовый класс...
через acedCommand, во только "З" надо нажимать вручную :)
А этого как раз и не хочется
Кстати в БД автокада на полилинии есть код 070 с типом 16 bit integer. Если значение установлено 1, то полилиния замкнута, если 0, но разомкнута. Может попробовать так? Вот только я не могу к нему достучаться :( Помогите кто -нибудь:)
> Николай
Что Вы так закнете? Ну окружность понятно Вы так замыкать не будете. Дугу? Но тогда ее нужно превратить в полилинию. Собственный примитив (custom entity)? Тогда он как минимум должен быть производным от одного из типа полилиний. Что конкретно вы собираетесь замыкать? Если уточните - я попробую подсказать.
> Николай
Как не можете достучаться? acdbEntGet - получает список примитива, проходитесь по нему, заменяете группу 70, если она есть (а она есть не у всех примитивов производных от AcDbCurve и есть у других примитивов с совершенно другим смыслом). А затем acdbEntMod на этот список и acdbEntUpd на сам примитив.
Полилинию, многоугольник, окружность.
Замыкать только полилинию, но вот проверки на замкнутость идут для всех. Поэтому и работаю с базовым классом, чтоб не создавать большого количества разнообразных переменных и увеличивать код
> Николай
Так не получится, т.к. у AcDbCurve нет метода типа makeClose(). Хотя бы по той причине, что не для всех производных классов допустимо "замыкание" (например дуга - AcDbArc), а некоторые, как окружность (AcDbCircle), эллипс (AcDbEllipse) могут быть только замкнутыми.
if( !pCurve->isClosed() ) { // замкнуть контур AcDbPolyline *pP = AcDbPolyline::cast(pCurve); if (pP) pP->setClosed(true); AcDb2dPolyline *pP2 = AcDb2dPolyline::cast(pCurve); if (pP2) pP2->makeClosed(true); AcDb3dPolyline *pP3 = AcDb3dPolyline::cast(pCurve); if (pP3) pP3->makeClosed(true); }
Кстати, и с производными от них классами будет работать, если они нормально написаны.
Unhandled exception at 0x7c81eb33 in acad.exe: 0xE0000001: 0xe0000001.
Это вылетает сразу при попытке замкнуть pP.
C точки зрения написания все вроде бы правильно. Что это может быть?
Что делает Ccast(ent,0,0)? Полностью исходный текст.
Вообще-то примитив должен быть корректно открыт для записи.
приблизительно тоже самое, что и ::cast()
Все, я со всем разобрался. Спасибо за помощь.
код стал выглядеть вот так:
... if( !pCurve->isClosed() ) { if (::MessageBox(0,"\nКонтур не замкнут!\nЗамкнуть контур?","Внимание!!!",1)!=IDOK) {pCurve->close();return;} AcDbPolyline *pP = AcDbPolyline::cast(pCurve); AcDb2dPolyline *pP2 = AcDb2dPolyline::cast(pCurve); AcDb3dPolyline *pP3 = AcDb3dPolyline::cast(pCurve); if (pP!=0) { pP->upgradeOpen(); pP->setClosed(true); pP->downgradeOpen(); pP->close(); } if (pP2!=0) { pP2->upgradeOpen(); pP2->makeClosed(); pP2->downgradeOpen(); pP2->close(); } if (pP3!=0) { pP3->upgradeOpen(); pP3->makeClosed(); pP3->downgradeOpen(); pP3->close(); } } pCurve->close(); ...
> Николай
В коде ошибка! Если примитив - один из типов полилиний, то объект закрывается дважды, что делать не следует. Например, может выполнится и pP->close(), и pCurve->close().
> Николай
И еще. Если собираешься закрывать примитив, то downgradeOpen() - совершенно лишняя операция.
Так мне кажется было бы лучше:
... if( !pCurve->isClosed() ) { if (::MessageBox(0,"\nКонтур не замкнут!\nЗамкнуть контур?","Внимание!!!",1)!=IDOK) { pCurve->close();return; } if (pCurve->upgradeOpen() == Acad::eOk) { AcDbPolyline *pP = AcDbPolyline::cast(pCurve); AcDb2dPolyline *pP2 = AcDb2dPolyline::cast(pCurve); AcDb3dPolyline *pP3 = AcDb3dPolyline::cast(pCurve); if (pP) pP->setClosed(true); if (pP2) pP2->makeClosed(); if (pP3) pP3->makeClosed(); } pCurve->close(); } else pCurve->close(); ...
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Форумы CADUser → Программирование → ObjectARX → Как закрыть полилинию?
Форум работает на PunBB, при поддержке Informer Technologies, Inc