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


返回   几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量 » 仿射空间:CAX软件开发(三)二次开发与程序设计 » CAD二次开发 » AutoCAD二次开发 » DirectDWG
用户名
密码
注册 帮助 会员 日历 银行 搜索 今日新帖 标记论坛为已读


回复
 
主题工具 搜索本主题 显示模式
旧 2009-05-06, 03:47 PM   #1
yang686526
高级会员
 
注册日期: 06-11
帖子: 14579
精华: 1
现金: 224494 标准币
资产: 234494 标准币
yang686526 向着好的方向发展
默认 【转帖】incomplete rendering to bitmap

incomplete rendering to bitmap
incomplete rendering to bitmap
our application renders cad drawings to bitmaps. the attached zip file contains two drawings that are rendered incorrectly with our application. however, they render fine with odamfcapp, so the problem must be something with our application. i have carefully compared our app with odamfcapp but i can not find what we are doing wrong. i am asking for some help to identify the problem. also please note that we have rendered 100's of drawings just fine. but these two drawings are causing a problem. there must be something interesting about these two files.
the specific problems are:
1) for the file 001-a1.dwg (for the model layout) our application renders a completely blank bitmap.
2) for the file cad.dwg (for the layout layout1) our application does not render any of the walls. this can be seen in the attached cad.bmp.
the relevant portions of our application are posted here. please let me know if you can identify what the problem might be, or if you need more information. thank you.
first, here is some initialization code:
code:
odrx_declare_static_module_entry_point(wingdimodule);
odrx_declare_static_module_entry_point(modelermodule);
// the architectural desktop (adt) elements are conditionally included.
// they greatly increase the executable code size.
#ifdef include_adt
odrx_declare_static_module_entry_point(aecarchbase);
odrx_declare_static_module_entry_point(aecarchbase40);
odrx_declare_static_module_entry_point(aecarchbase50);
odrx_declare_static_module_entry_point(aecarchdachbase);
odrx_declare_static_module_entry_point(aecarchdachbase40);
odrx_declare_static_module_entry_point(aecarchdachbase50);
odrx_declare_static_module_entry_point(aecareacalculationbase);
odrx_declare_static_module_entry_point(aecareacalculationbase40);
odrx_declare_static_module_entry_point(aecareacalculationbase50);
odrx_declare_static_module_entry_point(aecbase);
odrx_declare_static_module_entry_point(aecbase40);
odrx_declare_static_module_entry_point(aecbase50);
odrx_declare_static_module_entry_point(aecschedule);
odrx_declare_static_module_entry_point(aecschedule40);
odrx_declare_static_module_entry_point(aecschedule50);
odrx_declare_static_module_entry_point(aecscheduledata);
odrx_declare_static_module_entry_point(aecscheduledata40);
odrx_declare_static_module_entry_point(aecscheduledata50);
odrx_declare_static_module_entry_point(aecstructurebase);
odrx_declare_static_module_entry_point(aecstructurebase40);
odrx_declare_static_module_entry_point(aecstructurebase50);
#endif
odrx_begin_static_module_map()
odrx_define_static_application(dd_t("wingdi"), wingdimodule)
odrx_define_static_application(dd_t("modelergeometry"), modelermodule)
#ifdef include_adt
odrx_define_static_application(dd_t("aecarchbase"), aecarchbase)
odrx_define_static_application(dd_t("aecarchbase40"), aecarchbase40)
odrx_define_static_application(dd_t("aecarchbase50"), aecarchbase50)
odrx_define_static_application(dd_t("aecarchdachbase"), aecarchdachbase)
odrx_define_static_application(dd_t("aecarchdachbase40"), aecarchdachbase40)
odrx_define_static_application(dd_t("aecarchdachbase50"), aecarchdachbase50)
odrx_define_static_application(dd_t("aecareacalculationbase"), aecareacalculationbase)
odrx_define_static_application(dd_t("aecareacalculationbase40"), aecareacalculationbase40)
odrx_define_static_application(dd_t("aecareacalculationbase50"), aecareacalculationbase50)
odrx_define_static_application(dd_t("aecbase"), aecbase)
odrx_define_static_application(dd_t("aecbase40"), aecbase40)
odrx_define_static_application(dd_t("aecbase50"), aecbase50)
odrx_define_static_application(dd_t("aecschedule"), aecschedule)
odrx_define_static_application(dd_t("aecschedule40"), aecschedule40)
odrx_define_static_application(dd_t("aecschedule50"), aecschedule50)
odrx_define_static_application(dd_t("aecscheduledata"), aecscheduledata)
odrx_define_static_application(dd_t("aecscheduledata40"), aecscheduledata40)
odrx_define_static_application(dd_t("aecscheduledata50"), aecscheduledata50)
odrx_define_static_application(dd_t("aecstructurebase"), aecstructurebase)
odrx_define_static_application(dd_t("aecstructurebase40"), aecstructurebase40)
odrx_define_static_application(dd_t("aecstructurebase50"), aecstructurebase50)
#endif
odrx_end_static_module_map()
void initcadlibrary ()
{
// initialize the static module map
odrx_init_static_module_map();
// create the portion of the 's' structure that will hold c++ objects.
// note that 'sx' is just a #define for 's.pop' (see swapvars.h).
s.pop = (void *)new struct sop;
sx->pdb = 0;
sx->pgs = 0;
sx->pdevice = 0;
sx->pcontext = 0;
sx->playouthelper = 0;
#ifdef singleclient
// see swapvars.h for a description of singleclient mode.
// create the portion of the 's' structure that will hold the services c++ object.
// this must be in a separate structure because, due to dwgdirect library constraints,
// it must be destroyed separately from the objects in the 's.pop' structure.
// then, initialize dwgdirect.
s.pop2 = (void *)new struct sop2;
odinitialize(&(sx2->svcs));
#else
// only initialize dwgdirect once per process.
if (numlibclients == 0)
{
odinitialize(&svcs);
}
numlibclients++;
#endif
}
/**************************************************************************************************
* name: cadparseinput
*
* description:
* this function loads the input drawing into a cad library database,
* extracts data from the database to return to the client, and prepares for rendering a bitmap.
*
***************************************************************************************************/
void cadparseinput ()
{
try
{
// the adtdirect modules must be loaded.
#ifdef include_adt
:drxdynamiclinker()->loadapp( "aecbase" );
:drxdynamiclinker()->loadapp( "aecarchbase" );
:drxdynamiclinker()->loadapp( "aecarchdachbase" );
:drxdynamiclinker()->loadapp( "aecscheduledata" );
:drxdynamiclinker()->loadapp( "aecschedule" );
:drxdynamiclinker()->loadapp( "aecstructurebase" );
:drxdynamiclinker()->loadapp( "aecareacalculationbase" );
#endif
// load the cad drawing into a memory stream
odmemorystreamptr pmemstream = loadinputtomemorystream (s.pbindrawing, s.drawingsize);
// dwf files require special processing by the cad library. they must be imported into
// the database before they can be processed.
if (isdwfdrawing())
{
#ifdef singleclient
sx->pdb = sx2->svcs.createdatabase();
#else
sx->pdb = svcs.createdatabase();
#endif
oddwfimportptr importer = createimporter();
importer->properties()->putat( "database", sx->pdb );
importer->properties()->putat( "stream", pmemstream );
// set this property to true to ensure that 3d dwf drawings can be rendered.
importer->properties()->putat( "importw3d", odrxvariantvalue((bool)1) );
//set the memory stream back to the beginning of the buffer.
pmemstream->rewind();
importer->import();
}
else
{
// create a cad database and load the drawing into it.
#ifdef singleclient
sx->pdb = sx2->svcs.readfile(pmemstream, false, false);
#else
sx->pdb = svcs.readfile(pmemstream, false, false);
#endif
opverify(!sx->pdb.isnull(), s.pp, err_unexpected_error + cad_error_database_create);
}
// retrieve information from the cad drawing
getgeneralinfo(sx->pdb);
getlayerinfo(sx->pdb);
getlayoutinfo(sx->pdb);

// load the windows gdi module
sx->pgs = :drxdynamiclinker()->loadmodule("wingdi", false);
opverify(!sx->pgs.isnull(), s.pp, err_unexpected_error + cad_error_load_module);

// create a rendering context for the database
sx->pcontext = odgicontextfordbdatabase::createobject();
opverify(!sx->pcontext.isnull(), s.pp, err_unexpected_error + cad_error_create_context);
// associate the database with the context
sx->pcontext->setdatabase (sx->pdb);
// the memory stream can be released. the contents have been read into the database
// so we no longer need the memory stream.
pmemstream.release ();
}
catch (oderror& e)
{
#ifdef _debug
// capture the error description text to assist in debugging.
odstring s = e.description();
#endif
// force opverify to report an error and report the error code raised by the library
opverify(0, s.pp, err_unexpected_error - e.code());
}
catch (...)
{
// force opverify to report an error.
opverify(0, s.pp, err_unexpected_error);
}

return;
}the next chunk renders the bitmap:
code:
void cadrenderbitmap()
{
try
{
odgepoint3d position;
odgepoint3d target;
odgevector3d upvector;
double fieldwidth = 0;
double fieldheight = 0;
bool redrawrequired = false;
// in order to allow for multiple calls to req_exec for the same input file, the bitmap
// device must be created each time exec is called to render an image.
sx->pdevice = sx->pgs->createbitmapdevice();
opverify(!sx->pdevice.isnull(), s.pp, err_unexpected_error + cad_error_create_device);
// set the bit depth.
sx->pdevice->properties()->putat("bitperpixel", odrxvariantvalue(oduint32(s.pp->u.cad.renderbitdepth)));
// according to the open design alliance, setting this flag improves bitmap output and it should be set.
sx->pcontext->setplotgeneration(1);
// set the color of the area outside of the drawing and background area.
// this is visible if a drawing is rendered to a different aspect ratio than that contained in the layout.
// this area is analogous the black bands seen when viewing a widescreen movie on a non-widescreen tv.
odcolorref backgroundcolor = odrgb(s.pp->u.cad.backgroundcolor.rgbred,
s.pp->u.cad.backgroundcolor.rgbgreen,
s.pp->u.cad.backgroundcolor.rgbblue);
sx->pdevice->setbackgroundcolor(backgroundcolor);
// set the logical palette. this controls the color of the area directly behind the drawing elements.
// the key to making this work is ensuring that array element 0 of the palette copy array ("ppalcpy") is
// set to the desired background color. if this step is omitted, then the area directly behind the drawing elements will
// not be the desired color. this code was copied from the dwg direct bitmap rendering example.
const odcolorref* palette = odcmacadpalette(backgroundcolor);
odgspalette ppalcpy;
const int palettenumcolors = 256;
ppalcpy.insert(ppalcpy.begin(), palette, palette+palettenumcolors);
ppalcpy[0] = backgroundcolor;
sx->pdevice->setlogicalpalette(ppalcpy.asarrayptr(), palettenumcolors);
// set the color of the drawing background area.
sx->pcontext->setpalettebackground(backgroundcolor);
// set layers on or off, as requested by the client.
setlayeronoffstatus(sx->pdb);
if ( ((long)s.pp->u.cad.layouttorender != s.previouslayout) || (outputsizechanged()) )
{
redrawrequired = true;
s.previouslayout = (long)s.pp->u.cad.layouttorender;
if ( (s.pp->flags & f_crop) || (s.pp->flags & f_inputcrop) )
{
s.previouswidth = s.cropwidth;
s.previousheight = s.cropheight;
}
else
{
s.previouswidth = s.pp->u.cad.renderwidth;
s.previousheight = s.pp->u.cad.renderheight;
}
// determine the layout to render, based upon client input, and setup the layout.
oddbobjectid layoutid = getlayouttorender(sx->pdb);
if (isactivelayout(sx->pdb, layoutid))
{
sx->playouthelper = oddbgsmanager::setupactivelayoutviews(sx->pdevice, sx->pcontext);
}
else
{
sx->playouthelper = oddbgsmanager::setuplayoutviews (layoutid, sx->pdevice, sx->pcontext);
}
// open the layout.
oddblayoutptr playoutobj = layoutid.safeopenobject ();
opverify(!playoutobj.isnull(), s.pp, err_unexpected_error + cad_error_create_layout);
}
// set the device to the layout helper. for multiple req_execs, this may be a previously
// created layout helper.
sx->pdevice = sx->playouthelper;

// size the drawing to the size specified by the client.
odgsdcrect canvasrect(0, s.pp->u.cad.renderwidth, 0, s.pp->u.cad.renderheight);
sx->pdevice->onsize(canvasrect);
// redrawing the image is required if a different layout is being rendered, or the output size
// has changed from the previous output size.
if (redrawrequired)
{
// zooming to extents is sometimes required to fill the specified bitmap size with the drawing.
// for a model space layout, if we don't zoom to extents, for some drawings, some of the
// drawing elements are cropped. on the other hand, for some paper space layout drawings,
// for some drawings, zooming to extents causes some of the drawing elements to be cropped.
// therefore, only zoom to extents for the model space layout.
cad_layout *pcadlayouts = s.pp->u.cad.layouts;
if (strncmp(pcadlayouts[s.pp->u.cad.layouttorender].name, modellayoutname, modelnamelength) == 0)
{
odabstractviewpeptr(sx->playouthelper->activeview())->zoomextents(sx->playouthelper->activeview());
}
}
// save the current view attributes so they can be restored later.
position = sx->playouthelper->activeview()->position();
target = sx->playouthelper->activeview()->target();
upvector = sx->playouthelper->activeview()->upvector();
fieldwidth = sx->playouthelper->activeview()->fieldwidth();
fieldheight = sx->playouthelper->activeview()->fieldheight();
// some 3d images, when initially displayed, are tilted on the z-axis. in this case, when they are rendered
// again for a subsequent req_exec, the amount of tilt on the z-axis may change. in order to prevent this,
// setview is called here. this ensures that all 3d images are always displayed on a flat plane, with regards
// to the z-axis. some other cad viewers always display 3d images on a flat plane, others display the image
// tilted (if the current state of the image is tiled in the file). this means that our rendering may differ
// from those viewers which display the images tilted. however, at this point, this seems to be the only way
// to work around the issue of the image perspective changing on multiple execs.
sx->playouthelper->activeview()->setview(position,target,upvector,fieldwidth,fieldheight);
// if requested, crop the image.
if ( (s.pp->flags & f_crop) || (s.pp->flags & f_inputcrop) )
{
cropviewtorect(sx->playouthelper->activeview(), canvasrect, odgsdcrect(s.cropxoff, s.cropxoff + s.cropwidth,
s.cropyoff, s.cropyoff + s.cropheight));
// resize the drawing to the cropped size.
sx->pdevice->onsize(odgsdcrect(0, s.cropwidth, 0, s.cropheight));
}
// generate the bitmap and place it in the put queue.
sx->pdevice->update();
generatebitmap(odgirasterimageptr(sx->pdevice->properties()->getat("rasterimage")));
// in order to support multiple req_execs, the image must now be "uncropped" back to
// its original state. if we don't do this, a subsequent req_exec will be operating
// on the cropped image and the user will not get the expected results.
if ( (s.pp->flags & f_crop) || (s.pp->flags & f_inputcrop) )
{
// to "uncrop" the image, restore the previously saved view attributes.
sx->playouthelper->activeview()->setview(position,target,upvector,fieldwidth,fieldheight);
}
}
catch (oderror& e)
{
#ifdef _debug
// capture the error description text to assist in debugging.
odstring s = e.description();
#endif
// force opverify to report an error and report the error code raised by the library
opverify(0, s.pp, err_unexpected_error - e.code());
}
catch (...)
{
// force opverify to report an error.
opverify(0, s.pp, err_unexpected_error);
}
// dwgdirect is not terminated here, so that multiple req_execs can be executed. the device is recreated
// for each req_exec, so release it here.
if (!(sx->pdevice.isnull()))
{
sx->pdevice.release();
}
}
void generatebitmap(const odgirasterimage* praster)
{
// retrieve bitmapinfoheader information.
s.pp->head.bisize = sizeof(bitmapinfoheader);
s.pp->head.biwidth = praster->pixelwidth();
s.pp->head.biheight = praster->pixelheight();
s.pp->head.biplanes = 1;
s.pp->head.bibitcount = (word)praster->colordepth();
s.pp->head.bicompression = bi_rgb;
s.pp->head.bisizeimage = 0;
s.pp->head.bixpelspermeter = 0;
s.pp->head.biypelspermeter = 0;
s.pp->head.biclrused = praster->numcolors();
s.pp->head.biclrimportant = 0;
// retrieve the color palette.
praster->palettedata((oduint8 *)s.pp->colortable);
// retrieve the scan lines.
// note that the library always renders bitmaps and returns scanlines that are padded to
// 4-byte boundaries. there is no way to instruct the library to render different sized scanlines.
// however, the client may have requested no padding or a different amount of
// padding. this desired output line size is specified in the pic parms widthpad field.
oduint32 scanlinesize(praster->scanlinesize());
byte* pline;
pline = (byte *)opcalloc(1, scanlinesize);
// the bitmap is already in bottom up order, so we need to start with the last scan line.
for(long i = s.pp->head.biheight - 1; i >=0; i--)
{
// retrieve a single scan line, at position 'i'.
praster->scanlines(pline, i, 1);
pwritecrop(pline, s.pp->u.cad.widthpad, 0, min(s.pp->u.cad.widthpad, scanlinesize));
// if we need to yield, do so.
if (s.pp->u.cad.picflags & pf_yieldput)
{
s.pp->percentdone = ((s.pp->head.biheight - i) * 100) / s.pp->head.biheight;
s.pp->put.rear = s.pbcurrentput;
opdefer (s.pp, res_put_data_yield);
}
}
opfree(pline);
}attached files
w/o adt the rendering of the second file is still wrong?
vladimir
i get the same results on both files whether i include adt or not. do these files contain adt elements?
quote:
originally posted by sbucholtz@jpg.com
i get the same results on both files whether i include adt or not. do these files contain adt elements?
cad.dwg contains adt elements.
other file contains nothing unusual, so i'm quite at loss what might went wrong in your app.
vladimir
i'm at a loss also. i'll keep looking. in the meantime, if you see anything that looks suspicious, please let me know. thanks.
note that most of the rasterizing code is available with sources (./extensions/exrender),
and you may use them in debugging. (e.g. place a breakpoint in exgsbitmapdevice::update)
vladimir
i have made some progress in tracking down the problem with the file 001-a1.dwg.
you will see in the second chunk of code in the original post a call to zoomextents:
odabstractviewpeptr(sx->playouthelper->activeview())->zoomextents(sx->playouthelper->activeview());
if i comment this line out, then the drawing is rendered correctly. with this call to zoomextents present, i get a completely blank output bitmap.
why would zooming to extents cause a blank bitmap to be rendered? this seems like incorrect behavior in the library. i can't just remove the call to zoomextents, because i have come across other images that don't render correctly if i don't call zoomextents. is this a bug in the library or do i have to do something else so that zoomextents behaves correctly?
i also now see that if i open 001-a1.dwg in odamfcapp, vectorize it, and then zoom to extents that i get a blank display.
zooming to extents is somewhat more complicate.
look e.g. at ./examples/excustobjs/cmd_bmpout.cpp, _bmpout_cmd::execute, 57-90
vladimir
i'll study this example. but this doesn't explain why in odamfcapp, the display turns blank when you press the zoom to extents button.
(for me it doesn't.)
which dd version do you use?
vladimir
i get the same behavior in both version 2.5.1 and 2.6.1. for example, for version 2.6.1, i go to dd_vc2003\exe\vc2003\release and start odamfcappdll.exe. then i do the following:
1) file - open - i open the file 001-a1.dwg
2) under the vectorize menu, i select wingdi.gs - the drawing is shown correctly
3) i press the zoom extents button on the toolbar. the display is now blank.
also, using odamfcapp, when i execute the command bmpout, (by selecting the edit menu, then by selecting executecommand "bmpout", and when prompted with the question "what to export?", if i select extents, thus forcing the execution path into the code you referred to above which zooms to extents, i get a blank bitmap file output.
also, adding this code from cmd_bmpout.cpp to my application still gives me a blank bitmap.
well this is interesting. i just tried odamfcapp (version 2.6.1) on a different machine. on this machine, when rendering 001-a1.dwg then zooming to extents, it works. i don't get a blank display. also, when exporting to a bitmap and zooming to extents, this also works.
the first thing that comes to mind is maybe an uninitialized memory issue. on the first machine, the memory that might be uninitialized is such that is causes the problem. but on the other machine, the memory is such that is does not cause a problem. i'm going to try my application next on the other machine.
yes, my application also renders 001-a1.dwg correctly on the second machine.
yang686526离线中   回复时引用此帖
GDT自动化论坛(仅游客可见)
回复


主题工具 搜索本主题
搜索本主题:

高级搜索
显示模式

发帖规则
不可以发表新主题
不可以回复主题
不可以上传附件
不可以编辑您的帖子

vB 代码开启
[IMG]代码开启
HTML代码关闭

相似的主题
主题 主题发起者 论坛 回复 最后发表
【转帖】how to increase rendering speed yang686526 DirectDWG 0 2009-05-06 02:53 PM
【转帖】how to draw directly on bitmap yang686526 DirectDWG 0 2009-05-06 02:31 PM
【转帖】extremely slow rendering.... why please help me111 yang686526 DirectDWG 0 2009-05-05 10:43 AM
【转帖】cropping issues yang686526 DirectDWG 0 2009-05-04 06:51 PM
【转帖】adjusting texture bitmap yang686526 DirectDWG 0 2009-05-04 03:47 PM


所有的时间均为北京时间。 现在的时间是 05:48 AM.


于2004年创办,几何尺寸与公差论坛"致力于产品几何量公差标准GD&T | GPS研究/CAD设计/CAM加工/CMM测量"。免责声明:论坛严禁发布色情反动言论及有关违反国家法律法规内容!情节严重者提供其IP,并配合相关部门进行严厉查处,若內容有涉及侵权,请立即联系我们QQ:44671734。注:此论坛须管理员验证方可发帖。
沪ICP备06057009号-2
更多