Тема: Почему при работе AcEdJig идет двойная перерисовка примитива?

Ситуация такова: к уже созданному объекту применяется Jig, к примеру, объект преставляет собой сетку, в которой необходимо "на лету" удалять ячейки... Так вот, во время работы Jig'а, после отработки sampler'a, который возвращает kNoChange, происходит вторичная прорисовка примитива, т.е. примитив инвертируется. Как этого избежать?

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

Не понял. У иебя функция entity() возвращает указатель на объект в базе (текущей)? Если так, то у тебя конфликтует отрисовка собственно объекта (родная акадовская) и отрисовка джига (который сам вызывает отрисовку объекта)

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

Да, entity возвращает объект, который находится в базе. А каким образом избежать конфликта?
Насколько я понимаю, кроме Jig'a нет других инструментов для редактирования, описанного выше?

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Sandrick
Мощешь попробовать вместо Jig'а функцию acedDragGen.

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

P.S.: Альтернативный вариант - сделать клон твоего примитива (который находится в базе), и таскать этот клон. На время таскания оригинальный примитив скрыть (setVisibility). После завершения таскания все изменения внести в оригинальный примитив, а клон уничтожить.

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

хм... а Jig'ом никак?

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Sandrick
Хм... А прочесть мой последний пост слабо? Альтернативный вариант - это и есть использование Jig'а с клоном.

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Александр Ривилис
Александр, если можно, небольшой кусочек кода (клонирование для Jig'a). Имеешь ввиду AcDbEntity* pClone = Object->clone()? Тот же эффект...

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Sandrick
Значит у тебя что-то не то.

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Александр Ривилис

        Acad::ErrorStatus es;
        AcDbObjectId objID;
        AcDbEntity *pContBlock;
        AsdkContainerBlock *pClone;
        ads_name name, ent;
        ads_point pnt;
        
        if (acedSSGet("I",NULL,NULL,NULL,name) == RTERROR)
        {
start:        
            ads_printf("Please select AsdkContainerBlock! \n");
            if (acedSSGet(":S",NULL,NULL,NULL,name)!=RTNORM)
                return;
        };
        acedSSName(name,0L,ent);
        acdbGetObjectId(objID, ent);
        
        es = acdbOpenAcDbEntity(pContBlock,objID,AcDb::kForWrite);//curDoc()->database()
        if (pContBlock->isA() != AsdkContainerBlock::desc())
        {
            
            pContBlock->close();
            acedSSFree(name);
            goto start;
        };
        pClone = (AsdkContainerBlock*)pContBlock->clone();
        pContBlock->setVisibility(AcDb::Visibility::kInvisible);
        CExContainerJig *ContRemover = new CExContainerJig(NULL,pClone);
        ContRemover->dragIt();
        pContBlock->copyFrom(pClone);
        pContBlock->setVisibility(AcDb::Visibility::kVisible);
        pClone->erase();
        pClone->close();
        delete pClone;
        pClone = NULL;
        
        delete ContRemover;
        ContRemover = NULL;
        pContBlock->close();

...в ДНК? :)

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Sandrick
1) Оригинал закрой до запуска Jig.
2) Если клон не добавлен в базу, то и erase() ему делать не нужно, т.е. вместо:

pClone->erase();
pClone->close();

должно быть

delete pClone();

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

P.S.: А теперь приведи текст CExContainerJig

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Александр Ривилис
Спасибо, все вышло.
:) Другая теперь проблемка...
А теперь как запретить Jig'у перерисовку объекта во время движения мышью? :)

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Sandrick
Сначала ответь на вопрос что именно вышло и как ты этого достиг.

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

Как ты и сказал, оригинал был закрыт до запуска Jig'a, и многочисленные перерисовки database <-> Jig прекратились. Теперь перерисовывается клон, все действия, производимые мною сразу отображаются.
А вот как во время движения мышью запретить перерисовку... Дабы перерисовку я вызывал вручную, или непосредственно при вызове функции, которая содержит assertWriteEnabled()...

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Sandrick
Вот теперь понятно. Перерисовку можно запретить как минимум двумя способами:
1) Возвращать kNoChange. В этом случае не должен вызываться update().
2) Модифицировать метод(ы) своего примитива wordDraw/viewportDraw так, чтобы он не работал или работал "не так" в случае если mode->isDragging() возвращает Adesk::kTrue

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Александр Ривилис
... и возврат kNoChange ничего не дает... чуть тронул мышь, и вся структура перерисовывается, причем медленнее, раз эдак в 50...
Полагаю, Jigger запускает отдельным потоком действия с объектом...

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Sandrick
Наверное все-таки что-то в ДНК. :)
У меня в тестовой программе было использовался трюк - если мышь сдвинулась меньше чем на 10.0 от предыдущего значения - возвращал kNoChange. Перерисовка происходила дискретно. Все работает прекрасно.
На этом принципе построена и DynDraw (https://www.caduser.ru/forum/topic20171.html)
Еще раз советую показать CExContainerJig.

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

Тут столько уже наворочено.... лишнего... код "грязный"...

class CExContainerJig : public AcEdJig
    {
    public:
        
        CExContainerJig (AcDbDatabase *pDb, AsdkContainerBlock * pContainerBlock):
          mpContainerBlock(pContainerBlock), mpDb(pDb)
              {
              };
        virtual ~CExContainerJig()
            {
            };
        void dragIt(void)
            {
            AcEdJig::DragStatus stat;
            const TCHAR*pszPrompt2 = _T("\n\n\n*** Container block extension ***\n Please set base point: ");
            setDispPrompt(pszPrompt2);
            
            do
                {
                    stat = drag();
                    if (stat == AcEdJig::kNormal)
                    {
                        mpContainerBlock->RemoveContainer(coords.x+1,coords.y+1);
                    }
                } while (stat != AcEdJig::kCancel && stat != AcEdJig::kNull);
            pszPrompt2 = NULL;
            };
        DragStatus acquireDefPt()
            {
                AcEdJig::DragStatus stat;
                  setUserInputControls((UserInputControls)
                (AcEdJig::kAccept3dCoordinates
                | AcEdJig::kGovernedByOrthoMode
                | AcEdJig::kNullResponseAccepted
                | AcEdJig::kNoZeroResponseAccepted
                | AcEdJig::kDontUpdateLastPoint));
                AcGePoint3d pt;
                stat = acquirePoint(pt);
//                stat = kNoChange;
        if (stat == kNormal)
        {
            
            if (coords != mpContainerBlock->RetreiveContainerCoords (pt))
            {
                ContainerPointer = pt;
                stat = kNormal;            
            }
            else
            return kNoChange;
        }
        
        return stat;
            };
        virtual DragStatus sampler (void)
        {
            return acquireDefPt();
        };
        virtual Adesk::Boolean update()
            {
                coords = mpContainerBlock->RetreiveContainerCoords (ContainerPointer);
//                ads_printf("column: %d, row: %d, X: %.2f Y: %.2f\n",coords.x, coords.y,ContainerPointer.x,ContainerPointer.y);
                if ((coords.x*coords.y < 0) ||((coords.x+1)>mpContainerBlock->GetColumnsNumber())||((coords.y+1) >mpContainerBlock->GetRowsNumber()))
                    return Adesk::kFalse;
                return Adesk::kTrue;
            };
        virtual AcDbEntity * entity() const
            {
                return mpContainerBlock;
            };
        
    private:
        AsdkContainerBlock * mpContainerBlock;
        AcDbDatabase *mpDb;
        AcGePoint3d ContainerPointer;
        CPoint coords;
    public:
        // -----------------------------------------------------------------------------
        AcEdJig::DragStatus drag(void);
    };
// -----------------------------------------------------------------------------
AcEdJig::DragStatus CExContainerJig::drag(void)
{
    AcEdJig::DragStatus retCode =AcEdJig::drag () ;
    return (retCode) ;
}

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

Если я правильно понял твой код, то вместо:

      if (coords != mpContainerBlock->RetreiveContainerCoords (pt))
      {
        ContainerPointer = pt;
        stat = kNormal;
      }
      else
      return kNoChange;

нужно что-то похожее на это:

const double Step_Dragging 1e-3; // Задашь свое значение - это минимальный шаг
      if (coords != mpContainerBlock->RetreiveContainerCoords (pt) && pt.distanceTo(ContainerPointer) >= Step_Dragging)
      {
        ContainerPointer = pt;
        stat = kNormal;
      }
      else
      return kNoChange;

Надеюсь поможет. :)

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Александр Ривилис
... не помогло, да и не могло... тут что-то не так в самом Jig'е. Перепроверял, нет во время движения вызовов assertWrite(Read)Enabled...

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

Попробуй:

2) Модифицировать метод(ы) своего примитива wordDraw/viewportDraw так, чтобы он не работал или работал "не так" в случае если mode->isDragging() возвращает Adesk::kTrue

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

Странно другое, пока выполняется Drag, даже при движении "ручек", работает какая-то другая функция отрисовки примитива... Стоит "отпустить" "ручку", отрисовка происходит моментально!!!
Мой Entity содержит множество отрисовываемых объектов...
Интересно, как и чем кад "рисует", когда установлен флаг isDragging?

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

> Sandrick
Ничего не понял. Ты что запускаешь Jig, когда тянешь за "ручку"? Но тогда у тебя должна быть каша из отрисовок.

даже при движении "ручек", работает какая-то другая функция отрисовки примитива...

Таже самая. Только она вызывается при минимальном передвижении мыши. Возможно у тебя настолько сложный примитив, что между этими передвижениями он не успевает отрисовываться. Поэтому если isDragging == true, упрощай отрисовку. Ну, например, рисуй габаритный контейнер.

Re: Почему при работе AcEdJig идет двойная перерисовка примитива?

Нет, к Jig'у ручки не имеют, естественно, никакого отношения...
Габаритный не получится... Есть ли какой-нибудь класс, в который можно было бы всю геометрию засунуть, а потом, одним махом выплюнуть всю её в worldDraw, чтобы не производить отрисовку в главном методе отрисовки примитива?