高级会员
注册日期: 06-11
帖子: 14579
精华: 1
现金: 224494 标准币
资产: 234494 标准币
|
【转帖】setting A Layou
setting a layout
setting a layout
i know i must be doing something stupid, but i am having problems setting the active view.
i am using:
layout = pdb->findlayoutnamed(odlayname);
pdb->setcurrentlayout(layout);
that works fine if the drawings was last saved in paperspace, but if it was last saved in modelspace then the resulting view is empty.
if i use:
layout = oddbblocktablerecordptr(pdb->getactivelayoutbtrid().safeopenobject())->getlayoutid();
pdb->setcurrentlayout(layout);
then i always get the last saved view not the paperspace view.
so, what do i need to use so that a subsequent call to:
oddbgsmanager::setupactivelayoutviews(pdevice, pctx);
will result in rendering the main paperspace view regardless of whether paperspace or modelspace was the last saved view?
btw: i tried setting settilemode(0) and that did not help.
if rendering device is not already initialized and setupactivelayoutviews() is not already called, you can simply switch layout as you wrote:
quote:
code:
layout = pdb->findlayoutnamed(odlayname);
pdb->setcurrentlayout(layout);
but, if device initialized before layout switching, i recommend recreate rendering device after setcurrentlayout() call.
this is copy of another thread with same question:
q:
quote:
> 1- i need to switch between layouts and it's not working. it doesn't seem
> to
> work either in the odamfcapp sample. open for example acad's sample
> 'blocks
> and tables imperial.dwg', which by default opens on paper space layout
> 'd-size plot'. using the dialog 'set active layout' try to change to model
> space but nothing happens. same with my code. i tried
> oddbdatabase::setcurrentlayout(), and then:
>
> oddblayoutmanagerptr lm = m_pdb->appservices()->layoutmanager();
> lm->setcurrentlayout(m_pdb, layoutid);
>
> which internally might just be what oddbdatabase::setcurrentlayout() does,
> but nothing happens.
>
> what is missing here?
a:
quote:
1. switch between layouts:
oddblayoutmanagerptr lm = m_pdb->appservices()->layoutmanager();
lm->setcurrentlayout(m_pdb, layoutid);
this code only switches layout into database, you must additionally recreate
gs views:
minimum code to make this, call setupactivelayoutviews() again:
m_pdevice =
oddbgsmanager::setupactivelayoutviews(m_pdevice->underlyingdevice(), ctx);
this can work in simple viewer, but, for example, odamfcapp store some
pointers onto views, which will be incorrect after this call.
so i recommend more simple suggesion - recreate your view completely, i. e.
release all device pointers, recreate gs device and call
setupactivelayoutviews() (you can call your createdevice code again).
additionally i recommend add oddblayoutmanagerreactor to your code, connect
it to layout manager, and override layoutswitched method, because undo/redo
operations can also call setcurrentlayout() and you can react on this
correctly (disable it on exports, because some of them calls
setcurrentlayout() also).
unfortunately, that did not really apply as calling setupactivelayoutviews is one of the last things i do before calling update. i am using:
code:
pdevice = svcs.gsbitmapdevice();
odgicontextfordbdatabaseptr pctx = odgicontextfordbdatabase::createobject();
pctx->setdatabase(pdb);
playouthelper = oddbgsmanager::setupactivelayoutviews(pdevice, pctx);
odgsdcrect screenrect(odgsdcpoint(0,0), odgsdcpoint(newwidth, newheight));
playouthelper->onsize(screenrect);
playouthelper->update();so all of the layout manipulation stuff is done before i even create the device, much less the layouthelper.
hi,
if you call setcurrentlayout() before device creation, there is no any other layout manipulations needed for layout switch. make sure your [ layout = pdb->findlayoutnamed(odlayname); ] code returns correct layout.
the only time i am having a problem is when the default paperspace is being used - in other words, the paperspace layout is named "layout1", and modelspace is the last saved view.
in this case i end up with a blank white screen. if the layout is named something else then i get that layout (with the appropriate change in the first line ofcode below to allow an alternate layout name).
here is the code i am using distilled down to this particular case:
code:
oddbobjectid layout = pdb->findlayoutnamed("layout1");
if (layout)
{
pdb->setcurrentlayout(layout);
showtrace("create the custom rendering device","");
odgsdeviceptr pdevice = svcs.gsbitmapdevice();
showtrace("prepare the device to render the active layout in this database","");
odgicontextfordbdatabaseptr pctx = odgicontextfordbdatabase::createobject();
pctx->setdatabase(pdb);
showtrace("initiate rasterization","");
pdevice->properties()->putat("bitperpixel", odrxvariantvalue(oduint32(24)));
pdevice->setbackgroundcolor(white); // acad's color for paper bg, "device background"
pctx->setpalettebackground(white);
const odcolorref* palette = odcmacadpalette(white);
pdevice->setlogicalpalette(palette, 256);
pctx->setplotgeneration( 1 );
odgslayouthelperptr playouthelper = oddbgsmanager::setupactivelayoutviews(pdevice, pctx);
odgsdcrect screenrect(odgsdcpoint(0,0), odgsdcpoint(newwidth, newheight));
playouthelper->onsize(screenrect);
pdevice->update();
odgirasterimageptr praster = pdevice->properties()->getat(dd_t("rasterimage"));
convertrasterusinggfl(praster, outf);
showtrace("end conversion","");
hi,
i test your sample code, using modified cmd_bmpout command example and not have any problems with switching to "layout1" if it is present into drawing.
does this problem arise with all drawings, containing "layout1" or only with particular drawing?
may be this is your case:
quote:
dwgdirect creates default empty drawing with 3 layouts: model, layout1 and layout 2.
dwgdirect does not create viewport entities in layouts untill you do it yourself. the only exception is if you activate a paper layout for the first time (for example by changing tilemode variable). at this moment overall viewport is created if you switched to paper space for the first time.
autocad always create overall viewport for new layouts, but dwgdirect not. maybe your drawing not contain viewports in "layout1" paperspace, so you take empty result bitmap?
i switched over to 2.7.1 but that did not help, so i took the odvectorize example and added the following:
code:
oddbobjectid layout = pdb->findlayoutnamed("layout1");
if (layout)
{
odprintconsolestring(l"setting layout\n");
pdb->setcurrentlayout(layout);
}just before the "odgicontextfordbdatabaseptr pdwgcontext = odgicontextfordbdatabase::createobject();" line. so i know the current layout is set before anything else occurs.
i get the "setting layout" string printed, so i know that is occurring but all i get processed is the viewport. here is the result for that:
quote:
setting layout
start drawing <acdblayout>. . . . . . [4f4c]
draw_color. . . . . . . . . . . . . r0:g0:b0
draw_linewidth
weight. . . . . . . . . . . . . . klnwt000
pixellinewidth. . . . . . . . . . 0
draw_fill_mode. . . . . . . . . . . fillalways
start polygonproc
normal. . . . . . . . . . . . . . null
extrusion . . . . . . . . . . . . null
numpoints . . . . . . . . . . . . 4
vertex[0] . . . . . . . . . . . [27.4 134.8 0.0]
vertex[1] . . . . . . . . . . . [27.4 865.2 0.0]
vertex[2] . . . . . . . . . . . [972.6 865.2 0.0]
vertex[3] . . . . . . . . . . . [972.6 134.8 0.0]
reduced polygon data
start polygonout
numpoints . . . . . . . . . . 4
vertex[0] . . . . . . . . . [27.4 134.8 0.0]
vertex[1] . . . . . . . . . [27.4 865.2 0.0]
vertex[2] . . . . . . . . . [972.6 865.2 0.0]
vertex[3] . . . . . . . . . [972.6 134.8 0.0]
end polygonout
end polygonproc
draw_color_index. . . . . . . . . . 7
draw_linewidth
weight. . . . . . . . . . . . . . klnwt000
pixellinewidth. . . . . . . . . . 0
draw_fill_mode. . . . . . . . . . . fillnever
start polygonproc
normal. . . . . . . . . . . . . . null
extrusion . . . . . . . . . . . . null
numpoints . . . . . . . . . . . . 4
vertex[0] . . . . . . . . . . . [27.4 134.8 0.0]
vertex[1] . . . . . . . . . . . [27.4 865.2 0.0]
vertex[2] . . . . . . . . . . . [972.6 865.2 0.0]
vertex[3] . . . . . . . . . . . [972.6 134.8 0.0]
reduced polygon data
start polygonout
numpoints . . . . . . . . . . 4
vertex[0] . . . . . . . . . [27.4 134.8 0.0]
vertex[1] . . . . . . . . . [27.4 865.2 0.0]
vertex[2] . . . . . . . . . [972.6 865.2 0.0]
vertex[3] . . . . . . . . . [972.6 134.8 0.0]
end polygonout
end polygonproc
draw_color_index. . . . . . . . . . 7
draw_linewidth
weight. . . . . . . . . . . . . . klnwt000
pixellinewidth. . . . . . . . . . 0
draw_fill_mode. . . . . . . . . . . fillnever
start polygonproc
normal. . . . . . . . . . . . . . null
extrusion . . . . . . . . . . . . null
numpoints . . . . . . . . . . . . 4
vertex[0] . . . . . . . . . . . [48.9 156.3 0.0]
vertex[1] . . . . . . . . . . . [48.9 843.7 0.0]
vertex[2] . . . . . . . . . . . [951.1 843.7 0.0]
vertex[3] . . . . . . . . . . . [951.1 156.3 0.0]
reduced polygon data
start polygonout
numpoints . . . . . . . . . . 4
vertex[0] . . . . . . . . . [48.9 156.3 0.0]
vertex[1] . . . . . . . . . [48.9 843.7 0.0]
vertex[2] . . . . . . . . . [951.1 843.7 0.0]
vertex[3] . . . . . . . . . [951.1 156.3 0.0]
end polygonout
end polygonproc
end drawing <acdblayout>. . . . . . . [4f4c]
start drawing *paper_space. . . . . . [4f49]
start drawing <acdbviewport>. . . . [5173]
end drawing <acdbviewport>. . . . . [5173]
end drawing *paper_space. . . . . . . [4f49]
done.
i have attached one of the files i am trying to convert.
attached files (651.9 kb, 1 views)
hi,
yes, the attached drawing contains empty paperspace, without any geometry or viewports. on first activation dd create default viewport inside paperspace, but not initialize view for it (acad, for example, call zoomextents() for setup view on entire modelspace geometry in this case). in dd you can manually initialize view parameters as you want.
|