1 /****************************************************************************
2 * VCGLib                                                            o o     *
3 * Visual and Computer Graphics Library                            o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2006                                                \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program is distributed in the hope that it will be useful,           *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 
24 #ifndef __VCG_LIB_EXPORTER_SVG
25 #define __VCG_LIB_EXPORTER_SVG
26 
27 namespace vcg
28 {
29   namespace tri
30 	{
31 		namespace io
32 		{
33 
34 /**
35  * SVG Properties.
36  *
37  * Support class to set the properties of the SVG exporter.
38  */
39 class SVGProperties
40 {
41 	// definitions
42 public:
43 
44 	// When multiple meshes are passed, they are arranged in a grid according these two values.
45 	// the default is two column and enough row. If numRow is not sufficient it is automatically enlarged.
46 	int numCol;
47 	int numRow;
48 
49 	Point2f sizeCm; // The size, in the drawing, of each ViewBox (in cm)
50 
51  	Point2f marginCm; // how much space between each slice box (in cm)
52 
pageSizeCm()53 	Point2f pageSizeCm() // This is automatically computed from the above values
54 	{
55 		float xSize = numCol*sizeCm[0] + numCol*marginCm[0] + marginCm[0];
56 		float ySize = numRow*sizeCm[1] + numRow*marginCm[1] + marginCm[1];
57 		return Point2f(xSize,ySize);
58 	}
59 
60 
61 	Point3f projDir;	  // Direction of the Projection
62 	Point3f projUp;
63 	Point3f projCenter; // the 3d point that after projection will fall exactly in the center of the ViewBox.
64 
65 	// How the mesh will be scaled.
66 	// if this value is 0 the bounding box of all the passed meshes will be used to compute the scale and center
67 	// otherwise it is a scaling factor that is used to place the mesh in a unit cube (-1..1)
68 	// usually it is 2/bbox.Diag
69 	float scale;
70 
71 	// SVG Style Parameters
72 	int lineWidthPt;	// Line width.
73 	std::string strokeColor; 	// Stroke color (see StrokeColor).
74 	std::string strokeLineCap;// Stroke linecap (see StrokeLineCap).
75 
76 	//Text details
77 	bool showTextDetails;
78 
79 public:
80 
SVGProperties()81 		SVGProperties()
82 	{
83 		lineWidthPt = 1;
84 		strokeColor = "black";
85 		strokeLineCap = "round";
86 
87 		// default projection (XZ plane with the z up)
88 		projDir= Point3f(0.0, 1.0, 0.0);
89     projUp = Point3f(0.0, 0.0, 1.0);
90 		scale=0;
91 		//viewBox=Point2f(10, 10);
92 		projCenter=Point3f(0, 0, 0);
93 		sizeCm=Point2f(10,10);
94 		marginCm=Point2f(1,1);
95 		showTextDetails=true;
96 		numCol=2;
97 		numRow=10;
98 	}
99 
100 };
101 
102 
103 /**
104  * SVG exporter.
105  *
106  * This exporter save a mesh of EdgeMesh type in the SVG format.
107  * Most of the features of the SVG format are not supported.
108  * The given EdgeMesh is saved as a set lines. The properties
109  * of the SVG export can be set through the SVGProp class.
110  */
111 template <class EdgeMeshType>
112 class ExporterSVG
113 {
114 
115 public:
116 
117 	// Standard saving Function
118 	// just a wrapper to the below
Save(EdgeMeshType & m,const char * filename,SVGProperties & pro)119 	static bool Save(EdgeMeshType &m, const char *filename, SVGProperties & pro)
120 	{
121 		std::vector<EdgeMeshType*> MeshVec;
122 		MeshVec.push_back(&m);
123 		return Save(MeshVec,filename,pro);
124 	}
125 
126 
127 	// Main saving function
128 	// save a Multiple Set of Edge Meshes on a single SVG files
Save(std::vector<EdgeMeshType * > & meshVec,const char * filename,SVGProperties & pro)129 	static bool Save(std::vector<EdgeMeshType*> &meshVec, const char *filename, SVGProperties & pro)
130 	{
131 		FILE * fpo = fopen(filename,"w");
132 		if (fpo==NULL)			return false;
133 
134 		WriteXmlHead(fpo, pro);
135     for(size_t i=0;i<meshVec.size();++i)
136 		{
137 			WriteXmlBody(fpo, *meshVec[i], pro, i );
138 		}
139 		fprintf(fpo, "</svg>");
140 		fclose(fpo);
141 		return true;
142 	}
143 
144 
WriteXmlHead(FILE * o,SVGProperties & pro)145 static void WriteXmlHead(FILE *o, SVGProperties & pro)
146 {
147 	fprintf(o, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
148 	fprintf(o, "<!-- Created with vcg library -->\n");
149 	fprintf(o, "<svg width=\"%fcm\" height=\"%fcm\" \n",pro.pageSizeCm()[0], pro.pageSizeCm()[1]);
150 	fprintf(o, "	xmlns=\"http://www.w3.org/2000/svg\" \n");
151 	fprintf(o, "	xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n");
152 	fprintf(o, "	xmlns:dc=\"http://purl.org/dc/elements/1.1/\" \n");
153 	fprintf(o, "	xmlns:cc=\"http://web.resource.org/cc/\" \n");
154 	fprintf(o, "	xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" \n");
155 	fprintf(o, "	xmlns:svg=\"http://www.w3.org/2000/svg\" \n \n");
156 	fprintf(o, "id=\"svg2\"> \n");
157 	fprintf(o, "	<defs id=\"defs4\"/> \n");
158 	fprintf(o, "	<metadata id=\"metadata7\"> \n");
159 	fprintf(o, "	<rdf:RDF> \n");
160 	fprintf(o, "	<cc:Work rdf:about=\"\"> \n");
161 	fprintf(o, "	<dc:format>image/svg+xml</dc:format> \n");
162 	fprintf(o, "	<dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /> \n");
163 	fprintf(o, "	</cc:Work> \n");
164 	fprintf(o, "	</rdf:RDF> \n");
165 	fprintf(o, "</metadata> \n \n");
166 }
167 
WriteXmlBody(FILE * fpo,EdgeMeshType & mp,SVGProperties & pro,int meshIndex)168 static void WriteXmlBody(FILE* fpo, EdgeMeshType &mp, SVGProperties &pro, int meshIndex)
169 {
170 	int rowInd = meshIndex / pro.numCol;
171 	int colInd = meshIndex % pro.numCol;
172 
173 	fprintf(fpo, "  <rect width= \" %fcm \" height= \" %fcm \" x=\"%fcm \" y=\"%fcm \" "
174 					     "        style= \" stroke-width:1pt; fill-opacity:0.0; stroke:rgb(0,0,0)\" /> \n",
175 					     pro.sizeCm[0], pro.sizeCm[1], pro.marginCm[0]+colInd*(pro.sizeCm[0]+pro.marginCm[0]), pro.marginCm[1]+rowInd*(pro.sizeCm[1]+pro.marginCm[1]));
176 	fprintf(fpo, "<g stroke=\"%s\" stroke-linecap=\"%s\" stroke-width = \"%fpt\" > \n",  pro.strokeColor.c_str(), pro.strokeLineCap.c_str(),pro.lineWidthPt/100.0f);
177   fprintf(fpo, "  <svg id = \"SliceNum%d\" viewBox=\"-1000 -1000 2000 2000\" width=\"%fcm\" height=\"%fcm\" x=\"%fcm\" y=\"%fcm\" >\n", meshIndex,pro.sizeCm[0],pro.sizeCm[1],
178 					pro.marginCm[0]+colInd*(pro.sizeCm[0]+pro.marginCm[0]), pro.marginCm[1]+rowInd*(pro.sizeCm[1]+pro.marginCm[1]) );
179 
180 
181 	// Main loop of edge printing
182 		typename EdgeMeshType::EdgeIterator i;
183 
184 		// XY projection.
185 		// It is a classcial ortho projection
186 		// eg it resolves to a rotation Matrix such that
187 		// - the passed projDir become the z axis
188 		// - the passed projUp lie on the upper YZ plane.
189 
190 		// First Step align projDir to Z
191 		Matrix33f rotM = RotationMatrix(pro.projDir,Point3f(0,0,1),false);
192 		Point3f rotatedUp = rotM * pro.projUp;
193 		Point3f rotCenter = rotM * pro.projCenter;
194 		float scale = pro.scale;
195 		if(scale==0) scale = 2.0/mp.bbox.Diag();
196 
197     for (i = mp.edge.begin(); i != mp.edge.end(); ++i) if(!(*i).IsD())
198 		{
199 			Point3f p0 = (-rotCenter + rotM * ((*i).V(0)->P()))*scale*1000;
200 			Point3f p1 = (-rotCenter + rotM * ((*i).V(1)->P()))*scale*1000;
201 			fprintf(fpo, "        <line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" />\n", p0[0],p0[1],p1[0],p1[1]);
202 		}
203 
204 		fprintf(fpo, "  </svg>\n");
205 		fprintf(fpo, "</g>\n");
206 
207 }
208 
209 };
210 
211 
212 		};  // namespace io
213 	};  // namespace edge
214 };  // namespace vcg
215 #endif  // __VCG_LIB_EXPORTER_SVG
216