Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 21.04.11 17:23
Оценка:
Здравствуйте.

Судя по описанию возможностей AGG, в нём реализована возможность отсечения полигонов, не попадающих в clipping box. Самостоятельно не смог ни разобраться, ни нагуглить.
К примеру, в нижеприведённом коде строчка

path.move_to( 10000, 10000 ); path.line_to( 10000, 100001 );

замедляет выполнение более чем в 10 раз. Видимо, из-за того, что рендерер обрабатывает каждый пиксель этой мегалинии, вместо того, чтобы сразу отсечь её, как заведомо не попадающую в растр. Как это сделать средствами AGG?

void drawPolyLine( unsigned char* pixels, unsigned int width, unsigned int height, list<Point>& points )
{
    rendering_buffer        rbuf( pixels, width, height, width * 3 );

    pixfmt_rgb24            pixf( rbuf );
    renderer_base<pixfmt_rgb24>    renderer( pixf );


    rasterizer_scanline_aa<>    ras;
    scanline_p8            sl;
    path_storage            path;

    list<Point>::iterator p = points.begin();
    path.move_to( p->x, p->y );
    for( ++p; p != points.end(); ++p )
    {
        path.line_to( p->x, p->y );
    }
    path.move_to( 10000, 10000 ); path.line_to( 10000, 100001 );

    conv_stroke<path_storage> stroke( path );
    stroke.line_join( round_join );
    stroke.line_cap( round_cap );
    stroke.width( 5 );

    ras.add_path( stroke );

    render_scanlines_aa_solid( ras, sl, renderer, rgba(1,0.5,0.5) );
}
Re: Anti-Grain Geometry - векторное отсечение
От: WinterMute Россия http://yarrr.ru
Дата: 21.04.11 19:23
Оценка:
__>Судя по описанию возможностей AGG, в нём реализована возможность отсечения полигонов, не попадающих в clipping box. Самостоятельно не смог ни разобраться, ни нагуглить.
__>К примеру, в нижеприведённом коде строчка

__>
__>path.move_to( 10000, 10000 ); path.line_to( 10000, 100001 );
__>

__>замедляет выполнение более чем в 10 раз. Видимо, из-за того, что рендерер обрабатывает каждый пиксель этой мегалинии, вместо того, чтобы сразу отсечь её, как заведомо не попадающую в растр. Как это сделать средствами AGG?

А если увеличить длину этой линии в два раза, то как изменится время?
Re[2]: Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 21.04.11 19:58
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>А если увеличить длину этой линии в два раза, то как изменится время?


Если линия вертикальная( (10^4, 10^4) -> (10^4, 2 * 10^5) ), то время выполнения пропорционально длине.

Если же диагональная ( (10^4, 10^4) -> (10^5, 10^5) ), то время выполнения растёт быстрее, но непонятно как именно: ни ~sqrt(2) * 10^5, ни ~(10^5)^2.
Re[2]: Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 21.04.11 20:11
Оценка:
Оно, вроде, и логично — на сайте http://www.antigrain.com/doc/basic_renderers/basic_renderers.agdoc.html#toc0009 и написано, что renderer_base и renderer_mclip обеспечивают отсечение лишь на пиксельном уровне. А как использовать заявленное векторное отсечение я там не нашёл и по копанию в исходниках не понял. renderer_outline_aa тоже, вроде, не отсекает.
Re: Anti-Grain Geometry - векторное отсечение
От: nen777w  
Дата: 21.04.11 21:53
Оценка:
Там в сырцах пример такой есть multi_clip.cpp, детально не смотрел, по ненадобности.
Посмотрите может поможет вам?
Расскажите потом тут как решили проблему.
Re: Anti-Grain Geometry - векторное отсечение
От: WinterMute Россия http://yarrr.ru
Дата: 21.04.11 22:46
Оценка:
Подумалось: попробуй убрать conv_stroke и рисовать просто полигоны.
Соответственно вместо длинной линии нарисуй длинный прямоугольник.
Как будет зависеть время от длинны длинного прямоугольника?
Re[2]: Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 21.04.11 23:10
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Там в сырцах пример такой есть multi_clip.cpp, детально не смотрел, по ненадобности.

N>Посмотрите может поможет вам?
N>Расскажите потом тут как решили проблему.

multi_clip смотрел. Насколько я понимаю, там просто создаются несколько прямоугольников отсечения, но проверяется каждый пиксель. О чем косвенно свидетельствует то, что в дебажной версии отрисовка тормозит, если очень увеличить масштаб.
Re[2]: Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 21.04.11 23:37
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Подумалось: попробуй убрать conv_stroke и рисовать просто полигоны.

WM>Соответственно вместо длинной линии нарисуй длинный прямоугольник.
WM>Как будет зависеть время от длинны длинного прямоугольника?

Для длинного узкого вертикального прямоугольника зависимость времени от длины та же — пропорциональна длине.
Re: Anti-Grain Geometry - векторное отсечение
От: Ka3a4oK  
Дата: 22.04.11 05:39
Оценка:
Насколько я помню там два примера — с отсечением на уровни пикселей и с отсечением на уровне полигонов. Еще там есть сторонний исходник на Си, в котором собственно и реализуется быстрый алгоритм отсечения.
Re[2]: Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 22.04.11 13:16
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

KK>Насколько я помню там два примера — с отсечением на уровни пикселей и с отсечением на уровне полигонов. Еще там есть сторонний исходник на Си, в котором собственно и реализуется быстрый алгоритм отсечения.


Не скажешь названия файлов?
Re: Anti-Grain Geometry - векторное отсечение
От: WinterMute Россия http://yarrr.ru
Дата: 22.04.11 13:25
Оценка:
ras.clip_box() пробовал?

Хорошо бы услышать комментарии Максима, я был почти уверен что скорость отрисовки зависит скорее от числа линий, нежели от их длинны.
Re[2]: Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 22.04.11 16:29
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>ras.clip_box() пробовал?


WM>Хорошо бы услышать комментарии Максима, я был почти уверен что скорость отрисовки зависит скорее от числа линий, нежели от их длинны.


Ты знаешь, помогло Был уверен, что делал clip_box, но видимо, лишь для рендера, а не для rasterizer-а. Добавление строки
ras.clip_box( 0, 0, width-1, height-1 );

перед
ras.add_path( stroke );

решает проблему.

Дело оказалось вот в чём.

При описании класса растерайзера указывается тип клиппера. По умолчанию, это rasterizer_sl_clip_int:
rasterizer_scanline_aa<> эквивалентно rasterizer_scanline_aa<rasterizer_sl_clip_int>

У этого клиппера есть булева переменная m_clipping, значение которой, в конструкторе, устанавливается в false. reset_clipping также устанавливает false. И отсечение не производится. И вызов clip_box — единственный способ сделать её true. В move_to/line_to, в зависимости от значения этой переменной, точка либо просто добавляется, либо добавляется со всеми необходимыми пересчётами-отсечениями.

А я был уверен, что, если векторное отсечение не надо прикручивать отдельно, то оно должно быть включено по дефолту.
Re[3]: Anti-Grain Geometry - векторное отсечение
От: Ka3a4oK  
Дата: 22.04.11 17:15
Оценка:
Здравствуйте, _vanger_, Вы писали:

__>Здравствуйте, Ka3a4oK, Вы писали:


KK>>Насколько я помню там два примера — с отсечением на уровни пикселей и с отсечением на уровне полигонов. Еще там есть сторонний исходник на Си, в котором собственно и реализуется быстрый алгоритм отсечения.


__>Не скажешь названия файлов?


Пример называется gpc_test. Generic Polygon Clipper находится в папке gpc.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Re[3]: Anti-Grain Geometry - векторное отсечение
От: c-smile Канада http://terrainformatica.com
Дата: 22.04.11 20:14
Оценка:
Здравствуйте, _vanger_, Вы писали:

__>А я был уверен, что, если векторное отсечение не надо прикручивать отдельно, то оно должно быть включено по дефолту.


См: http://code.google.com/p/graphin/source/browse/trunk/src/agg/src/agg2D.cpp#330
Re[4]: Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 22.04.11 22:56
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>См: http://code.google.com/p/graphin/source/browse/trunk/src/agg/src/agg2D.cpp#330


Спасибо, про AGG2D не знал. В коде по ссылке как раз необходимая строчка
m_rasterizer.clip_box(x1, y1, x2, y2);
Re[4]: Anti-Grain Geometry - векторное отсечение
От: _vanger_  
Дата: 22.04.11 22:57
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

KK>Пример называется gpc_test. Generic Polygon Clipper находится в папке gpc.


Спасибо, посмотрю.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.