diff --git a/.gitignore b/.gitignore index 9a26149f..bb322015 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ html /SVGExportTest3.svg /SVGExportTest4.svg /SVGExportTest5.svg +/box.svg.png diff --git a/box.svg b/box.svg new file mode 100644 index 00000000..70a81d89 --- /dev/null +++ b/box.svg @@ -0,0 +1,287 @@ + + + + + + ABox + + + + Box - ABox + 2024-10-27 21:50:41 + https://boxes.hackerspace-bamberg.de/ABox?FingerJoint_style=rectangular&FingerJoint_surroundingspaces=2.0&FingerJoint_bottom_lip=0.0&FingerJoint_edge_width=1.0&FingerJoint_extra_length=0.0&FingerJoint_finger=2.0&FingerJoint_play=0.0&FingerJoint_space=2.0&FingerJoint_width=1.0&Lid_handle=none&Lid_style=none&Lid_handle_height=8.0&Lid_height=4.0&Lid_play=0.1&x=100.0&y=100.0&h=100.0&outside=0&outside=1&bottom_edge=h&thickness=3.0&format=svg&tabs=0.0&qr_code=0&debug=0&labels=0&labels=1&reference=100.0&inner_corners=loop&burn=0.1&language=en&render=1 + https://boxes.hackerspace-bamberg.de/ABox + A simple Box + +This box is kept simple on purpose. If you need more features have a look at the UniversalBox. + +Created with Boxes.py (https://boxes.hackerspace-bamberg.de/) +Command line: boxes ABox --FingerJoint_style=rectangular --FingerJoint_surroundingspaces=2.0 --FingerJoint_bottom_lip=0.0 --FingerJoint_edge_width=1.0 --FingerJoint_extra_length=0.0 --FingerJoint_finger=2.0 --FingerJoint_play=0.0 --FingerJoint_space=2.0 --FingerJoint_width=1.0 --Lid_handle=none --Lid_style=none --Lid_handle_height=8.0 --Lid_height=4.0 --Lid_play=0.1 --x=100.0 --y=100.0 --h=100.0 --outside=0 --outside=1 --bottom_edge=h --thickness=3.0 --format=svg --tabs=0.0 --qr_code=0 --debug=0 --labels=0 --labels=1 --reference=100.0 --inner_corners=loop --burn=0.1 +Command line short: boxes ABox +Url: https://boxes.hackerspace-bamberg.de/ABox?FingerJoint_style=rectangular&FingerJoint_surroundingspaces=2.0&FingerJoint_bottom_lip=0.0&FingerJoint_edge_width=1.0&FingerJoint_extra_length=0.0&FingerJoint_finger=2.0&FingerJoint_play=0.0&FingerJoint_space=2.0&FingerJoint_width=1.0&Lid_handle=none&Lid_style=none&Lid_handle_height=8.0&Lid_height=4.0&Lid_play=0.1&x=100.0&y=100.0&h=100.0&outside=0&outside=1&bottom_edge=h&thickness=3.0&format=svg&tabs=0.0&qr_code=0&debug=0&labels=0&labels=1&reference=100.0&inner_corners=loop&burn=0.1&language=en&render=1 +Url short: https://boxes.hackerspace-bamberg.de/ABox +SettingsUrl: https://boxes.hackerspace-bamberg.de/ABox?FingerJoint_style=rectangular&FingerJoint_surroundingspaces=2.0&FingerJoint_bottom_lip=0.0&FingerJoint_edge_width=1.0&FingerJoint_extra_length=0.0&FingerJoint_finger=2.0&FingerJoint_play=0.0&FingerJoint_space=2.0&FingerJoint_width=1.0&Lid_handle=none&Lid_style=none&Lid_handle_height=8.0&Lid_height=4.0&Lid_play=0.1&x=100.0&y=100.0&h=100.0&outside=0&outside=1&bottom_edge=h&thickness=3.0&format=svg&tabs=0.0&qr_code=0&debug=0&labels=0&labels=1&reference=100.0&inner_corners=loop&burn=0.1&language=en +SettingsUrl short: https://boxes.hackerspace-bamberg.de/ABox + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/eu/mihosoft/vrl/v3d/ext/org/poly2tri/PolygonUtil.java b/src/main/java/eu/mihosoft/vrl/v3d/ext/org/poly2tri/PolygonUtil.java index e3b71eea..cae27d9a 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/ext/org/poly2tri/PolygonUtil.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/ext/org/poly2tri/PolygonUtil.java @@ -48,6 +48,7 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.triangulate.polygon.ConstrainedDelaunayTriangulator; +import org.locationtech.jts.triangulate.polygon.PolygonTriangulator; /** * The Class PolygonUtil. @@ -109,17 +110,17 @@ public static List concaveToConvex(Polygon incoming) { return result; Polygon concave = incoming; Vector3d normalOfPlane = incoming.plane.getNormal(); - boolean reorent = normalOfPlane.z < 1.0-Plane.EPSILON; + boolean reorent = normalOfPlane.z < 1.0 - Plane.EPSILON; Transform orentationInv = null; boolean debug = false; if (reorent) { - double degreesToRotate = Math.toDegrees(Math.atan2(normalOfPlane.x,normalOfPlane.z)); + double degreesToRotate = Math.toDegrees(Math.atan2(normalOfPlane.x, normalOfPlane.z)); Transform orentation = new Transform().roty(degreesToRotate); Polygon tmp = incoming.transformed(orentation); - + Vector3d normal = tmp.plane.getNormal(); - double degreesToRotate2 =90+Math.toDegrees(Math.atan2(normal.z,normal.y)); + double degreesToRotate2 = 90 + Math.toDegrees(Math.atan2(normal.z, normal.y)); Transform orentation2 = orentation.rotx(degreesToRotate2);// th triangulation function needs // the polygon on the xy plane if (debug) { @@ -128,51 +129,63 @@ public static List concaveToConvex(Polygon incoming) { } concave = incoming.transformed(orentation2); orentationInv = orentation2.inverse(); - if(concave.plane.getNormal().z <0) { + if (concave.plane.getNormal().z < 0) { Transform orentation3 = orentation2.rotx(180); concave = incoming.transformed(orentation3); orentationInv = orentation3.inverse(); } } - Vector3d normal = concave.plane.getNormal().clone(); boolean cw = !Extrude.isCCW(concave); - //concave = Extrude.toCCW(concave); + // concave = Extrude.toCCW(concave); if (debug) { Debug3dProvider.clearScreen(); Debug3dProvider.addObject(concave); - //Debug3dProvider.clearScreen(); + // Debug3dProvider.clearScreen(); } - - Coordinate[] coordinates = new Coordinate[concave.vertices.size()+1]; - double zplane =concave.vertices.get(0).pos.z; - for(int i=0;i triPoints = new ArrayList<>(); - for (int i=0;i concaveToConvex(Polygon incoming) { Collections.reverse(triPoints); } Polygon poly = new Polygon(triPoints, concave.getStorage(), true); - //poly = Extrude.toCCW(poly); + // poly = Extrude.toCCW(poly); poly.plane.setNormal(concave.plane.getNormal()); boolean b = !Extrude.isCCW(poly); if (cw != b) { @@ -191,15 +204,15 @@ public static List concaveToConvex(Polygon incoming) { poly = new Polygon(triPoints, concave.getStorage(), true); b = !Extrude.isCCW(poly); if (cw != b) { - //com.neuronrobotics.sdk.common.Log.error("Error, polygon is reversed!"); + // com.neuronrobotics.sdk.common.Log.error("Error, polygon is reversed!"); } } if (debug) { - //Debug3dProvider.clearScreen(); - //Debug3dProvider.addObject(concave); + // Debug3dProvider.clearScreen(); + // Debug3dProvider.addObject(concave); Debug3dProvider.addObject(poly); } - + if (reorent) { poly = poly.transform(orentationInv); } @@ -324,7 +337,7 @@ public static Polygon pruneDuplicatePoints(Polygon incoming) { Vertex v = incoming.vertices.get(i); boolean duplicate = false; for (Vertex vx : newPoints) { - if (vx.pos.test(v.pos, Plane.EPSILON_duplicate)) { + if (vx.pos.test(v.pos, Plane.EPSILON_duplicate)) { duplicate = true; } } @@ -333,9 +346,9 @@ public static Polygon pruneDuplicatePoints(Polygon incoming) { } } - if(newPoints.size()<3) + if (newPoints.size() < 3) return null; - + return new Polygon(newPoints); } diff --git a/src/main/java/eu/mihosoft/vrl/v3d/svg/SVGLoad.java b/src/main/java/eu/mihosoft/vrl/v3d/svg/SVGLoad.java index 4a7830c6..36bc7987 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/svg/SVGLoad.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/svg/SVGLoad.java @@ -1,7 +1,5 @@ package eu.mihosoft.vrl.v3d.svg; - - import org.apache.batik.anim.dom.SAXSVGDocumentFactory; import org.apache.batik.anim.dom.SVGOMGElement; import org.apache.batik.anim.dom.SVGOMImageElement; @@ -51,9 +49,9 @@ public class SVGLoad { private static final String GROUP_ELEMENT_NAME = "g"; private Document svgDocument; boolean hp = true; - private HashMap> polygonByLayers = null; - private HashMap> csgByLayers = new HashMap>(); - private HashMap colors=new HashMap<>(); + private HashMap> polygonByLayers = null; + private HashMap> csgByLayers = new HashMap>(); + private HashMap colors = new HashMap<>(); // private ArrayList sections = null; // private ArrayList holes = null; // @@ -63,8 +61,8 @@ public class SVGLoad { private boolean negativeThickness = false; private double height = 0; private double width = 0; - private Double scale=null; - private HashMap units=new HashMap<>(); + private Double scale = null; + private HashMap units = new HashMap<>(); // static { // units.put("mm", (1/SVGExporter.Scale)); // units.put("px", 1.0); @@ -74,42 +72,45 @@ public class SVGLoad { // units.put("m", units.get("mm")/1000.0); // // } - - private double toPx(String value) { - for(String key : units.keySet()) { - if(value.endsWith(key)) { - String []split = value.split(key); - if(key.contentEquals("m")&& split.length>1) { + private double toPx(String value) { + + for (String key : units.keySet()) { + if (value.endsWith(key)) { + String[] split = value.split(key); + if (key.contentEquals("m") && split.length > 1) { // meters but not meters units break; } - ////com.neuronrobotics.sdk.common.Log.error("Units set to "+key+" for "+value); - return Double.parseDouble(split[0])/ units.get(key); + //// com.neuronrobotics.sdk.common.Log.error("Units set to "+key+" for "+value); + return Double.parseDouble(split[0]) / units.get(key); } } return Double.parseDouble(value); } + private void setScale(double value) { - - scale=value; - if(scale.isInfinite()||scale.isNaN()) + + scale = value; + if (scale.isInfinite() || scale.isNaN()) throw new RuntimeException("Scale must be real number"); - units.put("mm", (1/getScale())); + units.put("mm", (1 / getScale())); units.put("px", 1.0); - units.put("cm", units.get("mm")/10.0); - units.put("in", units.get("mm")/25.4); - units.put("ft", units.get("in")/12.0); - units.put("m", units.get("mm")/1000.0); + units.put("cm", units.get("mm") / 10.0); + units.put("in", units.get("mm") / 25.4); + units.put("ft", units.get("in") / 12.0); + units.put("m", units.get("mm") / 1000.0); } + private Double getScale() { return scale.doubleValue(); } - - private double toMM(String value) { - Double px= toPx(value); - return px*1/getScale(); + + private double toMM(String value) { + Double px = toPx(value); + return px * 1 / getScale(); } + private static ISVGLoadProgress progressDefault = new ISVGLoadProgress() { @Override @@ -136,9 +137,8 @@ class MetaPostPath2 { * Use to create an instance of a class that can parse an SVG path element to * produce MetaPost code. * - * @param pathNode - * The path node containing a "d" attribute (output as MetaPost - * code). + * @param pathNode The path node containing a "d" attribute (output as MetaPost + * code). */ public MetaPostPath2(Node pathNode) { setPathNode(pathNode); @@ -174,9 +174,8 @@ public String toCode() { /** * Typecasts the given pathNode to an SVGOMPathElement for later analysis. * - * @param pathNode - * The path element that contains curves, lines, and other SVG - * instructions. + * @param pathNode The path element that contains curves, lines, and other SVG + * instructions. */ private void setPathNode(Node pathNode) { this.pathElement = (SVGOMPathElement) pathNode; @@ -196,10 +195,8 @@ private SVGOMPathElement getPathElement() { /** * Creates an SVG Document given a URI. * - * @param uri - * Path to the file. - * @throws Exception - * Something went wrong parsing the SVG file. + * @param uri Path to the file. + * @throws Exception Something went wrong parsing the SVG file. */ public SVGLoad(URI uri) throws IOException { setSVGDocument(createSVGDocument(uri)); @@ -208,10 +205,8 @@ public SVGLoad(URI uri) throws IOException { /** * Creates an SVG Document given a URI. * - * @param f - * Path to the file. - * @throws Exception - * Something went wrong parsing the SVG file. + * @param f Path to the file. + * @throws Exception Something went wrong parsing the SVG file. */ public SVGLoad(File f) throws IOException { setSVGDocument(createSVGDocument(f.toURI())); @@ -220,10 +215,8 @@ public SVGLoad(File f) throws IOException { /** * Creates an SVG Document String of SVG data. * - * @param data - * Contents of an svg file - * @throws Exception - * Something went wrong parsing the SVG file. + * @param data Contents of an svg file + * @throws Exception Something went wrong parsing the SVG file. */ public SVGLoad(String data) throws IOException { File tmpsvg = new File(System.getProperty("java.io.tmpdir") + "/" + Math.random()); @@ -251,18 +244,17 @@ public static ArrayList extrude(File f, double thickness) throws IOExceptio * This function will create a list of polygons that can be exported back to an * SVG * - * @param f - * the file containing the SVG data + * @param f the file containing the SVG data * @return * @throws IOException */ - public static HashMap> toPolygons(File f) throws IOException { + public static HashMap> toPolygons(File f) throws IOException { return new SVGLoad(f.toURI()).toPolygons(); } - public HashMap> toPolygons(double resolution) { - if(polygonByLayers==null) + public HashMap> toPolygons(double resolution) { + if (polygonByLayers == null) try { loadAllGroups(resolution, new Transform()); } catch (Exception e) { @@ -273,7 +265,7 @@ public HashMap> toPolygons(double resolution) { return getPolygonByLayers(); } - public HashMap> toPolygons() { + public HashMap> toPolygons() { return toPolygons(0.001); } @@ -292,37 +284,39 @@ public static ArrayList extrude(URI uri, double thickness, double resolutio } private void loadAllGroups(double resolution, Transform startingFrame) { - + NodeList pn = getSVGDocument().getDocumentElement().getChildNodes();// .getElementsByTagName("g"); try { String hval = getSVGDocument().getDocumentElement().getAttribute("height"); String wval = getSVGDocument().getDocumentElement().getAttribute("width"); String viewbox = getSVGDocument().getDocumentElement().getAttribute("viewBox"); double viewW = Double.parseDouble(viewbox.split(" ")[2]); - setScale( 1);// use to compute bounds + setScale(1);// use to compute bounds height = toMM(hval); width = toMM(wval); - double value =viewW/width; - ////com.neuronrobotics.sdk.common.Log.error("Page size height = "+height+" width ="+width+" with scale "+(int)(value*25.4)+" DPI "); - setScale( value); + double value = viewW / width; + //// com.neuronrobotics.sdk.common.Log.error("Page size height = "+height+" + //// width ="+width+" with scale "+(int)(value*25.4)+" DPI "); + setScale(value); } catch (Throwable t) { t.printStackTrace(); height = 0; width = 0; - setScale( 3.543307); // Assume 90 DPI and mm + setScale(3.543307); // Assume 90 DPI and mm } // println "Loading groups from "+pn.getClass() int pnCount = pn.getLength(); for (int j = 0; j < pnCount; j++) { Node item = pn.item(j); - ////com.neuronrobotics.sdk.common.Log.error("\tTOP LEVEL :"+item); + //// com.neuronrobotics.sdk.common.Log.error("\tTOP LEVEL :"+item); if (SVGOMGElement.class.isInstance(item)) { - + SVGOMGElement element = (SVGOMGElement) item; - loadGroup(element, resolution, startingFrame,null); - } if(SVGOMPathElement.class.isInstance(item) || SVGOMImageElement.class.isInstance(item)) { + loadGroup(element, resolution, startingFrame, null); + } + if (SVGOMPathElement.class.isInstance(item) || SVGOMImageElement.class.isInstance(item)) { try { - loadPath(item, resolution, startingFrame,"TOP"); + loadPath(item, resolution, startingFrame, "TOP"); } catch (Throwable t) { t.printStackTrace(); @@ -332,34 +326,38 @@ private void loadAllGroups(double resolution, Transform startingFrame) { } - private void loadGroup(SVGOMGElement element, double resolution, Transform startingFrame, String encapsulatingLayer) { + private void loadGroup(SVGOMGElement element, double resolution, Transform startingFrame, + String encapsulatingLayer) { Node transforms = element.getAttributes().getNamedItem("transform"); Transform newFrame = getNewframe(startingFrame, transforms); String layername; - + try { - layername=element.getAttributeNS("http://www.inkscape.org/namespaces/inkscape", "label"); - if(layername==null|| layername.length()==0) + layername = element.getAttributeNS("http://www.inkscape.org/namespaces/inkscape", "label"); + if (layername == null || layername.length() == 0) throw new RuntimeException(); - }catch (Throwable t) { - layername=null; + } catch (Throwable t) { + layername = null; } - if(layername==null) { - layername=encapsulatingLayer; - }else { - ////com.neuronrobotics.sdk.common.Log.error("Updated to layer "+layername+" from "+encapsulatingLayer); + if (layername == null) { + layername = encapsulatingLayer; + } else { + //// com.neuronrobotics.sdk.common.Log.error("Updated to layer "+layername+" + //// from "+encapsulatingLayer); } - ////com.neuronrobotics.sdk.common.Log.error("\tGroup " + element.getAttribute("id") +"\n\t inkscape name: "+layername+ " \n\t root " + newFrame.getX() + " " + newFrame.getY()); - + //// com.neuronrobotics.sdk.common.Log.error("\tGroup " + + //// element.getAttribute("id") +"\n\t inkscape name: "+layername+ " \n\t root " + //// + newFrame.getX() + " " + newFrame.getY()); + NodeList children = element.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node n = children.item(i); if (SVGOMGElement.class.isInstance(n)) { - loadGroup((SVGOMGElement) n, resolution, newFrame,layername); + loadGroup((SVGOMGElement) n, resolution, newFrame, layername); } else { - ////com.neuronrobotics.sdk.common.Log.error("\tNot group:"+n); + //// com.neuronrobotics.sdk.common.Log.error("\tNot group:"+n); try { - loadPath(n, resolution, newFrame,layername); + loadPath(n, resolution, newFrame, layername); } catch (Throwable t) { t.printStackTrace(); @@ -373,26 +371,26 @@ private Transform getNewframe(Transform startingFrame, Node transforms) { return startingFrame; Transform newFrame = new Transform().apply(startingFrame); String transformValue = transforms.getNodeValue(); - ////com.neuronrobotics.sdk.common.Log.error("\tApply " + transformValue + " root " + startingFrame.getX() + " " + startingFrame.getY()); + //// com.neuronrobotics.sdk.common.Log.error("\tApply " + transformValue + " + //// root " + startingFrame.getX() + " " + startingFrame.getY()); if (transformValue.contains("translate")) { String[] transformValues = transformValue.replaceAll("translate", "").replaceAll("\\(", "") .replaceAll("\\)", "").split("\\,"); - newFrame.apply(new Transform().translate(toPx(transformValues[0]), - toPx(transformValues[1]), 0)); + newFrame.apply(new Transform().translate(toPx(transformValues[0]), toPx(transformValues[1]), 0)); - }else if (transformValue.contains("rotate")) { - String[] rotvals = transformValue.replaceAll("rotate", "").replaceAll("\\(", "") - .replaceAll("\\)", "").split("\\,"); - newFrame= startingFrame.inverse() - .apply(new Transform().rotZ(-Double.parseDouble(rotvals[0]))) + } else if (transformValue.contains("rotate")) { + String[] rotvals = transformValue.replaceAll("rotate", "").replaceAll("\\(", "").replaceAll("\\)", "") + .split("\\,"); + newFrame = startingFrame.inverse().apply(new Transform().rotZ(-Double.parseDouble(rotvals[0]))) .apply(startingFrame); - } else if (transformValue.contains("scale")) { + } else if (transformValue.contains("scale")) { String[] transformValues = transformValue.replaceAll("scale", "").replaceAll("\\(", "") .replaceAll("\\)", "").split("\\,"); - // //com.neuronrobotics.sdk.common.Log.error(id.getNodeValue() + " " + transformValues); + // //com.neuronrobotics.sdk.common.Log.error(id.getNodeValue() + " " + + // transformValues); double scalex = toPx(transformValues[0]); - double scaley = toPx(transformValues.length==2?transformValues[1]:transformValues[0]); + double scaley = toPx(transformValues.length == 2 ? transformValues[1] : transformValues[0]); newFrame.scale(scalex, scaley, 1); } else if (transformValue.contains("matrix")) { @@ -421,18 +419,17 @@ private void loadPath(Node pathNode, double resolution, Transform startingFrame, if (pathNode != null) { // //com.neuronrobotics.sdk.common.Log.error("\tPath // "+pathNode.getAttributes().getNamedItem("id").getNodeValue()); - ////com.neuronrobotics.sdk.common.Log.error("Path loading "+pathNode); - + //// com.neuronrobotics.sdk.common.Log.error("Path loading "+pathNode); - newFrame = startingFrame; - try { - Node transforms = pathNode.getAttributes().getNamedItem("transform"); - newFrame = getNewframe(startingFrame, transforms); - }catch(Exception ex) { - // no transform - } - try { - if(SVGOMPathElement.class.isInstance(pathNode)) { + newFrame = startingFrame; + try { + Node transforms = pathNode.getAttributes().getNamedItem("transform"); + newFrame = getNewframe(startingFrame, transforms); + } catch (Exception ex) { + // no transform + } + try { + if (SVGOMPathElement.class.isInstance(pathNode)) { // NamedNodeMap attribs = pathNode.getAttributes(); // for(int i=0;i 1) { // println "Seperated complex: " - loadSingle(sectionedPart, resolution, startingFrame,encapsulatingLayer, c); + loadSingle(sectionedPart, resolution, startingFrame, encapsulatingLayer, c); } } } - // //com.neuronrobotics.sdk.common.Log.error("SVG has this many elements loaded: "+sections.size()); + // //com.neuronrobotics.sdk.common.Log.error("SVG has this many elements loaded: + // "+sections.size()); // BowlerStudioController.setCsg(sections,null); } + public static boolean isCCW(Polygon polygon) { - double runningTotal=0; + double runningTotal = 0; List edges = Edge.fromPolygon(polygon); - for(Edge e:edges) { - //runningTotal+=((e.getP1().pos.x-e.getP2().pos.x)*(e.getP1().pos.y-e.getP2().pos.y)); - runningTotal+=e.getP1().pos.x*e.getP2().pos.y; - runningTotal-=e.getP2().pos.x*e.getP1().pos.y; + for (Edge e : edges) { + // runningTotal+=((e.getP1().pos.x-e.getP2().pos.x)*(e.getP1().pos.y-e.getP2().pos.y)); + runningTotal += e.getP1().pos.x * e.getP2().pos.y; + runningTotal -= e.getP2().pos.x * e.getP1().pos.y; } - - return runningTotal<0; + + return runningTotal < 0; } - private void loadSingle(String code, double resolution, Transform startingFrame, String encapsulatingLayer, Color c) { + + private void loadSingle(String code, double resolution, Transform startingFrame, String encapsulatingLayer, + Color c) { // println code BezierPath path = new BezierPath(); path.parsePathString(code); - + ArrayList p = path.evaluate(); for (Vector3d point : p) { point.transform(startingFrame); @@ -636,39 +638,44 @@ private void loadSingle(String code, double resolution, Transform startingFrame, // //com.neuronrobotics.sdk.common.Log.error(" Path " + code); Polygon poly = Polygon.fromPoints(p); - if(getPolygonByLayers()==null) + if (getPolygonByLayers() == null) setPolygonByLayers(new HashMap>()); if (getPolygonByLayers().get(encapsulatingLayer) == null) getPolygonByLayers().put(encapsulatingLayer, new ArrayList()); - List list = getPolygonByLayers().get(encapsulatingLayer); + List list = getPolygonByLayers().get(encapsulatingLayer); poly = Polygon.fromPoints(Extrude.toCCW(poly.getPoints())); - if(c!=null) + if (c != null) colors.put(poly, c); list.add(poly); } - public List getLayers(){ - ArrayList layers= new ArrayList(); - if(getPolygonByLayers()==null) { + + public List getLayers() { + ArrayList layers = new ArrayList(); + if (getPolygonByLayers() == null) { toPolygons(); } - for(Object key:getPolygonByLayers().keySet().stream().sorted().toArray() ) + for (Object key : getPolygonByLayers().keySet().stream().sorted().toArray()) layers.add((String) key); return layers; } - public CSG extrudeLayerToCSG(double t,String layer){ - CSG unionAll = CSG.unionAll(extrudeLayers(t,0.01,layer).get(layer)); + + public CSG extrudeLayerToCSG(double t, String layer) { + CSG unionAll = CSG.unionAll(extrudeLayers(t, 0.01, layer).get(layer)); unionAll.setName(layer); - + return unionAll; } - public ArrayList extrudeLayer(double t,String layer){ - return extrudeLayers(t,0.01,layer).get(layer); + + public ArrayList extrudeLayer(double t, String layer) { + return extrudeLayers(t, 0.01, layer).get(layer); } - public HashMap> extrudeLayers(double t){ - return extrudeLayers(t,0.01,null); + + public HashMap> extrudeLayers(double t) { + return extrudeLayers(t, 0.01, null); } - public HashMap> extrudeLayers(double t, double resolution, String targetLayer){ + + public HashMap> extrudeLayers(double t, double resolution, String targetLayer) { this.thickness = t; if (thickness < 0) { @@ -679,54 +686,54 @@ public HashMap> extrudeLayers(double t, double resolution, } toPolygons(0.001); - - for(String key: getPolygonByLayers().keySet()) { - if(targetLayer!=null) - if(!targetLayer.contentEquals(key)) + + for (String key : getPolygonByLayers().keySet()) { + if (targetLayer != null) + if (!targetLayer.contentEquals(key)) continue; - if(csgByLayers.get(key)==null) { + if (csgByLayers.get(key) == null) { csgByLayers.put(key, new ArrayList()); } ArrayList parts = csgByLayers.get(key); parts.clear(); - for(Polygon p:getPolygonByLayers().get(key)) { + for (Polygon p : getPolygonByLayers().get(key)) { CSG newbit; - newbit = Extrude.getExtrusionEngine().extrude(new Vector3d(0, 0, thickness), p); - if (negativeThickness) { - newbit = newbit.toZMax(); - } - if(colors.get(p)!=null) { - newbit.setColor(colors.get(p)); + try { + newbit = Extrude.getExtrusionEngine().extrude(new Vector3d(0, 0, thickness), p); + if (negativeThickness) { + newbit = newbit.toZMax(); + } + if (colors.get(p) != null) { + newbit.setColor(colors.get(p)); + } + parts.add(newbit); + } catch (Exception ex) { + ex.printStackTrace(); } - parts.add(newbit); } } - + return csgByLayers; } public ArrayList extrude(double t, double resolution) throws IOException { - - HashMap> layers =extrudeLayers( t, resolution,null); + HashMap> layers = extrudeLayers(t, resolution, null); ArrayList all = new ArrayList(); - for(String key:layers.keySet()) { + for (String key : layers.keySet()) { all.addAll(layers.get(key)); } - - + return all; } - /** * This will set the document to parse. This method also initializes the SVG DOM * enhancements, which are necessary to perform SVG and CSS manipulations. The * initialization is also required to extract information from the SVG path * elements. * - * @param document - * The document that contains SVG content. + * @param document The document that contains SVG content. */ public void setSVGDocument(Document document) { initSVGDOM(document); @@ -746,8 +753,7 @@ public Document getSVGDocument() { * Enhance the SVG DOM for the given document to provide CSS- and SVG-specific * DOM interfaces. * - * @param document - * The document to enhance. + * @param document The document to enhance. * @link http://wiki.apache.org/xmlgraphics-batik/BootSvgAndCssDom */ private void initSVGDOM(Document document) { @@ -763,11 +769,9 @@ private void initSVGDOM(Document document) { /** * Use the SAXSVGDocumentFactory to parse the given URI into a DOM. * - * @param uri - * The path to the SVG file to read. + * @param uri The path to the SVG file to read. * @return A Document instance that represents the SVG file. - * @throws Exception - * The file could not be read. + * @throws Exception The file could not be read. */ private Document createSVGDocument(URI uri) throws IOException { String parser = XMLResourceDescriptor.getXMLParserClassName(); @@ -786,13 +790,13 @@ public void setProgress(ISVGLoadProgress progress) { public static ISVGLoadProgress getProgressDefault() { return progressDefault; } - - private HashMap> getPolygonByLayers() { + + private HashMap> getPolygonByLayers() { return polygonByLayers; } - private void setPolygonByLayers(HashMap> polygonByLayers) { + + private void setPolygonByLayers(HashMap> polygonByLayers) { this.polygonByLayers = polygonByLayers; } - } diff --git a/src/test/java/eu/mihosoft/vrl/v3d/SVGLoadTest.java b/src/test/java/eu/mihosoft/vrl/v3d/SVGLoadTest.java index 6ab3af1f..1932743f 100644 --- a/src/test/java/eu/mihosoft/vrl/v3d/SVGLoadTest.java +++ b/src/test/java/eu/mihosoft/vrl/v3d/SVGLoadTest.java @@ -15,6 +15,24 @@ import javafx.scene.shape.CullFace; public class SVGLoadTest { + @Test + public void box() throws IOException { + JavaFXInitializer.go(); + File svg = new File("box.svg"); + if (!svg.exists()) + throw new RuntimeException("Test file missing!" + svg.getAbsolutePath()); + SVGLoad s = new SVGLoad(svg.toURI()); + ArrayListparts =run(s); + try { + ThumbnailImage.setCullFaceValue(CullFace.NONE); + ThumbnailImage.writeImage(parts,new File(svg.getAbsolutePath()+".png")).join(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + // fail("Not yet implemented"); + } @Test public void adversarial() throws IOException { JavaFXInitializer.go();