几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量

几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量 (http://www.dimcax.com/hust/index.php)
-   DirectDWG (http://www.dimcax.com/hust/forumdisplay.php?f=89)
-   -   【转帖】color problem with hatch while vectorization (http://www.dimcax.com/hust/showthread.php?t=15429)

yang686526 2009-05-04 05:55 PM

【转帖】color problem with hatch while vectorization
 
color problem with hatch while vectorization
color problem with hatch while vectorization
hi,
we're using the vectorization framework with dd static libs 2.1.0 built with vc8 for import of dwg/dxf files into our app.
we're handling the processing of the hatch overselves. here is a skeletal code of what we're trying to do:
code:
void exsimpleview::draw(const odgidrawable* pdrawable)
{
...
if (pdrawable->isa()->isderivedfrom(oddbhatch::desc()))
{
// map hatch ourself
const oddbhatch *phatch = reinterpret_cast<const oddbhatch *>(pdrawable)
...
odcmcolor color = phatch->color();
// point 1
oduint8 red = color.red();
oduint8 green = color.green();
oduint8 blue = color.blue();
...
}
else
{
odgsbasevectorizeview::draw(pdrawable);
}
...
}
void exsimpleview::ontraitsmodified()
{
odgsbasevectorizeview::ontraitsmodified();
const odgisubentitytraitsdata& currtraits = effectivetraits();
if(currtraits.truecolor().isbycolor())
{
device()->draw_color(odtocolorref(currtraits.truecolor()));
}
else
{
device()->draw_color_index(currtraits.color());
}
...
}
void exgssimpledevice::draw_color(odcolorref colorref)
{
odcmcolor color;
color.setrgb(odgetred(colorref), odgetgreen(colorref), odgetblue(colorref));
oduint8 red = color.red();
oduint8 green = color.green();
oduint8 blue = color.blue();
...
}
void exgssimpledevice::draw_color_index(oduint16 colorindex)
{
odcmcolor color;
color.setcolorindex(colorindex);
// point 2
oduint8 red = color.red();
oduint8 green = color.green();
oduint8 blue = color.blue();
...
}
when we run the attached file "blacklayer.dwg", we get values {red=0, green=0, blue=0} at both point 1fff"> and point 2fff">. as a result both the hatch and the circle come as black color.
however, when we run the attached file "whiltelayer.dwg", we get values {red=0, green=0, blue=0} at point 1fff"> and {red=255, green=255, blue=255} at point 2fff">. as a result the circle comes as white but the hatch comes as black.
both files have the circle and hatch colors as bylayer. how can i get correct values at point 1fff"> in the case of "whiltelayer.dwg"?
attached files
hi,
can anyone help me out with this one?
tia.
regards,
varun

the same thing is happening with the bylayer hatch in this drawing (bylayer_red.dwg). although the layer is red, i get rgb values corresponding to black for this hatch when i try to handle the hatch in exsimpleview::draw() as described in my earlier post.
am i missing something here? can someone from oda dev team please have a look at this?
attached files (24.4 kb, 2 views)

regards,
varun
at point 1 you get color bylayer. so you need to open the layer of the object and get the color from layer.
but where is a more complex case - byblock. if an object has byblock color and it resides in a block than block reference (insert) color is used. and if block reference color is byblock too than upper level block reference color is used (the process is recursive).
one more thing: if entity's layer is "0" and entity is inside a block than block reference layer is used. and if entity color is bylayer than you need use color of block reference's layer.
it's impossible to get correct color (linetype, lineweight etc.) for entity without context it's rendered in (point 1 - pent->color()).
if an entity is inside a block it can be rendered with different colors if the block is inserted multiple times.
vectorization framework takes care about it so you get correct values at point 2.
sergey slezkin
hi sergey,
our problem is that we don't want to call odgsbasevectorizeview::draw() for hatch as we can handle all its attributes (patterns, gradients etc.) better and map them to similar attributes supported in our application.
i understood about the layer thing and its simple to get around that problem.
however for the block case you mentioned, if a block is inside a block reference, we get a call to our draw() for block reference (insert) before that of the block (block_record) and then finally for hatch (hatch). why can't we have the color of the hatch entity resolved at the time we get a call to draw() for it?
can you illustrate how do we go about getting the correct color in case of byblock?
regards,
varun
ok. tried a few things and most of the cases are working:
- bylayer case: just get the layer's color (i am hoping that the layer's color will never be bylayer or byblock itself!!).
- byblock case: we're now keeping all the odgidrawable objects send to our device's draw() method in a stack like list, which grows/shrinks with each entry/exit to the draw() method. when we need to find the color for the hatch, we iterator thru the list in bottom first fashion and get the color of the block transform entities (recursively, if the color is byblock).
here is my method:
code:
odcmcolor getoddbentityresolvedcolor(const oddbentityptr pentity)
{
odcmcolor odcolor = pentity->color();
switch (odcolor.colormethod())
{
case odcmentitycolor::kbylayer:
{
oddblayertablerecordptr player = pentity->layerid().safeopenobject();
odcolor = player->color();
}
break;
case odcmentitycolor::kbyblock:
{
bool resolved = false;
// here we iterator through all the elements in the stack and
// get the block transforms and get their
for (drawableelementslistiterator iter = m_elementlist.begin();
(!resolved && iter != m_elementlist.end());
++iter)
{
if (iter->get()->isa()->isderivedfrom(oddbblockreference::desc()))
{
const oddbblockreference *pblockref = reinterpret_cast<const oddbblockreference *>(iter->get());
odcolor = pblockref->color();
switch (odcolor.colormethod())
{
case odcmentitycolor::kbylayer:
{
oddblayertablerecordptr player = pblockref->layerid().safeopenobject();
odcolor = player->color();
resolved = true;
}
break;
case odcmentitycolor::kbyblock:
// continue to next element in the list
break;
default:
{
resolved = true;
}
break;
}
}
}
}
break;
}
return odcolor;
}
is this approach good enough? do you see this breaking somewhere?
i still don't get the special case for "0" layer + block reference that you mentioned. it would be most helpful if you can you post a sample file to illustrate this?
tia.
regards,
varun
in file attched circle inside a block has layer 0 and color bylayer,
block reference has layer green.
the circle is rendered green. because layer 0 inside a block means "use block reference's layer".
in the stack which stores block reference color you also need to store block reference layer which is used for layer "0"
you may think of layer "0" as default layer which means layer of block reference.
real layer "0" which presents in layer table is used only for entities residing in layout block (model space or one of paper spaces).
attached files (11.3 kb, 3 views)

sergey slezkin
so if the entity color is bylayer and the name of its layer is "0" and it is inside a block reference then we need to find the layer of block reference and not the layer of the entity. right?
is the same true for block reference? i mean, if the entity (e) has color as byblock and the block reference (br1) containing the entity has color as bylayer with layer name "0" and that block reference (br1) is contained in another block reference (br2). in this case, should the color of the entity (e) be the color of layer of the outermost block reference (br2)?
regards,
varun
yes. and the same is for linetype, lineweight etc.
sergey slezkin
got it!
final version looks like:
code:
odcmcolor getoddbentityresolvedcolor(const oddbentityptr pentity)
{
odcmcolor odcolor = pentity->color();
switch (odcolor.colormethod())
{
case odcmentitycolor::kbylayer:
{
oddblayertablerecordptr player = pentity->layerid().safeopenobject();
if (pentity->layer().compare("0") == 0)
{
// layer "0" has special meaning if the element is inside a block reference.
for (drawableelementslistiterator iter = m_elementlist.begin();
(iter != m_elementlist.end());
++iter)
{
if (iter->get()->isa()->isderivedfrom(oddbblockreference::desc()))
{
// element is inside a block reference after all.
// hence bylayer actually means the layer of the block reference.
const oddbblockreference *pblockref = reinterpret_cast<const oddbblockreference *>(iter->get());
player.release();
player = pblockref->layerid().safeopenobject();
break;
}
}
}
odcolor = player->color();
}
break;
case odcmentitycolor::kbyblock:
{
bool resolved = false;
// here we iterator through all the elements in the stack and
// get the block reference and get the color from them.
for (drawableelementslistiterator iter = m_elementlist.begin();
(!resolved && iter != m_elementlist.end());
++iter)
{
if (iter->get()->isa()->isderivedfrom(oddbblockreference::desc()))
{
const oddbblockreference *pblockref = reinterpret_cast<const oddbblockreference *>(iter->get());
odcolor = pblockref->color();
switch (odcolor.colormethod())
{
case odcmentitycolor::kbylayer:
{
oddblayertablerecordptr player = pblockref->layerid().safeopenobject();
if (pblockref->layer().compare("0") == 0)
{
// layer "0" has special meaning if this block reference
// is inside another, enclosing block reference.
drawableelementslistiterator elemiter = iter;
for (++elemiter; (elemiter != m_elementlist.end()); ++elemiter)
{
if (elemiter->get()->isa()->isderivedfrom(oddbblockreference::desc()))
{
// found an enclosing block reference.
// hence bylayer actually means the layer of this enclosing block reference.
const oddbblockreference *penclosingblockref = reinterpret_cast<const oddbblockreference *>(elemiter->get());
player.release();
player = penclosingblockref->layerid().safeopenobject();
break;
}
}
}
odcolor = player->color();
resolved = true;
}
break;
case odcmentitycolor::kbyblock:
// continue to next element in the list.
break;
default:
{
resolved = true;
}
break;
}
}
}
}
break;
}
return odcolor;
}
sergey, does this take care of all the cases?
regards,
varun
ok, i see that this only takes me one level deep. to actually get it resolved in bylayer with layer "0" case, i have to make the calls recursive.
regards,
varun
in our vectorization we have a kind of stack storing current byblock parameters, "default" layer (used for layer "0") and current model transform.
at the moment a block reference vectorization is entered a new frame of parameters is pushed to stack. the contents of block table record is vectorized and after that the stack frame is poped.
sergey slezkin
thanks sergey. the color issue is resolved.
as we're handling the hatch mapping completely on our own, do we have to do something similar to get the correct transformation matrix as well?
here's what we're doing:
code:
void exsimpleview::draw(const odgidrawable* pdrawable)
{
...
if (pdrawable->isa()->isderivedfrom(oddbhatch::desc()))
{
const oddbhatch *phatch = reinterpret_cast<const oddbhatch *>(pdrawable);
odgeplane hatchplane;
oddb::planarity planarity;
phatch->getplane(hatchplane, planarity);
odgematrix3d ocs2wcsmatrix = odgematrix3d::planetoworld(hatchplane);
odgematrix3d ocs2screenmatrix = objecttodevicematrix() * ocs2wcsmatrix;
...
}
}
we're seen that ocs2screenmatrix comes the same for all instances of hatch if we have the hatch in a block which is inserted multiple times into the drawing, even though the placement/orientations of the insert are different.
how do we get the correct transformation in these cases?
regards,
varun
hi,
hmm...
odgematrix3d ocs2wcsmatrix = odgematrix3d:lanetoworld(hatchplane);
odgematrix3d ocs2screenmatrix = objecttodevicematrix() * ocs2wcsmatrix;
it seems to be correct, i guess exsimpleview:bjecttodevicematrix() is wrong...
last edited by dmitry a. novikov; 11th december 2006 at 01:10 pmfff">.
hi dmitry,
we were under the impression that the entire transformation (including the one's for block transforms) needed for correctly placing the object on screen are encapsulated in odgsbasevectorizeview::objecttodevicematrix(). this came out of a long discussion on the forum thread .
but for the attached file, we get the same value out of objecttodevicematrix() in our device's draw() method for both the hatches. are we supposed to somehow compensate for the block transforms on our own? if so, how do we go about computing it?
tia.
attached files (24.3 kb, 3 views)

regards,
varun


所有的时间均为北京时间。 现在的时间是 01:19 PM.