From 147eeb0d3c39749e115068fcb802fea30aa3ec38 Mon Sep 17 00:00:00 2001 From: Kevin Harrington Date: Fri, 21 Jul 2017 14:43:16 -0400 Subject: [PATCH 1/5] Adding additional primatives --- .../java/eu/mihosoft/jcsg/Dodecahedron.java | 150 ++++++++++++++++++ .../java/eu/mihosoft/jcsg/Icosahedron.java | 141 ++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 src/main/java/eu/mihosoft/jcsg/Dodecahedron.java create mode 100644 src/main/java/eu/mihosoft/jcsg/Icosahedron.java diff --git a/src/main/java/eu/mihosoft/jcsg/Dodecahedron.java b/src/main/java/eu/mihosoft/jcsg/Dodecahedron.java new file mode 100644 index 00000000..9c3a214d --- /dev/null +++ b/src/main/java/eu/mihosoft/jcsg/Dodecahedron.java @@ -0,0 +1,150 @@ +/** + * Dodecahedron.java + */ +package eu.mihosoft.jcsg; + +import java.util.ArrayList; +import java.util.List; + +import eu.mihosoft.jcsg.ext.quickhull3d.HullUtil; +import eu.mihosoft.vvecmath.Vector3d; + + +public class Dodecahedron implements Primitive { + + /** + * Center of this dodecahedron. + */ + private Vector3d center; + /** + * Dodecahedron circumscribed radius. + */ + private double radius; + + /** The centered. */ + private boolean centered = true; + + /** The properties. */ + private final PropertyStorage properties = new PropertyStorage(); + /** + * Constructor. Creates a new dodecahedron with center {@code [0,0,0]} and + * dimensions {@code [1,1,1]}. + */ + public Dodecahedron() { + center = Vector3d.xyz(0, 0, 0); + radius = 1; + } + + /** + * Constructor. Creates a new dodecahedron with center {@code [0,0,0]} and + * radius {@code size}. + * + * @param size size + */ + public Dodecahedron(double size) { + center = Vector3d.xyz(0, 0, 0); + radius = size; + } + + /** + * Constructor. Creates a new dodecahedron with the specified center and + * radius. + * + * @param center center of the dodecahedron + * @param circumradius of the dodecahedron + */ + public Dodecahedron(Vector3d center, double size) { + this.center = center; + this.radius = size; + } + + /* (non-Javadoc) + * @see eu.mihosoft.vrl.v3d.Primitive#toPolygons() + */ + @Override + public List toPolygons() { + + double phi = (Math.sqrt(5)+1)/2; + + List points = new ArrayList<>(); + points.add(Vector3d.xyz(-1,-1,-1)); + points.add(Vector3d.xyz(-1,-1,+1)); + points.add(Vector3d.xyz(-1,+1,-1)); + points.add(Vector3d.xyz(-1,+1,+1)); + points.add(Vector3d.xyz(+1,-1,-1)); + points.add(Vector3d.xyz(+1,-1,+1)); + points.add(Vector3d.xyz(+1,+1,-1)); + points.add(Vector3d.xyz(+1,+1,+1)); + points.add(Vector3d.xyz(0,1/phi,phi)); + points.add(Vector3d.xyz(0,-1/phi,phi)); + points.add(Vector3d.xyz(phi,0,1/phi)); + points.add(Vector3d.xyz(1/phi,phi,0)); + points.add(Vector3d.xyz(-1/phi,phi,0)); + points.add(Vector3d.xyz(-phi,0,1/phi)); + points.add(Vector3d.xyz(1/phi,-phi,0)); + points.add(Vector3d.xyz(phi,0,-1/phi)); + points.add(Vector3d.xyz(0,1/phi,-phi)); + points.add(Vector3d.xyz(-phi,0,-1/phi)); + points.add(Vector3d.xyz(-1/phi,-phi,0)); + points.add(Vector3d.xyz(0,-1/phi,-phi)); + + List polygons = HullUtil.hull(points).scale(radius*(phi-1)).getPolygons(); + + return polygons; + } + + /** + * Gets the center. + * + * @return the center + */ + public Vector3d getCenter() { + return center; + } + + /** + * Sets the center. + * + * @param center the center to set + */ + public Dodecahedron setCenter(Vector3d center) { + this.center = center; + return this; + } + + /** + * Gets the radius. + * + * @return the radius + */ + public double getRadius() { + return radius; + } + + /** + * Sets the radius. + * + * @param radius the radius to set + */ + public void setRadius(double radius) { + this.radius = radius; + } + + /* (non-Javadoc) + * @see eu.mihosoft.vrl.v3d.Primitive#getProperties() + */ + @Override + public PropertyStorage getProperties() { + return properties; + } + + /** + * Defines that this dodecahedron will not be centered. + * @return this dodecahedron + */ + public Dodecahedron noCenter() { + centered = false; + return this; + } + +} diff --git a/src/main/java/eu/mihosoft/jcsg/Icosahedron.java b/src/main/java/eu/mihosoft/jcsg/Icosahedron.java new file mode 100644 index 00000000..4ec22a49 --- /dev/null +++ b/src/main/java/eu/mihosoft/jcsg/Icosahedron.java @@ -0,0 +1,141 @@ +/** + * Icosahedron.java + */ +package eu.mihosoft.jcsg; + +import java.util.ArrayList; +import java.util.List; + +import eu.mihosoft.jcsg.ext.quickhull3d.HullUtil; +import eu.mihosoft.vvecmath.Vector3d; + +public class Icosahedron implements Primitive { + + /** + * Center of this icosahedron. + */ + private Vector3d center; + /** + * Icosahedron circumscribed radius. + */ + private double radius; + + /** The centered. */ + private boolean centered = true; + + /** The properties. */ + private final PropertyStorage properties = new PropertyStorage(); + /** + * Constructor. Creates a new icosahedron with center {@code [0,0,0]} and + * dimensions {@code [1,1,1]}. + */ + public Icosahedron() { + center = Vector3d.xyz(0, 0, 0); + radius = 1; + } + + /** + * Constructor. Creates a new icosahedron with center {@code [0,0,0]} and + * radius {@code size}. + * + * @param size size + */ + public Icosahedron(double size) { + center = Vector3d.xyz(0, 0, 0); + radius = size; + } + + /** + * Constructor. Creates a new icosahedron with the specified center and + * radius. + * + * @param center center of the icosahedron + * @param circumradius of the icosahedron + */ + public Icosahedron(Vector3d center, double size) { + this.center = center; + this.radius = size; + } + + /* (non-Javadoc) + * @see eu.mihosoft.vrl.v3d.Primitive#toPolygons() + */ + @Override + public List toPolygons() { + + double phi = (Math.sqrt(5)+1)/2; + + List points = new ArrayList<>(); + points.add(Vector3d.xyz(0,1,phi)); + points.add(Vector3d.xyz(0,-1,phi)); + points.add(Vector3d.xyz(phi,0,1)); + points.add(Vector3d.xyz(1,phi,0)); + points.add(Vector3d.xyz(-1,phi,0)); + points.add(Vector3d.xyz(-phi,0,1)); + points.add(Vector3d.xyz(1,-phi,0)); + points.add(Vector3d.xyz(phi,0,-1)); + points.add(Vector3d.xyz(0,1,-phi)); + points.add(Vector3d.xyz(-phi,0,-1)); + points.add(Vector3d.xyz(-1,-phi,0)); + points.add(Vector3d.xyz(0,-1,-phi)); + + List polygons = HullUtil.hull(points).scale(radius/(Math.sqrt(1+Math.pow(phi, 2)))).getPolygons(); + + return polygons; + } + + /** + * Gets the center. + * + * @return the center + */ + public Vector3d getCenter() { + return center; + } + + /** + * Sets the center. + * + * @param center the center to set + */ + public Icosahedron setCenter(Vector3d center) { + this.center = center; + return this; + } + + /** + * Gets the radius. + * + * @return the radius + */ + public double getRadius() { + return radius; + } + + /** + * Sets the radius. + * + * @param radius the radius to set + */ + public void setRadius(double radius) { + this.radius = radius; + } + + /* (non-Javadoc) + * @see eu.mihosoft.vrl.v3d.Primitive#getProperties() + */ + @Override + public PropertyStorage getProperties() { + return properties; + } + + /** + * Defines that this icosahedron will not be centered. + * @return this icosahedron + */ + public Icosahedron noCenter() { + centered = false; + return this; + } + +} From 2c272385e15873b4c3e3f160704013e116d9fb59 Mon Sep 17 00:00:00 2001 From: Kevin Harrington Date: Fri, 21 Jul 2017 14:43:38 -0400 Subject: [PATCH 2/5] Adding an API to HullUtil to deal with just a list of points. --- .../eu/mihosoft/jcsg/ext/quickhull3d/HullUtil.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/mihosoft/jcsg/ext/quickhull3d/HullUtil.java b/src/main/java/eu/mihosoft/jcsg/ext/quickhull3d/HullUtil.java index c301e5ac..7b646d14 100644 --- a/src/main/java/eu/mihosoft/jcsg/ext/quickhull3d/HullUtil.java +++ b/src/main/java/eu/mihosoft/jcsg/ext/quickhull3d/HullUtil.java @@ -21,7 +21,15 @@ public class HullUtil { private HullUtil() { throw new AssertionError("Don't instantiate me!", null); } - + /** + * Hull. + * + * @param points the points + * @return the csg + */ + public static CSG hull(List points) { + return hull(points, new PropertyStorage()); + } public static CSG hull(List points, PropertyStorage storage) { Point3d[] hullPoints = points.stream().map((vec) -> new Point3d(vec.x(), vec.y(), vec.z())).toArray(Point3d[]::new); From ca529cea33432f29fddb179a7d8cf033cf9eed84 Mon Sep 17 00:00:00 2001 From: Kevin Harrington Date: Fri, 21 Jul 2017 14:50:38 -0400 Subject: [PATCH 3/5] Adding main API update to close #40 These helper functions simplify the use of JCSG by making it easier for users to work with the API. --- src/main/java/eu/mihosoft/jcsg/CSG.java | 595 +++++++++++++++++++++++- 1 file changed, 587 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/mihosoft/jcsg/CSG.java b/src/main/java/eu/mihosoft/jcsg/CSG.java index e264d4a6..ee9d2f18 100644 --- a/src/main/java/eu/mihosoft/jcsg/CSG.java +++ b/src/main/java/eu/mihosoft/jcsg/CSG.java @@ -545,14 +545,39 @@ public CSG difference(CSG... csgs) { */ public CSG difference(CSG csg) { - switch (getOptType()) { - case CSG_BOUND: - return _differenceCSGBoundsOpt(csg); - case POLYGON_BOUND: - return _differencePolygonBoundsOpt(csg); - default: - return _differenceNoOpt(csg); - } + try { + // Check to see if a CSG operation is attempting to difference with + // no + // polygons + if (this.getPolygons().size() > 0 && csg.getPolygons().size() > 0) { + switch (getOptType()) { + case CSG_BOUND: + return _differenceCSGBoundsOpt(csg); + case POLYGON_BOUND: + return _differencePolygonBoundsOpt(csg); + default: + return _differenceNoOpt(csg); + } + } else + return this; + } catch (Exception ex) { + //System.err.println("CSG difference failed, performing workaround"); + ex.printStackTrace(); + CSG intersectingParts = csg + .intersect(this); + + if (intersectingParts.getPolygons().size() > 0) { + switch (getOptType()) { + case CSG_BOUND: + return _differenceCSGBoundsOpt(intersectingParts); + case POLYGON_BOUND: + return _differencePolygonBoundsOpt(intersectingParts); + default: + return _differenceNoOpt(intersectingParts); + } + } else + return this; + } } private CSG _differenceCSGBoundsOpt(CSG csg) { @@ -1199,5 +1224,559 @@ public static enum OptType { POLYGON_BOUND, NONE } + + /** + * Public API section + * These are publicly accessible helper functions + */ + + /** + * To z min. + * + * @param target + * the target + * @return the csg + */ + public CSG toZMin(CSG target) { + return this.transformed(new Transform().translateZ(-target.getBounds().getMin().z())); + } + + /** + * To z max. + * + * @param target + * the target + * @return the csg + */ + public CSG toZMax(CSG target) { + return this.transformed(new Transform().translateZ(-target.getBounds().getMax().z())); + } + + /** + * To x min. + * + * @param target + * the target + * @return the csg + */ + public CSG toXMin(CSG target) { + return this.transformed(new Transform().translateX(-target.getBounds().getMin().x())); + } + + /** + * To x max. + * + * @param target + * the target + * @return the csg + */ + public CSG toXMax(CSG target) { + return this.transformed(new Transform().translateX(-target.getBounds().getMax().x())); + } + + /** + * To y min. + * + * @param target + * the target + * @return the csg + */ + public CSG toYMin(CSG target) { + return this.transformed(new Transform().translateY(-target.getBounds().getMin().y())); + } + + /** + * To y max. + * + * @param target + * the target + * @return the csg + */ + public CSG toYMax(CSG target) { + return this.transformed(new Transform().translateY(-target.getBounds().getMax().y())); + } + + /** + * To z min. + * + * @return the csg + */ + public CSG toZMin() { + return toZMin(this); + } + + /** + * To z max. + * + * @return the csg + */ + public CSG toZMax() { + return toZMax(this); + } + + /** + * To x min. + * + * @return the csg + */ + public CSG toXMin() { + return toXMin(this); + } + + /** + * To x max. + * + * @return the csg + */ + public CSG toXMax() { + return toXMax(this); + } + + /** + * To y min. + * + * @return the csg + */ + public CSG toYMin() { + return toYMin(this); + } + + /** + * To y max. + * + * @return the csg + */ + public CSG toYMax() { + return toYMax(this); + } + + public CSG move(double x, double y, double z) { + return transformed(new Transform().translate(x,y,z)); + } + public CSG move(Vertex v) { + return transformed(new Transform().translate(v.pos)); + } + public CSG move(Vector3d v) { + return transformed(new Transform().translate(v.x(),v.y(),v.z())); + } + public CSG move(double[] posVector) { + return move(posVector[0], posVector[1], posVector[2]); + } + + /** + * Movey. + * + * @param howFarToMove + * the how far to move + * @return the csg + */ + // Helper/wrapper functions for movement + public CSG movey(double howFarToMove) { + return this.transformed(Transform.unity().translateY(howFarToMove)); + } + + /** + * Movez. + * + * @param howFarToMove + * the how far to move + * @return the csg + */ + public CSG movez(double howFarToMove) { + return this.transformed(Transform.unity().translateZ(howFarToMove)); + } + + /** + * Movex. + * + * @param howFarToMove + * the how far to move + * @return the csg + */ + public CSG movex(double howFarToMove) { + return this.transformed(Transform.unity().translateX(howFarToMove)); + } + + /** + * mirror about y axis. + * + + * @return the csg + */ + // Helper/wrapper functions for movement + public CSG mirrory() { + return this.scaley(-1); + } + + /** + * mirror about z axis. + * + * @return the csg + */ + public CSG mirrorz() { + return this.scalez(-1); + } + + /** + * mirror about x axis. + * + * @return the csg + */ + public CSG mirrorx() { + return this.scalex(-1); + } + + + public CSG rot(double x, double y, double z) { + return rotx(x).roty(y).rotz(z); + } + + public CSG rot(double[] posVector) { + return rot(posVector[0], posVector[1], posVector[2]); + } + + /** + * Rotz. + * + * @param degreesToRotate + * the degrees to rotate + * @return the csg + */ + // Rotation function, rotates the object + public CSG rotz(double degreesToRotate) { + return this.transformed(new Transform().rotZ(degreesToRotate)); + } + + /** + * Roty. + * + * @param degreesToRotate + * the degrees to rotate + * @return the csg + */ + public CSG roty(double degreesToRotate) { + return this.transformed(new Transform().rotY(degreesToRotate)); + } + + /** + * Rotx. + * + * @param degreesToRotate + * the degrees to rotate + * @return the csg + */ + public CSG rotx(double degreesToRotate) { + return this.transformed(new Transform().rotX(degreesToRotate)); + } + + /** + * Scalez. + * + * @param scaleValue + * the scale value + * @return the csg + */ + // Scale function, scales the object + public CSG scalez(double scaleValue) { + return this.transformed(new Transform().scaleZ(scaleValue)); + } + + /** + * Scaley. + * + * @param scaleValue + * the scale value + * @return the csg + */ + public CSG scaley(double scaleValue) { + return this.transformed(new Transform().scaleY(scaleValue)); + } + + /** + * Scalex. + * + * @param scaleValue + * the scale value + * @return the csg + */ + public CSG scalex(double scaleValue) { + return this.transformed(new Transform().scaleX(scaleValue)); + } + + /** + * Scale. + * + * @param scaleValue + * the scale value + * @return the csg + */ + public CSG scale(double scaleValue) { + return this.transformed(new Transform().scale(scaleValue)); + } + + public static CSG unionAll(CSG... csgs){ + return unionAll(Arrays.asList(csgs)); + } + public static CSG unionAll(List csgs){ + CSG first = csgs.remove(0); + return first.union(csgs); + } + + public static CSG hullAll(CSG... csgs){ + return hullAll(Arrays.asList(csgs)); + } + public static CSG hullAll(List csgs){ + CSG first = csgs.remove(0); + return first.hull(csgs); + } + public Vector3d getCenter(){ + return Vector3d.xyz( + getCenterX(), + getCenterY(), + getCenterZ()); + } + + /** + * Helper function wrapping bounding box values + * + * @return CenterX + */ + public double getCenterX() { + return ((getMinX()/2)+(getMaxX()/2)); + } + + /** + * Helper function wrapping bounding box values + * + * @return CenterY + */ + public double getCenterY() { + return ((getMinY()/2)+(getMaxY()/2)); + } + + /** + * Helper function wrapping bounding box values + * + * @return CenterZ + */ + public double getCenterZ() { + return ((getMinZ()/2)+(getMaxZ()/2)); + } + + /** + * Helper function wrapping bounding box values + * + * @return MaxX + */ + public double getMaxX() { + return getBounds().getMax().x(); + } + + /** + * Helper function wrapping bounding box values + * + * @return MaxY + */ + public double getMaxY() { + return getBounds().getMax().y(); + } + + /** + * Helper function wrapping bounding box values + * + * @return MaxZ + */ + public double getMaxZ() { + return getBounds().getMax().z(); + } + + /** + * Helper function wrapping bounding box values + * + * @return MinX + */ + public double getMinX() { + return getBounds().getMin().x(); + } + + /** + * Helper function wrapping bounding box values + * + * @return MinY + */ + public double getMinY() { + return getBounds().getMin().y(); + } + + /** + * Helper function wrapping bounding box values + * + * @return tMinZ + */ + public double getMinZ() { + return getBounds().getMin().z(); + } + /** + * Hail Zeon! In case you forget the name of minkowski and are a Gundam fan + * @param travelingShape + * @return + */ + @Deprecated + public ArrayList minovsky( CSG travelingShape){ + System.out.println("Hail Zeon!"); + return minkowski(travelingShape); + } + /** + * Shortened name In case you forget the name of minkowski + * @param travelingShape + * @return + */ + public ArrayList mink( CSG travelingShape){ + return minkowski(travelingShape); + } + /** + * This is a simplified version of a minkowski transform using convex hull and the internal list of convex polygons + * The shape is placed at the vertex of each point on a polygon, and the result is convex hulled together. + * This collection is returned. + * To make a normal insets, difference this collection + * To make an outset by the normals, union this collection with this object. + * + * This will hull the elements together forming a smooth shell, this process is much slower + * @param travelingShape a shape to sweep around + * @return + */ + public ArrayList minkowskiHull( CSG travelingShape){ + ArrayList allFaces = new ArrayList(); + for(Polygon p: getPolygons()){ + ArrayList corners =new ArrayList(); + for(Vertex v:p.vertices){ + corners.add(travelingShape.move(v)); + } + CSG face = corners.remove(0); + face=face.hull(corners); + allFaces.add(face); + } + return allFaces; + } + + /** + * This is a simplified version of a minkowski transform using convex hull and the internal list of convex polygons + * The shape is placed at the vertex of each point on a polygon, and the result is convex hulled together. + * This collection is returned. + * To make a normal insets, difference this collection + * To make an outset by the normals, union this collection with this object. + * + * @param travelingShape a shape to sweep around + * @return + */ + public ArrayList minkowski( CSG travelingShape){ + HashMap map= new HashMap<>(); + for(Polygon p: travelingShape.getPolygons()){ + for(Vertex v:p.vertices){ + if(map.get(v)==null)// use hashmap to avoid duplicate locations + map.put(v,this.move(v)); + } + } + return new ArrayList(map.values()); + } + /** + * minkowskiDifference performs an efficient difference of the minkowski transform + * of the intersection of an object. if you have 2 objects and need them to fit with a + * specific tolerance as described as the distance from he normal of the surface, then + * this function will effectinatly compute that value. + * @param itemToDifference the object that needs to fit + * @param minkowskiObject the object to represent the offset + * @return + */ + public CSG minkowskiDifference(CSG itemToDifference, CSG minkowskiObject) { + CSG intersection = this.intersect(itemToDifference); + + ArrayList csgDiff = intersection.mink(minkowskiObject); + CSG result = this; + for (int i=0;i mikObjs = minkowski(printNozzel); + CSG remaining = this; + for(CSG bit: mikObjs){ + remaining=remaining.intersect(bit); + } + return remaining; + } + return union(minkowski(printNozzel)); + } + + public CSG makeKeepaway(double shellThickness) { + + double x = Math.abs(this.getBounds().getMax().x()) + Math.abs(this.getBounds().getMin().x()); + double y = Math.abs(this.getBounds().getMax().y()) + Math.abs(this.getBounds().getMin().y()); + + double z = Math.abs(this.getBounds().getMax().z()) + Math.abs(this.getBounds().getMin().z()); + + double xtol = (x + shellThickness) / x; + double ytol = (y + shellThickness) / y; + double ztol = (z + shellThickness) / z; + + double xPer = -(Math.abs(this.getBounds().getMax().x()) - Math.abs(this.getBounds().getMin().x())) / x; + double yPer = -(Math.abs(this.getBounds().getMax().y()) - Math.abs(this.getBounds().getMin().y())) / y; + double zPer = -(Math.abs(this.getBounds().getMax().z()) - Math.abs(this.getBounds().getMin().z())) / z; + + // println " Keep away x = "+y+" new = "+ytol + return this.transformed(new Transform().scale(xtol, ytol, ztol)) + .transformed(new Transform().translateX(shellThickness * xPer)) + .transformed(new Transform().translateY(shellThickness * yPer)) + .transformed(new Transform().translateZ(shellThickness * zPer)); + + } + /** + * A test to see if 2 CSG's are touching. The fast-return is a bounding box + * check If bounding boxes overlap, then an intersection is performed and + * the existance of an interscting object is returned + * + * @param incoming + * @return + */ + public boolean touching(CSG incoming) { + // Fast bounding box overlap check, quick fail if not intersecting + // bounding boxes + if (this.getMaxX() > incoming.getMinX() && this.getMinX() < incoming.getMaxX() + && this.getMaxY() > incoming.getMinY() && this.getMinY() < incoming.getMaxY() + && this.getMaxZ() > incoming.getMinZ() && this.getMinZ() < incoming.getMaxZ()) { + // Run a full intersection + CSG inter = this.intersect(incoming); + if (inter.getPolygons().size() > 0) { + // intersection success + return true; + } + } + return false; + } } From e26b0cee74cb5dd2abb335f9fb6bafd88a1b3647 Mon Sep 17 00:00:00 2001 From: Kevin Harrington Date: Fri, 21 Jul 2017 15:00:53 -0400 Subject: [PATCH 4/5] Adding the deep minkowski wrappers and bounding box API --- src/main/java/eu/mihosoft/jcsg/CSG.java | 119 +++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/mihosoft/jcsg/CSG.java b/src/main/java/eu/mihosoft/jcsg/CSG.java index ee9d2f18..9c562655 100644 --- a/src/main/java/eu/mihosoft/jcsg/CSG.java +++ b/src/main/java/eu/mihosoft/jcsg/CSG.java @@ -1616,6 +1616,33 @@ public double getMinY() { public double getMinZ() { return getBounds().getMin().z(); } + + /** + * Helper function wrapping bounding box values + * + * @return MinX + */ + public double getTotalX() { + return (-this.getMinX()+this.getMaxX()); + } + + /** + * Helper function wrapping bounding box values + * + * @return MinY + */ + public double getTotalY() { + return (-this.getMinY()+this.getMaxY()); + } + + /** + * Helper function wrapping bounding box values + * + * @return tMinZ + */ + public double getTotalZ() { + return (-this.getMinZ()+this.getMaxZ()); + } /** * Hail Zeon! In case you forget the name of minkowski and are a Gundam fan * @param travelingShape @@ -1713,7 +1740,75 @@ public CSG minkowskiDifference(CSG itemToDifference, double tolerance) { if(shellThickness<0.001) return this; return minkowskiDifference(itemToDifference,new Cube(shellThickness).toCSG()); + } + /** + * minkowskiDifference performs an efficient difference of the minkowski transform + * of the intersection of an object. if you have 2 objects and need them to fit with a + * specific tolerance as described as the distance from he normal of the surface, then + * this function will effectinatly compute that value. + * * This uses the deep minkowski and takse a long time + + * @param itemToDifference the object that needs to fit + * @param minkowskiObject the object to represent the offset + * @return + */ + public CSG minkowskiHullDifference(CSG itemToDifference, CSG minkowskiObject) { + CSG intersection = this.intersect(itemToDifference); + + ArrayList csgDiff = intersection.minkowskiHull(minkowskiObject); + CSG result = this; + for (int i=0;i mikObjs = minkowskiHull(printNozzel); + CSG remaining = this; + for(CSG bit: mikObjs){ + remaining=remaining.intersect(bit); + } + return remaining; + } + return union(minkowskiHull(printNozzel)); + } + /** + * A more accurate tooling offset using an Icosohedron as the corner setting. + * @param shellThickness + * @return + */ public CSG toolOffset(double shellThickness) { boolean cut =shellThickness<0; @@ -1732,7 +1827,13 @@ public CSG toolOffset(double shellThickness) { } return union(minkowski(printNozzel)); } - + /** + * makeKeepaway + * + * Perform a dumb scale version of a keepaway. This is inaccurate, but fast + * @param shellThickness + * @return + */ public CSG makeKeepaway(double shellThickness) { double x = Math.abs(this.getBounds().getMax().x()) + Math.abs(this.getBounds().getMin().x()); @@ -1778,5 +1879,21 @@ public boolean touching(CSG incoming) { } return false; } + /** + * Get Bounding box + * @return A CSG that completely encapsulates the base CSG, centered around it + */ + CSG getBoundingBox(){ + return new Cube( (-this.getMinX()+this.getMaxX()), + (-this.getMinY()+this.getMaxY()), + (-this.getMinZ()+this.getMaxZ())) + .toCSG() + .toXMax() + .movex(this.getMaxX()) + .toYMax() + .movey(this.getMaxY()) + .toZMax() + .movez(this.getMaxZ()); + } } From 70f3f2062d51f20e747853f86eb119e3b18e8905 Mon Sep 17 00:00:00 2001 From: Kevin Harrington Date: Fri, 21 Jul 2017 15:11:58 -0400 Subject: [PATCH 5/5] Simplified CSG difference validation checks --- src/main/java/eu/mihosoft/jcsg/CSG.java | 45 +++++++++++-------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/main/java/eu/mihosoft/jcsg/CSG.java b/src/main/java/eu/mihosoft/jcsg/CSG.java index 9c562655..dc777441 100644 --- a/src/main/java/eu/mihosoft/jcsg/CSG.java +++ b/src/main/java/eu/mihosoft/jcsg/CSG.java @@ -520,6 +520,22 @@ public CSG difference(CSG... csgs) { return difference(Arrays.asList(csgs)); } + private CSG simpleDifference(CSG csg){ + // Check to see if a CSG operation is attempting to difference with + // no + // polygons + if (this.getPolygons().size() > 0 && csg.getPolygons().size() > 0) { + switch (getOptType()) { + case CSG_BOUND: + return _differenceCSGBoundsOpt(csg); + case POLYGON_BOUND: + return _differencePolygonBoundsOpt(csg); + default: + return _differenceNoOpt(csg); + } + } else + return this; + } /** * Return a new CSG solid representing the difference of this csg and the @@ -546,37 +562,14 @@ public CSG difference(CSG... csgs) { public CSG difference(CSG csg) { try { - // Check to see if a CSG operation is attempting to difference with - // no - // polygons - if (this.getPolygons().size() > 0 && csg.getPolygons().size() > 0) { - switch (getOptType()) { - case CSG_BOUND: - return _differenceCSGBoundsOpt(csg); - case POLYGON_BOUND: - return _differencePolygonBoundsOpt(csg); - default: - return _differenceNoOpt(csg); - } - } else - return this; + + return simpleDifference( csg); } catch (Exception ex) { //System.err.println("CSG difference failed, performing workaround"); ex.printStackTrace(); CSG intersectingParts = csg .intersect(this); - - if (intersectingParts.getPolygons().size() > 0) { - switch (getOptType()) { - case CSG_BOUND: - return _differenceCSGBoundsOpt(intersectingParts); - case POLYGON_BOUND: - return _differencePolygonBoundsOpt(intersectingParts); - default: - return _differenceNoOpt(intersectingParts); - } - } else - return this; + return simpleDifference( intersectingParts); } }