高级会员
注册日期: 06-11
帖子: 14579
精华: 1
现金: 224494 标准币
资产: 234494 标准币
|
【转帖】one color gradient hatch
one color gradient hatch
one color gradient hatch
hi,
i have a question about one color gradient hatch.
i've used the next code to create an one color gradient hatch:
code:
oddbobjectid idhatchtemp;
oddbdatabaseptr pdb = this->m_pdb;
{
oddbblocktablerecordptr precord = pdb->getactivelayoutbtrid().safeopenobject(); pdb->getactivelayoutbtrid().safeopenobject(oddb::kforwrite);;
//create new hatch
oddbhatchptr phatch = oddbhatch::createobject();
phatch->setdatabasedefaults(precord->database());
oddbobjectid hatchid = precord->appendoddbentity(phatch);
idhatchtemp = hatchid;
}
{
oddbhatchptr phatch = idhatchtemp.safeopenobject(oddb::kforwrite);
odgevector3d normal(0.0, 0.0, 1.0);
phatch->setnormal(normal);
phatch->setelevation(0.0);
// set non associative hatch
//
phatch->setassociative(false);
// set hatch pattern to solidfill type
//
phatch->setpattern(oddbhatch::kpredefined, "solid");
// set hatch style to knormal
//
phatch->sethatchstyle(oddbhatch::knormal);
// construct hatch external boundary
//
odgepoint2darray vertexpts;
odgedoublearray vertexbulges;
vertexpts.setphysicallength(0).setlogicallength(5);
vertexpts[0].set(2.0, 2.0);
vertexpts[1].set(8.0, 2.0);
vertexpts[2].set(8.0, 8.0);
vertexpts[3].set(2.0, 8.0);
vertexpts[4].set(2.0, 2.0);
vertexbulges.setphysicallength(0).setlogicallength(5);
for (int i = 0; i < 5; i++)
vertexbulges[i] = 0.0;
// append an external loop (rectangle) to hatch boundary
phatch->appendloop(oddbhatch::kpolyline, vertexpts, vertexbulges);
//gradient params
phatch->sethatchobjecttype(oddbhatch::kgradientobject);
phatch->setgradient(oddbhatch::kpredefinedgradient,"spherical");
odcmcolorarray cols;
odgedoublearray vals;
vals.push_back(0.0);vals.push_back(1.0);
//rgb colors
odcmcolor color1(odcmentitycolor::kbycolor);
color1.setrgb(255,0,0);
cols.push_back(color1);
odcmcolor color2(odcmentitycolor::kbycolor);
color2.setrgb(0,0,255);
cols.push_back(color2);
assert(cols.size() == vals.size());
phatch->setgradientcolors(2, &cols[0], &vals[0]);
phatch->setgradientonecolormode(true);
phatch->setshadetintvalue(0.5);
phatch->setgradientangle(0.0);
phatch->setgradientshift(0.0);
phatch->evaluatehatch(true);
}
i expect to have an one color gradient hatch, because of
phatch->setgradientonecolormode(true);
with a shadetint value 0.5, which means the nuance should be just like the main color(according to the gradient hatch dialog in acad). but the hatch is drawn with the nuance of the black color in odamfcapp.
if such a hatch is opened in acad (saved with odamfcapp) it is drawn with the colors, set with the oddbhatch::setgradientcolors(),(red and blue - see the code above).
how could an one color gradient hatch be created like in acad(with the nuance of the main color)?
is there anything else to be set for an one color gradient hatch to make it to be drawn properly?
thanks for all the suggestions and advices,
nino
gradient hatch always store 2 colors in color array. and autocad always use these 2 colors for rendering. single color flag is used only in hatch edit dialog. main entity color is not used at all.
results you get show that dd rendering is incorrect - it does not use 2 colors if single color flag is on. instead this it calculates the second color.
sergey slezkin
we checked how it works in objectarx api:
1) description of acdbhatch::setgradientcolors in arx reference is correct. it accepts only 2 colors, and only two values (that must be 0.0 and 1.0). in case single-color-gradient hatch, effect of this function is coincident with changing colors manually in dxf (displayed colors are changed, but dialog still think that it is still one-color-gradient hatch)
2) acdbhatch::setshadetintvalue doesn't recompute any colors. also its behaviour doesn't depend on single-color/double color gradient hatch is.
3) acdbhatch::setgradientonecolormode doesn't recompute any colors too. only switches the flag, displayed in dialog.
so, in arx:
1) two colors are always used for rendering. shade tint is never used for rendering.
2) computing colors from shade tint (in case single-color gradient hatch) is user responsibility.
it appeares that "single color mode" flag (dxf 452) and shade-tint value (dxf 462) are used only by hatch edit dialog. (as it described in dxf help).
the fix for defect in dd rendering will be available in next release/update.
sergey slezkin
thanks for the explanation, sergey.
"2) computing colors from shade tint (in case single-color gradient hatch) is user responsibility." - i post some source code for such a calcualation, i hope it will be useful for the developers:
code:
void evaluateluminancedrgbcolor(int nrgbcolor, double dluminance, int& nnewrgbcolor)
{
int nr = getrvalue(nrgbcolor), ng = getgvalue(nrgbcolor), nb = getbvalue(nrgbcolor);
double dh = 0, ds = 0, dl = 0;
convertrgbtohsl(nr, ng, nb, dh, ds, dl);
dl = dluminance;
converthsltorgb(dh, ds, dl, nr, ng, nb);
nnewrgbcolor = rgb(nr, ng, nb);
}
and the real calculating functions:
code:
void convertrgbtohsl(uint nred, uint ngreen, uint nblue, double& dh, double& ds, double& dl)
{
double var_r = (nred / 255.); //where rgb values = 0 where rgb values = 0 - 255
double var_g = (ngreen / 255.);
double var_b = (nblue / 255.);
double var_min = min(var_r, var_g);
var_min = min(var_min, var_b); //min. value of rgb
double var_max = max(var_r, var_g);
var_max = max(var_max, var_b); //max. value of rgb
double del_max = var_max - var_min; //delta rgb value
dl = ( var_max + var_min ) / 2.;
if ( del_max == 0 ) //this is a gray, no chroma...
{
dh = 0; //hsl results = 0 - 1
ds = 0;
}
else //chromatic data...
{
if ( dl < 0.5 )
ds = del_max / ( var_max + var_min );
else
ds = del_max / ( 2 - var_max - var_min );
double del_r = ( ( ( var_max - var_r ) / 6. ) + ( del_max / 2. ) ) / del_max;
double del_g = ( ( ( var_max - var_g ) / 6. ) + ( del_max / 2. ) ) / del_max;
double del_b = ( ( ( var_max - var_b ) / 6. ) + ( del_max / 2. ) ) / del_max;
if ( var_r == var_max )
dh = del_b - del_g;
else if ( var_g == var_max )
dh = ( 1. / 3. ) + del_r - del_b;
else if ( var_b == var_max )
dh = ( 2. / 3. ) + del_g - del_r;
if ( dh < 0 )
dh += 1;
if ( dh > 1 )
dh -= 1;
}
}
double hue_2_rgb( double v1, double v2, double vh ) //function hue_2_rgb
{
if ( vh < 0 )
vh += 1;
if ( vh > 1 )
vh -= 1;
if ( ( 6 * vh ) < 1 )
return ( v1 + ( v2 - v1 ) * 6 * vh );
if ( ( 2 * vh ) < 1 )
return ( v2 );
if ( ( 3 * vh ) < 2 )
return ( v1 + ( v2 - v1 ) * ( ( 2. / 3. ) - vh ) * 6 );
return ( v1 );
}
void converthsltorgb(double dh, double ds, double dl, int& nred, int& ngreen, int& nblue)
{
if ( ds == 0 ) //hsl values = 0 - 1
{
nred = (int)odround(dl * 255); //rgb results = 0 - 255
ngreen = (int)odround(dl * 255);
nblue = (int)odround(dl * 255);
}
else
{
double var_2 = 0;
if ( dl < 0.5 )
var_2 = dl * ( 1 + ds );
else
var_2 = ( dl + ds ) - ( ds * dl );
double var_1 = 2 * dl - var_2;
nred = (int)odround(255 * hue_2_rgb( var_1, var_2, dh + ( 1. / 3. ) ));
ngreen = (int)odround(255 * hue_2_rgb( var_1, var_2, dh ));
nblue = (int)odround(255 * hue_2_rgb( var_1, var_2, dh - ( 1. / 3. ) ));
}
}
|