2006-02-13 17:18:09 +01:00
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright ( C ) 2006 \ / ) \ / *
* Visual Computing Lab / \ / | *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved . *
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License ( http : //www.gnu.org/licenses/gpl.txt) *
* for more details . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/****************************************************************************
History
$ Log : not supported by cvs2svn $
2008-04-06 08:50:00 +02:00
Revision 1.11 2007 / 07 / 12 11 : 02 : 06 andrenucci
Scale in SingleFile mode changed , it have to be calcolated before draw .
2007-07-12 13:02:06 +02:00
Revision 1.10 2007 / 07 / 10 07 : 48 : 41 cignoni
changed a template > > into > >
2007-07-10 09:48:41 +02:00
Revision 1.9 2007 / 07 / 10 06 : 58 : 31 cignoni
added a missing typename
2007-07-10 08:58:31 +02:00
Revision 1.8 2007 / 07 / 09 15 : 36 : 40 andrenucci
fix bug with exporting of translate plans
2007-07-09 17:36:40 +02:00
Revision 1.7 2007 / 06 / 13 09 : 17 : 14 andrenucci
Fix problem with scale
2007-06-09 12:52:24 +02:00
Revision 1.5 2007 / 05 / 29 10 : 09 : 29 cignoni
Added a const ( and reformatted )
2007-05-29 12:09:29 +02:00
Revision 1.4 2007 / 05 / 21 13 : 22 : 40 cignoni
Corrected gcc compiling issues
2007-05-21 15:22:40 +02:00
Revision 1.3 2006 / 02 / 16 15 : 16 : 51 corsini
Add reference plane support
2006-02-16 16:16:51 +01:00
Revision 1.2 2006 / 02 / 15 15 : 40 : 06 corsini
Decouple SVG properties and exporter for simmetry with the other exporter
2006-02-15 16:40:06 +01:00
Revision 1.1 2006 / 02 / 13 16 : 18 : 09 corsini
first working version
2006-02-13 17:18:09 +01:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef __VCG_LIB_EXPORTER_SVG
# define __VCG_LIB_EXPORTER_SVG
namespace vcg
{
2008-09-30 12:15:51 +02:00
namespace edg
2006-02-13 17:18:09 +01:00
{
namespace io
{
/**
2006-02-15 16:40:06 +01:00
* SVG Properties .
2006-02-13 17:18:09 +01:00
*
2006-02-15 16:40:06 +01:00
* Support class to set the properties of the SVG exporter .
2006-02-13 17:18:09 +01:00
*/
2006-02-15 16:40:06 +01:00
class SVGProperties
2006-02-13 17:18:09 +01:00
{
2006-02-15 16:40:06 +01:00
// definitions
2006-02-13 17:18:09 +01:00
public :
//! Stroke colors.
enum StrokeColor
{
2007-05-29 12:09:29 +02:00
BLACK , SILVER , GRAY , WHITE ,
MAROON , RED , PURPLE , FUCHSIA ,
GREEN , LIME , OLIVE , YELLOW ,
NAVY , BLUE , TEAL , AQUA
2006-02-13 17:18:09 +01:00
} ;
//! Stroke linecap types.
enum StrokeLineCap
{
2007-05-29 12:09:29 +02:00
BUTT , ROUND , SQUARE
2006-02-13 17:18:09 +01:00
} ;
2007-06-09 12:52:24 +02:00
static const int DEFAULT_LINE_WIDTH = 2 ;
2007-07-09 17:36:40 +02:00
//in single-file export make the grid of sessiones
2007-06-09 12:52:24 +02:00
int numCol ;
int numRow ;
2006-02-15 16:40:06 +01:00
2006-02-13 17:18:09 +01:00
// private data members
private :
2007-06-09 12:52:24 +02:00
// Line width.
2006-02-13 17:18:09 +01:00
int lwidth ;
2007-06-09 12:52:24 +02:00
// Stroke color (see StrokeColor).
2006-02-13 17:18:09 +01:00
std : : string stroke_color ;
2007-06-09 12:52:24 +02:00
// Stroke linecap (see StrokeLineCap).
2006-02-13 17:18:09 +01:00
std : : string stroke_linecap ;
2007-06-09 12:52:24 +02:00
// Plane where to project the edge mesh.
2006-02-16 16:16:51 +01:00
Plane3d proj ;
2008-08-07 09:24:52 +02:00
Plane3f projf ;
2007-06-09 12:52:24 +02:00
// Scale of rdrawing respect coordinates of mesh
float scale ;
// Dimension of the drawing square
Point2d ViewBox ;
int width , height ; //Express in cm
// Position of the drawing square
Point2d position ;
2007-06-13 11:17:14 +02:00
//Text details
bool showDetails ;
2007-07-09 17:36:40 +02:00
//Starting offset
float Xmin , Ymin ;
Point2f * minPos ;
2007-07-12 13:02:06 +02:00
Point2f * maxPos ;
2007-07-09 17:36:40 +02:00
2007-06-09 12:52:24 +02:00
2006-02-15 16:40:06 +01:00
// construction
2006-02-13 17:18:09 +01:00
public :
2006-02-15 16:40:06 +01:00
SVGProperties ( )
2006-02-13 17:18:09 +01:00
{
2006-02-15 16:40:06 +01:00
lwidth = DEFAULT_LINE_WIDTH ;
2007-07-10 08:58:31 +02:00
const char * DEFAULT_LINE_COLOR = " black " ;
const char * DEFAULT_LINE_CAP = " round " ;
2006-02-15 16:40:06 +01:00
stroke_color = DEFAULT_LINE_COLOR ;
stroke_linecap = DEFAULT_LINE_CAP ;
2006-02-16 16:16:51 +01:00
// default projection plane (XZ plane)
Point3d n ( 0.0 , 1.0 , 0.0 ) ;
2008-08-07 09:24:52 +02:00
Point3f nf ( 0.0 , 1.0 , 0.0 ) ;
2006-02-16 16:16:51 +01:00
proj . SetDirection ( n ) ;
proj . SetOffset ( 0.0 ) ;
2008-08-07 09:24:52 +02:00
projf . SetDirection ( nf ) ;
projf . SetOffset ( 0.0 ) ;
2007-06-09 12:52:24 +02:00
scale = 0 ; //scale=0 it means expanded to the boards of the canvas
ViewBox = Point2d ( 1000 , 1000 ) ;
position = Point2d ( 0 , 0 ) ;
2008-08-07 09:24:52 +02:00
width = 15 ; //width of the windows
height = 15 ; //height of the windows
2007-06-13 11:17:14 +02:00
showDetails = true ;
2007-07-09 17:36:40 +02:00
Xmin = 0 ;
Ymin = 0 ;
minPos = new Point2f ( 0 , 0 ) ;
2007-07-12 13:02:06 +02:00
maxPos = new Point2f ( 0 , 0 ) ;
2006-02-13 17:18:09 +01:00
}
2006-02-15 16:40:06 +01:00
// public methods
public :
//! Set the line width.
void setLineWidth ( int width )
2006-02-13 17:18:09 +01:00
{
lwidth = width ;
}
2006-02-15 16:40:06 +01:00
//! Set the stroke color.
void setColor ( enum StrokeColor color )
2006-02-13 17:18:09 +01:00
{
2007-05-29 12:09:29 +02:00
switch ( color )
{
case BLACK : stroke_color = " black " ; break ;
case SILVER : stroke_color = " silver " ; break ;
case GRAY : stroke_color = " gray " ; break ;
case WHITE : stroke_color = " white " ; break ;
case MAROON : stroke_color = " maroon " ; break ;
case RED : stroke_color = " red " ; break ;
case PURPLE : stroke_color = " purple " ; break ;
case FUCHSIA : stroke_color = " fuchsia " ; break ;
case GREEN : stroke_color = " green " ; break ;
case OLIVE : stroke_color = " olive " ; break ;
case LIME : stroke_color = " lime " ; break ;
case NAVY : stroke_color = " navy " ; break ;
case TEAL : stroke_color = " teal " ; break ;
case AQUA : stroke_color = " aqua " ; break ;
default : assert ( 0 ) ;
}
2006-02-13 17:18:09 +01:00
}
2006-02-15 16:40:06 +01:00
//! Set the line cap style.
void setLineCap ( enum StrokeLineCap linecap )
2006-02-13 17:18:09 +01:00
{
2008-08-07 09:24:52 +02:00
if ( linecap = = BUTT ) stroke_linecap = " butt " ;
2007-05-29 12:09:29 +02:00
else if ( linecap = = ROUND ) stroke_linecap = " round " ;
else if ( linecap = = SQUARE ) stroke_linecap = " square " ;
2006-02-13 17:18:09 +01:00
}
2006-02-15 16:40:06 +01:00
2007-05-29 12:09:29 +02:00
void setPlane ( double distance , const Point3d & direction )
2006-02-16 16:16:51 +01:00
{
proj . SetDirection ( direction ) ;
proj . SetOffset ( distance ) ;
}
2008-08-07 09:24:52 +02:00
void setPlanef ( float distance , const Point3f & direction )
{
projf . SetDirection ( direction ) ;
projf . SetOffset ( distance ) ;
}
2007-06-09 12:52:24 +02:00
void setScale ( float x ) { scale = x ; } //Define the scale between 2d coordinate and mesh
void setViewBox ( Point2d x ) { ViewBox = x ; } //Define the dimension of the square
void setPosition ( Point2d x ) { position = x ; } //Define the starting position of the canvas
2007-06-13 11:17:14 +02:00
void setTextDetails ( bool x ) { showDetails = x ; }
2007-06-09 12:52:24 +02:00
void setDimension ( int width , int height ) { this - > width = width ; this - > height = height ; }
2006-02-15 16:40:06 +01:00
// accessors
public :
int lineWidth ( ) { return lwidth ; }
const char * lineColor ( ) { return stroke_color . c_str ( ) ; }
const char * lineCapStyle ( ) { return stroke_linecap . c_str ( ) ; }
2006-02-16 16:16:51 +01:00
const Plane3d * projPlane ( ) { return & proj ; }
2008-08-07 09:24:52 +02:00
const Plane3f * projPlanef ( ) { return & projf ; }
2007-06-09 12:52:24 +02:00
float getScale ( ) { return scale ; }
Point2d getViewBox ( ) { return ViewBox ; }
Point2d getPosition ( ) { return position ; }
2007-06-13 11:17:14 +02:00
2007-06-09 12:52:24 +02:00
int getWidth ( ) { return width ; }
2007-06-13 11:17:14 +02:00
bool showTextDetails ( ) { return showDetails ; }
2007-06-09 12:52:24 +02:00
int getHeight ( ) { return height ; }
2007-07-09 17:36:40 +02:00
void setMinPoint ( Point2f * p ) {
minPos = p ;
}
2007-07-12 13:02:06 +02:00
void setMaxPoint ( Point2f * p ) {
maxPos = p ;
}
2007-07-09 17:36:40 +02:00
Point2f * getminPoint ( ) { return ( minPos ) ; }
2007-07-12 13:02:06 +02:00
Point2f * getmaxPoint ( ) { return ( maxPos ) ; }
2006-02-15 16:40:06 +01:00
} ;
2007-07-09 17:36:40 +02:00
2006-02-15 16:40:06 +01:00
/**
* SVG exporter .
*
* This exporter save a mesh of EdgeMesh type in the SVG format .
* Most of the features of the SVG format are not supported .
* The given EdgeMesh is saved as a set lines . The properties
* of the SVG export can be set through the SVGProp class .
*/
template < class EdgeMeshType >
class ExporterSVG
{
public :
//! Save with the default SVG properties.
static bool Save ( EdgeMeshType * mp , const char * filename )
{
SVGProperties properties ;
return Save ( mp , filename , properties ) ;
}
2008-04-06 08:50:00 +02:00
static bool Save ( std : : vector < EdgeMeshType * > * vp , const char * filename , SVGProperties & pro ) {
2007-06-09 12:52:24 +02:00
//Function that export a vector of EdgeMesh in an unic single SVG file.
FILE * o = fopen ( filename , " w " ) ;
if ( o = = NULL )
2006-02-13 17:18:09 +01:00
return false ;
2007-06-09 12:52:24 +02:00
int num = ( * vp ) . size ( ) ; //number of square to draw
WriteXmlHead ( o , pro . getWidth ( ) , pro . getHeight ( ) , pro . getViewBox ( ) , Point2d ( 0 , 0 ) ) ;
float scale = pro . getScale ( ) ;
2007-07-10 08:58:31 +02:00
typename std : : vector < EdgeMeshType * > : : iterator it ;
2007-06-09 12:52:24 +02:00
int i = 0 ;
2007-07-09 17:36:40 +02:00
Point2f pmin ( 100000000.0f , 100000000.0f ) ;
2007-07-12 13:02:06 +02:00
Point2f pmax ( - 10000000.0f , - 10000000.0f ) ;
2007-07-09 17:36:40 +02:00
for ( it = ( * vp ) . begin ( ) ; it ! = ( * vp ) . end ( ) ; it + + ) {
EdgeMeshType * ed ;
ed = ( * it ) ;
Save ( ed , o , pro , - 2 ) ;
2007-07-12 13:02:06 +02:00
Point2f * pmi = pro . getminPoint ( ) ;
Point2f * pma = pro . getmaxPoint ( ) ;
2008-07-04 09:30:49 +02:00
pmin [ 0 ] = std : : min ( pmin [ 0 ] , pmi - > X ( ) ) ;
pmin [ 1 ] = std : : min ( pmin [ 1 ] , pmi - > Y ( ) ) ;
pmax [ 0 ] = std : : max ( pmax [ 0 ] , pma - > X ( ) ) ;
pmax [ 1 ] = std : : max ( pmax [ 1 ] , pma - > Y ( ) ) ;
2007-07-09 17:36:40 +02:00
}
2008-04-06 08:50:00 +02:00
float maxEdge = std : : max ( pmax [ 0 ] - pmin [ 0 ] , pmax [ 1 ] - pmin [ 1 ] ) ;
2007-07-12 13:02:06 +02:00
float scl = ( pro . getViewBox ( ) . V ( 0 ) / pro . numCol ) / maxEdge ;
pro . setScale ( scl ) ;
2007-07-09 17:36:40 +02:00
pro . setMinPoint ( new Point2f ( pmin [ 0 ] , pmin [ 1 ] ) ) ;
2007-07-12 13:02:06 +02:00
pro . setMaxPoint ( new Point2f ( pmax [ 0 ] , pmax [ 1 ] ) ) ;
2007-06-09 12:52:24 +02:00
for ( it = ( * vp ) . begin ( ) ; it ! = ( * vp ) . end ( ) ; it + + ) {
EdgeMeshType * ed ;
ed = ( * it ) ;
pro . setPosition ( Point2d ( ( pro . getViewBox ( ) . V ( 0 ) / pro . numCol ) * i , 40 ) ) ;
2008-08-07 09:24:52 +02:00
//pro.setPosition(Point2d((pro.getViewBox().V(0)/pro.numCol),40));
2007-06-09 12:52:24 +02:00
int x = pro . getViewBox ( ) . V ( 0 ) ;
int y = pro . getViewBox ( ) . V ( 1 ) ;
2007-07-09 17:36:40 +02:00
/*
2008-08-07 09:24:52 +02:00
fprintf ( o , " <rect width= \" %d \" height= \" %d \" x= \" %d \" y= \" %d \" style= \" stroke-width:1; fill-opacity:0.0; stroke:rgb(0,0,0) \" /> \n " , x / pro . numCol , y , ( x / pro . numCol ) * i , 40 ) ;
2007-07-09 17:36:40 +02:00
*/
Save ( ed , o , pro , i ) ;
2007-06-13 11:17:14 +02:00
if ( pro . showTextDetails ( ) ) {
2007-07-09 17:36:40 +02:00
fprintf ( o , " <text x= \" %d \" y= \" 30 \" font-family= \" Verdana \" font-size= \" 30 \" > \n " , ( x / pro . numCol ) * i ) ;
fprintf ( o , " Slice num:%d </text> \n " , i ) ; }
2007-06-09 12:52:24 +02:00
i + + ;
}
fprintf ( o , " </svg> " ) ;
fclose ( o ) ;
return true ;
}
2007-07-09 17:36:40 +02:00
//! Save with the given SVG properties.
2007-06-09 12:52:24 +02:00
static bool Save ( EdgeMeshType * mp , const char * filename , SVGProperties & props )
{
2007-07-09 17:36:40 +02:00
2007-06-09 12:52:24 +02:00
FILE * o = fopen ( filename , " w " ) ;
if ( o = = NULL )
return false ;
WriteXmlHead ( o , props . getWidth ( ) , props . getHeight ( ) , props . getViewBox ( ) , props . getPosition ( ) ) ;
2007-07-09 17:36:40 +02:00
2008-08-07 09:24:52 +02:00
2007-07-12 13:02:06 +02:00
Save ( mp , o , props , - 1 ) ;
2007-07-09 17:36:40 +02:00
fprintf ( o , " </svg> " ) ;
2006-02-13 17:18:09 +01:00
// final xml tags
fclose ( o ) ;
return true ;
}
2008-08-07 09:24:52 +02:00
/************************************************ Here is my code ****************************************************/
/********* I've use the function's surdefinition to build my own Save function, by this way I've changed nothing ********/
/* This is an other WmlHead constructor cause I need to define the width and the height of the svg file in pixels, and not in cms */
static void WriteXmlhead ( FILE * o , int width , int height )
{
fprintf ( o , " <?xml version= \" 1.0 \" encoding= \" UTF-8 \" standalone= \" no \" ?> \n " ) ;
fprintf ( o , " <!-- Created with vcg library --> \n " ) ;
fprintf ( o , " <svg width= \" %d \" height= \" %d \" viewBox= \" 0 0 %d %d \" \n \n " , width , height , width + 100 , height + 100 ) ;
fprintf ( o , " xmlns= \" http://www.w3.org/2000/svg \" \n " ) ;
fprintf ( o , " xmlns:xlink= \" http://www.w3.org/1999/xlink \" \n " ) ;
fprintf ( o , " xmlns:dc= \" http://purl.org/dc/elements/1.1/ \" \n " ) ;
fprintf ( o , " xmlns:cc= \" http://web.resource.org/cc/ \" \n " ) ;
fprintf ( o , " xmlns:rdf= \" http://www.w3.org/1999/02/22-rdf-syntax-ns# \" \n " ) ;
fprintf ( o , " xmlns:svg= \" http://www.w3.org/2000/svg \" \n \n " ) ;
fprintf ( o , " id= \" svg2 \" > \n " ) ;
fprintf ( o , " <defs id= \" defs4 \" /> \n " ) ;
fprintf ( o , " <metadata id= \" metadata7 \" > \n " ) ;
fprintf ( o , " <rdf:RDF> \n " ) ;
fprintf ( o , " <cc:Work rdf:about= \" \" > \n " ) ;
fprintf ( o , " <dc:format>image/svg+xml</dc:format> \n " ) ;
fprintf ( o , " <dc:type rdf:resource= \" http://purl.org/dc/dcmitype/StillImage \" /> \n " ) ;
fprintf ( o , " </cc:Work> \n " ) ;
fprintf ( o , " </rdf:RDF> \n " ) ;
fprintf ( o , " </metadata> \n \n " ) ;
}
/* The six float are the bbow parameters used to buiold the framing box. You'll fid them in the two functions*/
static bool Save ( EdgeMeshType * mp , const char * filename , SVGProperties & props , float mix , float miy , float max , float may , float centerx , float centery )
{
FILE * o = fopen ( filename , " w " ) ;
if ( o = = NULL )
return false ;
props . setDimension ( ( max - mix ) * props . getScale ( ) - ( mix - centerx ) * props . getScale ( ) , ( may - miy ) * props . getScale ( ) - ( miy - centery ) * props . getScale ( ) ) ;
WriteXmlhead ( o , props . getWidth ( ) , props . getHeight ( ) ) ;
Save ( mp , o , props , - 1 , mix , miy , max , may , centerx , centery ) ;
fprintf ( o , " </svg> " ) ;
fclose ( o ) ;
return true ;
}
static void Save ( EdgeMeshType * mp , FILE * o , SVGProperties props , int numSlice , float mix , float miy , float max , float may , float centerx , float centery )
{
// build vector basis (n, v1, v2)
Point3d p1 ( 0.0 , 0.0 , 0.0 ) ;
Point3d p2 ( 1.0 , 0.0 , 0.0 ) ;
Point3d p2less ( - 1.0 , 0.0 , 0.0 ) ;
Point3d d = props . projPlane ( ) - > Direction ( ) - p2 ;
Point3d dless = props . projPlane ( ) - > Direction ( ) - p2less ;
Point3d v1 ;
if ( ( d . Norm ( ) < 0.5 ) | | ( dless . Norm ( ) < 0.5 ) )
v1 = Point3d ( 0.0 , 0.0 , 1.0 ) - p1 ;
else
v1 = p2 - p1 ;
v1 . Normalize ( ) ;
Point3d v2 = v1 ^ props . projPlane ( ) - > Direction ( ) ;
//Global points
std : : vector < Point2f > pts ;
pts . clear ( ) ;
Point2f pmin ( 100000000.0f , 100000000.0f ) ;
Point2f pmax ( - 100000000.0f , - 100000000.0f ) ;
Point3d bbMin ;
float scale = props . getScale ( ) ;
typename EdgeMeshType : : EdgeIterator i ;
for ( i = mp - > edges . begin ( ) ; i ! = mp - > edges . end ( ) ; + + i )
{
Point3 < typename EdgeMeshType : : ScalarType > p1 ;
Point3 < typename EdgeMeshType : : ScalarType > p2 ;
p1 = ( * i ) . V ( 0 ) - > P ( ) ;
p2 = ( * i ) . V ( 1 ) - > P ( ) ;
Point3d p1d ( p1 [ 0 ] , p1 [ 1 ] , p1 [ 2 ] ) ;
Point3d p2d ( p2 [ 0 ] , p2 [ 1 ] , p2 [ 2 ] ) ;
// Project the line on the reference plane
Point3d p1proj = props . projPlane ( ) - > Projection ( p1d ) ;
Point3d p2proj = props . projPlane ( ) - > Projection ( p2d ) ;
// Convert the 3D coordinates of the line to the uv coordinates of the plane
Point2f pt1 ( static_cast < float > ( p1proj * v1 ) , static_cast < float > ( p1proj * v2 ) ) ;
Point2f pt2 ( static_cast < float > ( p2proj * v1 ) , static_cast < float > ( p2proj * v2 ) ) ;
pts . push_back ( pt1 ) ;
pts . push_back ( pt2 ) ;
pmin [ 0 ] = math : : Min ( math : : Min ( pt1 [ 0 ] , pmin [ 0 ] ) , pt2 [ 0 ] ) ;
pmin [ 1 ] = math : : Min ( math : : Min ( pt1 [ 1 ] , pmin [ 1 ] ) , pt2 [ 1 ] ) ;
pmax [ 0 ] = math : : Max ( math : : Max ( pt1 [ 0 ] , pmax [ 0 ] ) , pt2 [ 0 ] ) ;
pmax [ 1 ] = math : : Max ( math : : Max ( pt1 [ 1 ] , pmax [ 1 ] ) , pt2 [ 1 ] ) ;
}
// line settings
fprintf ( o , " <g stroke= \" %s \" stroke-linecap= \" %s \" > \n " ,
props . lineColor ( ) , props . lineCapStyle ( ) ) ;
fprintf ( o , " <svg id = \" %d \" > \n " , numSlice ) ;
int x = props . getViewBox ( ) . V ( 0 ) ;
int y = props . getViewBox ( ) . V ( 1 ) ;
fprintf ( o , " <rect width= \" %d \" height= \" %d \" x= \" %d \" y= \" %d \" style= \" stroke-width:1; fill-opacity:0.0; stroke:rgb(0,0,0) \" /> \n " , x / props . numCol , y , 0 , 40 ) ;
fprintf ( o , " <rect x= \" %f \" y= \" %f \" width= \" %f \" height= \" %f \" fill= \" none \" stroke-width= \" 5 \" /> \n " , 0.0 , 0.0 , ( max - mix ) * scale - ( mix - centerx ) * scale , ( may - miy ) * scale - ( miy - centery ) * scale ) ; // Here is the framing box construction
std : : vector < Point2f > : : iterator itPoints ;
for ( itPoints = pts . begin ( ) ; itPoints ! = pts . end ( ) ; + + itPoints )
{
Point2f p1 = * itPoints ;
+ + itPoints ;
Point2f p2 = * itPoints ;
fprintf ( o , " <line x1= \" %f \" y1= \" %f \" x2= \" %f \" y2= \" %f \" \n " ,
( ( p1 [ 0 ] - pmin [ 0 ] ) * scale - 0.5 * ( mix - centerx ) * scale ) , ( ( p1 [ 1 ] - pmin [ 1 ] ) * scale - 0.5 * ( miy - centery ) * scale ) ,
( ( p2 [ 0 ] - pmin [ 0 ] ) * scale - 0.5 * ( mix - centerx ) * scale ) , ( ( p2 [ 1 ] - pmin [ 1 ] ) * scale - 0.5 * ( miy - centery ) * scale ) ) ;
fprintf ( o , " stroke-width = \" %d \" " , props . lineWidth ( ) ) ;
fprintf ( o , " /> \n " ) ;
}
fprintf ( o , " </svg> " ) ;
fprintf ( o , " </g> \n " ) ;
}
/*********************************************** End of what I've made *****************************************/
static void Save ( EdgeMeshType * mp , FILE * o , SVGProperties props , int numSlice )
{
2007-07-09 17:36:40 +02:00
bool preCal = false ;
2007-07-12 13:02:06 +02:00
2007-07-09 17:36:40 +02:00
if ( numSlice = = - 2 ) preCal = true ;
2006-02-16 16:16:51 +01:00
// build vector basis (n, v1, v2)
Point3d p1 ( 0.0 , 0.0 , 0.0 ) ;
Point3d p2 ( 1.0 , 0.0 , 0.0 ) ;
2007-06-13 11:17:14 +02:00
Point3d p2less ( - 1.0 , 0.0 , 0.0 ) ;
2006-02-16 16:16:51 +01:00
Point3d d = props . projPlane ( ) - > Direction ( ) - p2 ;
2007-06-13 11:17:14 +02:00
Point3d dless = props . projPlane ( ) - > Direction ( ) - p2less ;
2006-02-16 16:16:51 +01:00
Point3d v1 ;
2007-06-13 11:17:14 +02:00
if ( ( d . Norm ( ) < 0.5 ) | | ( dless . Norm ( ) < 0.5 ) )
2006-02-16 16:16:51 +01:00
v1 = Point3d ( 0.0 , 0.0 , 1.0 ) - p1 ;
else
v1 = p2 - p1 ;
v1 . Normalize ( ) ;
Point3d v2 = v1 ^ props . projPlane ( ) - > Direction ( ) ;
2007-07-09 17:36:40 +02:00
//Global points
2008-08-07 09:24:52 +02:00
std : : vector < std : : vector < Point2f > > * glb ;
2006-02-16 16:16:51 +01:00
std : : vector < Point2f > pts ;
2008-08-07 09:24:52 +02:00
pts . clear ( ) ;
2006-02-16 16:16:51 +01:00
Point2f pmin ( 100000000.0f , 100000000.0f ) ;
Point2f pmax ( - 100000000.0f , - 100000000.0f ) ;
2007-07-09 17:36:40 +02:00
Point3d bbMin ;
2007-06-09 12:52:24 +02:00
2007-05-21 15:22:40 +02:00
typename EdgeMeshType : : EdgeIterator i ;
2007-06-09 12:52:24 +02:00
2006-02-16 16:16:51 +01:00
for ( i = mp - > edges . begin ( ) ; i ! = mp - > edges . end ( ) ; + + i )
{
2007-06-09 12:52:24 +02:00
Point3 < typename EdgeMeshType : : ScalarType > p1 ;
Point3 < typename EdgeMeshType : : ScalarType > p2 ;
p1 = ( * i ) . V ( 0 ) - > P ( ) ;
p2 = ( * i ) . V ( 1 ) - > P ( ) ;
2007-07-09 17:36:40 +02:00
2006-02-16 16:16:51 +01:00
Point3d p1d ( p1 [ 0 ] , p1 [ 1 ] , p1 [ 2 ] ) ;
Point3d p2d ( p2 [ 0 ] , p2 [ 1 ] , p2 [ 2 ] ) ;
2007-07-09 17:36:40 +02:00
2006-02-16 16:16:51 +01:00
// Project the line on the reference plane
2007-07-09 17:36:40 +02:00
2006-02-16 16:16:51 +01:00
Point3d p1proj = props . projPlane ( ) - > Projection ( p1d ) ;
Point3d p2proj = props . projPlane ( ) - > Projection ( p2d ) ;
2007-07-09 17:36:40 +02:00
2006-02-16 16:16:51 +01:00
// Convert the 3D coordinates of the line to the uv coordinates of the plane
Point2f pt1 ( static_cast < float > ( p1proj * v1 ) , static_cast < float > ( p1proj * v2 ) ) ;
Point2f pt2 ( static_cast < float > ( p2proj * v1 ) , static_cast < float > ( p2proj * v2 ) ) ;
pts . push_back ( pt1 ) ;
pts . push_back ( pt2 ) ;
2007-06-09 12:52:24 +02:00
pmin [ 0 ] = math : : Min ( math : : Min ( pt1 [ 0 ] , pmin [ 0 ] ) , pt2 [ 0 ] ) ;
pmin [ 1 ] = math : : Min ( math : : Min ( pt1 [ 1 ] , pmin [ 1 ] ) , pt2 [ 1 ] ) ;
pmax [ 0 ] = math : : Max ( math : : Max ( pt1 [ 0 ] , pmax [ 0 ] ) , pt2 [ 0 ] ) ;
pmax [ 1 ] = math : : Max ( math : : Max ( pt1 [ 1 ] , pmax [ 1 ] ) , pt2 [ 1 ] ) ;
2006-02-16 16:16:51 +01:00
2007-06-09 12:52:24 +02:00
2006-02-16 16:16:51 +01:00
}
2007-06-09 12:52:24 +02:00
2007-07-09 17:36:40 +02:00
//Point2f bbp(static_cast<float>(bbMin * v1), static_cast<float>(bbMin * v2));
if ( ! preCal ) {
float scale = props . getScale ( ) ;
2006-02-13 17:18:09 +01:00
2007-07-09 17:36:40 +02:00
// line settings
Point2d pos = props . getPosition ( ) ;
2007-06-13 11:17:14 +02:00
2007-07-09 17:36:40 +02:00
fprintf ( o , " <g stroke= \" %s \" stroke-linecap= \" %s \" > \n " ,
props . lineColor ( ) , props . lineCapStyle ( ) ) ;
float maxEdges = math : : Max ( ( pmax [ 0 ] - pmin [ 0 ] ) , ( pmax [ 1 ] - pmin [ 1 ] ) ) ;
if ( numSlice = = 0 )
Draw_proportions_scale ( o , maxEdges , props ) ;
fprintf ( o , " <svg id = \" %d \" > \n " , numSlice ) ;
int x = props . getViewBox ( ) . V ( 0 ) ;
int y = props . getViewBox ( ) . V ( 1 ) ;
2007-07-12 13:02:06 +02:00
if ( numSlice > = 0 )
2008-08-07 09:24:52 +02:00
fprintf ( o , " <rect width= \" %d \" height= \" %d \" x= \" %d \" y= \" %d \" style= \" stroke-width:1; fill-opacity:0.0; stroke:rgb(0,0,0) \" /> \n " , x / props . numCol , y , ( x / props . numCol ) * numSlice , 40 ) ;
2007-07-12 13:02:06 +02:00
else
fprintf ( o , " <rect width= \" %d \" height= \" %d \" x= \" %d \" y= \" %d \" style= \" stroke-width:1; fill-opacity:0.0; stroke:rgb(0,0,0) \" /> \n " , x / props . numCol , y , 0 , 40 ) ;
2007-06-09 12:52:24 +02:00
2008-08-07 09:24:52 +02:00
2007-07-09 17:36:40 +02:00
std : : vector < Point2f > : : iterator itPoints ;
for ( itPoints = pts . begin ( ) ; itPoints ! = pts . end ( ) ; + + itPoints )
{
Point2f p1 = * itPoints ;
+ + itPoints ;
Point2f p2 = * itPoints ;
2007-07-12 13:02:06 +02:00
if ( numSlice = = - 1 ) {
2007-07-09 17:36:40 +02:00
fprintf ( o , " <line x1= \" %f \" y1= \" %f \" x2= \" %f \" y2= \" %f \" \n " ,
2008-08-07 09:24:52 +02:00
( pos . X ( ) + ( ( p1 [ 0 ] - pmin [ 0 ] ) * scale ) ) , pos . Y ( ) + ( ( p1 [ 1 ] - pmin [ 1 ] ) * scale ) ,
pos . X ( ) + ( ( p2 [ 0 ] - pmin [ 0 ] ) * scale ) , pos . Y ( ) + ( ( p2 [ 1 ] - pmin [ 1 ] ) * scale ) ) ;
2007-07-09 17:36:40 +02:00
fprintf ( o , " stroke-width = \" %d \" " , props . lineWidth ( ) ) ;
fprintf ( o , " /> \n " ) ;
}
else {
fprintf ( o , " <line x1= \" %f \" y1= \" %f \" x2= \" %f \" y2= \" %f \" \n " ,
2008-08-07 09:24:52 +02:00
( pos . X ( ) + ( ( p1 [ 0 ] - props . getminPoint ( ) - > X ( ) ) * scale ) ) , pos . Y ( ) + ( ( p1 [ 1 ] - props . getminPoint ( ) - > Y ( ) ) * scale ) ,
pos . X ( ) + ( ( p2 [ 0 ] - props . getminPoint ( ) - > X ( ) ) * scale ) , pos . Y ( ) + ( ( p2 [ 1 ] - props . getminPoint ( ) - > Y ( ) ) * scale ) ) ;
2007-07-09 17:36:40 +02:00
fprintf ( o , " stroke-width = \" %d \" " , props . lineWidth ( ) ) ;
fprintf ( o , " /> \n " ) ; }
2006-02-13 17:18:09 +01:00
}
2007-07-09 17:36:40 +02:00
fprintf ( o , " </svg> " ) ;
2006-02-13 17:18:09 +01:00
fprintf ( o , " </g> \n " ) ;
2007-07-09 17:36:40 +02:00
}
else {
2007-07-12 13:02:06 +02:00
Point2f * pmi = props . getminPoint ( ) ;
Point2f * pma = props . getmaxPoint ( ) ;
pmi - > X ( ) = pmin [ 0 ] ;
pmi - > Y ( ) = pmin [ 1 ] ;
pma - > X ( ) = pmax [ 0 ] ;
pma - > Y ( ) = pmax [ 1 ] ;
props . setMinPoint ( pmi ) ;
props . setMaxPoint ( pma ) ;
2007-07-09 17:36:40 +02:00
2006-02-13 17:18:09 +01:00
}
2008-08-07 09:24:52 +02:00
}
2006-02-13 17:18:09 +01:00
2007-06-13 11:17:14 +02:00
private :
static void Draw_proportions_scale ( FILE * o , float maxEdge , SVGProperties & prop ) {
if ( prop . showTextDetails ( ) ) {
int num_order = log10 ( maxEdge ) ;
int pox = pow ( 10.0 , num_order ) ;
int assX = prop . getViewBox ( ) [ 0 ] ;
int assY = prop . getViewBox ( ) [ 1 ] ;
int nullAss = 0 ;
int OffsetXAs = 50 ;
float comput = OffsetXAs + ( pox * prop . getScale ( ) ) ;
2008-08-07 09:24:52 +02:00
fprintf ( o , " <line x1= \" %d \" y1= \" %d \" x2= \" %f \" y2= \" %d \" \n " , ( ( nullAss + OffsetXAs ) ) , ( assY + 50 ) , comput , ( assY + 50 ) ) ;
2007-06-13 11:17:14 +02:00
fprintf ( o , " stroke-width = \" 5 \" " ) ;
fprintf ( o , " /> \n " ) ;
fprintf ( o , " <text x= \" %d \" y= \" %d \" font-family= \" Verdana \" font-size= \" 25 \" > " , ( nullAss + OffsetXAs ) , ( assY + 80 ) ) ;
fprintf ( o , " %d px -- Scale %f : 1 </text> " , pox , prop . getScale ( ) ) ;
}
}
2008-08-07 09:24:52 +02:00
static void WriteXmlHead ( FILE * o , int width , int height , Point2d viewBox , Point2d position ) {
2007-06-13 11:17:14 +02:00
int Vx = viewBox [ 0 ] ;
int Vy = viewBox [ 1 ] ;
2008-08-07 09:24:52 +02:00
2007-06-13 11:17:14 +02:00
fprintf ( o , " <?xml version= \" 1.0 \" encoding= \" UTF-8 \" standalone= \" no \" ?> \n " ) ;
fprintf ( o , " <!-- Created with vcg library --> \n " ) ;
2008-08-07 09:24:52 +02:00
fprintf ( o , " <svg width= \" %dcm \" height= \" %dcm \" viewBox= \" 0 0 %d %d \" \n \n " , width , height , Vx , Vy + 100 ) ;
fprintf ( o , " xmlns= \" http://www.w3.org/2000/svg \" \n " ) ;
fprintf ( o , " xmlns:xlink= \" http://www.w3.org/1999/xlink \" \n " ) ;
fprintf ( o , " xmlns:dc= \" http://purl.org/dc/elements/1.1/ \" \n " ) ;
fprintf ( o , " xmlns:cc= \" http://web.resource.org/cc/ \" \n " ) ;
fprintf ( o , " xmlns:rdf= \" http://www.w3.org/1999/02/22-rdf-syntax-ns# \" \n " ) ;
fprintf ( o , " xmlns:svg= \" http://www.w3.org/2000/svg \" \n \n " ) ;
fprintf ( o , " id= \" svg2 \" > \n " ) ;
fprintf ( o , " <defs id= \" defs4 \" /> \n " ) ;
fprintf ( o , " <metadata id= \" metadata7 \" > \n " ) ;
fprintf ( o , " <rdf:RDF> \n " ) ;
fprintf ( o , " <cc:Work rdf:about= \" \" > \n " ) ;
fprintf ( o , " <dc:format>image/svg+xml</dc:format> \n " ) ;
fprintf ( o , " <dc:type rdf:resource= \" http://purl.org/dc/dcmitype/StillImage \" /> \n " ) ;
fprintf ( o , " </cc:Work> \n " ) ;
fprintf ( o , " </rdf:RDF> \n " ) ;
fprintf ( o , " </metadata> \n \n " ) ;
2007-06-13 11:17:14 +02:00
}
2007-07-09 17:36:40 +02:00
2006-02-13 17:18:09 +01:00
} ;
} ; // namespace io
} ; // namespace edge
} ; // namespace vcg
# endif // __VCG_LIB_EXPORTER_SVG