JavaCAD
SVGExporter.java
Go to the documentation of this file.
1 package eu.mihosoft.vrl.v3d.svg;
2 
3 import java.io.BufferedWriter;
4 import java.io.File;
5 import java.io.FileWriter;
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.Arrays;
9 import java.util.List;
10 import eu.mihosoft.vrl.v3d.CSG;
11 import eu.mihosoft.vrl.v3d.Polygon;
12 import eu.mihosoft.vrl.v3d.Slice;
13 import eu.mihosoft.vrl.v3d.Transform;
14 import eu.mihosoft.vrl.v3d.Vector3d;
15 import eu.mihosoft.vrl.v3d.Vertex;
16 
17 @SuppressWarnings("restriction")
18 public class SVGExporter {
19  private String footer = "</svg>";
20  private String section = "";
21  //0.376975
22  //public static final double Scale = 3.543307;// SVG px to MM scale facto
23  private static final double Scale = 3.543307;
24  private static final double VueBoxSize = 100;
25  private int colorTicker=0;
26  public static List<String> colorNames = Arrays.asList("crimson","gray","darkmagenta","darkolivegreen","darkgreen",
27  "darkblue",
28  "deeppink",
29  "chartreuse",
30  "green",
31  "orange",
32  "lime",
33  "black",
34  "tomato");
35  double min[] = { 0, 0 };
36  double max[] = { VueBoxSize, VueBoxSize };
37  private ArrayList<String> polylines= new ArrayList<>() ;
38  private ArrayList<String> groups= new ArrayList<>() ;
39  private ArrayList<String> layers= new ArrayList<>() ;
40  private int layerCounter = 1;
41  private int groupCounter = 1;
42  private int lineCounter=0;
43  private String name="";
44  public SVGExporter(){
45 
46  }
47  public String make(){
48  makeLayer();// make the final group
49  String output = "";
50  for(String s:layers){
51  output+=s+"\n";
52  }
53  double totalX = Math.abs(max[0]) + Math.abs(min[0]);
54  double totalY = Math.abs(max[1]) + Math.abs(min[1]);
55  double totalXmm = totalX/Scale;
56  double totalYmm = totalY/Scale;
57  String header = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
58  + "<svg xmlns:dc=\"http://purl.org/dc/elements/1.1/\""+
59  " xmlns:cc=\"http://creativecommons.org/ns#\""+
60  " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""+
61  " xmlns:svg=\"http://www.w3.org/2000/svg\""+
62  " xmlns=\"http://www.w3.org/2000/svg\""+
63  " xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\""+
64  " xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" version=\"1.1\"\n viewBox=\"" + (0 ) + " "
65  + (0) + " " + (totalX) + " "+
66  (totalY ) + "\""+
67  "\n id=\"svg2\" "+
68  "\n width=\""+totalXmm+"mm\""+
69  "\n height=\""+totalYmm+"mm\""+
70  ">\n";
71  header+= " <defs \n"+
72  " id=\"defs4\" /> \n"+
73  " <sodipodi:namedview \n"+
74  " id=\"base\" \n"+
75  " pagecolor=\"#ffffff\" \n"+
76  " bordercolor=\"#666666\" \n"+
77  " borderopacity=\"1.0\" \n"+
78  " inkscape:pageopacity=\"0.0\" \n"+
79  " inkscape:pageshadow=\"2\" \n"+
80  " inkscape:document-units=\"mm\" \n"+
81  " inkscape:current-layer=\"layer1\" \n"+
82  " showgrid=\"false\" \n"+
83  " />\n";
84 
85  output += footer;
86  output = header + output;
87  return output;
88  }
89 
90  private void colorTick(){
91  colorTicker++;
92  if(colorTicker==colorNames.size())
93  colorTicker=0;
94  makeLayer();
95  }
96 
97  public void makeGroup(){
98  if(polylines.size()==0)
99  return;
100  String groupsLine= "<g\nid=\"g37"+groupCounter+"\">\n"
101  ;
102  for(String p:polylines){
103  groupsLine+=p+"\n";
104  }
105  groupsLine+="</g>";
106  groupCounter++;
107  groups.add(groupsLine);
108  polylines.clear();
109  }
110  private void makeLayer(){
111  makeGroup();
112 // if(groups.size()==0)
113 // return;
114  String groupsLine="<g\n"+
115  "inkscape:label=\""+name+"Slice "+layerCounter+"\"\n"+
116  "inkscape:groupmode=\"layer\" \n"+
117  "id=\"layer"+layerCounter+"\" \n"+
118  ">"
119  ;
120  for(String p:groups){
121  groupsLine+=p+"\n";
122  }
123  groupsLine+="</g>";
124  layerCounter++;
125  layers.add(groupsLine);
126  groups.clear();
127  }
128 
129  private void toPolyLine(Polygon p){
130 
131  String color = colorNames.get(colorTicker);
132  String section = " <polyline points=\"";
133 
134  for (Vertex v : p.vertices) {
135  Vector3d position = v.pos.transformed(new Transform().rotX(180));
136  double x = (position.x * Scale);
137  double y = (position.y * Scale)+VueBoxSize;
138  section += x + "," + y + " ";
139  }
140  // Close loop
141  Vector3d position = p.vertices.get(0).pos.transformed(new Transform().rotX(180));
142  double x = (position.x * Scale);
143  double y = (position.y * Scale)+VueBoxSize;
144  section += x + "," + y + " ";
145  section= section + "\" \nstroke=\""+color+"\" \nstroke-width=\"1\" \nfill=\"none\"\nid=\"line"+(lineCounter++)+"\" />\n";
146  polylines.add(section);
147  }
148 
149 // public static void export(List<Polygon> polygons, File defaultDir) throws IOException {
150 // export(polygons,defaultDir,true);
151 // }
152  public static void export(List<Polygon> polygons, File defaultDir, boolean groupAll) throws IOException {
153  SVGExporter svg = new SVGExporter();
154 
155  for( Polygon p: polygons){
156  svg.toPolyLine(p);
157  if(!groupAll)
158  svg.colorTick();
159  }
160 
161  write(svg.make(), defaultDir);
162  }
163  private static void write(String output, File defaultDir) throws IOException{
164  // if file doesnt exists, then create it
165  if (!defaultDir.exists()) {
166  defaultDir.createNewFile();
167  }
168  FileWriter fw = new FileWriter(defaultDir.getAbsoluteFile());
169  BufferedWriter bw = new BufferedWriter(fw);
170  bw.write(output);
171  bw.close();
172  }
173  public static void export(CSG currentCsg, File defaultDir) throws IOException {
174  SVGExporter svg = new SVGExporter();
175  addCsg(currentCsg,svg);
176  write(svg.make(), defaultDir);
177  }
178  public static void export(List<CSG> currentCsg, File defaultDir) throws IOException {
179  try {
180  eu.mihosoft.vrl.v3d.JavaFXInitializer.go();
181  } catch (Throwable t) {
182  t.printStackTrace();
183  System.err.println("ERROR No UI engine availible");
184  }
185  if (!eu.mihosoft.vrl.v3d.JavaFXInitializer.errored) {
186  SVGExporter svg = new SVGExporter();
187  int i = 0;
188  long start = System.currentTimeMillis();
189  for (CSG tmp : currentCsg) {
190  System.out.println("Slicing CSG " + tmp.getName() + " " + (i + 1) + " of " + (currentCsg.size()));
191  addCsg(tmp, svg);
192  i++;
193  }
194 
195  write(svg.make(), defaultDir);
196  System.out.println("Finished slicing CSGs took "
197  + ((((double) (System.currentTimeMillis() - start))) / 1000.0) + " seconds");
198  } else {
199  System.err.println("ERROR No UI engine availible, SVG slicing is GPU accelerated and will not work");
200  }
201  }
202  private static void addCsg(CSG currentCsg, SVGExporter svg) throws IOException {
203  svg.setName(currentCsg.getName());
204  for(Transform slicePlane:currentCsg.getSlicePlanes()){
205  List<Polygon> polygons = Slice.slice(currentCsg.prepMfg(), slicePlane, 0);
206  for( Polygon p: polygons){
207  svg.toPolyLine(p );
208  }
209  svg.colorTick();// group the polygons from the single CSG together by layer
210  }
211 
212  }
213  private void setName(String name) {
214  if(name == null)
215  return;
216  this.name = name;
217  }
218 
219 }
final List< Vertex > vertices
Definition: Polygon.java:54
static List< Polygon > slice(CSG incoming, Transform slicePlane, double normalInsetDistance)
Definition: Slice.java:456
Transform rotX(double degrees)
Definition: Transform.java:106
static Vector3d y(double y)
Definition: Vector3d.java:484
Vector3d transformed(Transform transform)
Definition: Vector3d.java:361
static Vector3d x(double x)
Definition: Vector3d.java:474
static void export(List< Polygon > polygons, File defaultDir, boolean groupAll)
static void export(List< CSG > currentCsg, File defaultDir)
static void addCsg(CSG currentCsg, SVGExporter svg)
static void write(String output, File defaultDir)
static void export(CSG currentCsg, File defaultDir)