JavaCAD
CSG.java
Go to the documentation of this file.
1 /*
2  * CSG.java
3  *
4  * Copyright 2014-2014 Michael Hoffer info@michaelhoffer.de. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
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.
16  *
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.
28  *
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
32  * info@michaelhoffer.de.
33  */
34 package eu.mihosoft.vrl.v3d;
35 
36 import eu.mihosoft.vrl.v3d.ext.org.poly2tri.PolygonUtil;
37 import eu.mihosoft.vrl.v3d.ext.quickhull3d.HullUtil;
38 import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase;
39 import eu.mihosoft.vrl.v3d.parametrics.IParametric;
40 import eu.mihosoft.vrl.v3d.parametrics.IRegenerate;
41 import eu.mihosoft.vrl.v3d.parametrics.LengthParameter;
42 import eu.mihosoft.vrl.v3d.parametrics.Parameter;
43 
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.HashMap;
47 import java.util.List;
48 import java.util.Optional;
49 import java.util.Set;
50 import java.util.stream.Collectors;
51 import java.util.stream.Stream;
52 
53 import com.neuronrobotics.interaction.CadInteractionEvent;
54 
55 import javafx.scene.paint.Color;
56 import javafx.scene.paint.PhongMaterial;
57 import javafx.scene.shape.CullFace;
58 import javafx.scene.shape.DrawMode;
59 import javafx.scene.shape.MeshView;
60 import javafx.scene.transform.Affine;
61 
108 @SuppressWarnings("restriction")
109 public class CSG implements IuserAPI {
110  private static IDebug3dProvider providerOf3d = null;
111  private static int numFacesInOffset = 15;
112 
114  private List<Polygon> polygons;
115 
117  private static OptType defaultOptType = OptType.CSG_BOUND;
118 
120  private OptType optType = null;
121 
125 
127  private MeshView current;
128 
129  private static Color defaultcolor = Color.web("#007956");
130 
132  private Color color = getDefaultColor();
133 
135  private Affine manipulator;
136  private Bounds bounds;
137  public static final int INDEX_OF_PARAMETRIC_DEFAULT = 0;
138  public static final int INDEX_OF_PARAMETRIC_LOWER = 1;
139  public static final int INDEX_OF_PARAMETRIC_UPPER = 2;
140  private ArrayList<String> groovyFileLines = new ArrayList<>();
141  private PrepForManufacturing manufactuing = null;
142  private HashMap<String, IParametric> mapOfparametrics = null;
143  private IRegenerate regenerate = null;
144  private boolean markForRegeneration = false;
145  private String name = "";
146  private ArrayList<Transform> slicePlanes = null;
147  private ArrayList<String> exportFormats = null;
148  private ArrayList<Transform> datumReferences = null;
149  private boolean triangulated;
150  private static boolean needsDegeneratesPruned=false;
151  private static boolean useStackTraces = true;
152 
153  private static ICSGProgress progressMoniter = new ICSGProgress() {
154  @Override
155  public void progressUpdate(int currentIndex, int finalIndex, String type, CSG intermediateShape) {
156  System.out.println(type + "ing " + currentIndex + " of " + finalIndex);
157  }
158  };
159 
163  public CSG() {
164  setStorage(new PropertyStorage());
165 
166  if (useStackTraces) {
167  // This is the trace for where this csg was created
168  addStackTrace(new Exception());
169  }
170  }
171 
173  if (getDatumReferences() == null)
174  setDatumReferences(new ArrayList<Transform>());
175  getDatumReferences().add(t);
176  return this;
177  }
178 
180  if (getManufacturing() == null)
181  return this;
182  CSG ret = getManufacturing().prep(this);
183  if (ret == null)
184  return null;
185  ret.setName(getName());
186  ret.setColor(getColor());
187  ret.slicePlanes = slicePlanes;
188  ret.mapOfparametrics = mapOfparametrics;
189  ret.exportFormats = exportFormats;
190  return ret;
191  }
192 
198  public Color getColor() {
199  return color;
200  }
201 
207  public CSG setColor(Color color) {
208  this.color = color;
209  if (current != null) {
210  PhongMaterial m = new PhongMaterial(getColor());
211  current.setMaterial(m);
212  }
213  return this;
214  }
215 
221  public CSG setTemporaryColor(Color color) {
222  if (current != null) {
223  PhongMaterial m = new PhongMaterial(color);
224  current.setMaterial(m);
225  }
226  return this;
227  }
228 
235  public CSG setManipulator(Affine manipulator) {
236  if (manipulator == null)
237  return this;
238  Affine old = manipulator;
239  this.manipulator = manipulator;
240  if (current != null) {
241  current.getTransforms().clear();
242  current.getTransforms().add(manipulator);
243  }
244  return this;
245  }
246 
252  public MeshView getMesh() {
253  if (current != null)
254  return current;
255  current = newMesh();
256  return current;
257  }
258 
264  public MeshView newMesh() {
265 
266  MeshContainer meshContainer = toJavaFXMesh(null);
267 
268  MeshView current = meshContainer.getAsMeshViews().get(0);
269 
270  PhongMaterial m = new PhongMaterial(getColor());
271  current.setMaterial(m);
272 
273  boolean hasManipulator = getManipulator() != null;
274  boolean hasAssembly = getAssemblyStorage().getValue("AssembleAffine") != Optional.empty();
275 
276  if (hasManipulator || hasAssembly)
277  current.getTransforms().clear();
278 
279  if (hasManipulator)
280  current.getTransforms().add(getManipulator());
281  if (hasAssembly)
282  current.getTransforms().add((Affine) getAssemblyStorage().getValue("AssembleAffine").get());
283 
284  current.setCullFace(CullFace.NONE);
285  if (isWireFrame())
286  current.setDrawMode(DrawMode.LINE);
287  else
288  current.setDrawMode(DrawMode.FILL);
289  return current;
290  }
291 
298  public CSG toZMin(CSG target) {
299  return this.transformed(new Transform().translateZ(-target.getBounds().getMin().z));
300  }
301 
308  public CSG toZMax(CSG target) {
309  return this.transformed(new Transform().translateZ(-target.getBounds().getMax().z));
310  }
311 
318  public CSG toXMin(CSG target) {
319  return this.transformed(new Transform().translateX(-target.getBounds().getMin().x));
320  }
321 
328  public CSG toXMax(CSG target) {
329  return this.transformed(new Transform().translateX(-target.getBounds().getMax().x));
330  }
331 
338  public CSG toYMin(CSG target) {
339  return this.transformed(new Transform().translateY(-target.getBounds().getMin().y));
340  }
341 
348  public CSG toYMax(CSG target) {
349  return this.transformed(new Transform().translateY(-target.getBounds().getMax().y));
350  }
351 
357  public CSG toZMin() {
358  return toZMin(this);
359  }
360 
366  public CSG toZMax() {
367  return toZMax(this);
368  }
369 
375  public CSG toXMin() {
376  return toXMin(this);
377  }
378 
384  public CSG toXMax() {
385  return toXMax(this);
386  }
387 
393  public CSG toYMin() {
394  return toYMin(this);
395  }
396 
402  public CSG toYMax() {
403  return toYMax(this);
404  }
405 
406  public CSG move(Number x, Number y, Number z) {
407  return transformed(new Transform().translate(x.doubleValue(), y.doubleValue(), z.doubleValue()));
408  }
409 
410  public CSG move(Vertex v) {
411  return transformed(new Transform().translate(v.getX(), v.getY(), v.getZ()));
412  }
413 
414  public CSG move(Vector3d v) {
415  return transformed(new Transform().translate(v.x, v.y, v.z));
416  }
417 
418  public CSG move(Number[] posVector) {
419  return move(posVector[0], posVector[1], posVector[2]);
420  }
421 
428  // Helper/wrapper functions for movement
429  public CSG movey(Number howFarToMove) {
430  return this.transformed(Transform.unity().translateY(howFarToMove.doubleValue()));
431  }
432 
439  public CSG movez(Number howFarToMove) {
440  return this.transformed(Transform.unity().translateZ(howFarToMove.doubleValue()));
441  }
442 
449  public CSG movex(Number howFarToMove) {
450  return this.transformed(Transform.unity().translateX(howFarToMove.doubleValue()));
451  }
452 
458  public CSG moveToCenterX() {
459  return this.movex(-this.getCenterX());
460  }
461 
467  public CSG moveToCenterY() {
468  return this.movey(-this.getCenterY());
469  }
470 
476  public CSG moveToCenterZ() {
477  return this.movez(-this.getCenterZ());
478  }
479 
485  public CSG moveToCenter() {
486  return this.movex(-this.getCenterX()).movey(-this.getCenterY()).movez(-this.getCenterZ());
487  }
488 
489  public ArrayList<CSG> move(ArrayList<Transform> p) {
490  ArrayList<CSG> bits = new ArrayList<CSG>();
491  for (Transform t : p) {
492  bits.add(this.clone());
493  }
494  return move(bits, p);
495  }
496 
497  public static ArrayList<CSG> move(ArrayList<CSG> slice, ArrayList<Transform> p) {
498  ArrayList<CSG> s = new ArrayList<CSG>();
499  // s.add(slice.get(0));
500  for (int i = 0; i < slice.size() && i < p.size(); i++) {
501  s.add(slice.get(i).transformed(p.get(i)));
502  }
503  return s;
504  }
505 
512  // Helper/wrapper functions for movement
513  public CSG mirrory() {
514  return this.scaley(-1);
515  }
516 
522  public CSG mirrorz() {
523  return this.scalez(-1);
524  }
525 
531  public CSG mirrorx() {
532  return this.scalex(-1);
533  }
534 
535  public CSG rot(Number x, Number y, Number z) {
536  return rotx(x.doubleValue()).roty(y.doubleValue()).rotz(z.doubleValue());
537  }
538 
539  public CSG rot(Number[] posVector) {
540  return rot(posVector[0], posVector[1], posVector[2]);
541  }
542 
549  // Rotation function, rotates the object
550  public CSG rotz(Number degreesToRotate) {
551  return this.transformed(new Transform().rotZ(degreesToRotate.doubleValue()));
552  }
553 
560  public CSG roty(Number degreesToRotate) {
561  return this.transformed(new Transform().rotY(degreesToRotate.doubleValue()));
562  }
563 
570  public CSG rotx(Number degreesToRotate) {
571  return this.transformed(new Transform().rotX(degreesToRotate.doubleValue()));
572  }
573 
580  // Scale function, scales the object
581  public CSG scalez(Number scaleValue) {
582  return this.transformed(new Transform().scaleZ(scaleValue.doubleValue()));
583  }
584 
591  public CSG scaley(Number scaleValue) {
592  return this.transformed(new Transform().scaleY(scaleValue.doubleValue()));
593  }
594 
601  public CSG scalex(Number scaleValue) {
602  return this.transformed(new Transform().scaleX(scaleValue.doubleValue()));
603  }
604 
611  public CSG scale(Number scaleValue) {
612  return this.transformed(new Transform().scale(scaleValue.doubleValue()));
613  }
614 
621  public static CSG fromPolygons(List<Polygon> polygons) {
622 
623  CSG csg = new CSG();
624  csg.setPolygons(polygons);
625  return csg;
626  }
627 
634  public static CSG fromPolygons(Polygon... polygons) {
635  return fromPolygons(Arrays.asList(polygons));
636  }
637 
645  public static CSG fromPolygons(PropertyStorage storage, List<Polygon> polygons) {
646 
647  CSG csg = new CSG();
648  csg.setPolygons(polygons);
649 
650  csg.setStorage(storage);
651 
652  for (Polygon polygon : polygons) {
653  polygon.setStorage(storage);
654  }
655  return csg;
656  }
657 
665  public static CSG fromPolygons(PropertyStorage storage, Polygon... polygons) {
666  return fromPolygons(storage, Arrays.asList(polygons));
667  }
668 
669  /*
670  * (non-Javadoc)
671  *
672  * @see java.lang.Object#clone()
673  */
674  @Override
675  public CSG clone() {
676  CSG csg = new CSG();
677 
678  csg.setOptType(this.getOptType());
679 
680  Stream<Polygon> polygonStream;
681 
682 // if (getPolygons().size() > 200) {
683 // polygonStream = getPolygons().parallelStream();
684 // } else {
685 // polygonStream =getPolygons().stream();
686 // }
687  polygonStream=getPolygons().stream();
688  csg.setPolygons(polygonStream.map((Polygon p) -> p!=null?p.clone():null).filter(p-> p!=null).collect(Collectors.toList()));
689 
690  return csg.historySync(this);
691  }
692 
698  public List<Polygon> getPolygons() {
699  return polygons;
700  }
701 
708  public CSG optimization(OptType type) {
709  this.setOptType(type);
710  return this;
711  }
712 
736  public CSG union(CSG csg) {
737 // triangulate();
738 // csg.triangulate();
739  switch (getOptType()) {
740  case CSG_BOUND:
741  return _unionCSGBoundsOpt(csg).historySync(this).historySync(csg);
742  case POLYGON_BOUND:
743  return _unionPolygonBoundsOpt(csg).historySync(this).historySync(csg);
744  default:
745  // return _unionIntersectOpt(csg);
746  return _unionNoOpt(csg).historySync(this).historySync(csg);
747  }
748  }
749 
763  public CSG dumbUnion(CSG csg) {
764  boolean tri = triangulated&&csg.triangulated;
765  CSG result = this.clone();
766  CSG other = csg.clone();
767 
768  result.getPolygons().addAll(other.getPolygons());
769  bounds = null;
770  result.triangulated = tri;
771  return result.historySync(other);
772  }
773 
797  public CSG union(List<CSG> csgs) {
798 // ArrayList<Polygon> incomingPolys = new ArrayList<>();
799 // for(int i=0;i<csgs.size();i++) {
800 // incomingPolys.addAll(csgs.get(i).getPolygons());
801 // }
802 // //System.out.println("Node list A");
803 // Node a = new Node(this.clone().getPolygons());
804 // //System.out.println("Node list B");
805 // Node b = new Node(incomingPolys);
806 // //System.out.println("a.clipTo(b)");
807 // a.clipTo(b);
808 // //System.out.println("b.clipTo(a)");
809 // b.clipTo(a);
810 // //System.out.println("b.invert();");
811 // b.invert();
812 // //System.out.println("b.clipTo(a);");
813 // b.clipTo(a);
814 // //System.out.println("b.invert();");
815 // b.invert();
816 // //System.out.println("a.build(b.allPolygons());");
817 // a.build(b.allPolygons());
818 // //System.out.println("CSG.fromPolygons(a.allPolygons()).optimization(getOptType())");
819 // return CSG.fromPolygons(a.allPolygons()).optimization(getOptType());
820 
821  CSG result = this;
822 
823  for (int i = 0; i < csgs.size(); i++) {
824  CSG csg = csgs.get(i);
825  result = result.union(csg);
826  if (Thread.interrupted())
827  break;
828  progressMoniter.progressUpdate(i, csgs.size(), "Union", result);
829  }
830 
831  return result;
832  }
833 
857  public CSG union(CSG... csgs) {
858  return union(Arrays.asList(csgs));
859  }
860 
866  public CSG hull() {
867 
868  return HullUtil.hull(this, getStorage()).historySync(this);
869  }
870 
871  public static CSG unionAll(CSG... csgs) {
872  return unionAll(Arrays.asList(csgs));
873  }
874 
875  public static CSG unionAll(List<CSG> csgs) {
876  CSG first = csgs.get(0);
877  return first.union(csgs.stream().skip(1).collect(Collectors.toList()));
878  }
879 
880  public static CSG hullAll(CSG... csgs) {
881  return hullAll(Arrays.asList(csgs));
882  }
883 
884  public static CSG hullAll(List<CSG> csgs) {
885  // CSG first = csgs.remove(0);
886  return HullUtil.hull(csgs);// first.hull(csgs);
887  }
888 
895  public CSG hull(List<CSG> csgs) {
896 
897  CSG csgsUnion = new CSG();
898  // csgsUnion.setStorage(storage);
899  csgsUnion.optType = optType;
900  csgsUnion.setPolygons(this.clone().getPolygons());
901 
902  csgs.stream().forEach((csg) -> {
903  csgsUnion.getPolygons().addAll(csg.clone().getPolygons());
904  csgsUnion.historySync(csg);
905  });
906 
907  csgsUnion.getPolygons().forEach(p -> p.setStorage(getStorage()));
908  bounds = null;
909  return csgsUnion.hull();
910 
911  // CSG csgsUnion = this;
912  //
913  // for (CSG csg : csgs) {
914  // csgsUnion = csgsUnion.union(csg);
915  // }
916  //
917  // return csgsUnion.hull();
918  }
919 
926  public CSG hull(CSG... csgs) {
927 
928  return hull(Arrays.asList(csgs));
929  }
930 
937  private CSG _unionCSGBoundsOpt(CSG csg) {
938  // System.err.println("WARNING: using " + CSG.OptType.NONE
939  // + " since other optimization types missing for union operation.");
940  return _unionIntersectOpt(csg);
941  }
942 
950  List<Polygon> inner = new ArrayList<>();
951  List<Polygon> outer = new ArrayList<>();
952 
953  Bounds b = csg.getBounds();
954 
955  this.getPolygons().stream().forEach((p) -> {
956  if (b.intersects(p.getBounds())) {
957  inner.add(p);
958  } else {
959  outer.add(p);
960  }
961  });
962 
963  List<Polygon> allPolygons = new ArrayList<>();
964 
965  if (!inner.isEmpty()) {
966  CSG innerCSG = CSG.fromPolygons(inner);
967 
968  allPolygons.addAll(outer);
969  allPolygons.addAll(innerCSG._unionNoOpt(csg).getPolygons());
970  } else {
971  allPolygons.addAll(this.getPolygons());
972  allPolygons.addAll(csg.getPolygons());
973  }
974  bounds = null;
975  CSG back = CSG.fromPolygons(allPolygons).optimization(getOptType());
976  if (getName().length() != 0 && csg.getName().length() != 0) {
977  back.setName(name + " unioned to " + csg.getName());
978  }
979  return back;
980  }
981 
990  private CSG _unionIntersectOpt(CSG csg) {
991  boolean intersects = false;
992 
993  Bounds bounds = csg.getBounds();
994 
995  for (Polygon p : getPolygons()) {
996  if (bounds.intersects(p.getBounds())) {
997  intersects = true;
998  break;
999  }
1000  }
1001 
1002  List<Polygon> allPolygons = new ArrayList<>();
1003 
1004  if (intersects) {
1005  return _unionNoOpt(csg);
1006  } else {
1007  allPolygons.addAll(this.getPolygons());
1008  allPolygons.addAll(csg.getPolygons());
1009  }
1010  CSG back = CSG.fromPolygons(allPolygons).optimization(getOptType());
1011  if (getName().length() != 0 && csg.getName().length() != 0) {
1012  back.setName(name + " unioned to " + csg.getName());
1013  }
1014  return back;
1015  }
1016 
1023  private CSG _unionNoOpt(CSG csg) {
1024  Node a = new Node(this.clone().getPolygons());
1025  Node b = new Node(csg.clone().getPolygons());
1026  a.clipTo(b);
1027  b.clipTo(a);
1028  b.invert();
1029  b.clipTo(a);
1030  b.invert();
1031  a.build(b.allPolygons());
1032  CSG back = CSG.fromPolygons(a.allPolygons()).optimization(getOptType());
1033  if (getName().length() != 0 && csg.getName().length() != 0) {
1034  back.setName(name + " unioned to " + csg.getName());
1035  }
1036  return back;
1037  }
1038 
1061  public CSG difference(List<CSG> csgs) {
1062 
1063  if (csgs.isEmpty()) {
1064  return this.clone();
1065  }
1066 
1067  CSG csgsUnion = csgs.get(0);
1068 
1069  for (int i = 1; i < csgs.size(); i++) {
1070  csgsUnion = csgsUnion.union(csgs.get(i));
1071  progressMoniter.progressUpdate(i, csgs.size(), "Difference", csgsUnion);
1072  csgsUnion.historySync(csgs.get(i));
1073  if (Thread.interrupted())
1074  break;
1075  }
1076 
1077  return difference(csgsUnion);
1078  }
1079 
1102  public CSG difference(CSG... csgs) {
1103 
1104  return difference(Arrays.asList(csgs));
1105  }
1106 
1129  public CSG difference(CSG csg) {
1130 // triangulate();
1131 // csg.triangulate();
1132  try {
1133  // Check to see if a CSG operation is attempting to difference with
1134  // no
1135  // polygons
1136  if (this.getPolygons().size() > 0 && csg.getPolygons().size() > 0) {
1137  switch (getOptType()) {
1138  case CSG_BOUND:
1139  return _differenceCSGBoundsOpt(csg).historySync(this).historySync(csg);
1140  case POLYGON_BOUND:
1141  return _differencePolygonBoundsOpt(csg).historySync(this).historySync(csg);
1142  default:
1143  return _differenceNoOpt(csg).historySync(this).historySync(csg);
1144  }
1145  } else
1146  return this;
1147  } catch (Exception ex) {
1148  // ex.printStackTrace();
1149  try {
1150  // System.err.println("CSG difference failed, performing workaround");
1151  // ex.printStackTrace();
1152  CSG intersectingParts = csg.intersect(this);
1153 
1154  if (intersectingParts.getPolygons().size() > 0) {
1155  switch (getOptType()) {
1156  case CSG_BOUND:
1157  return _differenceCSGBoundsOpt(intersectingParts).historySync(this)
1158  .historySync(intersectingParts);
1159  case POLYGON_BOUND:
1160  return _differencePolygonBoundsOpt(intersectingParts).historySync(this)
1161  .historySync(intersectingParts);
1162  default:
1163  return _differenceNoOpt(intersectingParts).historySync(this).historySync(intersectingParts);
1164  }
1165  } else
1166  return this;
1167  } catch (Exception e) {
1168  e.printStackTrace();
1169  return this;
1170  }
1171  }
1172 
1173  }
1174 
1182  CSG b = csg;
1183 
1184  CSG a1 = this._differenceNoOpt(csg.getBounds().toCSG());
1185  CSG a2 = this.intersect(csg.getBounds().toCSG());
1186  CSG BACK = a2._differenceNoOpt(b)._unionIntersectOpt(a1).optimization(getOptType());
1187  if (getName().length() != 0 && csg.getName().length() != 0) {
1188  BACK.setName(csg.getName() + " differenced from " + name);
1189  }
1190  return BACK;
1191  }
1192 
1200  List<Polygon> inner = new ArrayList<>();
1201  List<Polygon> outer = new ArrayList<>();
1202 
1203  Bounds bounds = csg.getBounds();
1204 
1205  this.getPolygons().stream().forEach((p) -> {
1206  if (bounds.intersects(p.getBounds())) {
1207  inner.add(p);
1208  } else {
1209  outer.add(p);
1210  }
1211  });
1212 
1213  CSG innerCSG = CSG.fromPolygons(inner);
1214 
1215  List<Polygon> allPolygons = new ArrayList<>();
1216  allPolygons.addAll(outer);
1217  allPolygons.addAll(innerCSG._differenceNoOpt(csg).getPolygons());
1218  CSG BACK = CSG.fromPolygons(allPolygons).optimization(getOptType());
1219  if (getName().length() != 0 && csg.getName().length() != 0) {
1220  BACK.setName(csg.getName() + " differenced from " + name);
1221  }
1222  return BACK;
1223  }
1224 
1231  private CSG _differenceNoOpt(CSG csg) {
1232 
1233  Node a = new Node(this.clone().getPolygons());
1234  Node b = new Node(csg.clone().getPolygons());
1235 
1236  a.invert();
1237  a.clipTo(b);
1238  b.clipTo(a);
1239  b.invert();
1240  b.clipTo(a);
1241  b.invert();
1242  a.build(b.allPolygons());
1243  a.invert();
1244 
1245  CSG csgA = CSG.fromPolygons(a.allPolygons()).optimization(getOptType());
1246  if (getName().length() != 0 && csg.getName().length() != 0) {
1247  csgA.setName(csg.getName() + " differenced from " + name);
1248  }
1249  return csgA;
1250  }
1251 
1275  public CSG intersect(CSG csg) {
1276 // triangulate();
1277 // csg.triangulate();
1278  Node a = new Node(this.clone().getPolygons());
1279  Node b = new Node(csg.clone().getPolygons());
1280  a.invert();
1281  b.clipTo(a);
1282  b.invert();
1283  a.clipTo(b);
1284  b.clipTo(a);
1285  a.build(b.allPolygons());
1286  a.invert();
1287  CSG back = CSG.fromPolygons(a.allPolygons()).optimization(getOptType()).historySync(csg)
1288  .historySync(this);
1289  if (getName().length() != 0 && csg.getName().length() != 0) {
1290  back.setName(csg.getName() + " intersection with " + name);
1291  }
1292  return back;
1293  }
1294 
1318  public CSG intersect(List<CSG> csgs) {
1319 
1320  if (csgs.isEmpty()) {
1321  return this.clone();
1322  }
1323 
1324  CSG csgsUnion = csgs.get(0);
1325 
1326  for (int i = 1; i < csgs.size(); i++) {
1327  csgsUnion = csgsUnion.union(csgs.get(i));
1328  progressMoniter.progressUpdate(i, csgs.size(), "Intersect", csgsUnion);
1329  csgsUnion.historySync(csgs.get(i));
1330  if (Thread.interrupted())
1331  break;
1332  }
1333 
1334  return intersect(csgsUnion);
1335  }
1336 
1360  public CSG intersect(CSG... csgs) {
1361 
1362  return intersect(Arrays.asList(csgs));
1363  }
1364 
1370  public String toStlString() {
1371  StringBuilder sb = new StringBuilder();
1372  toStlString(sb);
1373  return sb.toString();
1374  }
1375 
1383  public StringBuilder toStlString(StringBuilder sb) {
1384  triangulate(false);
1385  try {
1386  sb.append("solid v3d.csg\n");
1387  this.getPolygons().stream().forEach((Polygon p) -> {
1388  p.toStlString(sb);
1389  });
1390  sb.append("endsolid v3d.csg\n");
1391  return sb;
1392  } catch (Throwable t) {
1393 
1394  t.printStackTrace();
1395  throw new RuntimeException("STL failed to build for " + name);
1396  }
1397  }
1398  public CSG triangulate() {
1399  return triangulate(false);
1400  }
1401  public CSG triangulate(boolean fix) {
1402  if(fix && needsDegeneratesPruned)
1403  triangulated=false;
1404  if(triangulated)
1405  return this;
1406 
1407  //System.out.println("CSG triangulating for " + name+"..");
1408  ArrayList<Polygon> toAdd = new ArrayList<Polygon>();
1409  ArrayList<Polygon> degenerates = new ArrayList<Polygon>();
1410  if (providerOf3d == null && Debug3dProvider.provider != null)
1411  providerOf3d = Debug3dProvider.provider;
1412  IDebug3dProvider start = Debug3dProvider.provider;
1414  try {
1415  Stream<Polygon> polygonStream;
1416  polygonStream =polygons.stream();
1417  // TODO this should work in paralell but throws immpossible NPE's instead.
1418 // if (getPolygons().size() > 200) {
1419 // polygonStream = polygons.parallelStream();
1420 // }
1421  polygonStream.forEach(p -> updatePolygons(toAdd, degenerates, p));
1422 // for (int i = 0; i < polygons.size(); i++) {
1423 // Polygon p = polygons.get(i);
1424 // updatePolygons(toAdd, degenerates, p);
1425 // }
1426 
1427 
1428  if(degenerates.size()>0) {
1429  //
1430  //Debug3dProvider.setProvider(providerOf3d);
1431 
1432  if(fix) {
1434  Stream<Polygon> degenStreeam;
1435  degenStreeam =polygons.stream(); // this operation is read-modify-write and can not be done in parallel
1436  System.out.println("Found "+degenerates.size()+" degenerate triangles, Attempting to fix");
1437  degenStreeam.forEach(p -> fixDegenerates(toAdd, p));
1438  }else {
1439  needsDegeneratesPruned=true;
1440  toAdd.addAll(degenerates);
1441  }
1442  }
1443  if (toAdd.size() > 0) {
1444  setPolygons(toAdd);
1445  }
1446  // now all polygons are definantly triangles
1447  triangulated=true;
1448  } catch (Throwable t) {
1449  t.printStackTrace();
1450 
1451  }
1453  return this;
1454  }
1455 
1456  private void fixDegenerates(ArrayList<Polygon> toAdd, Polygon p) {
1459  ArrayList<Vertex> degen =p.getDegeneratePoints();
1460  Edge longEdge = p.getLongEdge();
1461  ArrayList<Polygon> polygonsSharing = new ArrayList<Polygon>();
1462  ArrayList<Polygon> polygonsSharingFixed = new ArrayList<Polygon>();
1463 
1464  for(Polygon ptoA:toAdd) {
1465  ArrayList<Edge> edges = ptoA.edges();
1466  for(Edge e :edges) {
1467  if(e.equals(longEdge)) {
1468  //System.out.println("Degenerate Mate Found!");
1469  polygonsSharing.add(ptoA);
1470  Debug3dProvider.addObject(ptoA);
1471  // TODO inject the points into the found edge
1472  // upstream reparirs to mesh generation made this code effectivly unreachable
1473  // in case that turns out to be false, pick up here
1474  // the points in degen need to be inserted into the matching polygons
1475  // both list of points should be right hand, but since they are other polygons,
1476  // that may not be the case, so sorting needs to take place
1477  ArrayList<Vertex> newpoints = new ArrayList<Vertex>();
1478  for(Vertex v:ptoA.vertices) {
1479  newpoints.add(v);
1480  if(e.isThisPointOneOfMine(v)) {
1481  for(Vertex v2:degen)
1482  newpoints.add(v2);
1483  }
1484  }
1485  Polygon e2 = new Polygon(newpoints, ptoA.getStorage());
1486  try {
1487  List<Polygon> t = PolygonUtil.concaveToConvex(e2);
1488  for(Polygon poly :t) {
1489  if(!poly.isDegenerate()) {
1490  polygonsSharingFixed.add(poly);
1491  }
1492 
1493  }
1494  }catch(Exception ex) {
1495  ex.printStackTrace();
1496  // retriangulation failed, ok, whatever man, moving on...
1497  }
1498  }
1499  }
1500  }
1501  if(polygonsSharing.size()==0) {
1502  //System.out.println("Error! Degenerate triangle does not share edge with any triangle");
1503  }
1504  if(polygonsSharingFixed.size()>0) {
1505  toAdd.removeAll(polygonsSharing);
1506  toAdd.addAll(polygonsSharingFixed);
1507  }
1508  }
1509 
1510  private void updatePolygons(ArrayList<Polygon> toAdd, ArrayList<Polygon> degenerates, Polygon p) {
1511  //p=PolygonUtil.pruneDuplicatePoints(p);
1512  if(p==null)
1513  return;
1514 // if(p.isDegenerate()) {
1515 // degenerates.add(p);
1516 // return;
1517 // }
1518 
1519  if (p.vertices.size() == 3) {
1520  toAdd.add(p);
1521  }else{
1522  // System.out.println("Fixing error in STL " + name + " polygon# " + i + "
1523  // number of vertices " + p.vertices.size());
1524  try {
1525  List<Polygon> triangles = PolygonUtil.concaveToConvex(p,true);
1526  for(Polygon poly :triangles) {
1527  if(poly.isDegenerate()) {
1528  degenerates.add(poly);
1529  }else
1530  toAdd.add(poly);
1531  }
1532  } catch (Throwable ex) {
1533  Debug3dProvider.setProvider(providerOf3d);
1534  ex.printStackTrace();
1537  try {
1538  List<Polygon> triangles = PolygonUtil.concaveToConvex(p,true);
1539  toAdd.addAll(triangles);
1540  }catch(java.lang.IllegalStateException ise) {
1541  ise.printStackTrace();
1542  }
1544  }
1545 
1546  }
1547  }
1548 
1555  public CSG color(Color c) {
1556  getStorage().set("material:color", "" + c.getRed() + " " + c.getGreen() + " " + c.getBlue());
1557 
1558  return this;
1559  }
1560 
1567  public StringBuilder toObjString(StringBuilder sb) {
1568  triangulate(true);
1569  sb.append("# Group").append("\n");
1570  sb.append("g v3d.csg\n");
1571  sb.append("o " + (name == null || name.length() == 0 ? "CSG Export" : getName()) + "\n");
1572  class PolygonStruct {
1573 
1574  PropertyStorage storage;
1575  List<Integer> indices;
1576  String materialName;
1577 
1578  public PolygonStruct(PropertyStorage storage, List<Integer> indices, String materialName) {
1579  this.storage = storage;
1580  this.indices = indices;
1581  this.materialName = materialName;
1582  }
1583  }
1584 
1585  List<Vertex> vertices = new ArrayList<>();
1586  List<PolygonStruct> indices = new ArrayList<>();
1587 
1588  sb.append("\n# Vertices\n");
1589 
1590  for (Polygon p : getPolygons()) {
1591  List<Integer> polyIndices = new ArrayList<>();
1592 
1593  p.vertices.stream().forEach((v) -> {
1594  if (!vertices.contains(v)) {
1595  vertices.add(v);
1596  v.toObjString(sb);
1597  polyIndices.add(vertices.size());
1598  } else {
1599  polyIndices.add(vertices.indexOf(v) + 1);
1600  }
1601  });
1602  indices.add(new PolygonStruct(getStorage(), polyIndices, " "));
1603 
1604  }
1605  HashMap<Vertex, Integer> mapping = new HashMap<Vertex, Integer>();
1606  HashMap<Transform, Vertex> mappingTF = new HashMap<>();
1607  if (datumReferences != null) {
1608  int startingIndex = vertices.size() + 1;
1609  sb.append("\n# Reference Datum").append("\n");
1610  for (Transform t : datumReferences) {
1611  Vertex v = new Vertex(new Vector3d(0, 0, 0), new Vector3d(0, 0, 1)).transform(t);
1612  Vertex v1 = new Vertex(new Vector3d(0, 0, 1), new Vector3d(0, 0, 1)).transform(t);
1613  mapping.put(v, startingIndex++);
1614  mapping.put(v1, startingIndex++);
1615  mappingTF.put(t, v);
1616  v.toObjString(sb);
1617  v1.toObjString(sb);
1618  }
1619  sb.append("\n# Datum Lines").append("\n");
1620  for (Transform t : mappingTF.keySet()) {
1621  Vertex key = mappingTF.get(t);
1622  Integer obj = mapping.get(key);
1623  sb.append("\nl ").append(obj + " ").append(obj + 1).append("\n");
1624  }
1625  }
1626 
1627  sb.append("\n# Faces").append("\n");
1628 
1629  for (PolygonStruct ps : indices) {
1630  // we triangulate the polygon to ensure
1631  // compatibility with 3d printer software
1632  List<Integer> pVerts = ps.indices;
1633  if (pVerts.size() != 3)
1634  throw new RuntimeException(name + " can not be exported until triangulated");
1635  int index1 = pVerts.get(0);
1636  for (int i = 0; i < pVerts.size() - 2; i++) {
1637  int index2 = pVerts.get(i + 1);
1638  int index3 = pVerts.get(i + 2);
1639 
1640  sb.append("f ").append(index1).append(" ").append(index2).append(" ").append(index3).append("\n");
1641  }
1642  }
1643 
1644  sb.append("\n# End Group v3d.csg").append("\n");
1645 
1646  return sb;
1647  }
1648 
1654  public String toObjString() {
1655  StringBuilder sb = new StringBuilder();
1656  return toObjString(sb).toString();
1657  }
1658 
1666  return new Modifier(f).modified(this);
1667  }
1668 
1676  public CSG transformed(Transform transform) {
1677 
1678  if (getPolygons().isEmpty()) {
1679  return clone();
1680  }
1681 
1682  List<Polygon> newpolygons = this.getPolygons().stream().map(p -> p.transformed(transform))
1683  .collect(Collectors.toList());
1684 
1685  CSG csg = CSG.fromPolygons(newpolygons).optimization(getOptType());
1686 
1687  // csg.setStorage(storage);
1688 
1689  if (getName().length() != 0) {
1690  csg.setName(name + " transformed by[" + transform + "]");
1691  }
1692 
1693  return csg.historySync(this);
1694  }
1695 
1702  // TODO finish experiment (20.7.2014)
1704 
1705  return toJavaFXMeshSimple(interact);
1706 
1707  // TODO test obj approach with multiple materials
1708  // try {
1709  // ObjImporter importer = new ObjImporter(toObj());
1710  //
1711  // List<Mesh> meshes = new ArrayList<>(importer.getMeshCollection());
1712  // return new MeshContainer(getBounds().getMin(), getBounds().getMax(),
1713  // meshes, new ArrayList<>(importer.getMaterialCollection()));
1714  // } catch (IOException ex) {
1715  // Logger.getLogger(CSG.class.getName()).log(Level.SEVERE, null, ex);
1716  // }
1717  // // we have no backup strategy for broken streams :(
1718  // return null;
1719  }
1720 
1728 
1729  return CSGtoJavafx.meshFromPolygon(getPolygons());
1730  }
1731 
1738  public Bounds getBounds() {
1739  if (bounds != null)
1740  return bounds;
1741  if (getPolygons().isEmpty()) {
1742  bounds = new Bounds(Vector3d.ZERO, Vector3d.ZERO);
1743  return bounds;
1744  }
1745 
1746  double minX = Double.POSITIVE_INFINITY;
1747  double minY = Double.POSITIVE_INFINITY;
1748  double minZ = Double.POSITIVE_INFINITY;
1749 
1750  double maxX = Double.NEGATIVE_INFINITY;
1751  double maxY = Double.NEGATIVE_INFINITY;
1752  double maxZ = Double.NEGATIVE_INFINITY;
1753 
1754  for (Polygon p : getPolygons()) {
1755 
1756  for (int i = 0; i < p.vertices.size(); i++) {
1757 
1758  Vertex vert = p.vertices.get(i);
1759 
1760  if (vert.pos.x < minX) {
1761  minX = vert.pos.x;
1762  }
1763  if (vert.pos.y < minY) {
1764  minY = vert.pos.y;
1765  }
1766  if (vert.pos.z < minZ) {
1767  minZ = vert.pos.z;
1768  }
1769 
1770  if (vert.pos.x > maxX) {
1771  maxX = vert.pos.x;
1772  }
1773  if (vert.pos.y > maxY) {
1774  maxY = vert.pos.y;
1775  }
1776  if (vert.pos.z > maxZ) {
1777  maxZ = vert.pos.z;
1778  }
1779 
1780  } // end for vertices
1781 
1782  } // end for polygon
1783 
1784  bounds = new Bounds(new Vector3d(minX, minY, minZ), new Vector3d(maxX, maxY, maxZ));
1785  return bounds;
1786  }
1787 
1788  public Vector3d getCenter() {
1789  return new Vector3d(getCenterX(), getCenterY(), getCenterZ());
1790  }
1791 
1797  public double getCenterX() {
1798  return ((getMinX() / 2) + (getMaxX() / 2));
1799  }
1800 
1806  public double getCenterY() {
1807  return ((getMinY() / 2) + (getMaxY() / 2));
1808  }
1809 
1815  public double getCenterZ() {
1816  return ((getMinZ() / 2) + (getMaxZ() / 2));
1817  }
1818 
1824  public double getMaxX() {
1825  return getBounds().getMax().x;
1826  }
1827 
1833  public double getMaxY() {
1834  return getBounds().getMax().y;
1835  }
1836 
1842  public double getMaxZ() {
1843  return getBounds().getMax().z;
1844  }
1845 
1851  public double getMinX() {
1852  return getBounds().getMin().x;
1853  }
1854 
1860  public double getMinY() {
1861  return getBounds().getMin().y;
1862  }
1863 
1869  public double getMinZ() {
1870  return getBounds().getMin().z;
1871  }
1872 
1878  public double getTotalX() {
1879  return (-this.getMinX() + this.getMaxX());
1880  }
1881 
1887  public double getTotalY() {
1888  return (-this.getMinY() + this.getMaxY());
1889  }
1890 
1896  public double getTotalZ() {
1897  return (-this.getMinZ() + this.getMaxZ());
1898  }
1899 
1905  private OptType getOptType() {
1906  return optType != null ? optType : defaultOptType;
1907  }
1908 
1914  public static void setDefaultOptType(OptType optType) {
1915  defaultOptType = optType;
1916  }
1917 
1923  public void setOptType(OptType optType) {
1924  this.optType = optType;
1925  }
1926 
1932  public void setPolygons(List<Polygon> polygons) {
1933  bounds = null;
1934  triangulated=false;
1935  this.polygons = polygons;
1936  }
1937 
1941  public static enum OptType {
1942 
1944  CSG_BOUND,
1945 
1947  POLYGON_BOUND,
1948 
1950  NONE
1951  }
1952 
1959  @Deprecated
1960  public ArrayList<CSG> minovsky(CSG travelingShape) {
1961  System.out.println("Hail Zeon!");
1962  return minkowski(travelingShape);
1963  }
1964 
1971  public ArrayList<CSG> mink(CSG travelingShape) {
1972  return minkowski(travelingShape);
1973  }
1974 
1985  public ArrayList<CSG> minkowskiHullShape(CSG travelingShape) {
1986  ArrayList<CSG> bits = new ArrayList<>();
1987  for (Polygon p : this.getPolygons()) {
1988  List<Vector3d> plist = new ArrayList<>();
1989  for (Vertex v : p.vertices) {
1990  CSG newSHape = travelingShape.move(v);
1991  for (Polygon np : newSHape.getPolygons()) {
1992  for (Vertex nv : np.vertices) {
1993  plist.add(nv.pos);
1994  }
1995  }
1996  }
1997  bits.add(HullUtil.hull(plist));
1998  }
1999  return bits;
2000  }
2001 
2012  public ArrayList<CSG> minkowski(CSG travelingShape) {
2013  HashMap<Vertex, CSG> map = new HashMap<>();
2014  for (Polygon p : travelingShape.getPolygons()) {
2015  for (Vertex v : p.vertices) {
2016  if (map.get(v) == null)// use hashmap to avoid duplicate locations
2017  map.put(v, this.move(v));
2018  }
2019  }
2020  return new ArrayList<CSG>(map.values());
2021  }
2022 
2034  public CSG minkowskiDifference(CSG itemToDifference, CSG minkowskiObject) {
2035  CSG intersection = this.intersect(itemToDifference);
2036 
2037  ArrayList<CSG> csgDiff = intersection.minkowskiHullShape(minkowskiObject);
2038  CSG result = this;
2039  for (int i = 0; i < csgDiff.size(); i++) {
2040  result = result.difference(csgDiff.get(i));
2041  progressMoniter.progressUpdate(i, csgDiff.size(), "Minkowski difference", result);
2042  }
2043  return result;
2044  }
2045 
2057  public CSG minkowskiDifference(CSG itemToDifference, double tolerance) {
2058  double shellThickness = Math.abs(tolerance);
2059  if (shellThickness < 0.001)
2060  return this;
2061  return minkowskiDifference(itemToDifference, new Sphere(shellThickness / 2.0, 8, 4).toCSG());
2062  }
2063 
2064  public CSG toolOffset(Number sn) {
2065  double shellThickness = sn.doubleValue();
2066  boolean cut = shellThickness < 0;
2067  shellThickness = Math.abs(shellThickness);
2068  if (shellThickness < 0.001)
2069  return this;
2070  double z = shellThickness;
2071  if (z > this.getTotalZ() / 2)
2072  z = this.getTotalZ() / 2;
2073  CSG printNozzel = new Sphere(z / 2.0, 8, 4).toCSG();
2074 
2075  if (cut) {
2076  ArrayList<CSG> mikObjs = minkowski(printNozzel);
2077  CSG remaining = this;
2078  for (CSG bit : mikObjs) {
2079  remaining = remaining.intersect(bit);
2080  }
2081  return remaining;
2082  }
2083  return union(minkowskiHullShape(printNozzel));
2084  }
2085 
2086  private int getNumFacesForOffsets() {
2087  return getNumfacesinoffset();
2088  }
2089 
2090  public CSG makeKeepaway(Number sn) {
2091  double shellThickness = sn.doubleValue();
2092 
2093  double x = Math.abs(this.getBounds().getMax().x) + Math.abs(this.getBounds().getMin().x);
2094  double y = Math.abs(this.getBounds().getMax().y) + Math.abs(this.getBounds().getMin().y);
2095 
2096  double z = Math.abs(this.getBounds().getMax().z) + Math.abs(this.getBounds().getMin().z);
2097 
2098  double xtol = (x + shellThickness) / x;
2099  double ytol = (y + shellThickness) / y;
2100  double ztol = (z + shellThickness) / z;
2101 
2102  double xPer = -(Math.abs(this.getBounds().getMax().x) - Math.abs(this.getBounds().getMin().x)) / x;
2103  double yPer = -(Math.abs(this.getBounds().getMax().y) - Math.abs(this.getBounds().getMin().y)) / y;
2104  double zPer = -(Math.abs(this.getBounds().getMax().z) - Math.abs(this.getBounds().getMin().z)) / z;
2105 
2106  // println " Keep away x = "+y+" new = "+ytol
2107  return this.transformed(new Transform().scale(xtol, ytol, ztol))
2108  .transformed(new Transform().translateX(shellThickness * xPer))
2109  .transformed(new Transform().translateY(shellThickness * yPer))
2110  .transformed(new Transform().translateZ(shellThickness * zPer)).historySync(this);
2111 
2112  }
2113 
2114  public Affine getManipulator() {
2115  if (manipulator == null)
2116  manipulator = new Affine();
2117  return manipulator;
2118  }
2119 
2120  public CSG addCreationEventStackTraceList(ArrayList<Exception> incoming) {
2121  for (Exception ex : incoming) {
2122  addStackTrace(ex);
2123 
2124  }
2125  return this;
2126  }
2127 
2128  private void addStackTrace(Exception creationEventStackTrace2) {
2129  for (StackTraceElement el : creationEventStackTrace2.getStackTrace()) {
2130  try {
2131  if (!el.getFileName().endsWith(".java") && el.getLineNumber() > 0) {
2132  boolean dupLine = false;
2133  String thisline = el.getFileName() + ":" + el.getLineNumber();
2134  for (String s : groovyFileLines) {
2135  if (s.contentEquals(thisline)) {
2136  dupLine = true;
2137  // System.err.println("Dupe: "+thisline);
2138  break;
2139  }
2140  }
2141  if (dupLine == false) {
2142  groovyFileLines.add(thisline);
2143  // System.err.println("Line: "+thisline);
2144  // for(String s:groovyFileLines){
2145  // //System.err.println("\t\t "+s);
2146  // creationEventStackTrace2.printStackTrace();
2147  // }
2148  }
2149  }
2150  } catch (NullPointerException ex) {
2151 
2152  }
2153  }
2154  }
2155 
2156  public CSG historySync(CSG dyingCSG) {
2157  if (useStackTraces) {
2158  this.addCreationEventStringList(dyingCSG.getCreationEventStackTraceList());
2159  }
2160  Set<String> params = dyingCSG.getParameters();
2161  for (String param : params) {
2162  boolean existing = false;
2163  for (String s : this.getParameters()) {
2164  if (s.contentEquals(param))
2165  existing = true;
2166  }
2167  if (!existing) {
2168  Parameter vals = CSGDatabase.get(param);
2169  if (vals != null)
2170  this.setParameter(vals, dyingCSG.getMapOfparametrics().get(param));
2171  }
2172  }
2173  this.setColor(dyingCSG.getColor());
2174  if (getName().length() == 0)
2175  setName(dyingCSG.getName());
2176  return this;
2177  }
2178 
2179  public CSG addCreationEventStringList(ArrayList<String> incoming) {
2180  if (useStackTraces)
2181  for (String s : incoming) {
2182  addCreationEventString(s);
2183  }
2184 
2185  return this;
2186  }
2187 
2188  public CSG addCreationEventString(String thisline) {
2189  if (useStackTraces) {
2190  boolean dupLine = false;
2191  for (String s : groovyFileLines) {
2192  if (s.contentEquals(thisline)) {
2193  dupLine = true;
2194  break;
2195  }
2196  }
2197  if (!dupLine) {
2198  groovyFileLines.add(thisline);
2199  }
2200  }
2201 
2202  return this;
2203  }
2204 
2205  public ArrayList<String> getCreationEventStackTraceList() {
2206  return groovyFileLines;
2207  }
2208 
2209  public CSG prepMfg() {
2210  return prepForManufacturing();
2211  }
2212 
2214  return manufactuing;
2215  }
2216 
2218  return getManufacturing();
2219  }
2220 
2221  public CSG setMfg(PrepForManufacturing manufactuing) {
2222  return setManufacturing(manufactuing);
2223  }
2224 
2226  this.manufactuing = manufactuing;
2227  return this;
2228  }
2229 
2230  @Deprecated
2232  return getManufacturing();
2233  }
2234 
2235  @Deprecated
2237  return setManufacturing(manufactuing);
2238  }
2239 
2240  public CSG setParameter(Parameter w, IParametric function) {
2241  if (w == null)
2242  return this;
2243  if (CSGDatabase.get(w.getName()) == null)
2244  CSGDatabase.set(w.getName(), w);
2245  if (getMapOfparametrics().get(w.getName()) == null)
2246  getMapOfparametrics().put(w.getName(), function);
2247  return this;
2248  }
2249 
2251  setParameter(w, new IParametric() {
2252  @Override
2253  public CSG change(CSG oldCSG, String parameterKey, Long newValue) {
2254  if (parameterKey.contentEquals(w.getName()))
2255  CSGDatabase.get(w.getName()).setValue(newValue);
2256  return oldCSG;
2257  }
2258  });
2259  return this;
2260  }
2261 
2262  public CSG setParameter(String key, double defaultValue, double upperBound, double lowerBound,
2263  IParametric function) {
2264  ArrayList<Double> vals = new ArrayList<Double>();
2265  vals.add(upperBound);
2266  vals.add(lowerBound);
2267  setParameter(new LengthParameter(key, defaultValue, vals), function);
2268  return this;
2269  }
2270 
2271  public CSG setParameterIfNull(String key) {
2272  if (getMapOfparametrics().get(key) == null)
2273  getMapOfparametrics().put(key, new IParametric() {
2274 
2275  @Override
2276  public CSG change(CSG oldCSG, String parameterKey, Long newValue) {
2277  CSGDatabase.get(key).setValue(newValue);
2278  return oldCSG;
2279  }
2280  });
2281  return this;
2282  }
2283 
2284  public Set<String> getParameters() {
2285 
2286  return getMapOfparametrics().keySet();
2287  }
2288 
2289  public CSG setParameterNewValue(String key, double newValue) {
2290  IParametric function = getMapOfparametrics().get(key);
2291  if (function != null)
2292  return function.change(this, key, new Long((long) (newValue * 1000))).setManipulator(this.getManipulator())
2293  .setColor(this.getColor());
2294  return this;
2295  }
2296 
2297  public CSG setRegenerate(IRegenerate function) {
2298  regenerate = function;
2299  return this;
2300  }
2301 
2302  public CSG regenerate() {
2303  this.markForRegeneration = false;
2304  if (regenerate == null)
2305  return this;
2306  CSG regenerate2 = regenerate.regenerate(this);
2307  if (regenerate2 != null)
2308  return regenerate2.setManipulator(this.getManipulator()).setColor(this.getColor());
2309  return this;
2310  }
2311 
2312  public HashMap<String, IParametric> getMapOfparametrics() {
2313  if (mapOfparametrics == null) {
2314  mapOfparametrics = new HashMap<>();
2315  }
2316  return mapOfparametrics;
2317  }
2318 
2319  public boolean isMarkedForRegeneration() {
2320  return markForRegeneration;
2321  }
2322 
2323  public void markForRegeneration() {
2324  this.markForRegeneration = true;
2325  }
2326 
2335  public boolean touching(CSG incoming) {
2336  // Fast bounding box overlap check, quick fail if not intersecting
2337  // bounding boxes
2338  if (this.getMaxX() > incoming.getMinX() && this.getMinX() < incoming.getMaxX()
2339  && this.getMaxY() > incoming.getMinY() && this.getMinY() < incoming.getMaxY()
2340  && this.getMaxZ() > incoming.getMinZ() && this.getMinZ() < incoming.getMaxZ()) {
2341  // Run a full intersection
2342  CSG inter = this.intersect(incoming);
2343  if (inter.getPolygons().size() > 0) {
2344  // intersection success
2345  return true;
2346  }
2347  }
2348  return false;
2349  }
2350 
2352  return progressMoniter;
2353  }
2354 
2355  public static void setProgressMoniter(ICSGProgress progressMoniter) {
2356  CSG.progressMoniter = progressMoniter;
2357  }
2358 
2359  public static Color getDefaultColor() {
2360  return defaultcolor;
2361  }
2362 
2363  public static void setDefaultColor(Color defaultcolor) {
2364  CSG.defaultcolor = defaultcolor;
2365  }
2366 
2372  public CSG getBoundingBox() {
2373  return new Cube((-this.getMinX() + this.getMaxX()), (-this.getMinY() + this.getMaxY()),
2374  (-this.getMinZ() + this.getMaxZ())).toCSG().toXMax().movex(this.getMaxX()).toYMax()
2375  .movey(this.getMaxY()).toZMax().movez(this.getMaxZ());
2376  }
2377 
2378  public String getName() {
2379  return name;
2380  }
2381 
2382  public CSG setName(String name) {
2383  this.name = name;
2384  return this;
2385  }
2386 
2387  @Override
2388  public String toString() {
2389  if (name == null)
2390  return getColor().toString();
2391  return getName() + " " + getColor().toString();
2392  }
2393 
2394  public ArrayList<Transform> getSlicePlanes() {
2395  return slicePlanes;
2396  }
2397 
2398  public void addSlicePlane(Transform slicePlane) {
2399  if (slicePlanes == null)
2400  slicePlanes = new ArrayList<>();
2401  this.slicePlanes.add(slicePlane);
2402 
2403  }
2404 
2408  public ArrayList<String> getExportFormats() {
2409  return exportFormats;
2410  }
2411 
2412  public void clearExportFormats() {
2413  if (exportFormats != null)
2414  exportFormats.clear();
2415  }
2416 
2420  public void addExportFormat(String exportFormat) {
2421  if (this.exportFormats == null)
2422  this.exportFormats = new ArrayList<>();
2423  for (String f : exportFormats) {
2424  if (f.toLowerCase().contains(exportFormat.toLowerCase())) {
2425  return;
2426  }
2427  }
2428  this.exportFormats.add(exportFormat.toLowerCase());
2429  }
2430 
2431  public static int getNumfacesinoffset() {
2432  return getNumFacesInOffset();
2433  }
2434 
2435  public static int getNumFacesInOffset() {
2436  return numFacesInOffset;
2437  }
2438 
2439  public static void setNumFacesInOffset(int numFacesInOffset) {
2440  CSG.numFacesInOffset = numFacesInOffset;
2441  }
2442 
2443  public static boolean isUseStackTraces() {
2444  return useStackTraces;
2445  }
2446 
2447  public static void setUseStackTraces(boolean useStackTraces) {
2448  CSG.useStackTraces = useStackTraces;
2449  }
2450 
2451  public ArrayList<Transform> getDatumReferences() {
2452  return datumReferences;
2453  }
2454 
2455  private void setDatumReferences(ArrayList<Transform> datumReferences) {
2456  this.datumReferences = datumReferences;
2457  }
2458 
2460  return str;
2461  }
2462 
2463  public void setStorage(PropertyStorage storage) {
2464  this.str = storage;
2465  }
2466 
2513  public ArrayList<CSG> addTabs(Vector3d edgeDirection, CSG fastener) throws Exception {
2514 
2515  ArrayList<CSG> result = new ArrayList<CSG>();
2516  ArrayList<CSG> fasteners = new ArrayList<CSG>();
2517 
2518  // Apply cumulative transformation to the board
2519  Transform boardTrans = addTabsReorientation(edgeDirection);
2520  CSG boardTemp = this.transformed(boardTrans);
2521 
2522  // TODO: Here, find the polygon defined by the XY plane slice that is perhaps
2523  // 0.5mm into the +Y. Add tabs to THAT polygon's minX/maxX instead of part's
2524  // global minX/maxX.
2525 
2526  // Define the size of the tabs and the distance between tab cycles
2527  double tabSize = boardTemp.getMaxZ() * 2;
2528  double cycleSize = tabSize * 3;
2529 
2530  // Determine the minimum buffer space between the edge of the board and the tabs
2531  double minBuffer = boardTemp.getMaxZ();
2532 
2533  // Create a temporary CSG object for a single tab
2534  CSG tabTemp = new Cube(tabSize, boardTemp.getMaxZ(), boardTemp.getMaxZ()).toCSG();
2535 
2536  // Position the temporary tab object at the first tab location
2537  tabTemp = tabTemp.movex(tabTemp.getMaxX()).movey(-tabTemp.getMaxY() + boardTemp.getMinY())
2538  .movez(tabTemp.getMaxZ());
2539 
2540  // Position the temporary fastener hole object at an initial fastener hole
2541  // location that does not actually render (analogous to the first tab location,
2542  // but the first tab is not associated with a fastener)
2543  CSG fastenerHoleTemp = fastener.rotx(-90).movex(-tabSize).movey(0).movez(boardTemp.getMaxZ() / 2);
2544 
2545  // Calculate the number of full tab-space cycles to add, not including the first
2546  // tab (this is also the number of fastener objects to return)
2547  int iterNum = (int) Math.floor((boardTemp.getMaxX() - tabSize - minBuffer * 2) / cycleSize); // Round down to
2548  // ensure an
2549  // integer value
2550 
2551  // Calculate the clearance beyond the outermost tabs, equal on both sides and
2552  // never more than minBuffer
2553  double bufferVal = (boardTemp.getMaxX() - (tabSize + cycleSize * iterNum)) / 2;
2554 
2555  // Add the first tab if there is enough room, which due to not being paired with
2556  // a fastener is removed from the loop
2557  if (boardTemp.getTotalX() > tabSize + 2 * bufferVal) {
2558  boardTemp = boardTemp.union(tabTemp.movex(bufferVal));
2559  }
2560 
2561  // Add the desired number of tabs & fasteners at regular intervals
2562  for (int i = 1; i <= iterNum; i++) {
2563  double xVal = bufferVal + i * cycleSize;
2564  boardTemp = boardTemp.union(tabTemp.movex(xVal));
2565  fasteners.add(fastenerHoleTemp.movex(xVal).transformed(boardTrans.inverse()));
2566  }
2567 
2568  // Translate the boardTemp object back to its original position
2569  boardTemp = boardTemp.transformed(boardTrans.inverse());
2570 
2571  result.add(boardTemp);
2572  result.addAll(fasteners);
2573 
2574  return result;
2575  }
2576 
2582  private Transform addTabsReorientation(Vector3d edgeDirection) throws Exception {
2583  // Instantiate a new transformation which will capture cumulative
2584  // transformations being operated on the input board, to be reversed later
2585  Transform boardTrans = new Transform();
2586 
2587  // Determine orientation transformation, based on edgeDirection vector
2588  if (edgeDirection.equals(Vector3d.X_ONE)) {
2589  boardTrans = boardTrans.rotz(90);
2590  } else if (edgeDirection.equals(Vector3d.X_ONE.negated())) {
2591  boardTrans = boardTrans.rotz(-90);
2592  } else if (edgeDirection.equals(Vector3d.Y_ONE)) {
2593  boardTrans = boardTrans.rotz(180);
2594  } else if (edgeDirection.equals(Vector3d.Y_ONE.negated())) {
2595  // boardTrans = boardTrans; // original addTabs orientation, so no
2596  // transformation needed
2597  } else if (edgeDirection.equals(Vector3d.Z_ONE)) {
2598  boardTrans = boardTrans.rotx(-90);
2599  } else if (edgeDirection.equals(Vector3d.Z_ONE.negated())) {
2600  boardTrans = boardTrans.rotx(90);
2601  } else {
2602  throw new Exception(
2603  "Invalid edge direction: edgeDirection must be a cartesian unit Vector3d object. Try Vector3d.Y_ONE.negated() - Current value: "
2604  + edgeDirection.toString());
2605  }
2606 
2607  // Apply orientation transformation
2608  CSG boardTemp = this.transformed(boardTrans);
2609 
2610  // Translate the boardTemp object so that its minimum corner is at the origin,
2611  // adding to cumulative transformation
2612  boardTrans = boardTrans.movex(-boardTemp.getMinX()).movey(-boardTemp.getMinY()).movez(-boardTemp.getMinZ());
2613 
2614  // Apply translation transformation
2615  boardTemp = this.transformed(boardTrans);
2616 
2617  // If the board is larger in Z than in X, assume that the board is oriented into
2618  // the XY plane and rotate to flatten it onto the XY plane
2619  if (boardTemp.getTotalZ() > boardTemp.getTotalX()) {
2620  boardTrans = boardTrans.roty(-90).movez(boardTemp.getMaxX());
2621  }
2622  return boardTrans;
2623  }
2624 
2625  public ArrayList<CSG> addTabs(Vector3d edgeDirection, LengthParameter fastenerHoleDiameter) throws Exception {
2626 
2627  // Apply cumulative transformation to the board
2628  Transform boardTrans = addTabsReorientation(edgeDirection);
2629  CSG boardTemp = this.transformed(boardTrans);
2630 
2631  // Create a temporary CSG object for a single fastener hole
2632  double fastenerHoleRadius = fastenerHoleDiameter.getMM() / 2.0;
2633  double fastenerHoleDepth = boardTemp.getMaxZ();
2634  CSG fastenerHoleTemp = new Cylinder(fastenerHoleRadius, fastenerHoleDepth).toCSG();
2635  ArrayList<CSG> result = this.addTabs(edgeDirection, fastenerHoleTemp);
2636  return result;
2637  }
2638 
2639  CSG addAssemblyStep(int stepNumber, Transform explodedPose) {
2640  String key = "AssemblySteps";
2641  PropertyStorage incomingGetStorage = getAssemblyStorage();
2642  if (incomingGetStorage.getValue(key) == Optional.empty()) {
2643  HashMap<Integer, Transform> map = new HashMap<>();
2644  incomingGetStorage.set(key, map);
2645  }
2646  if (incomingGetStorage.getValue("MaxAssemblyStep") == Optional.empty()) {
2647  incomingGetStorage.set("MaxAssemblyStep", Integer.valueOf(stepNumber));
2648  }
2649  Integer max = (Integer) incomingGetStorage.getValue("MaxAssemblyStep").get();
2650  if (stepNumber > max.intValue()) {
2651  incomingGetStorage.set("MaxAssemblyStep", Integer.valueOf(stepNumber));
2652  }
2653  HashMap<Integer, Transform> map = (HashMap<Integer, Transform>) incomingGetStorage.getValue(key).get();
2654  map.put(stepNumber, explodedPose);
2655  if (incomingGetStorage.getValue("AssembleAffine") == Optional.empty())
2656  incomingGetStorage.set("AssembleAffine", new Affine());
2657  return this;
2658  }
2659 
2661  if (assembly == null)
2662  assembly = new PropertyStorage();
2663  return assembly;
2664  }
2665 
2666  public boolean isWireFrame() {
2667  if (!getStorage().getValue("skeleton").isPresent())
2668  return false;
2669  return (boolean) getStorage().getValue("skeleton").get();
2670  }
2671 
2672  public void setIsWireFrame(boolean b) {
2673  getStorage().set("skeleton", b);
2674  }
2675 
2676  public void setPrintBedNumber(int index) {
2677  getStorage().set("printBedIndex", index);
2678  }
2679 
2680  public int getPrintBedIndex() {
2681  if (!getStorage().getValue("printBedIndex").isPresent())
2682  return 0;
2683  return (int) getStorage().getValue("printBedIndex").get();
2684  }
2685  public static CSG text(String text, double height, double fontSize) {
2686  return text( text, height, fontSize, "Arial");
2687  }
2688  public static CSG text(String text, double height) {
2689  return text( text, height, 30);
2690  }
2691  public static CSG text(String text, double height, double fontSize, String fontType) {
2692  javafx.scene.text.Font font = new javafx.scene.text.Font(fontType, fontSize);
2693  ArrayList<CSG> stuff = TextExtrude.text(height,text,font);
2694  CSG back =null;
2695  for(int i=0;i<stuff.size();i++) {
2696  if(back==null)
2697  back=stuff.get(i);
2698  else {
2699  back=back.dumbUnion(stuff.get(i));
2700  }
2701  }
2702  back=back.rotx(180)
2703  .toZMin();
2704  return back;
2705  }
2714  public static CSG textToSize(String text, double x, double y, double z) {
2715  CSG startText = CSG.text( text, z) ;
2716  double scalex = x/startText.getTotalX();
2717  double scaley = y/startText.getTotalY();
2718  return startText
2719  .scalex(scalex)
2720  .scaley(scaley)
2721  .toXMin();
2722  }
2723 
2724 
2725 
2726 }
boolean intersects(Polygon p)
Definition: Bounds.java:159
CSG movez(Number howFarToMove)
Definition: CSG.java:439
void setOptType(OptType optType)
Definition: CSG.java:1923
CSG setParameter(Parameter w)
Definition: CSG.java:2250
CSG move(Vertex v)
Definition: CSG.java:410
PrepForManufacturing getMfg()
Definition: CSG.java:2217
void markForRegeneration()
Definition: CSG.java:2323
Vector3d getCenter()
Definition: CSG.java:1788
static void setProgressMoniter(ICSGProgress progressMoniter)
Definition: CSG.java:2355
CSG minkowskiDifference(CSG itemToDifference, CSG minkowskiObject)
Definition: CSG.java:2034
CSG _unionCSGBoundsOpt(CSG csg)
Definition: CSG.java:937
static CSG fromPolygons(Polygon... polygons)
Definition: CSG.java:634
MeshView getMesh()
Definition: CSG.java:252
CSG setParameterNewValue(String key, double newValue)
Definition: CSG.java:2289
CSG addCreationEventStackTraceList(ArrayList< Exception > incoming)
Definition: CSG.java:2120
CSG movex(Number howFarToMove)
Definition: CSG.java:449
String toObjString()
Definition: CSG.java:1654
static CSG text(String text, double height, double fontSize, String fontType)
Definition: CSG.java:2691
CSG toYMin(CSG target)
Definition: CSG.java:338
CSG transformed(Transform transform)
Definition: CSG.java:1676
CSG move(Number[] posVector)
Definition: CSG.java:418
void setPolygons(List< Polygon > polygons)
Definition: CSG.java:1932
void fixDegenerates(ArrayList< Polygon > toAdd, Polygon p)
Definition: CSG.java:1456
List< Polygon > getPolygons()
Definition: CSG.java:698
ArrayList< CSG > move(ArrayList< Transform > p)
Definition: CSG.java:489
CSG _differencePolygonBoundsOpt(CSG csg)
Definition: CSG.java:1199
CSG color(Color c)
Definition: CSG.java:1555
void clearExportFormats()
Definition: CSG.java:2412
ArrayList< CSG > minkowski(CSG travelingShape)
Definition: CSG.java:2012
CSG _differenceCSGBoundsOpt(CSG csg)
Definition: CSG.java:1181
CSG dumbUnion(CSG csg)
Definition: CSG.java:763
Set< String > getParameters()
Definition: CSG.java:2284
static int getNumFacesInOffset()
Definition: CSG.java:2435
CSG setName(String name)
Definition: CSG.java:2382
CSG scaley(Number scaleValue)
Definition: CSG.java:591
Transform addTabsReorientation(Vector3d edgeDirection)
Definition: CSG.java:2582
HashMap< String, IParametric > getMapOfparametrics()
Definition: CSG.java:2312
CSG setManipulator(Affine manipulator)
Definition: CSG.java:235
MeshView newMesh()
Definition: CSG.java:264
ArrayList< String > exportFormats
Definition: CSG.java:147
void addExportFormat(String exportFormat)
Definition: CSG.java:2420
void addSlicePlane(Transform slicePlane)
Definition: CSG.java:2398
boolean triangulated
Definition: CSG.java:149
CSG setParameter(String key, double defaultValue, double upperBound, double lowerBound, IParametric function)
Definition: CSG.java:2262
void addStackTrace(Exception creationEventStackTrace2)
Definition: CSG.java:2128
StringBuilder toObjString(StringBuilder sb)
Definition: CSG.java:1567
ArrayList< CSG > addTabs(Vector3d edgeDirection, LengthParameter fastenerHoleDiameter)
Definition: CSG.java:2625
static CSG fromPolygons(PropertyStorage storage, List< Polygon > polygons)
Definition: CSG.java:645
CSG hull(List< CSG > csgs)
Definition: CSG.java:895
CSG setParameter(Parameter w, IParametric function)
Definition: CSG.java:2240
MeshContainer toJavaFXMesh(CadInteractionEvent interact)
Definition: CSG.java:1703
CSG rotz(Number degreesToRotate)
Definition: CSG.java:550
CSG prepForManufacturing()
Definition: CSG.java:179
static CSG unionAll(CSG... csgs)
Definition: CSG.java:871
CSG move(Number x, Number y, Number z)
Definition: CSG.java:406
CSG toXMin(CSG target)
Definition: CSG.java:318
static Color defaultcolor
Definition: CSG.java:129
CSG union(CSG csg)
Definition: CSG.java:736
CSG minkowskiDifference(CSG itemToDifference, double tolerance)
Definition: CSG.java:2057
CSG optimization(OptType type)
Definition: CSG.java:708
CSG triangulate(boolean fix)
Definition: CSG.java:1401
StringBuilder toStlString(StringBuilder sb)
Definition: CSG.java:1383
CSG setManufactuing(PrepForManufacturing manufactuing)
Definition: CSG.java:2236
static boolean isUseStackTraces()
Definition: CSG.java:2443
void setPrintBedNumber(int index)
Definition: CSG.java:2676
CSG setTemporaryColor(Color color)
Definition: CSG.java:221
MeshContainer toJavaFXMeshSimple(CadInteractionEvent interact)
Definition: CSG.java:1727
ArrayList< CSG > addTabs(Vector3d edgeDirection, CSG fastener)
Definition: CSG.java:2513
CSG toYMax(CSG target)
Definition: CSG.java:348
static CSG hullAll(CSG... csgs)
Definition: CSG.java:880
CSG scale(Number scaleValue)
Definition: CSG.java:611
static int getNumfacesinoffset()
Definition: CSG.java:2431
CSG _unionPolygonBoundsOpt(CSG csg)
Definition: CSG.java:949
boolean isMarkedForRegeneration()
Definition: CSG.java:2319
PropertyStorage getAssemblyStorage()
Definition: CSG.java:2660
CSG difference(List< CSG > csgs)
Definition: CSG.java:1061
PropertyStorage getStorage()
Definition: CSG.java:2459
ArrayList< CSG > mink(CSG travelingShape)
Definition: CSG.java:1971
PrepForManufacturing getManufactuing()
Definition: CSG.java:2231
ArrayList< Transform > getDatumReferences()
Definition: CSG.java:2451
CSG addDatumReference(Transform t)
Definition: CSG.java:172
CSG movey(Number howFarToMove)
Definition: CSG.java:429
CSG move(Vector3d v)
Definition: CSG.java:414
CSG setManufacturing(PrepForManufacturing manufactuing)
Definition: CSG.java:2225
static boolean useStackTraces
Definition: CSG.java:151
static CSG hullAll(List< CSG > csgs)
Definition: CSG.java:884
boolean touching(CSG incoming)
Definition: CSG.java:2335
static void setUseStackTraces(boolean useStackTraces)
Definition: CSG.java:2447
List< Polygon > polygons
Definition: CSG.java:114
ArrayList< String > getExportFormats()
Definition: CSG.java:2408
String toStlString()
Definition: CSG.java:1370
static ArrayList< CSG > move(ArrayList< CSG > slice, ArrayList< Transform > p)
Definition: CSG.java:497
CSG difference(CSG... csgs)
Definition: CSG.java:1102
CSG _unionIntersectOpt(CSG csg)
Definition: CSG.java:990
CSG rot(Number[] posVector)
Definition: CSG.java:539
Affine getManipulator()
Definition: CSG.java:2114
void setDatumReferences(ArrayList< Transform > datumReferences)
Definition: CSG.java:2455
CSG historySync(CSG dyingCSG)
Definition: CSG.java:2156
boolean isWireFrame()
Definition: CSG.java:2666
CSG setRegenerate(IRegenerate function)
Definition: CSG.java:2297
CSG makeKeepaway(Number sn)
Definition: CSG.java:2090
static CSG fromPolygons(PropertyStorage storage, Polygon... polygons)
Definition: CSG.java:665
ArrayList< CSG > minovsky(CSG travelingShape)
Definition: CSG.java:1960
CSG setColor(Color color)
Definition: CSG.java:207
CSG intersect(List< CSG > csgs)
Definition: CSG.java:1318
ArrayList< String > getCreationEventStackTraceList()
Definition: CSG.java:2205
PropertyStorage str
Definition: CSG.java:123
CSG difference(CSG csg)
Definition: CSG.java:1129
static int numFacesInOffset
Definition: CSG.java:111
CSG hull(CSG... csgs)
Definition: CSG.java:926
CSG intersect(CSG... csgs)
Definition: CSG.java:1360
CSG toXMax(CSG target)
Definition: CSG.java:328
CSG rotx(Number degreesToRotate)
Definition: CSG.java:570
CSG intersect(CSG csg)
Definition: CSG.java:1275
CSG toZMin(CSG target)
Definition: CSG.java:298
void updatePolygons(ArrayList< Polygon > toAdd, ArrayList< Polygon > degenerates, Polygon p)
Definition: CSG.java:1510
OptType getOptType()
Definition: CSG.java:1905
static void setDefaultOptType(OptType optType)
Definition: CSG.java:1914
CSG addCreationEventStringList(ArrayList< String > incoming)
Definition: CSG.java:2179
static Color getDefaultColor()
Definition: CSG.java:2359
ArrayList< Transform > getSlicePlanes()
Definition: CSG.java:2394
CSG rot(Number x, Number y, Number z)
Definition: CSG.java:535
static CSG text(String text, double height, double fontSize)
Definition: CSG.java:2685
CSG addCreationEventString(String thisline)
Definition: CSG.java:2188
HashMap< String, IParametric > mapOfparametrics
Definition: CSG.java:142
CSG setMfg(PrepForManufacturing manufactuing)
Definition: CSG.java:2221
static void setDefaultColor(Color defaultcolor)
Definition: CSG.java:2363
CSG scalex(Number scaleValue)
Definition: CSG.java:601
PropertyStorage assembly
Definition: CSG.java:124
CSG _differenceNoOpt(CSG csg)
Definition: CSG.java:1231
PrepForManufacturing getManufacturing()
Definition: CSG.java:2213
CSG toolOffset(Number sn)
Definition: CSG.java:2064
static CSG fromPolygons(List< Polygon > polygons)
Definition: CSG.java:621
ArrayList< Transform > slicePlanes
Definition: CSG.java:146
int getNumFacesForOffsets()
Definition: CSG.java:2086
static ICSGProgress getProgressMoniter()
Definition: CSG.java:2351
CSG _unionNoOpt(CSG csg)
Definition: CSG.java:1023
void setIsWireFrame(boolean b)
Definition: CSG.java:2672
static void setNumFacesInOffset(int numFacesInOffset)
Definition: CSG.java:2439
static ICSGProgress progressMoniter
Definition: CSG.java:153
CSG roty(Number degreesToRotate)
Definition: CSG.java:560
static CSG textToSize(String text, double x, double y, double z)
Definition: CSG.java:2714
CSG toZMax(CSG target)
Definition: CSG.java:308
static CSG unionAll(List< CSG > csgs)
Definition: CSG.java:875
CSG scalez(Number scaleValue)
Definition: CSG.java:581
CSG setParameterIfNull(String key)
Definition: CSG.java:2271
CSG weighted(WeightFunction f)
Definition: CSG.java:1665
ArrayList< CSG > minkowskiHullShape(CSG travelingShape)
Definition: CSG.java:1985
static CSG text(String text, double height)
Definition: CSG.java:2688
void setStorage(PropertyStorage storage)
Definition: CSG.java:2463
static MeshContainer meshFromPolygon(Polygon... poly)
static void setProvider(IDebug3dProvider provider)
final List< Vertex > vertices
Definition: Polygon.java:54
ArrayList< Vertex > getDegeneratePoints()
Definition: Polygon.java:688
void set(String key, Object property)
Transform movey(Number howFarToMove)
Definition: Transform.java:631
Transform roty(Number degreesToRotate)
Definition: Transform.java:705
Transform rotx(Number degreesToRotate)
Definition: Transform.java:716
Transform translateZ(double value)
Definition: Transform.java:313
Transform rotz(Number degreesToRotate)
Definition: Transform.java:694
Transform movez(Number howFarToMove)
Definition: Transform.java:642
Transform translateX(double value)
Definition: Transform.java:217
static Transform unity()
Definition: Transform.java:85
Transform translateY(double value)
Definition: Transform.java:299
Transform movex(Number howFarToMove)
Definition: Transform.java:653
static final Vector3d X_ONE
Definition: Vector3d.java:63
static Vector3d y(double y)
Definition: Vector3d.java:484
static final Vector3d ZERO
Definition: Vector3d.java:57
static Vector3d z(double z)
Definition: Vector3d.java:494
static Vector3d x(double x)
Definition: Vector3d.java:474
static final Vector3d Z_ONE
Definition: Vector3d.java:69
static final Vector3d Y_ONE
Definition: Vector3d.java:66
Vertex transform(Transform transform)
Definition: Vertex.java:158
StringBuilder toObjString(StringBuilder sb)
Definition: Vertex.java:138
static List< eu.mihosoft.vrl.v3d.Polygon > concaveToConvex(eu.mihosoft.vrl.v3d.Polygon incoming)
static void set(String key, Parameter value)
static Parameter get(String key)
void progressUpdate(int currentIndex, int finalIndex, String type, CSG intermediateShape)
CSG change(CSG oldCSG, String parameterKey, Long newValue)