redering a dwg file to svg
redering a dwg file to svg
i believe this question is similar to
hi,
why you wouldn't look into (or even use as a base) our svg exporter ..?
dwgdirect\exports\svgexport\
you can try it from odamfcapp: file->export to svg...
that is what i am using, unfortunately it isn't acting the way i expected it to.
code:
void mybaseclasswithacompositedwgfileloaded::saveassvg(odwrfilebufptr psvgfile)
{
// ok, @ this point, the _pdb should have the complete autocad db in it,
// and the odwrfilebufptr should be the target for the explosion to svg
// the _pdb has modelspace as the currently active view, and a zoom extents has been performed
// create output file
if ( psvgfile.isnull() ) return;
// create export device
// psvgmodule is a odgsmoduleptr that was loaded via psvgmodule = :

drxdynamiclinker()->loadmodule("dd_svgexport");
odgsdeviceptr dev = psvgmodule->createdevice();
// setup output stream
dev->properties()->putat( dd_t("output"), psvgfile.get() );
// size of pixel in device units
double lineweightscale;
lineweightscale = 1.0;
dev->properties()->putat( dd_t("lineweightscale"), odrxvariantvalue( lineweightscale ) );
// checks a std::map for the string background
if(hasattribute(_t("background")))
{
// colored background
const wchar_t* pbackground = getattribute(_t("background"));
int r, g, b;
this->parsecolor(pbackground, r, g, b);
dev->properties()->putat( "background", odrxvariantvalue( odrgb( r, g, b )) );
}
else
{
// by default the background is white!!!
dev->properties()->putat( "background", odrxvariantvalue( odrgb( 0xff, 0xff, 0xff )) );
}
// number of digits in float values (6 by default)
odint32 precision = 6;
//
dev->properties()->putat( dd_t("precision"), odrxvariantvalue( precision ) );
// generic font family
odstring genericfontfamily = dd_t("sans-serif");
dev->properties()->putat( dd_t("genericfontfamily"), odrxvariantvalue( genericfontfamily ) );
// set active palette
//odcmacadlightpalette / odcmacaddarkpalette
dev->setlogicalpalette( odcmacadlightpalette(), 256 );
// prepare database context for device
odgicontextfordbdatabaseptr pdwgcontext = odgicontextfordbdatabase::createobject();
pdwgcontext->setdatabase( _pdb );
// do not render paper
pdwgcontext->setplotgeneration( true );
odgsdeviceptr pview = oddbgsmanager::setupactivelayoutviews( dev, pdwgcontext );
// setup device coordinate space
odgepoint3d p3dextmin,p3dextmax;
odgsdcpoint pdcextmin,pdcextmax;
_pdb->updateext(); // update the extents
p3dextmin=_pdb->getextmin();
p3dextmax=_pdb->getextmax();
// normal way fo doing things
pdcextmin.x=(long)(p3dextmin.x - (0.55));
pdcextmin.y=(long)(p3dextmin.y - (0.55));
pdcextmax.x=(long)(p3dextmax.x + (0.55));
pdcextmax.y=(long)(p3dextmax.y + (0.55));
odsvgdevice::fixactivelayoutviews(pdwgcontext);// this call intends to "fix" the svg issues where the y axis is inverted
odgsdcrect screenrect(pdcextmin,pdcextmax);
pview->onsize(screenrect);
bool benablegouraudshading = true;
dev->properties()->putat( l"enablegouraudshading", odrxvariantvalue( benablegouraudshading ) );
// initiate rendering.
pview->update( 0 );
}
ok, here is a more detailed example of the behavior i am seeing.
attached are 2 files, the dwg file, and the resulting svg output (renamed to .txt) from the above section of code.
attached files (23.3 kb, 3 views)
(1.9 kb, 4 views)
do you want to get svg with primitives' coordinates the same that is in model space of source dwg ?..
ultimatly that would be ideal.
my main issue at this point is getting the "background" viewbox to fill the default view. i would also like to be able to pad the default extents by some arbritrary value (ex: 3% of the width and height for padding around the border).
try this:
code:
if ( psvgfile.isnull() )
return;
odgsmoduleptr psvgmodule = :

drxdynamiclinker()->loadmodule("dd_svgexport");
odgsdeviceptr dev = psvgmodule->createdevice();
// setup output stream
dev->properties()->putat( dd_t("output"), psvgfile.get() );
// size of pixel in device units
double lineweightscale;
lineweightscale = 1.0;
dev->properties()->putat( dd_t("lineweightscale"), odrxvariantvalue( lineweightscale ) );
dev->properties()->putat( dd_t("background"), odrxvariantvalue( odrgb( 0xff, 0xff, 0xff )) );
// number of digits in float values (6 by default)
odint32 precision = 6;
//
dev->properties()->putat( dd_t("precision"), odrxvariantvalue( precision ) );
// generic font family
odstring genericfontfamily = dd_t("sans-serif");
dev->properties()->putat( dd_t("genericfontfamily"), odrxvariantvalue( genericfontfamily ) );
// set active palette
//odcmacadlightpalette / odcmacaddarkpalette
dev->setlogicalpalette( odcmacadlightpalette(), 256 );
// prepare database context for device
odgicontextfordbdatabaseptr pdwgcontext = odgicontextfordbdatabase::createobject();
pdwgcontext->setdatabase( _pdb );
// do not render paper
pdwgcontext->setplotgeneration( true );
// zoom to extents active viewport
odgslayouthelperptr phelper = oddbgsmanager::setupactivelayoutviews( dev, pdwgcontext );
oddbobjectptr pvpobj = _pdb->activeviewportid().safeopenobject(oddb::kforwrite);
oddbabstractviewportdataptr pvpe(pvpobj);
pvpe->zoomextents(pvpobj);
odgsviewptr pview = pvpe->gsview(pvpobj);
// elliminate rounding error in onsize():
double f = odround(odmax(pview->fieldwidth(), pview->fieldheight()));
pview->setview(pview->position(), pview->target(), pview->upvector(), f, f);
//odsvgdevice::fixactivelayoutviews(pdwgcontext);// this call intends to "fix" the svg issues where the y axis is inverted
odgsdcrectdouble screenrect;
screenrect.m_min.x = 0.0;
screenrect.m_min.y =
screenrect.m_max.x = odmax(f, 1.);
screenrect.m_max.y = 0.0;
phelper->onsize(screenrect);
bool benablegouraudshading = true;
dev->properties()->putat( l"enablegouraudshading", odrxvariantvalue( benablegouraudshading ) );
// initiate rendering.
phelper->update( 0 );
hmmm, i tried the code, and i am getting an access violation due to:
code:
odgsviewptr pview = pvpe->gsview(pvpobj);
returning a null pointer.
i lack the symbols do debug it any further than disassembly, but this call is in e:\opendwg\dd2.3\dwgdirect_vc8\source\database\tab les\dbabstractviewportdatafordbvptabrec.cpp
code:
odgsdeviceptr dev = psvgmodule->createdevice();
// setup output stream
dev->properties()->putat( dd_t("output"), psvgfile.get() );
// size of pixel in device units
double lineweightscale;
lineweightscale = 1.0;
dev->properties()->putat( dd_t("lineweightscale"), odrxvariantvalue( lineweightscale ) );
dev->properties()->putat( dd_t("background"), odrxvariantvalue( odrgb( 0xff, 0xff, 0xff )) );
// number of digits in float values (6 by default)
odint32 precision = 6;
//
dev->properties()->putat( dd_t("precision"), odrxvariantvalue( precision ) );
// generic font family
odstring genericfontfamily = dd_t("sans-serif");
dev->properties()->putat( dd_t("genericfontfamily"), odrxvariantvalue( genericfontfamily ) );
// set active palette
//odcmacadlightpalette / odcmacaddarkpalette
dev->setlogicalpalette( odcmacadlightpalette(), 256 );
// prepare database context for device
odgicontextfordbdatabaseptr pdwgcontext = odgicontextfordbdatabase::createobject();
pdwgcontext->setdatabase( _pdb );
// do not render paper
pdwgcontext->setplotgeneration( true );
// zoom to extents active viewport
oddbobjectptr pvpobj = _pdb->activeviewportid().safeopenobject(oddb::kforwrite);
oddbabstractviewportdataptr pvpe(pvpobj);
pvpe->zoomextents(pvpobj);
odgslayouthelperptr phelper = oddbgsmanager::setupactivelayoutviews( dev, pdwgcontext );
odgsviewptr pview = phelper->activeview();
// elliminate rounding error in onsize():
double f = odround(odmax(pview->fieldwidth(), pview->fieldheight()));
pview->setview(pview->position(), pview->target(), pview->upvector(), f, f);
//odsvgdevice::fixactivelayoutviews(pdwgcontext);// this call intends to "fix" the svg issues where the y axis is inverted
odgsdcrectdouble screenrect;
screenrect.m_min.x = 0.0;
screenrect.m_min.y =
screenrect.m_max.x = odmax(f, 1.);
screenrect.m_max.y = 0.0;
phelper->onsize(screenrect);
bool benablegouraudshading = true;
dev->properties()->putat( l"enablegouraudshading", odrxvariantvalue( benablegouraudshading ) );
// initiate rendering.
phelper->update( 0 );
this is awful close... but still, when i populate a background color, the
code:
<rect width="100%" height="100%" fill="rgb(221,0,221)" />
line in the svg doesn't fill the entire default view. (there is a large hunk of "white space" on the left hand side of the default view.)
also, in the example autocad drawing the circle has the following attributes:
code:
circle layer: "circle"
space: model space
handle = 5c78
center point, x= 21.588 y= 15.000 z= 0.000
radius 9.000
circumference 56.549
area 254.469
and in the svg output:
code:
<ellipse rx="9" ry="9" cx="17.478" cy="21.44467" />
is there a reason the center point coords don't match?
hi,
you should set view cs to wcs:
pview->setview(odgepoint3d::korigin+odgevector3d::kzaxis , odgepoint3d::korigin, odgevector3d::kyaxis, f, f);
but in this case geometry will go away from viewport (you will look to empty space at origin of model space).