Тема: Как закрыть полилинию?

Посмотрел по форуму на тему как закрыть полилинию, предложен вариант с pedit
Мне интересно, можно ли как-то иначе программно замкнуть полилинию, чтоб акад не выбрасывал лишние строчки в командную строку

Re: Как закрыть полилинию?

> Николай
Конечно можно. Причем разными способами. Не указано о каком типе полилинии идет речь, что не правильно, т.к. их как минимум три типа.
1) Просто задать признак замкнутости:
AcDbPolyline::setClosed
AcDb2dPolyline::makeClosed
AcDb3dPolyline::makeClosed
2) Добавить еще одну вершину, совпадающую с первой - мене красивый способ - не рекомендую.

Re: Как закрыть полилинию?

Это все не плохо, но такой вариант распространяется ТОЛЬКО на польлинию заданного типа. Мне необходимо закрыть 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() )
{
// замкнуть контур
}

Re: Как закрыть полилинию?

> Николай
И как вы рассчитывали замкнуть AcDbCurve при помощи _PEDIT? Наивный! smile Это же базовый класс...

Re: Как закрыть полилинию?

через acedCommand, во только "З" надо нажимать вручную :)
А этого как раз и не хочется

Re: Как закрыть полилинию?

Кстати в БД автокада на полилинии есть код 070 с типом 16 bit integer. Если значение установлено 1, то полилиния замкнута, если 0, но разомкнута. Может попробовать так? Вот только я не могу к нему достучаться :( Помогите кто -нибудь:)

Re: Как закрыть полилинию?

> Николай
Что Вы так закнете? Ну окружность понятно Вы так замыкать не будете. Дугу? Но тогда ее нужно превратить в полилинию. Собственный примитив (custom entity)? Тогда он как минимум должен быть производным от одного из типа полилиний. Что конкретно вы собираетесь замыкать? Если уточните - я попробую подсказать.

Re: Как закрыть полилинию?

> Николай
Как не можете достучаться? acdbEntGet - получает список примитива, проходитесь по нему, заменяете группу 70, если она есть (а она есть не у всех примитивов производных от AcDbCurve и есть у других примитивов с совершенно другим смыслом). А затем acdbEntMod на этот  список и acdbEntUpd на сам примитив.

Re: Как закрыть полилинию?

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

Re: Как закрыть полилинию?

> Николай
Так не получится, т.к. у AcDbCurve нет метода типа makeClose(). Хотя бы по той причине, что не для всех производных классов допустимо "замыкание" (например дуга - AcDbArc), а некоторые, как окружность (AcDbCircle), эллипс (AcDbEllipse) могут быть только замкнутыми.

Re: Как закрыть полилинию?

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);
}

Кстати, и с производными от них классами будет работать, если они нормально написаны.

Re: Как закрыть полилинию?

Unhandled exception at 0x7c81eb33 in acad.exe: 0xE0000001: 0xe0000001.
Это вылетает сразу при попытке замкнуть pP.
C точки зрения написания все вроде бы правильно. Что это может быть?

Re: Как закрыть полилинию?

Что делает Ccast(ent,0,0)? Полностью исходный текст.
Вообще-то примитив должен быть корректно открыт для записи.

Re: Как закрыть полилинию?

приблизительно тоже самое, что и ::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();
...

Re: Как закрыть полилинию?

> Николай
В коде ошибка! Если примитив - один из типов полилиний, то объект закрывается дважды, что делать не следует. Например, может выполнится и pP->close(), и pCurve->close().

Re: Как закрыть полилинию?

> Николай
И еще. Если собираешься закрывать примитив, то 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();
...

Re: Как закрыть полилинию?

Понятно.
Спасибо :)