11/**
22 * CSG.java
33 *
4- * Copyright 2014-2014 Michael Hoffer <info@michaelhoffer.de>. All rights
5- * reserved.
4+ * Copyright 2014-2014 Michael Hoffer <info@michaelhoffer.de>. All rights reserved.
65 *
7- * Redistribution and use in source and binary forms, with or without
8- * modification, are permitted provided that the following conditions are met:
6+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
7+ * following conditions are met:
98 *
10- * 1. Redistributions of source code must retain the above copyright notice,
11- * this list of conditions and the following disclaimer.
9+ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
10+ * disclaimer.
1211 *
13- * 2. Redistributions in binary form must reproduce the above copyright notice,
14- * this list of conditions and the following disclaimer in the documentation
15- * and/or other materials provided with the distribution.
12+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
13+ * following disclaimer in the documentation and/or other materials provided with the distribution.
1614 *
17- * THIS SOFTWARE IS PROVIDED BY Michael Hoffer <info@michaelhoffer.de> "AS IS"
18- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20- * ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer <info@michaelhoffer.de> OR
21- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15+ * THIS SOFTWARE IS PROVIDED BY Michael Hoffer <info@michaelhoffer.de> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+ * DISCLAIMED. IN NO EVENT SHALL Michael Hoffer <info@michaelhoffer.de> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
21+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2822 *
29- * The views and conclusions contained in the software and documentation are
30- * those of the authors and should not be interpreted as representing official
31- * policies, either expressed or implied, of Michael Hoffer
23+ * The views and conclusions contained in the software and documentation are those of the authors and should not be
24+ * interpreted as representing official policies, either expressed or implied, of Michael Hoffer
3225 * <info@michaelhoffer.de>.
3326 */
3427package eu .mihosoft .jcsg ;
3528
29+ import static eu .mihosoft .jcsg .STL .file ;
3630import eu .mihosoft .vvecmath .Vector3d ;
3731import eu .mihosoft .vvecmath .Transform ;
3832import eu .mihosoft .jcsg .ext .quickhull3d .HullUtil ;
33+ import java .io .BufferedWriter ;
34+ import java .io .File ;
35+ import java .io .FileWriter ;
36+ import java .io .IOException ;
3937
4038import java .util .ArrayList ;
4139import java .util .Arrays ;
4240import java .util .HashMap ;
4341import java .util .List ;
4442import java .util .Map ;
43+ import java .util .logging .Level ;
44+ import java .util .logging .Logger ;
4545import java .util .stream .Collectors ;
4646import java .util .stream .Stream ;
4747import javafx .scene .paint .Color ;
5353 * This implementation is a Java port of
5454 * <a
5555 * href="https://github.com/evanw/csg.js/">https://github.com/evanw/csg.js/</a>
56- * with some additional features like polygon extrude, transformations etc.
57- * Thanks to the author for creating the CSG.js library.<br><br>
56+ * with some additional features like polygon extrude, transformations etc. Thanks to the author for creating the CSG.js
57+ * library.<br><br>
5858 *
5959 * <b>Implementation Details</b>
6060 *
61- * All CSG operations are implemented in terms of two functions,
62- * {@link Node#clipTo(Node)} and {@link Node#invert()}, which remove parts of a
63- * BSP tree inside another BSP tree and swap solid and empty space,
64- * respectively. To find the union of {@code a} and {@code b}, we want to remove
65- * everything in {@code a} inside {@code b} and everything in {@code b} inside
66- * {@code a}, then combine polygons from {@code a} and {@code b} into one solid:
61+ * All CSG operations are implemented in terms of two functions, {@link Node#clipTo(Node)} and {@link Node#invert()},
62+ * which remove parts of a BSP tree inside another BSP tree and swap solid and empty space, respectively. To find the
63+ * union of {@code a} and {@code b}, we want to remove everything in {@code a} inside {@code b} and everything in
64+ * {@code b} inside {@code a}, then combine polygons from {@code a} and {@code b} into one solid:
6765 *
6866 * <blockquote><pre>
6967 * a.clipTo(b);
7068 * b.clipTo(a);
7169 * a.build(b.allPolygons());
7270 * </pre></blockquote>
7371 *
74- * The only tricky part is handling overlapping coplanar polygons in both trees.
75- * The code above keeps both copies, but we need to keep them in one tree and
76- * remove them in the other tree. To remove them from {@code b} we can clip the
77- * inverse of {@code b} against {@code a}. The code for union now looks like
78- * this:
72+ * The only tricky part is handling overlapping coplanar polygons in both trees. The code above keeps both copies, but
73+ * we need to keep them in one tree and remove them in the other tree. To remove them from {@code b} we can clip the
74+ * inverse of {@code b} against {@code a}. The code for union now looks like this:
7975 *
8076 * <blockquote><pre>
8177 * a.clipTo(b);
8682 * a.build(b.allPolygons());
8783 * </pre></blockquote>
8884 *
89- * Subtraction and intersection naturally follow from set operations. If union
90- * is {@code A | B}, differenceion is {@code A - B = ~(~A | B)} and intersection
91- * is {@code A & B =
85+ * Subtraction and intersection naturally follow from set operations. If union is {@code A | B}, differenceion is
86+ * {@code A - B = ~(~A | B)} and intersection is {@code A & B =
9287 * ~(~A | ~B)} where {@code ~} is the complement operator.
9388 */
9489public class CSG {
@@ -203,8 +198,7 @@ public CSG optimization(OptType type) {
203198 }
204199
205200 /**
206- * Return a new CSG solid representing the union of this csg and the
207- * specified csg.
201+ * Return a new CSG solid representing the union of this csg and the specified csg.
208202 *
209203 * <b>Note:</b> Neither this csg nor the specified csg are weighted.
210204 *
@@ -240,20 +234,17 @@ public CSG union(CSG csg) {
240234 }
241235
242236 /**
243- * Returns a csg consisting of the polygons of this csg and the specified
244- * csg.
237+ * Returns a csg consisting of the polygons of this csg and the specified csg.
245238 *
246- * The purpose of this method is to allow fast union operations for objects
247- * that do not intersect.
239+ * The purpose of this method is to allow fast union operations for objects that do not intersect.
248240 *
249241 * <p>
250- * <b>WARNING:</b> this method does not apply the csg algorithms. Therefore,
251- * please ensure that this csg and the specified csg do not intersect.
242+ * <b>WARNING:</b> this method does not apply the csg algorithms. Therefore, please ensure that this csg and the
243+ * specified csg do not intersect.
252244 *
253245 * @param csg csg
254246 *
255- * @return a csg consisting of the polygons of this csg and the specified
256- * csg
247+ * @return a csg consisting of the polygons of this csg and the specified csg
257248 */
258249 public CSG dumbUnion (CSG csg ) {
259250
@@ -266,8 +257,7 @@ public CSG dumbUnion(CSG csg) {
266257 }
267258
268259 /**
269- * Return a new CSG solid representing the union of this csg and the
270- * specified csgs.
260+ * Return a new CSG solid representing the union of this csg and the specified csgs.
271261 *
272262 * <b>Note:</b> Neither this csg nor the specified csg are weighted.
273263 *
@@ -301,8 +291,7 @@ public CSG union(List<CSG> csgs) {
301291 }
302292
303293 /**
304- * Return a new CSG solid representing the union of this csg and the
305- * specified csgs.
294+ * Return a new CSG solid representing the union of this csg and the specified csgs.
306295 *
307296 * <b>Note:</b> Neither this csg nor the specified csg are weighted.
308297 *
@@ -414,9 +403,8 @@ private CSG _unionPolygonBoundsOpt(CSG csg) {
414403 }
415404
416405 /**
417- * Optimizes for intersection. If csgs do not intersect create a new csg
418- * that consists of the polygon lists of this csg and the specified csg. In
419- * this case no further space partitioning is performed.
406+ * Optimizes for intersection. If csgs do not intersect create a new csg that consists of the polygon lists of this
407+ * csg and the specified csg. In this case no further space partitioning is performed.
420408 *
421409 * @param csg csg
422410 * @return the union of this csg and the specified csg
@@ -458,8 +446,7 @@ private CSG _unionNoOpt(CSG csg) {
458446 }
459447
460448 /**
461- * Return a new CSG solid representing the difference of this csg and the
462- * specified csgs.
449+ * Return a new CSG solid representing the difference of this csg and the specified csgs.
463450 *
464451 * <b>Note:</b> Neither this csg nor the specified csgs are weighted.
465452 *
@@ -495,8 +482,7 @@ public CSG difference(List<CSG> csgs) {
495482 }
496483
497484 /**
498- * Return a new CSG solid representing the difference of this csg and the
499- * specified csgs.
485+ * Return a new CSG solid representing the difference of this csg and the specified csgs.
500486 *
501487 * <b>Note:</b> Neither this csg nor the specified csgs are weighted.
502488 *
@@ -522,8 +508,7 @@ public CSG difference(CSG... csgs) {
522508 }
523509
524510 /**
525- * Return a new CSG solid representing the difference of this csg and the
526- * specified csg.
511+ * Return a new CSG solid representing the difference of this csg and the specified csg.
527512 *
528513 * <b>Note:</b> Neither this csg nor the specified csg are weighted.
529514 *
@@ -606,8 +591,7 @@ private CSG _differenceNoOpt(CSG csg) {
606591 }
607592
608593 /**
609- * Return a new CSG solid representing the intersection of this csg and the
610- * specified csg.
594+ * Return a new CSG solid representing the intersection of this csg and the specified csg.
611595 *
612596 * <b>Note:</b> Neither this csg nor the specified csg are weighted.
613597 *
@@ -643,8 +627,7 @@ public CSG intersect(CSG csg) {
643627 }
644628
645629 /**
646- * Return a new CSG solid representing the intersection of this csg and the
647- * specified csgs.
630+ * Return a new CSG solid representing the intersection of this csg and the specified csgs.
648631 *
649632 * <b>Note:</b> Neither this csg nor the specified csgs are weighted.
650633 *
@@ -681,8 +664,7 @@ public CSG intersect(List<CSG> csgs) {
681664 }
682665
683666 /**
684- * Return a new CSG solid representing the intersection of this csg and the
685- * specified csgs.
667+ * Return a new CSG solid representing the intersection of this csg and the specified csgs.
686668 *
687669 * <b>Note:</b> Neither this csg nor the specified csgs are weighted.
688670 *
@@ -719,6 +701,7 @@ public String toStlString() {
719701 return sb .toString ();
720702 }
721703
704+
722705 /**
723706 * Returns this csg in STL string format.
724707 *
@@ -755,8 +738,8 @@ public ObjFile toObj() {
755738 }
756739
757740 public ObjFile toObj (int maxNumberOfVerts ) {
758-
759- if (maxNumberOfVerts != 3 ) {
741+
742+ if (maxNumberOfVerts != 3 ) {
760743 throw new UnsupportedOperationException (
761744 "maxNumberOfVerts > 3 not supported yet" );
762745 }
@@ -1126,7 +1109,7 @@ public Bounds getBounds() {
11261109 if (polygons .isEmpty ()) {
11271110 return new Bounds (Vector3d .ZERO , Vector3d .ZERO );
11281111 }
1129-
1112+
11301113 Vector3d initial = polygons .get (0 ).vertices .get (0 ).pos ;
11311114
11321115 double minX = initial .x ();
0 commit comments