Тема: Фон внутри замкнутой полилинии

Помогите, пожалуйста, найти решение такой проблемы: необходимо, чтобы область внутри замкнутой полилинии была непрозрачной (т.е. перекрывала лежащие под ней объекты) и в тоже время была цвета фона. Каким механизмом мне воспользоваться? Буду очень благодарна за наиболее универсальный метод.

Re: Фон внутри замкнутой полилинии

Как я понимаю, лучшим решением есть использование AcDbWipeout. Если кто работал с этим объектом, помогите пожалуйста примером его использования в собственном entity.

Re: Фон внутри замкнутой полилинии

ну например так

#include "dbwipe.h"
#pragma comment (lib ,"AcWipeoutObj18.lib") // для акада 2010/2011/2012
#pragma comment (lib ,"AcWipeoutObj17.lib") // для акада 2007/2008/2009. только для 2008 сам файл лежит в папке inc a не lib. как всегда все через Ж... перекинь его в lib

//...
Acad::ErrorStatus es;
AcDbWipeout::createImageDefinition();
AcDbWipeout *pWipe = new AcDbWipeout();
pWipe->setDatabaseDefaults();

AcGePoint2dArray ptArray; // <- сюда перегрузить точки твоей замкнутой полилинии

es = pWipe->setClipBoundary(AcDbRasterImage::kPoly, ptArray);
if (es = Acad::eOk)
{
  // потом добавление pWipe в БД чертежа и
  pWipe->close();
}

Re: Фон внутри замкнутой полилинии

Да, такой штукой воспользовалась. Как отдельная команда - работает. А вот когда запихиваю код в метод subWorldDraw ничего не получается. Вот пример:

...
    Acad::ErrorStatus es = AcDbWipeout::createImageDefinition();
    AcDbWipeout *pWipe = new AcDbWipeout();
    if( pWipe == NULL ) return (Adesk::kFalse);
    pWipe->setDatabaseDefaults();

    AcGePoint3d originPnt(-0.5,0.5,0);
    AcGeVector3d Udirection(1,0,0);
    AcGeVector3d Vdirection(0,-1,0);
    pWipe->setOrientation(originPnt, Udirection, Vdirection);


    // Set the clip boundary for the wipeout - this is very important 
    AcGePoint2dArray *ptArray = new AcGePoint2dArray(5,5);
    ptArray->append(AcGePoint2d(0,0));
    ptArray->append(AcGePoint2d(5,0));
    ptArray->append(AcGePoint2d(5,5));
    ptArray->append(AcGePoint2d(0,5));
    ptArray->append(AcGePoint2d(0,0));
    pWipe->setClipBoundary(AcDbRasterImage::kPoly, *ptArray);
    pWipe->worldDraw(mode);
     delete pWipe;
     pWipe = NULL;
...

Все проходит нормально, без ошибок, но почему-то не отображается (нет эффекта)  :(

Re: Фон внутри замкнутой полилинии

Попробуй pWipe сделать членом класса, создавай его в конструкторе класса, а удаляй в деструкторе.

Re: Фон внутри замкнутой полилинии

К сожалению не помогло.

Re: Фон внутри замкнутой полилинии

Savka Antonina пишет:

К сожалению не помогло.

А если еще заменить:

 pWipe->worldDraw(mode); 

на

 mode->geometry().draw(pWipe); 

:?:

Re: Фон внутри замкнутой полилинии

=( Никак не хочет: ни как член класса, ни как динамическая переменная в методе subWorldDraw, ни через моде, ни через дров на объекте.
Ошибка наверно какая-то простая и глупая, не не могу ее увидеть.

Re: Фон внутри замкнутой полилинии

Ошибка наверно какая-то простая и глупая, не не могу ее увидеть.

код в студию :) а то как-то отсюда тоже не видно в чем ошибка.

(изменено: Savka Antonina, 13 июля 2010г. 15:45:08)

Re: Фон внутри замкнутой полилинии

Весь файл слать - громадно и нельзя =)
Так что все таки вернулась снова к динамической переменной:

Adesk::Boolean CGeoHoleColumn::subWorldDraw(AcGiWorldDraw *mode)
{
    assertReadEnabled () ;
    if( isDrawAsPlan() ){
        //рисуем внутренний круг скважины
                ...
    }else{
        //рисуем елементы базовой выноски
        CGeoHoleBase::subWorldDraw(mode);

         //Подложка
         Acad::ErrorStatus es = AcDbWipeout::createImageDefinition();
         AcDbWipeout *pWipe = new AcDbWipeout();
         if( pWipe == NULL ) return (Adesk::kFalse);
         pWipe->setDatabaseDefaults();

        AcGePoint3d originPnt(-0.5,0.5,0);
         AcGeVector3d Udirection(1,0,0);
         AcGeVector3d Vdirection(0,-1,0);
         pWipe->setOrientation(originPnt, Udirection, Vdirection);
 
 
         // Set the clip boundary for the wipeout - this is very important 
         AcGePoint2dArray *ptArray = new AcGePoint2dArray(5,5);
         ptArray->append(AcGePoint2d(0,0));
         ptArray->append(AcGePoint2d(5,0));
         ptArray->append(AcGePoint2d(5,5));
         ptArray->append(AcGePoint2d(0,5));
         ptArray->append(AcGePoint2d(0,0));
         pWipe->setClipBoundary(AcDbRasterImage::kPoly, *ptArray);
         pWipe->worldDraw(mode);
          delete pWipe;
          pWipe = NULL;

        //рисуем колонку
        AcDbPolyline* poly = new AcDbPolyline;
        if(poly == NULL) return (Adesk::kFalse);
        getColonkaElem(poly);
        poly->worldDraw(mode);
        delete poly;
        poly = NULL;

        //Штриховки
        if( DrawHatch(mode) != Adesk::kTrue ){
            return (Adesk::kFalse);
        }

        //Линии
        if( DrawLines(mode) != Adesk::kTrue ){
            return (Adesk::kFalse);
        }

        //Символы проб
        if( DrawSymbols(mode) != Adesk::kTrue ){
            return (Adesk::kFalse);
        }

        //Глубины/отметки
        if( DrawDepth(mode) != Adesk::kTrue ){
            return (Adesk::kFalse);
        }

        //Номера слоев
        if( DrawLayerNumbers(mode) != Adesk::kTrue ){
            return (Adesk::kFalse);
        }

        //Символы утраченого конекта
        if( DrawConnectSymd(mode) != Adesk::kTrue ){
            return (Adesk::kFalse);
        }
    }

    return Adesk::kTrue;
}//CGeoHoleColumn::subWorldDraw

Хочется чтобы хоть хард-кодный примерный wipeout отобразился на экране

(изменено: Savka Antonina, 14 июля 2010г. 15:03:50)

Re: Фон внутри замкнутой полилинии

Доброго всем дня.
Проблема остается открытой. Код

mode->geometry().draw(pWipe);

работает, но сам AcDbWipeOut не перекрывает объектов, что лежат под мои объектом.

В чем может быть проблема?

Re: Фон внутри замкнутой полилинии

Код mode->geometry().draw(pWipe); последний в методе CGeoHoleColumn::subWorldDraw? Если нет - сделай его последним. Возможно это поможет.

Re: Фон внутри замкнутой полилинии

Спасибо за совет. Поставила отрисовку подложки последней. Но тут 2 нюанса:
1. Ничего не изменилось
2. Возможно присутствуют какие-то параметры отображения? Воспользовалась еще методом

pWipe->setDisplayOpt( AcDbRasterImage::kShow, true);

но тоже не ощутила разницы.

Re: Фон внутри замкнутой полилинии

Боюсь, что здесь не все так просто. Попробуй свой объект поместить над остальными:

Command: _DRAWORDER
Select objects: 1 found

Select objects:
Enter object ordering option [Above objects/Under objects/Front/Back] <Back>: _F

Если так будет работать нормально, то тебе нужно будет создать реактор (пока не думал какой), который будет помещать твои объекты над остальными.

Re: Фон внутри замкнутой полилинии

Попробовала переместить свой объект на передний план, а также пробовала переместить все остальные коме моего объекты на задний план - не помогло. Ощущение такое, что моя подложка в объекте - прозрачная.

Опишу текущее состояние моего кода (может где-то увидим стратегическую ошибку):
1) Указатель на AcDbWipeOut сделала членом класса
2) В конструкторе вызываю метод AcDbWipeout::createImageDefinition(); и инициализирую указатель на подложку динамически созданным объектом
3) В методе subWorldDraw для подложки задаю направление и контур, ну и соответственно рисую
4) В деструкторе удаляю объект.

Возможно у меня проблемы с местом вызова AcDbWipeout::createImageDefinition(); или это особого значения не имеет?

(изменено: Александр Ривилис, 14 июля 2010г. 19:04:37)

Re: Фон внутри замкнутой полилинии

Savka Antonina пишет:

2) В конструкторе вызываю метод AcDbWipeout::createImageDefinition(); и инициализирую указатель на подложку динамически созданным объектом

Боюсь, что проблема именно в этом. Давай от wipeout откажемся и попробуем другой вариант:

AcCmEntityColor gBackColor;
// Здесь нужно будет настоить цвет - я поставил белый
gBackColor.setRed(255); gBackColor.setGreen(255); gBackColor.setBlue(255);
AcGePoint3d *arr = new AcGePoint3d[nPoints];
// Здесь заполняешь arr точками контура  
mode->subEntityTraits().setTrueColor(gBackColor);  // 
mode->subEntityTraits().setFillType( kAcGiFillAlways );
// Рисуем залитый полигон
mode->geometry().polygon(nPoints,arr);
delete arr;

Re: Фон внутри замкнутой полилинии

Тоже задумывалась над этим обходным путем. И по ходу возник один вопрос: как определить фоновый цвет текущего чертежа?

Re: Фон внутри замкнутой полилинии

Savka Antonina пишет:

И по ходу возник один вопрос: как определить фоновый цвет текущего чертежа?

А вот это очень интересный и совсем неоднозначный вопрос.
Если вывод идет на печать, что цвет устанавливать всегда в белый.
Если считать что в качестве хоста используется только AutoCAD (или его вертикальные приложения), то можно линковать dbx-файл с acad.lib
В этом случае можно использовать функцию unsigned long  acedGetRGB(int color); с параметром 0 для получения цвета фона. Другой вариант - использовать функцию acedGetCurrentColors из которой можно получить dwGfxModelBkColor и dwGfxLayoutBkColor и (в зависимости от значения tilemode) использовать нужный.
А вот если host не AutoCAD, то все сложнее - нужно пользоваться Windows API для получения цвета фона.

Re: Фон внутри замкнутой полилинии

Воспользовалась последним решением и столкнулась с неприятностью: если открыть чертеж с моим объектом без загрузки arx-модуля и (!!!) с другим фоном, то внутри моего объекта остается фон, на котором объект был сохранен. Тоже происходить и с объектами AcDbMText в фоном цвета рабочего полотна, которые рисую внутри своего объекта. А нужно, чтобы объект и при выгруженном arx-модуле работал как и при загруженном.
Как можно выкрутиться в этом случае?

Re: Фон внутри замкнутой полилинии

Savka Antonina пишет:

Как можно выкрутиться в этом случае?

А как ты задаешь цвет фону?

Re: Фон внутри замкнутой полилинии

Для елементов многострочного текста:

text->setBackgroundFill(true);
text->setUseBackgroundColor( true );

Для тела объекта (извините за некрасивый код  :oops:):

    AcColorSettings colorSetings;
    acedGetCurrentColors( &colorSetings );
    AcCmEntityColor bgColor;

    if(!mode->context()->isPlotGeneration()){
        COLORREF rgbColor = (COLORREF)colorSetings.dwGfxModelBkColor;
        bgColor.setRed( GetRValue(rgbColor) );
        bgColor.setGreen( GetGValue(rgbColor) );
        bgColor.setBlue( GetBValue(rgbColor) );
        mode->subEntityTraits().setTrueColor( bgColor );
    }else{
        COLORREF rgbColor = (COLORREF)colorSetings.dwGfxLayoutBkColor;
        bgColor.setRed( GetRValue(rgbColor) );
        bgColor.setGreen( GetGValue(rgbColor) );
        bgColor.setBlue( GetBValue(rgbColor) );
        mode->subEntityTraits().setTrueColor( bgColor );
    }
    mode->subEntityTraits().setFillType( kAcGiFillAlways );
.........
    mode->geometry().polygon( wipePnts.length(), wipePnts.asArrayPtr() );

Re: Фон внутри замкнутой полилинии

Вроде бы все правильно. Не понятно тогда какой цвет возвращает acedGetCurrentColors( &colorSetings ); в данной ситуации, т.к. он должен вернуть текущий цвет фона. Попробуй посмотреть под отладчиком.

Re: Фон внутри замкнутой полилинии

Проблема вот в чем (распишу по шагам):
1) на черном фоне создала объект (arx-модуль подгружен) - программа правильно залила тело объекта черным цветом
2) сохраняю - сработал метод saveAs, который записал этот черный фон в объект
3) отрываю тот же сохраненный файл в автокаде, например, с белым фоном, но без моего arx-модуля - автокад подгрузил объект с теми данными, что были записаны в него методом saveAs. А поскольку модуль не подгружен, то соответственно программа не может залить тело моего объекта светлым фоном. Таким образом что моя программа сохранила в чертеже, то я и увидела.

Возможно я неправильно понимаю принцип роботы загрузки объекта без соответствующего arx-модуля?

Re: Фон внутри замкнутой полилинии

Savka Antonina пишет:

Возможно я неправильно понимаю принцип роботы загрузки объекта без соответствующего arx-модуля?

Без arx-модуля или без dbx-модуля? Без dbx-модуля действительно будет сохраненный фон и с этим ничего поделать нельзя, т.к. вместо вашего объекта прокси. И это нормально. А arx-модуль на цвет влиять не должен, т.к. цвет вы определяете в dbx-модуле (в методе worldDraw(), если я правильно понял).

Re: Фон внутри замкнутой полилинии

Александр Ривилис пишет:

Без arx-модуля или без dbx-модуля

Да, без dbx-модуля

Александр Ривилис пишет:

Без dbx-модуля действительно будет сохраненный фон и с этим ничего поделать нельзя

:(  Жаль, очень некрасиво получается