34 package eu.mihosoft.vrl.v3d;
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;
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;
50 import java.util.stream.Collectors;
51 import java.util.stream.Stream;
53 import com.neuronrobotics.interaction.CadInteractionEvent;
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;
108 @SuppressWarnings(
"restriction")
111 private static int numFacesInOffset = 15;
117 private static OptType defaultOptType = OptType.CSG_BOUND;
120 private OptType optType =
null;
129 private static Color defaultcolor = Color.web(
"#007956");
132 private Color color = getDefaultColor();
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<>();
142 private HashMap<String, IParametric> mapOfparametrics =
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;
150 private static boolean needsDegeneratesPruned=
false;
151 private static boolean useStackTraces =
true;
155 public void progressUpdate(
int currentIndex,
int finalIndex, String type,
CSG intermediateShape) {
156 System.out.println(type +
"ing " + currentIndex +
" of " + finalIndex);
166 if (useStackTraces) {
168 addStackTrace(
new Exception());
173 if (getDatumReferences() ==
null)
174 setDatumReferences(
new ArrayList<Transform>());
175 getDatumReferences().add(t);
180 if (getManufacturing() ==
null)
182 CSG ret = getManufacturing().prep(
this);
209 if (current !=
null) {
210 PhongMaterial m =
new PhongMaterial(getColor());
211 current.setMaterial(m);
222 if (current !=
null) {
223 PhongMaterial m =
new PhongMaterial(color);
224 current.setMaterial(m);
236 if (manipulator ==
null)
238 Affine old = manipulator;
239 this.manipulator = manipulator;
240 if (current !=
null) {
241 current.getTransforms().clear();
242 current.getTransforms().add(manipulator);
270 PhongMaterial m =
new PhongMaterial(getColor());
271 current.setMaterial(m);
273 boolean hasManipulator = getManipulator() !=
null;
274 boolean hasAssembly = getAssemblyStorage().getValue(
"AssembleAffine") != Optional.empty();
276 if (hasManipulator || hasAssembly)
277 current.getTransforms().clear();
280 current.getTransforms().add(getManipulator());
282 current.getTransforms().add((Affine) getAssemblyStorage().getValue(
"AssembleAffine").
get());
284 current.setCullFace(CullFace.NONE);
286 current.setDrawMode(DrawMode.LINE);
288 current.setDrawMode(DrawMode.FILL);
406 public CSG move(Number x, Number y, Number z) {
407 return transformed(
new Transform().translate(x.doubleValue(), y.doubleValue(), z.doubleValue()));
415 return transformed(
new Transform().translate(v.
x, v.
y, v.
z));
419 return move(posVector[0], posVector[1], posVector[2]);
459 return this.movex(-this.getCenterX());
468 return this.movey(-this.getCenterY());
477 return this.movez(-this.getCenterZ());
486 return this.movex(-this.getCenterX()).
movey(-this.getCenterY()).
movez(-this.getCenterZ());
489 public ArrayList<CSG>
move(ArrayList<Transform> p) {
490 ArrayList<CSG> bits =
new ArrayList<CSG>();
492 bits.add(this.clone());
494 return move(bits, p);
497 public static ArrayList<CSG>
move(ArrayList<CSG> slice, ArrayList<Transform> p) {
498 ArrayList<CSG> s =
new ArrayList<CSG>();
500 for (
int i = 0; i < slice.size() && i < p.size(); i++) {
501 s.add(slice.get(i).transformed(p.get(i)));
514 return this.scaley(-1);
523 return this.scalez(-1);
532 return this.scalex(-1);
535 public CSG rot(Number x, Number y, Number z) {
536 return rotx(x.doubleValue()).
roty(y.doubleValue()).
rotz(z.doubleValue());
540 return rot(posVector[0], posVector[1], posVector[2]);
551 return this.transformed(
new Transform().rotZ(degreesToRotate.doubleValue()));
561 return this.transformed(
new Transform().rotY(degreesToRotate.doubleValue()));
571 return this.transformed(
new Transform().rotX(degreesToRotate.doubleValue()));
582 return this.transformed(
new Transform().scaleZ(scaleValue.doubleValue()));
592 return this.transformed(
new Transform().scaleY(scaleValue.doubleValue()));
602 return this.transformed(
new Transform().scaleX(scaleValue.doubleValue()));
612 return this.transformed(
new Transform().scale(scaleValue.doubleValue()));
635 return fromPolygons(Arrays.asList(polygons));
652 for (
Polygon polygon : polygons) {
653 polygon.setStorage(storage);
666 return fromPolygons(storage, Arrays.asList(polygons));
680 Stream<Polygon> polygonStream;
687 polygonStream=getPolygons().stream();
688 csg.
setPolygons(polygonStream.map((
Polygon p) -> p!=
null?p.
clone():
null).filter(p-> p!=
null).collect(Collectors.toList()));
709 this.setOptType(type);
739 switch (getOptType()) {
765 CSG result = this.clone();
797 public CSG union(List<CSG> csgs) {
823 for (
int i = 0; i < csgs.size(); i++) {
824 CSG csg = csgs.get(i);
825 result = result.
union(csg);
826 if (Thread.interrupted())
858 return union(Arrays.asList(csgs));
872 return unionAll(Arrays.asList(csgs));
876 CSG first = csgs.get(0);
877 return first.
union(csgs.stream().skip(1).collect(Collectors.toList()));
881 return hullAll(Arrays.asList(csgs));
897 CSG csgsUnion =
new CSG();
902 csgs.stream().forEach((csg) -> {
903 csgsUnion.
getPolygons().addAll(csg.clone().getPolygons());
907 csgsUnion.
getPolygons().forEach(p -> p.setStorage(getStorage()));
909 return csgsUnion.
hull();
928 return hull(Arrays.asList(csgs));
940 return _unionIntersectOpt(csg);
950 List<Polygon> inner =
new ArrayList<>();
951 List<Polygon> outer =
new ArrayList<>();
955 this.getPolygons().stream().forEach((p) -> {
963 List<Polygon> allPolygons =
new ArrayList<>();
965 if (!inner.isEmpty()) {
968 allPolygons.addAll(outer);
971 allPolygons.addAll(this.getPolygons());
976 if (getName().length() != 0 && csg.
getName().length() != 0) {
991 boolean intersects =
false;
995 for (
Polygon p : getPolygons()) {
1002 List<Polygon> allPolygons =
new ArrayList<>();
1005 return _unionNoOpt(csg);
1007 allPolygons.addAll(this.getPolygons());
1011 if (getName().length() != 0 && csg.
getName().length() != 0) {
1024 Node a =
new Node(this.clone().getPolygons());
1031 a.build(b.allPolygons());
1033 if (getName().length() != 0 && csg.
getName().length() != 0) {
1063 if (csgs.isEmpty()) {
1064 return this.clone();
1067 CSG csgsUnion = csgs.get(0);
1069 for (
int i = 1; i < csgs.size(); i++) {
1070 csgsUnion = csgsUnion.
union(csgs.get(i));
1071 progressMoniter.
progressUpdate(i, csgs.size(),
"Difference", csgsUnion);
1073 if (Thread.interrupted())
1077 return difference(csgsUnion);
1104 return difference(Arrays.asList(csgs));
1136 if (this.getPolygons().size() > 0 && csg.
getPolygons().size() > 0) {
1137 switch (getOptType()) {
1147 }
catch (Exception ex) {
1155 switch (getOptType()) {
1157 return _differenceCSGBoundsOpt(intersectingParts).
historySync(
this)
1160 return _differencePolygonBoundsOpt(intersectingParts).
historySync(
this)
1167 }
catch (Exception e) {
1168 e.printStackTrace();
1187 if (getName().length() != 0 && csg.
getName().length() != 0) {
1200 List<Polygon> inner =
new ArrayList<>();
1201 List<Polygon> outer =
new ArrayList<>();
1205 this.getPolygons().stream().forEach((p) -> {
1215 List<Polygon> allPolygons =
new ArrayList<>();
1216 allPolygons.addAll(outer);
1219 if (getName().length() != 0 && csg.
getName().length() != 0) {
1233 Node a =
new Node(this.clone().getPolygons());
1242 a.build(b.allPolygons());
1246 if (getName().length() != 0 && csg.
getName().length() != 0) {
1278 Node a =
new Node(this.clone().getPolygons());
1285 a.build(b.allPolygons());
1289 if (getName().length() != 0 && csg.
getName().length() != 0) {
1320 if (csgs.isEmpty()) {
1321 return this.clone();
1324 CSG csgsUnion = csgs.get(0);
1326 for (
int i = 1; i < csgs.size(); i++) {
1327 csgsUnion = csgsUnion.
union(csgs.get(i));
1328 progressMoniter.
progressUpdate(i, csgs.size(),
"Intersect", csgsUnion);
1330 if (Thread.interrupted())
1334 return intersect(csgsUnion);
1362 return intersect(Arrays.asList(csgs));
1371 StringBuilder sb =
new StringBuilder();
1373 return sb.toString();
1386 sb.append(
"solid v3d.csg\n");
1387 this.getPolygons().stream().forEach((
Polygon p) -> {
1390 sb.append(
"endsolid v3d.csg\n");
1392 }
catch (Throwable t) {
1394 t.printStackTrace();
1395 throw new RuntimeException(
"STL failed to build for " + name);
1399 return triangulate(
false);
1402 if(fix && needsDegeneratesPruned)
1408 ArrayList<Polygon> toAdd =
new ArrayList<Polygon>();
1409 ArrayList<Polygon> degenerates =
new ArrayList<Polygon>();
1415 Stream<Polygon> polygonStream;
1416 polygonStream =polygons.stream();
1421 polygonStream.forEach(p -> updatePolygons(toAdd, degenerates, p));
1428 if(degenerates.size()>0) {
1434 Stream<Polygon> degenStreeam;
1435 degenStreeam =polygons.stream();
1436 System.out.println(
"Found "+degenerates.size()+
" degenerate triangles, Attempting to fix");
1437 degenStreeam.forEach(p -> fixDegenerates(toAdd, p));
1439 needsDegeneratesPruned=
true;
1440 toAdd.addAll(degenerates);
1443 if (toAdd.size() > 0) {
1448 }
catch (Throwable t) {
1449 t.printStackTrace();
1461 ArrayList<Polygon> polygonsSharing =
new ArrayList<Polygon>();
1462 ArrayList<Polygon> polygonsSharingFixed =
new ArrayList<Polygon>();
1465 ArrayList<Edge> edges = ptoA.edges();
1466 for(
Edge e :edges) {
1467 if(e.equals(longEdge)) {
1469 polygonsSharing.add(ptoA);
1477 ArrayList<Vertex> newpoints =
new ArrayList<Vertex>();
1478 for(
Vertex v:ptoA.vertices) {
1480 if(e.isThisPointOneOfMine(v)) {
1489 if(!poly.isDegenerate()) {
1490 polygonsSharingFixed.add(poly);
1494 }
catch(Exception ex) {
1495 ex.printStackTrace();
1501 if(polygonsSharing.size()==0) {
1504 if(polygonsSharingFixed.size()>0) {
1505 toAdd.removeAll(polygonsSharing);
1506 toAdd.addAll(polygonsSharingFixed);
1526 for(
Polygon poly :triangles) {
1527 if(poly.isDegenerate()) {
1528 degenerates.add(poly);
1532 }
catch (Throwable ex) {
1534 ex.printStackTrace();
1539 toAdd.addAll(triangles);
1540 }
catch(java.lang.IllegalStateException ise) {
1541 ise.printStackTrace();
1556 getStorage().set(
"material:color",
"" + c.getRed() +
" " + c.getGreen() +
" " + c.getBlue());
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 {
1575 List<Integer> indices;
1576 String materialName;
1578 public PolygonStruct(
PropertyStorage storage, List<Integer> indices, String materialName) {
1579 this.storage = storage;
1580 this.indices = indices;
1581 this.materialName = materialName;
1585 List<Vertex> vertices =
new ArrayList<>();
1586 List<PolygonStruct> indices =
new ArrayList<>();
1588 sb.append(
"\n# Vertices\n");
1590 for (
Polygon p : getPolygons()) {
1591 List<Integer> polyIndices =
new ArrayList<>();
1593 p.vertices.stream().forEach((v) -> {
1594 if (!vertices.contains(v)) {
1597 polyIndices.add(vertices.size());
1599 polyIndices.add(vertices.indexOf(v) + 1);
1602 indices.add(
new PolygonStruct(getStorage(), polyIndices,
" "));
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");
1613 mapping.put(v, startingIndex++);
1614 mapping.put(v1, startingIndex++);
1615 mappingTF.put(t, v);
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");
1627 sb.append(
"\n# Faces").append(
"\n");
1629 for (PolygonStruct ps : indices) {
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);
1640 sb.append(
"f ").append(index1).append(
" ").append(index2).append(
" ").append(index3).append(
"\n");
1644 sb.append(
"\n# End Group v3d.csg").append(
"\n");
1655 StringBuilder sb =
new StringBuilder();
1656 return toObjString(sb).toString();
1666 return new Modifier(f).modified(
this);
1678 if (getPolygons().isEmpty()) {
1682 List<Polygon> newpolygons = this.getPolygons().stream().map(p -> p.transformed(transform))
1683 .collect(Collectors.toList());
1689 if (getName().length() != 0) {
1690 csg.
setName(name +
" transformed by[" + transform +
"]");
1705 return toJavaFXMeshSimple(interact);
1741 if (getPolygons().isEmpty()) {
1746 double minX = Double.POSITIVE_INFINITY;
1747 double minY = Double.POSITIVE_INFINITY;
1748 double minZ = Double.POSITIVE_INFINITY;
1750 double maxX = Double.NEGATIVE_INFINITY;
1751 double maxY = Double.NEGATIVE_INFINITY;
1752 double maxZ = Double.NEGATIVE_INFINITY;
1754 for (
Polygon p : getPolygons()) {
1756 for (
int i = 0; i < p.vertices.size(); i++) {
1758 Vertex vert = p.vertices.get(i);
1760 if (vert.
pos.
x < minX) {
1763 if (vert.
pos.
y < minY) {
1766 if (vert.
pos.
z < minZ) {
1770 if (vert.
pos.
x > maxX) {
1773 if (vert.
pos.
y > maxY) {
1776 if (vert.
pos.
z > maxZ) {
1789 return new Vector3d(getCenterX(), getCenterY(), getCenterZ());
1798 return ((getMinX() / 2) + (getMaxX() / 2));
1807 return ((getMinY() / 2) + (getMaxY() / 2));
1816 return ((getMinZ() / 2) + (getMaxZ() / 2));
1825 return getBounds().getMax().x;
1834 return getBounds().getMax().y;
1843 return getBounds().getMax().z;
1852 return getBounds().getMin().x;
1861 return getBounds().getMin().y;
1870 return getBounds().getMin().z;
1879 return (-this.getMinX() + this.getMaxX());
1888 return (-this.getMinY() + this.getMaxY());
1897 return (-this.getMinZ() + this.getMaxZ());
1906 return optType !=
null ? optType : defaultOptType;
1915 defaultOptType = optType;
1924 this.optType = optType;
1935 this.polygons = polygons;
1941 public static enum OptType {
1961 System.out.println(
"Hail Zeon!");
1962 return minkowski(travelingShape);
1972 return minkowski(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);
1992 for (
Vertex nv : np.vertices) {
2013 HashMap<Vertex, CSG> map =
new HashMap<>();
2015 for (
Vertex v : p.vertices) {
2016 if (map.get(v) ==
null)
2017 map.put(v, this.move(v));
2020 return new ArrayList<CSG>(map.values());
2035 CSG intersection = this.intersect(itemToDifference);
2039 for (
int i = 0; i < csgDiff.size(); i++) {
2041 progressMoniter.
progressUpdate(i, csgDiff.size(),
"Minkowski difference", result);
2058 double shellThickness = Math.abs(tolerance);
2059 if (shellThickness < 0.001)
2061 return minkowskiDifference(itemToDifference,
new Sphere(shellThickness / 2.0, 8, 4).toCSG());
2065 double shellThickness = sn.doubleValue();
2066 boolean cut = shellThickness < 0;
2067 shellThickness = Math.abs(shellThickness);
2068 if (shellThickness < 0.001)
2070 double z = shellThickness;
2071 if (z > this.getTotalZ() / 2)
2072 z = this.getTotalZ() / 2;
2076 ArrayList<CSG> mikObjs = minkowski(printNozzel);
2077 CSG remaining =
this;
2078 for (
CSG bit : mikObjs) {
2083 return union(minkowskiHullShape(printNozzel));
2087 return getNumfacesinoffset();
2091 double shellThickness = sn.doubleValue();
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);
2096 double z = Math.abs(this.getBounds().getMax().z) + Math.abs(this.getBounds().getMin().z);
2098 double xtol = (x + shellThickness) / x;
2099 double ytol = (y + shellThickness) / y;
2100 double ztol = (z + shellThickness) / z;
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;
2107 return this.transformed(
new Transform().scale(xtol, ytol, ztol))
2115 if (manipulator ==
null)
2116 manipulator =
new Affine();
2121 for (Exception ex : incoming) {
2129 for (StackTraceElement el : creationEventStackTrace2.getStackTrace()) {
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)) {
2141 if (dupLine ==
false) {
2142 groovyFileLines.add(thisline);
2150 }
catch (NullPointerException ex) {
2157 if (useStackTraces) {
2161 for (String param : params) {
2162 boolean existing =
false;
2163 for (String s : this.getParameters()) {
2164 if (s.contentEquals(param))
2173 this.setColor(dyingCSG.
getColor());
2174 if (getName().length() == 0)
2181 for (String s : incoming) {
2182 addCreationEventString(s);
2189 if (useStackTraces) {
2190 boolean dupLine =
false;
2191 for (String s : groovyFileLines) {
2192 if (s.contentEquals(thisline)) {
2198 groovyFileLines.add(thisline);
2206 return groovyFileLines;
2210 return prepForManufacturing();
2214 return manufactuing;
2218 return getManufacturing();
2222 return setManufacturing(manufactuing);
2226 this.manufactuing = manufactuing;
2232 return getManufacturing();
2237 return setManufacturing(manufactuing);
2245 if (getMapOfparametrics().
get(w.
getName()) ==
null)
2246 getMapOfparametrics().put(w.
getName(),
function);
2253 public CSG change(
CSG oldCSG, String parameterKey, Long newValue) {
2254 if (parameterKey.contentEquals(w.
getName()))
2262 public CSG setParameter(String key,
double defaultValue,
double upperBound,
double lowerBound,
2264 ArrayList<Double> vals =
new ArrayList<Double>();
2265 vals.add(upperBound);
2266 vals.add(lowerBound);
2272 if (getMapOfparametrics().
get(key) ==
null)
2273 getMapOfparametrics().put(key,
new IParametric() {
2276 public CSG change(
CSG oldCSG, String parameterKey, Long newValue) {
2286 return getMapOfparametrics().keySet();
2290 IParametric function = getMapOfparametrics().get(key);
2291 if (
function !=
null)
2292 return function.
change(
this, key,
new Long((
long) (newValue * 1000))).
setManipulator(this.getManipulator())
2298 regenerate =
function;
2303 this.markForRegeneration =
false;
2304 if (regenerate ==
null)
2307 if (regenerate2 !=
null)
2313 if (mapOfparametrics ==
null) {
2314 mapOfparametrics =
new HashMap<>();
2316 return mapOfparametrics;
2320 return markForRegeneration;
2324 this.markForRegeneration =
true;
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()) {
2342 CSG inter = this.intersect(incoming);
2352 return progressMoniter;
2360 return defaultcolor;
2373 return new Cube((-this.getMinX() + this.getMaxX()), (-this.getMinY() + this.getMaxY()),
2390 return getColor().toString();
2391 return getName() +
" " + getColor().toString();
2399 if (slicePlanes ==
null)
2400 slicePlanes =
new ArrayList<>();
2401 this.slicePlanes.add(slicePlane);
2409 return exportFormats;
2413 if (exportFormats !=
null)
2414 exportFormats.clear();
2421 if (this.exportFormats ==
null)
2422 this.exportFormats =
new ArrayList<>();
2423 for (String f : exportFormats) {
2424 if (f.toLowerCase().contains(exportFormat.toLowerCase())) {
2428 this.exportFormats.add(exportFormat.toLowerCase());
2432 return getNumFacesInOffset();
2436 return numFacesInOffset;
2444 return useStackTraces;
2452 return datumReferences;
2456 this.datumReferences = datumReferences;
2515 ArrayList<CSG> result =
new ArrayList<CSG>();
2516 ArrayList<CSG> fasteners =
new ArrayList<CSG>();
2519 Transform boardTrans = addTabsReorientation(edgeDirection);
2520 CSG boardTemp = this.transformed(boardTrans);
2527 double tabSize = boardTemp.
getMaxZ() * 2;
2528 double cycleSize = tabSize * 3;
2531 double minBuffer = boardTemp.
getMaxZ();
2547 int iterNum = (int) Math.floor((boardTemp.
getMaxX() - tabSize - minBuffer * 2) / cycleSize);
2553 double bufferVal = (boardTemp.
getMaxX() - (tabSize + cycleSize * iterNum)) / 2;
2557 if (boardTemp.
getTotalX() > tabSize + 2 * bufferVal) {
2558 boardTemp = boardTemp.
union(tabTemp.
movex(bufferVal));
2562 for (
int i = 1; i <= iterNum; i++) {
2563 double xVal = bufferVal + i * cycleSize;
2564 boardTemp = boardTemp.
union(tabTemp.
movex(xVal));
2571 result.add(boardTemp);
2572 result.addAll(fasteners);
2589 boardTrans = boardTrans.
rotz(90);
2591 boardTrans = boardTrans.
rotz(-90);
2593 boardTrans = boardTrans.
rotz(180);
2598 boardTrans = boardTrans.
rotx(-90);
2600 boardTrans = boardTrans.
rotx(90);
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());
2608 CSG boardTemp = this.transformed(boardTrans);
2615 boardTemp = this.transformed(boardTrans);
2628 Transform boardTrans = addTabsReorientation(edgeDirection);
2629 CSG boardTemp = this.transformed(boardTrans);
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);
2639 CSG addAssemblyStep(
int stepNumber,
Transform explodedPose) {
2640 String key =
"AssemblySteps";
2642 if (incomingGetStorage.getValue(key) == Optional.empty()) {
2643 HashMap<Integer, Transform> map =
new HashMap<>();
2644 incomingGetStorage.
set(key, map);
2646 if (incomingGetStorage.getValue(
"MaxAssemblyStep") == Optional.empty()) {
2647 incomingGetStorage.
set(
"MaxAssemblyStep", Integer.valueOf(stepNumber));
2649 Integer max = (Integer) incomingGetStorage.getValue(
"MaxAssemblyStep").get();
2650 if (stepNumber > max.intValue()) {
2651 incomingGetStorage.
set(
"MaxAssemblyStep", Integer.valueOf(stepNumber));
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());
2661 if (assembly ==
null)
2667 if (!getStorage().getValue(
"skeleton").isPresent())
2669 return (
boolean) getStorage().getValue(
"skeleton").get();
2673 getStorage().set(
"skeleton", b);
2677 getStorage().set(
"printBedIndex", index);
2681 if (!getStorage().getValue(
"printBedIndex").isPresent())
2683 return (
int) getStorage().getValue(
"printBedIndex").get();
2685 public static CSG text(String text,
double height,
double fontSize) {
2686 return text( text, height, fontSize,
"Arial");
2688 public static CSG text(String text,
double height) {
2689 return text( text, height, 30);
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);
2695 for(
int i=0;i<stuff.size();i++) {
2716 double scalex = x/startText.
getTotalX();
2717 double scaley = y/startText.
getTotalY();
boolean intersects(Polygon p)
CSG movez(Number howFarToMove)
void setOptType(OptType optType)
CSG setParameter(Parameter w)
PrepForManufacturing getMfg()
void markForRegeneration()
static void setProgressMoniter(ICSGProgress progressMoniter)
CSG minkowskiDifference(CSG itemToDifference, CSG minkowskiObject)
CSG _unionCSGBoundsOpt(CSG csg)
static CSG fromPolygons(Polygon... polygons)
CSG setParameterNewValue(String key, double newValue)
CSG addCreationEventStackTraceList(ArrayList< Exception > incoming)
CSG movex(Number howFarToMove)
static CSG text(String text, double height, double fontSize, String fontType)
CSG transformed(Transform transform)
CSG move(Number[] posVector)
void setPolygons(List< Polygon > polygons)
void fixDegenerates(ArrayList< Polygon > toAdd, Polygon p)
List< Polygon > getPolygons()
ArrayList< CSG > move(ArrayList< Transform > p)
CSG _differencePolygonBoundsOpt(CSG csg)
void clearExportFormats()
ArrayList< CSG > minkowski(CSG travelingShape)
CSG _differenceCSGBoundsOpt(CSG csg)
Set< String > getParameters()
static int getNumFacesInOffset()
CSG scaley(Number scaleValue)
Transform addTabsReorientation(Vector3d edgeDirection)
HashMap< String, IParametric > getMapOfparametrics()
CSG setManipulator(Affine manipulator)
ArrayList< String > exportFormats
void addExportFormat(String exportFormat)
void addSlicePlane(Transform slicePlane)
CSG setParameter(String key, double defaultValue, double upperBound, double lowerBound, IParametric function)
void addStackTrace(Exception creationEventStackTrace2)
StringBuilder toObjString(StringBuilder sb)
ArrayList< CSG > addTabs(Vector3d edgeDirection, LengthParameter fastenerHoleDiameter)
static CSG fromPolygons(PropertyStorage storage, List< Polygon > polygons)
CSG hull(List< CSG > csgs)
CSG setParameter(Parameter w, IParametric function)
MeshContainer toJavaFXMesh(CadInteractionEvent interact)
CSG rotz(Number degreesToRotate)
CSG prepForManufacturing()
static CSG unionAll(CSG... csgs)
CSG move(Number x, Number y, Number z)
static Color defaultcolor
CSG minkowskiDifference(CSG itemToDifference, double tolerance)
CSG optimization(OptType type)
CSG triangulate(boolean fix)
StringBuilder toStlString(StringBuilder sb)
CSG setManufactuing(PrepForManufacturing manufactuing)
static boolean isUseStackTraces()
void setPrintBedNumber(int index)
CSG setTemporaryColor(Color color)
MeshContainer toJavaFXMeshSimple(CadInteractionEvent interact)
ArrayList< CSG > addTabs(Vector3d edgeDirection, CSG fastener)
static CSG hullAll(CSG... csgs)
CSG scale(Number scaleValue)
static int getNumfacesinoffset()
CSG _unionPolygonBoundsOpt(CSG csg)
boolean isMarkedForRegeneration()
PropertyStorage getAssemblyStorage()
CSG difference(List< CSG > csgs)
PropertyStorage getStorage()
ArrayList< CSG > mink(CSG travelingShape)
PrepForManufacturing getManufactuing()
ArrayList< Transform > getDatumReferences()
CSG addDatumReference(Transform t)
CSG movey(Number howFarToMove)
CSG setManufacturing(PrepForManufacturing manufactuing)
static boolean useStackTraces
static CSG hullAll(List< CSG > csgs)
boolean touching(CSG incoming)
static void setUseStackTraces(boolean useStackTraces)
ArrayList< String > getExportFormats()
static ArrayList< CSG > move(ArrayList< CSG > slice, ArrayList< Transform > p)
CSG difference(CSG... csgs)
CSG _unionIntersectOpt(CSG csg)
CSG rot(Number[] posVector)
void setDatumReferences(ArrayList< Transform > datumReferences)
CSG historySync(CSG dyingCSG)
CSG setRegenerate(IRegenerate function)
CSG makeKeepaway(Number sn)
static CSG fromPolygons(PropertyStorage storage, Polygon... polygons)
ArrayList< CSG > minovsky(CSG travelingShape)
CSG setColor(Color color)
CSG intersect(List< CSG > csgs)
ArrayList< String > getCreationEventStackTraceList()
static int numFacesInOffset
CSG intersect(CSG... csgs)
CSG rotx(Number degreesToRotate)
void updatePolygons(ArrayList< Polygon > toAdd, ArrayList< Polygon > degenerates, Polygon p)
static void setDefaultOptType(OptType optType)
CSG addCreationEventStringList(ArrayList< String > incoming)
static Color getDefaultColor()
ArrayList< Transform > getSlicePlanes()
CSG rot(Number x, Number y, Number z)
static CSG text(String text, double height, double fontSize)
CSG addCreationEventString(String thisline)
HashMap< String, IParametric > mapOfparametrics
CSG setMfg(PrepForManufacturing manufactuing)
static void setDefaultColor(Color defaultcolor)
CSG scalex(Number scaleValue)
CSG _differenceNoOpt(CSG csg)
PrepForManufacturing getManufacturing()
CSG toolOffset(Number sn)
static CSG fromPolygons(List< Polygon > polygons)
ArrayList< Transform > slicePlanes
int getNumFacesForOffsets()
static ICSGProgress getProgressMoniter()
void setIsWireFrame(boolean b)
static void setNumFacesInOffset(int numFacesInOffset)
static ICSGProgress progressMoniter
CSG roty(Number degreesToRotate)
static CSG textToSize(String text, double x, double y, double z)
static CSG unionAll(List< CSG > csgs)
CSG scalez(Number scaleValue)
CSG setParameterIfNull(String key)
CSG weighted(WeightFunction f)
ArrayList< CSG > minkowskiHullShape(CSG travelingShape)
static CSG text(String text, double height)
void setStorage(PropertyStorage storage)
static MeshContainer meshFromPolygon(Polygon... poly)
static void setProvider(IDebug3dProvider provider)
static void clearScreen()
static void addObject(Object o)
List< MeshView > getAsMeshViews()
final List< Vertex > vertices
ArrayList< Vertex > getDegeneratePoints()
void set(String key, Object property)
static final Vector3d X_ONE
static Vector3d y(double y)
static final Vector3d ZERO
static Vector3d z(double z)
static Vector3d x(double x)
static final Vector3d Z_ONE
static final Vector3d Y_ONE
Vertex transform(Transform transform)
StringBuilder toObjString(StringBuilder sb)
static List< eu.mihosoft.vrl.v3d.Polygon > concaveToConvex(eu.mihosoft.vrl.v3d.Polygon incoming)
static CSG hull(List<?> points)
static void set(String key, Parameter value)
static Parameter get(String key)
void setValue(Long newVal)
void progressUpdate(int currentIndex, int finalIndex, String type, CSG intermediateShape)
CSG change(CSG oldCSG, String parameterKey, Long newValue)
CSG regenerate(CSG previous)