diff --git a/src/main/java/eu/mihosoft/vrl/v3d/CSG.java b/src/main/java/eu/mihosoft/vrl/v3d/CSG.java index a442f3a6..a539e709 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/CSG.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/CSG.java @@ -36,6 +36,7 @@ import eu.mihosoft.vrl.v3d.ext.org.poly2tri.PolygonUtil; import eu.mihosoft.vrl.v3d.ext.quickhull3d.HullUtil; import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import eu.mihosoft.vrl.v3d.parametrics.IParametric; import eu.mihosoft.vrl.v3d.parametrics.IRegenerate; import eu.mihosoft.vrl.v3d.parametrics.LengthParameter; @@ -54,6 +55,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinWorkerThread; import java.util.concurrent.TimeUnit; @@ -134,17 +136,39 @@ @SuppressWarnings("restriction") public class CSG implements IuserAPI, Serializable { - private static final double POINTS_CONTACT_DISTANCE = 0.00001; - private static int MinPolygonsForOffloading = 200; - private static final long serialVersionUID = 4071874097772427063L; - private static IDebug3dProvider providerOf3d = null; - private static int numFacesInOffset = 15; + transient private static final double POINTS_CONTACT_DISTANCE = 0.00001; + transient private static int MinPolygonsForOffloading = 200; + transient private static final long serialVersionUID = 4071874097772427063L; + transient private static IDebug3dProvider providerOf3d = null; + transient private static int numFacesInOffset = 15; + transient public static final int INDEX_OF_PARAMETRIC_DEFAULT = 0; + transient public static final int INDEX_OF_PARAMETRIC_LOWER = 1; + transient public static final int INDEX_OF_PARAMETRIC_UPPER = 2; + transient private static HashMap manufactuingMap = new HashMap(); + transient private static HashMap regenerate = new HashMap(); + transient private static HashMap manipulator = new HashMap(); + + transient private static OptType defaultOptType = OptType.CSG_BOUND; + transient private static String defaultcolor = "#007956"; + // private boolean triangulated; + transient private static boolean useStackTraces = true; + transient private static boolean preventNonManifoldTriangles = false; + transient private static boolean warned = false; + // GPU processing + transient private static boolean useGPU = true; + transient private static int ExtraSpace = 100; + transient private static ICSGProgress progressMoniter = new ICSGProgress() { + @Override + public void progressUpdate(int currentIndex, int finalIndex, String type, CSG intermediateShape) { + System.err.println(type + " cur:" + currentIndex + " of " + finalIndex); + } + }; + transient private static ForkJoinPool poolGlobal = null; /** The polygons. */ private ArrayList polygons; /** The default opt type. */ - private static OptType defaultOptType = OptType.CSG_BOUND; /** The opt type. */ private OptType optType = null; @@ -154,9 +178,7 @@ public class CSG implements IuserAPI, Serializable { private PropertyStorage assembly; /** The current. */ - private MeshView current; - - private static String defaultcolor = "#007956"; + transient private MeshView current; /** The color. */ // private Color color = getDefaultColor(); @@ -165,36 +187,18 @@ public class CSG implements IuserAPI, Serializable { private double b = getDefaultColor().getBlue(); private double o = getDefaultColor().getOpacity(); /** The manipulator. */ - private Affine manipulator; private Bounds bounds; - public static final int INDEX_OF_PARAMETRIC_DEFAULT = 0; - public static final int INDEX_OF_PARAMETRIC_LOWER = 1; - public static final int INDEX_OF_PARAMETRIC_UPPER = 2; + private ArrayList groovyFileLines = new ArrayList<>(); - private PrepForManufacturing manufactuing = null; - private HashMap mapOfparametrics = null; - private IRegenerate regenerate = null; + private boolean markForRegeneration = false; private String name = ""; private ArrayList slicePlanes = null; private ArrayList exportFormats = null; private ArrayList datumReferences = null; - // private boolean triangulated; - private static boolean useStackTraces = true; - private static boolean preventNonManifoldTriangles = false; - private static boolean warned = false; - // GPU processing - private static boolean useGPU = true; - private int pointsAdded; - private static int ExtraSpace = 100; - private static ICSGProgress progressMoniter = new ICSGProgress() { - @Override - public void progressUpdate(int currentIndex, int finalIndex, String type, CSG intermediateShape) { - System.err.println(type + " cur:" + currentIndex + " of " + finalIndex); - } - }; - private static ForkJoinPool poolGlobal=null; + private int pointsAdded; + private final String uniqueId = UUID.randomUUID().toString(); /** * Instantiates a new csg. @@ -207,7 +211,23 @@ public CSG() { addStackTrace(new Exception()); } } - + @Override + public boolean equals(Object obj) { + // Check if same reference + if (this == obj) return true; + + // Check if null or different class + if (obj == null || getClass() != obj.getClass()) return false; + + // Cast and compare fields + CSG test = (CSG) obj; + return this.getUniqueId().contentEquals(test.getUniqueId()); + } + @Override + public int hashCode() { + return getUniqueId().hashCode(); + } + public CSG addDatumReference(Transform t) { if (getDatumReferences() == null) setDatumReferences(new ArrayList()); @@ -224,7 +244,6 @@ public CSG prepForManufacturing() { ret.setName(getName()); ret.setColor(getColor()); ret.slicePlanes = slicePlanes; - ret.mapOfparametrics = mapOfparametrics; ret.exportFormats = exportFormats; return ret; } @@ -279,14 +298,13 @@ public CSG setTemporaryColor(Color color) { * @param manipulator the manipulator * @return the affine */ - public CSG setManipulator(javafx.scene.transform.Affine manipulator) { + public CSG setManipulator(javafx.scene.transform.Affine m) { if (manipulator == null) return this; - Affine old = manipulator; - this.manipulator = manipulator; + manipulator.put(getUniqueId(), m); if (getCurrentMeshView() != null) { getCurrentMeshView().getTransforms().clear(); - getCurrentMeshView().getTransforms().add(manipulator); + getCurrentMeshView().getTransforms().add(m); } return this; } @@ -535,7 +553,7 @@ public CSG moveToCenter() { public ArrayList move(ArrayList p) { ArrayList bits = new ArrayList(); - for (Transform t : p) { + for (int i = 0; i < p.size(); i++) { bits.add(this.clone()); } return move(bits, p); @@ -913,13 +931,13 @@ public CSG union(List incoming) { if(test==null) continue; boolean touching =false; - int t=-1; + //int t=-1; for(int j=0;j unique = new HashSet(); - int running = 0; + //int running = 0; for (int i = 0; i < numberOfPolygons; i++) { int ps = polyStartIndex[i]; int size = polySizes[i]; @@ -2860,9 +2878,9 @@ public CSG toolOffset(Number sn) { return union(minkowskiHullShape(printNozzel)); } - private int getNumFacesForOffsets() { - return getNumfacesinoffset(); - } +// private int getNumFacesForOffsets() { +// return getNumfacesinoffset(); +// } public CSG makeKeepaway(Number sn) { double shellThickness = sn.doubleValue(); @@ -2891,9 +2909,9 @@ public boolean hasManipulator() { return manipulator!=null; } public Affine getManipulator() { - if (manipulator == null) - return new Affine(); - return manipulator; + if (manipulator.get(uniqueId) == null) + manipulator.put(uniqueId, new Affine()); + return manipulator.get(uniqueId); } public CSG addCreationEventStackTraceList(ArrayList incoming) { @@ -2937,22 +2955,30 @@ public CSG historySync(CSG dyingCSG) { if (useStackTraces) { this.addCreationEventStringList(dyingCSG.getCreationEventStackTraceList()); } - Set params = dyingCSG.getParameters(); + if (getName().length() == 0) + setName(dyingCSG.getName()); + setColor(dyingCSG.getColor()); + //str.syncProperties(dyingCSG.str); + syncCadoodleCatagories(dyingCSG); + return this; + } + + + public CSG syncParameter(CSGDatabaseInstance instance,CSG dyingCSG) { + syncCadoodleCatagories(dyingCSG); + Set params = dyingCSG.getParameters(instance); for (String param : params) { boolean existing = false; - for (String s : this.getParameters()) { + for (String s : this.getParameters(instance)) { if (s.contentEquals(param)) existing = true; } if (!existing) { - Parameter vals = CSGDatabase.get(param); + Parameter vals = instance.get(param); if (vals != null) - this.setParameter(vals, dyingCSG.getMapOfparametrics().get(param)); + this.setParameter(instance,vals, dyingCSG.getMapOfparametrics(instance).get(param)); } } - if (getName().length() == 0) - setName(dyingCSG.getName()); - setColor(dyingCSG.getColor()); return this; } @@ -2991,7 +3017,15 @@ public CSG prepMfg() { } public PrepForManufacturing getManufacturing() { - return manufactuing; + if(manufactuingMap.get(this.getUniqueId())==null) { + manufactuingMap.put(this.getUniqueId(), new PrepForManufacturing() { + @Override + public CSG prep(CSG incoming) { + return incoming; + } + }); + } + return manufactuingMap.get(this.getUniqueId()); } public PrepForManufacturing getMfg() { @@ -3003,106 +3037,109 @@ public CSG setMfg(PrepForManufacturing manufactuing) { } public CSG setManufacturing(PrepForManufacturing manufactuing) { - this.manufactuing = manufactuing; + manufactuingMap.put(this.getUniqueId(), manufactuing); return this; } -// @Deprecated -// public PrepForManufacturing getManufactuing() { -// return getManufacturing(); -// } - -// @Deprecated -// public CSG setManufactuing(PrepForManufacturing manufactuing) { -// return setManufacturing(manufactuing); -// } - - public CSG setParameter(Parameter w, IParametric function) { - if (w == null) - return this; - if (CSGDatabase.get(w.getName()) == null) - CSGDatabase.set(w.getName(), w); - if (getMapOfparametrics().get(w.getName()) == null) - getMapOfparametrics().put(w.getName(), function); + public CSG setParameter(CSGDatabaseInstance instance,Parameter w) { + instance.setParameter(this, w); return this; } - - public CSG setParameter(Parameter w) { - setParameter(w, new IParametric() { - @Override - public CSG change(CSG oldCSG, String parameterKey, Long newValue) { - if (parameterKey.contentEquals(w.getName())) - CSGDatabase.get(w.getName()).setValue(newValue); - return oldCSG; - } - }); + public CSG setParameter(CSGDatabaseInstance instance,String key, double defaultValue, double upperBound, double lowerBound, + IParametric function) { + instance.setParameter(this, key, defaultValue, upperBound, lowerBound, function); return this; } - - public CSG setParameter(String key, double defaultValue, double upperBound, double lowerBound, - IParametric function) { - ArrayList vals = new ArrayList(); - vals.add(upperBound); - vals.add(lowerBound); - setParameter(new LengthParameter(key, defaultValue, vals), function); + public CSG setParameter(CSGDatabaseInstance instance,Parameter w, IParametric function) { + if (w == null) + return this; + instance.setParameter(this, w, function); return this; } - - public CSG setParameterIfNull(String key) { - if (getMapOfparametrics().get(key) == null) - getMapOfparametrics().put(key, new IParametric() { - - @Override - public CSG change(CSG oldCSG, String parameterKey, Long newValue) { - CSGDatabase.get(key).setValue(newValue); - return oldCSG; - } - }); + public CSG setParameterIfNull(CSGDatabaseInstance instance,String key) { + instance.setParameterIfNull(this, key); return this; } - - public Set getParameters() { - - return getMapOfparametrics().keySet(); + public Set getParameters(CSGDatabaseInstance instance) { + return instance.getMapOfparametrics(this).keySet(); } - - public CSG setParameterNewValue(String key, double newValue) { - IParametric function = getMapOfparametrics().get(key); - if (function != null) { - CSG setManipulator = function.change(this, key, new Long((long) (newValue * 1000))) - .setManipulator(this.getManipulator()); - setManipulator.setColor(getColor()); - return setManipulator; - } + public CSG setParameterNewValue(CSGDatabaseInstance instance, String key, double newValue) { + instance.setParameterNewValue(this, key, newValue); return this; } + public HashMap getMapOfparametrics(CSGDatabaseInstance instance){ + return instance.getMapOfparametrics(this); + } + +// @Deprecated +// public HashMap getMapOfparametrics(){ +// new RuntimeException("This is using LEGACY database!").printStackTrace(); +// return CSGDatabase.getInstance().getMapOfparametrics(this); +// } +// @Deprecated +// public CSG setParameter(Parameter w) { +// new RuntimeException("This is using LEGACY database!").printStackTrace(); +// return setParameter(CSGDatabase.getInstance(),w); +// } +// @Deprecated +// public CSG setParameter(String key, double defaultValue, double upperBound, double lowerBound, +// IParametric function) { +// new RuntimeException("This is using LEGACY database!").printStackTrace(); +// setParameter(CSGDatabase.getInstance(), key, defaultValue, upperBound, lowerBound, function); +// return this; +// } +// @Deprecated +// public CSG setParameter(Parameter w, IParametric function) { +// new RuntimeException("This is using LEGACY database!").printStackTrace(); +// return setParameter(CSGDatabase.getInstance(), w, function); +// } +// @Deprecated +// public CSG setParameterIfNull(String key) { +// new RuntimeException("This is using LEGACY database!").printStackTrace(); +// setParameterIfNull(CSGDatabase.getInstance(), key); +// return this; +// } +// @Deprecated +// public Set getParameters() { +// new RuntimeException("This is using LEGACY database!").printStackTrace(); +// return getParameters(CSGDatabase.getInstance()); +// } +// @Deprecated +// public CSG setParameterNewValue( String key, double newValue) { +// new RuntimeException("This is using LEGACY database!").printStackTrace(); +// return setParameterNewValue(CSGDatabase.getInstance(),key,newValue); +// } public CSG setRegenerate(IRegenerate function) { - regenerate = function; + regenerate.put(getUniqueId(), function); return this; } public IRegenerate getRegenerate() { - return regenerate; + if(regenerate.get(getUniqueId())==null) { + regenerate.put(getUniqueId(), new IRegenerate() { + @Override + public CSG regenerate(CSG previous) { + return previous; + } + }); + + } + return regenerate.get(getUniqueId()); } public CSG regenerate() { this.markForRegeneration = false; if (regenerate == null) return this; - CSG regenerate2 = regenerate.regenerate(this); + CSG regenerate2 = regenerate.get(getUniqueId()).regenerate(this); if (regenerate2 != null) return regenerate2.setManipulator(this.getManipulator()).historySync(this); ; return this; } - public HashMap getMapOfparametrics() { - if (mapOfparametrics == null) { - mapOfparametrics = new HashMap<>(); - } - return mapOfparametrics; - } + public boolean isMarkedForRegeneration() { return markForRegeneration; @@ -3124,9 +3161,7 @@ public CSG markForRegeneration() { 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()) { + if (isBoundsTouching(incoming)) { // Run a full intersection CSG inter = this.intersect(incoming); if (inter.getPolygons().size() > 0) { @@ -3623,6 +3658,9 @@ public boolean isGroupResult() { // Hole public CSG setIsMotionLock(boolean Lock) { +// if(Lock) { +// new RuntimeException("Motion Lock Enabled here").printStackTrace(); +// } getStorage().set("isMotionLock", Lock); return this; } @@ -3674,6 +3712,7 @@ public CSG setIsAlwaysShow(boolean Hide) { getStorage().set("isAlwaysShow", Hide); return this; } + public boolean isAlwaysShow() { Optional o = getStorage().getValue("isAlwaysShow"); @@ -3694,6 +3733,26 @@ public boolean isHole() { return o.get(); return false; } + + private void syncCadoodleCatagories(CSG dyingCSG) { + setIsHole(dyingCSG.isHole()); + setIsHide(dyingCSG.isHide()); + setIsAlwaysShow(dyingCSG.isAlwaysShow()); + setIsLock(dyingCSG.isLock()); + setIsMotionLock(dyingCSG.isMotionLock()); + setIsWireFrame(dyingCSG.isWireFrame()); + setColor(dyingCSG.getColor()); + setNoScale(dyingCSG.isNoScale()); + } + public void setDefaultCadoodleCatagories() { + setIsHole(false); + setIsHide(false); + setIsAlwaysShow(false); + setIsLock(false); + setIsMotionLock(false); + setIsWireFrame(false); + setNoScale(false); + } // Hole public CSG setLimbName(String name) { getStorage().set("LimbName", name); @@ -3712,10 +3771,11 @@ public CSG setMobileBaseName(String name) { public Optional getMobileBaseName() { return getStorage().getValue("MobileBaseName"); } - public CSG syncProperties(CSG dying) { + public CSG syncProperties(CSGDatabaseInstance instance,CSG dying) { getStorage().syncProperties(dying.getStorage()); - regenerate = dying.regenerate; - setManipulator(dying.manipulator); + regenerate.put(uniqueId,regenerate.get(dying.uniqueId)) ; + setManipulator(manipulator.get(dying.uniqueId)); + syncParameter(instance,dying); return this; } @@ -4025,5 +4085,9 @@ public MeshView getCurrentMeshView() { public void setCurrentMeshView(MeshView current) { this.current = current; } + + public String getUniqueId() { + return uniqueId; + } } diff --git a/src/main/java/eu/mihosoft/vrl/v3d/Cube.java b/src/main/java/eu/mihosoft/vrl/v3d/Cube.java index 96d1c52f..96786dc5 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/Cube.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/Cube.java @@ -105,15 +105,15 @@ public Cube(Vector3d center, Vector3d dimensions) { public Cube(double w, double h, double d) { this(Vector3d.ZERO, new Vector3d(w, h, d)); } - public Cube(LengthParameter w, LengthParameter h, LengthParameter d) { - this(Vector3d.ZERO, new Vector3d(w.getMM(), h.getMM(), d.getMM())); - parametrics.add(w); - parametrics.add(h); - parametrics.add(d); - } - public Cube(LengthParameter size) { - this(size,size,size); - } +// public Cube(LengthParameter w, LengthParameter h, LengthParameter d) { +// this(Vector3d.ZERO, new Vector3d(w.getMM(), h.getMM(), d.getMM())); +//// parametrics.add(w); +//// parametrics.add(h); +//// parametrics.add(d); +// } +// public Cube(LengthParameter size) { +// this(size,size,size); +// } /* (non-Javadoc) * @see eu.mihosoft.vrl.v3d.Primitive#toPolygons() */ diff --git a/src/main/java/eu/mihosoft/vrl/v3d/Cylinder.java b/src/main/java/eu/mihosoft/vrl/v3d/Cylinder.java index 77a9ed47..93abd128 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/Cylinder.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/Cylinder.java @@ -186,24 +186,24 @@ public Cylinder(double startRadius, double endRadius, double height) { this.startRadius = startRadius parametrics=new ArrayList<>(); +// ArrayList parametrics=new ArrayList<>(); /** @@ -62,9 +62,9 @@ public abstract class Primitive implements ItoCSG{ */ public CSG toCSG() { CSG tmp = CSG.fromPolygons(getProperties(),new ArrayList<>(toPolygons())); - if(parametrics!=null) - for(Parameter p:parametrics) - tmp.setParameter(p); +// if(parametrics!=null) +// for(Parameter p:parametrics) +// tmp.setParameter(p); //tmp.triangulate(); return tmp; } diff --git a/src/main/java/eu/mihosoft/vrl/v3d/PropertyStorage.java b/src/main/java/eu/mihosoft/vrl/v3d/PropertyStorage.java index e7e1801b..0467316e 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/PropertyStorage.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/PropertyStorage.java @@ -40,6 +40,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import javafx.scene.paint.Color; @@ -50,8 +51,10 @@ */ public class PropertyStorage implements Serializable{ - /** The map. */ - private final Map map = new HashMap<>(); + private static final long serialVersionUID = 1460815261025940141L; + + /** The map. */ + private final ConcurrentHashMap map = new ConcurrentHashMap<>(); /** The Constant colors. */ private static final Color[] colors = { diff --git a/src/main/java/eu/mihosoft/vrl/v3d/RoundedCube.java b/src/main/java/eu/mihosoft/vrl/v3d/RoundedCube.java index f9c311f3..88781df0 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/RoundedCube.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/RoundedCube.java @@ -59,15 +59,15 @@ public RoundedCube(double size) { } - public RoundedCube(LengthParameter w, LengthParameter h, LengthParameter d) { - this(Vector3d.ZERO, new Vector3d(w.getMM(), h.getMM(), d.getMM())); - parametrics.add(w); - parametrics.add(h); - parametrics.add(d); - } - public RoundedCube(LengthParameter size) { - this(size,size,size); - } +// public RoundedCube(LengthParameter w, LengthParameter h, LengthParameter d) { +// this(Vector3d.ZERO, new Vector3d(w.getMM(), h.getMM(), d.getMM())); +// parametrics.add(w); +// parametrics.add(h); +// parametrics.add(d); +// } +// public RoundedCube(LengthParameter size) { +// this(size,size,size); +// } /** * Constructor. Creates a new rounded cuboid with the specified center and diff --git a/src/main/java/eu/mihosoft/vrl/v3d/Sphere.java b/src/main/java/eu/mihosoft/vrl/v3d/Sphere.java index 44556e20..5d87646c 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/Sphere.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/Sphere.java @@ -91,14 +91,14 @@ public Sphere(double radius) { // this(Vector3d.ZERO, new Vector3d(w.getMM(), h.getMM(), d.getMM())); // // } - public Sphere(LengthParameter size) { - this(size.getMM()); - parametrics.add(size); - } - public Sphere(LengthParameter size, int numSlices, int numStacks) { - this(size.getMM(), numSlices, numStacks); - parametrics.add(size); - } +// public Sphere(LengthParameter size) { +// this(size.getMM()); +// parametrics.add(size); +// } +// public Sphere(LengthParameter size, int numSlices, int numStacks) { +// this(size.getMM(), numSlices, numStacks); +// parametrics.add(size); +// } /** * Constructor. Creates a sphere with the specified radius, number of slices * and stacks. diff --git a/src/main/java/eu/mihosoft/vrl/v3d/TextExtrude.java b/src/main/java/eu/mihosoft/vrl/v3d/TextExtrude.java index 311abf44..bbddc45e 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/TextExtrude.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/TextExtrude.java @@ -168,12 +168,12 @@ private TextExtrude(String text, Font font, double dir) { // subtract.getElements().forEach(this::getPoints); for (int i = 0; i < sections.size(); i++) { + sections.get(i).setIsHole(false); for (CSG h : holes) { try { if (sections.get(i).isBoundsTouching(h)) { // println "Hole found " - CSG nl = sections.get(i).difference(h); - + CSG nl = sections.get(i).difference(h).setIsHole(false); sections.set(i, nl); } } catch (Exception e) { diff --git a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/CSGDatabase.java b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/CSGDatabase.java index f04ed30f..aed4971f 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/CSGDatabase.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/CSGDatabase.java @@ -1,68 +1,81 @@ package eu.mihosoft.vrl.v3d.parametrics; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.HashMap; import java.util.concurrent.CopyOnWriteArrayList; -public class CSGDatabase { - private static CSGDatabaseInstance instance = new CSGDatabaseInstance(new File("CSGdatabase.json")); - - public static void set(String key, Parameter value) { - getInstance().set(key, value); - } - - public static Parameter get(String key) { - return getInstance().get(key); - } - - public static void clear() { - getInstance().clear(); - } - - public static void addParameterListener(String key, IParameterChanged l) { - getInstance().addParameterListener(key, l); - } - - public static void clearParameterListeners(String key) { - getInstance().clearParameterListeners(key); - } - - public static void removeParameterListener(String key, IParameterChanged l) { - getInstance().removeParameterListener(key, l); - } - - public static CopyOnWriteArrayList getParamListeners(String key) { - return getInstance().getParamListeners(key); - } - - public static void delete(String key) { - getInstance().delete(key); - } - - public static void loadDatabaseFromFile(File f) { - getInstance().loadDatabaseFromFile(f); - } - - public static String getDataBaseString() { - return getInstance().getDataBaseString(); - } - public static void saveDatabase() { - getInstance().saveDatabase(); - } - - - public static File getDbFile() { - return getInstance().getDbFile(); - } +import eu.mihosoft.vrl.v3d.CSG; - public static void reLoadDbFile() { - getInstance().reLoadDbFile(); - } +public class CSGDatabase { + private static CSGDatabaseInstance instance ; +// public static void set(String key, Parameter value) { +// getInstance().set(key, value); +// } +// +// public static Parameter get(String key) { +// return getInstance().get(key); +// } +// +// public static void clear() { +// getInstance().clear(); +// } +// +// public static void addParameterListener(String key, IParameterChanged l) { +// getInstance().addParameterListener(key, l); +// } +// +// public static void clearParameterListeners(String key) { +// getInstance().clearParameterListeners(key); +// } +// +// public static void removeParameterListener(String key, IParameterChanged l) { +// getInstance().removeParameterListener(key, l); +// } +// +// public static CopyOnWriteArrayList getParamListeners(String key) { +// return getInstance().getParamListeners(key); +// } +// +// public static void delete(String key) { +// getInstance().delete(key); +// } +// +// public static void loadDatabaseFromFile(File f) { +// getInstance().loadDatabaseFromFile(f); +// } +// +// public static String getDataBaseString() { +// return getInstance().getDataBaseString(); +// } +// +// public static void saveDatabase() { +// getInstance().saveDatabase(); +// } +// +// +// public static File getDbFile() { +// return getInstance().getDbFile(); +// } +// +// public static void reLoadDbFile() { +// getInstance().reLoadDbFile(); +// } public static CSGDatabaseInstance getInstance() { + new Exception("Depricated database access!").printStackTrace(); + if(instance==null) { + try { + instance = new CSGDatabaseInstance( Files.createTempFile("CSGDatabase", ".json").toFile()); + } catch (IOException e) { + throw new RuntimeException(e); + } + + } return instance; } - public static void setInstance(CSGDatabaseInstance instance) { System.out.println("\n\nCSG Instance Set here to "+instance.getDbFile().getAbsolutePath()+"\n\n"); CSGDatabase.instance = instance; diff --git a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/CSGDatabaseInstance.java b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/CSGDatabaseInstance.java index 9cc011c0..526da27d 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/CSGDatabaseInstance.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/CSGDatabaseInstance.java @@ -5,6 +5,9 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -14,30 +17,115 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; +import eu.mihosoft.vrl.v3d.CSG; + public class CSGDatabaseInstance { ConcurrentHashMap database = null; File dbFile = null; final Type TT_mapStringString = new TypeToken>() { }.getType(); - final Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); + // final Gson gson = new + // GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); + private static Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting() + .excludeFieldsWithoutExposeAnnotation().create(); final ConcurrentHashMap> parameterListeners = new ConcurrentHashMap<>(); + private HashMap> mapOfAllparametrics = null; + + private HashMap> getMap() { + if (mapOfAllparametrics == null) { + mapOfAllparametrics = new HashMap>(); + } + return mapOfAllparametrics; + } + + public HashMap getMapOfparametrics(CSG source) { + if (getMap().get(source.getUniqueId()) == null) { + getMap().put(source.getUniqueId(), new HashMap<>()); + } + return getMap().get(source.getUniqueId()); + } + + public CSGDatabaseInstance setParameter(CSG instance, Parameter w) { + setParameter(instance, w, new IParametric() { + @Override + public CSG change(CSG oldCSG, String parameterKey, Long newValue) { + if (parameterKey.contentEquals(w.getName())) + get(w.getName()).setValue(newValue); + return oldCSG; + } + }); + return this; + } + + public CSGDatabaseInstance setParameter(CSG instance, String key, double defaultValue, double upperBound, + double lowerBound, IParametric function) { + ArrayList vals = new ArrayList(); + vals.add(upperBound); + vals.add(lowerBound); + setParameter(instance, new LengthParameter(this, key, defaultValue, vals), function); + return this; + } + + public CSGDatabaseInstance setParameter(CSG obj, Parameter w, IParametric function) { + if (w == null) + return this; + if (get(w.getName()) == null) + set(w.getName(), w); + if (getMapOfparametrics(obj).get(w.getName()) == null) + getMapOfparametrics(obj).put(w.getName(), function); + return this; + } + + public CSGDatabaseInstance setParameterIfNull(CSG instance, String key) { + if (getMapOfparametrics(instance).get(key) == null) + getMapOfparametrics(instance).put(key, new IParametric() { + + @Override + public CSG change(CSG oldCSG, String parameterKey, Long newValue) { + get(key).setValue(newValue); + return oldCSG; + } + }); + return this; + } + + public Set getParameters(CSG instance) { + + return getMapOfparametrics(instance).keySet(); + } + + public CSGDatabaseInstance setParameterNewValue(CSG instance, String key, double newValue) { + IParametric function = getMapOfparametrics(instance).get(key); + if (function != null) { + CSG setManipulator = function.change(instance, key, new Long((long) (newValue * 1000))) + .setManipulator(instance.getManipulator()); + setManipulator.setColor(instance.getColor()); + return this; + } + return this; + } + public CSGDatabaseInstance(File db) { dbFile = db; - if(!dbFile.exists()) + if (!dbFile.exists()) { try { dbFile.createNewFile(); - } catch (IOException e) { + saveDatabase(); + } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } + } + getDatabase(); + } public void set(String key, Parameter value) { getDatabase(); // synchronized(database){ - if(value==null) + if (value == null) throw new RuntimeException(); getDatabase().put(key, value); // } @@ -45,22 +133,21 @@ public void set(String key, Parameter value) { public Parameter get(String key) { Parameter ret = null; - getDatabase();// load database before synchronization // synchronized(database){ ret = getDatabase().get(key); // } return ret; } - public void clear() { - - getDatabase(); - // synchronized(database){ - database.clear(); - // } - parameterListeners.clear(); - saveDatabase(); - } +// public void clear() { +// +// getDatabase(); +// // synchronized(database){ +// database.clear(); +// // } +// parameterListeners.clear(); +// saveDatabase(); +// } public void addParameterListener(String key, IParameterChanged l) { CopyOnWriteArrayList list = getParamListeners(key); @@ -127,31 +214,33 @@ private ConcurrentHashMap getDatabase() { ConcurrentHashMap tm = gson.fromJson(jsonString, TT_mapStringString); if (tm != null) { -// ////System.out.println("Hash Map loaded from "+jsonString); -// for(String k:tm.keySet()){ -// ////System.out.println("Key: "+k+" vlaue= "+tm.get(k)); -// } + for (String k : tm.keySet()) { + tm.get(k).setInstance(this); + } setDatabase(tm); - }else { + } else { setDatabase(new ConcurrentHashMap()); - saveDatabase(); } } } catch (Exception e) { - //e.printStackTrace(); - //System.err.println("Failed to load " + dbFile.getAbsolutePath()); + e.printStackTrace(); + System.err.println("Failed to load " + dbFile.getAbsolutePath()); setDatabase(new ConcurrentHashMap()); - saveDatabase(); } Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { - saveDatabase(); + try { + saveDatabase(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } }); } - if(database==null) + if (database == null) throw new RuntimeException(); return database; } @@ -167,7 +256,9 @@ public void loadDatabaseFromFile(File f) { ConcurrentHashMap tm = gson.fromJson(jsonString, TT_mapStringString); if (tm != null) for (String k : tm.keySet()) { - set(k, tm.get(k)); + Parameter value = tm.get(k); + value.setInstance(this); + set(k, value); } saveDatabase(); } catch (Exception e) { @@ -188,7 +279,11 @@ public String getDataBaseString() { return writeOut; } - public void saveDatabase() { + public void saveDatabase() throws Exception { + if(database.size()==0) { + new Exception("Can not save an empty database! to "+getDbFile().getAbsolutePath()).printStackTrace();; + return; + } String writeOut = getDataBaseString(); try { if (!getDbFile().exists()) { diff --git a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/LengthParameter.java b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/LengthParameter.java index 2b03acda..051c71ad 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/LengthParameter.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/LengthParameter.java @@ -3,9 +3,12 @@ import java.util.ArrayList; public class LengthParameter extends Parameter { - - public LengthParameter(String key, Double defaultValue, ArrayList options) { - ArrayList opts=new ArrayList(); +// public LengthParameter(String key, Double defaultValue, ArrayList options) { +// this(CSGDatabase.getInstance(),key,defaultValue,options); +// } + public LengthParameter(CSGDatabaseInstance instance,String key, Double defaultValue, ArrayList options) { + super(instance); + ArrayList opts=new ArrayList(); for(Object d:options) opts.add(d.toString()); setup(key, new Long((long) (defaultValue*1000.0)), opts); diff --git a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/Parameter.java b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/Parameter.java index 15832ca8..34007226 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/Parameter.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/Parameter.java @@ -3,23 +3,32 @@ import java.util.ArrayList; import java.util.concurrent.CopyOnWriteArrayList; +import com.google.gson.annotations.Expose; + public class Parameter { - + @Expose(serialize = true, deserialize = true) private String name=null; + @Expose(serialize = true, deserialize = true) private final ArrayList options=new ArrayList(); + @Expose(serialize = true, deserialize = true) private Long value=null; + @Expose(serialize = true, deserialize = true) private String strValue=null; + @Expose(serialize = false, deserialize = false) + private CSGDatabaseInstance instance; - public Parameter(){} + //public Parameter(){} + public Parameter(CSGDatabaseInstance instance){ + this.setInstance(instance);} protected void setup(String key,Long defaultValue,ArrayList options){ this.name = key; - if(CSGDatabase.get(name)==null) + if(getInstance().get(name)==null) setValue(defaultValue); else{ - setValue(CSGDatabase.get(name).getValue()); + setValue(getInstance().get(name).getValue()); } - CSGDatabase.addParameterListener(name, new IParameterChanged() { + getInstance().addParameterListener(name, new IParameterChanged() { @Override public void parameterChanged(String name, Parameter p) { value = p.getValue();// if another instance of parameter with this key changes value @@ -28,16 +37,16 @@ public void parameterChanged(String name, Parameter p) { for(String o:options){ this.options.add(o); } - CSGDatabase.set(key, this); + getInstance().set(key, this); } protected void setup(String key,String defaultValue,ArrayList options){ this.name = key; - if(CSGDatabase.get(name)==null) + if(getInstance().get(name)==null) this.strValue = defaultValue; else{ - this.strValue = CSGDatabase.get(name).getStrValue(); + this.strValue = getInstance().get(name).getStrValue(); } - CSGDatabase.addParameterListener(name, new IParameterChanged() { + getInstance().addParameterListener(name, new IParameterChanged() { @Override public void parameterChanged(String name, Parameter p) { strValue = p.getStrValue();// if another instance of parameter with this key changes value @@ -46,7 +55,7 @@ public void parameterChanged(String name, Parameter p) { for(String o:options){ this.options.add(o); } - CSGDatabase.set(key, this); + getInstance().set(key, this); } public String getName() { return name; @@ -55,7 +64,7 @@ public String getName() { public void setValue(Long newVal){ if(value!=newVal){ value=newVal; - CopyOnWriteArrayList listeners = CSGDatabase.getParamListeners(name); + CopyOnWriteArrayList listeners = getInstance().getParamListeners(name); for(int i=0;i listeners = CSGDatabase.getParamListeners(name); + CopyOnWriteArrayList listeners = getInstance().getParamListeners(name); for(IParameterChanged l:listeners){ l.parameterChanged(name, this); } @@ -99,6 +108,12 @@ public double getMM(){ public double getMicrons(){ return (Long)getValue(); } + public CSGDatabaseInstance getInstance() { + return instance; + } + public void setInstance(CSGDatabaseInstance instance) { + this.instance = instance; + } } diff --git a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/StringParameter.java b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/StringParameter.java index 104ec4c0..9f67be8a 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/parametrics/StringParameter.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/parametrics/StringParameter.java @@ -6,7 +6,11 @@ public class StringParameter extends Parameter { private List options2; - public StringParameter(String key, String defaultValue, ArrayList options) { +// public StringParameter(String key, String defaultValue, ArrayList options) { +// this(CSGDatabase.getInstance(),key, defaultValue, options); +// } + public StringParameter(CSGDatabaseInstance instance,String key, String defaultValue, ArrayList options) { + super(instance); setup(key, defaultValue, options); options2 = options; } diff --git a/src/main/java/eu/mihosoft/vrl/v3d/thumbnail/ThumbnailImage.java b/src/main/java/eu/mihosoft/vrl/v3d/thumbnail/ThumbnailImage.java index 08f133dd..bb04046a 100644 --- a/src/main/java/eu/mihosoft/vrl/v3d/thumbnail/ThumbnailImage.java +++ b/src/main/java/eu/mihosoft/vrl/v3d/thumbnail/ThumbnailImage.java @@ -11,6 +11,7 @@ import eu.mihosoft.vrl.v3d.Bounds; import eu.mihosoft.vrl.v3d.CSG; import eu.mihosoft.vrl.v3d.Vector3d; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.SceneAntialiasing; @@ -66,11 +67,11 @@ public static Bounds getSellectedBounds(List incoming) { return new Bounds(min, max); } - public static WritableImage get(List c) { + public static WritableImage get(List c,CSGDatabaseInstance instance) { ArrayList csgList = new ArrayList(); for (CSG cs : c) { if (cs.getManipulator() != null) { - csgList.add(cs.transformed(TransformConverter.fromAffine(cs.getManipulator())).syncProperties(cs)); + csgList.add(cs.transformed(TransformConverter.fromAffine(cs.getManipulator())).syncProperties(instance,cs)); } else csgList.add(cs); } @@ -153,20 +154,20 @@ public static WritableImage get(List c) { return snapshot; } - public static Thread writeImage(CSG incoming, File toPNG) { + public static Thread writeImage(CSGDatabaseInstance instance,CSG incoming, File toPNG) { ArrayList bits = new ArrayList(); bits.add(incoming); - return writeImage(bits, toPNG); + return writeImage(instance,bits, toPNG); } - public static Thread writeImage(List incoming, File toPNG) { + public static Thread writeImage(CSGDatabaseInstance instance,List incoming, File toPNG) { Thread t = new Thread(new Runnable() { WritableImage img = null; @Override public void run() { File image = toPNG; - javafx.application.Platform.runLater(() -> img = ThumbnailImage.get(incoming)); + javafx.application.Platform.runLater(() -> img = ThumbnailImage.get(incoming,instance)); while (img == null) try { Thread.sleep(16); diff --git a/src/test/java/eu/mihosoft/vrl/v3d/GroupingTest.java b/src/test/java/eu/mihosoft/vrl/v3d/GroupingTest.java index 2760642b..153859c4 100644 --- a/src/test/java/eu/mihosoft/vrl/v3d/GroupingTest.java +++ b/src/test/java/eu/mihosoft/vrl/v3d/GroupingTest.java @@ -4,6 +4,8 @@ import org.junit.Test; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; + public class GroupingTest { @Test @@ -13,7 +15,7 @@ public void test() { c.addGroupMembership(groupID); c.setName("MyName"); c.addIsGroupResult(groupID); - CSG copy = c.clone().syncProperties(c).setName(c.getName()); + CSG copy = c.clone().syncProperties(CSGDatabase.getInstance(),c).setName(c.getName()); copy.removeGroupMembership(groupID); copy.removeIsGroupResult(groupID); diff --git a/src/test/java/eu/mihosoft/vrl/v3d/SVGLoadTest.java b/src/test/java/eu/mihosoft/vrl/v3d/SVGLoadTest.java index d9ea4d37..d966cc33 100644 --- a/src/test/java/eu/mihosoft/vrl/v3d/SVGLoadTest.java +++ b/src/test/java/eu/mihosoft/vrl/v3d/SVGLoadTest.java @@ -13,6 +13,7 @@ import org.junit.Before; import org.junit.Test; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; import eu.mihosoft.vrl.v3d.svg.SVGLoad; import eu.mihosoft.vrl.v3d.thumbnail.ThumbnailImage; import javafx.scene.paint.Color; @@ -76,7 +77,7 @@ public void flame() throws IOException { throw new RuntimeException("Failed to load"); try { ThumbnailImage.setCullFaceValue(CullFace.NONE); - ThumbnailImage.writeImage(parts,new File(svg.getAbsolutePath()+".png")).join(); + ThumbnailImage.writeImage(CSGDatabase.getInstance(),parts,new File(svg.getAbsolutePath()+".png")).join(); } catch (InterruptedException e) { // Auto-generated catch block e.printStackTrace(); @@ -127,7 +128,7 @@ public void box() throws IOException { ArrayListparts =run(s); try { ThumbnailImage.setCullFaceValue(CullFace.NONE); - ThumbnailImage.writeImage(parts,new File(svg.getAbsolutePath()+".png")).join(); + ThumbnailImage.writeImage(CSGDatabase.getInstance(),parts,new File(svg.getAbsolutePath()+".png")).join(); } catch (InterruptedException e) { // Auto-generated catch block e.printStackTrace(); @@ -146,7 +147,7 @@ public void inside() throws IOException { ArrayListparts =new ArrayList<>(Arrays.asList(CSG.unionAll(run(s)))); try { ThumbnailImage.setCullFaceValue(CullFace.NONE); - ThumbnailImage.writeImage(parts,new File(svg.getAbsolutePath()+".png")).join(); + ThumbnailImage.writeImage(CSGDatabase.getInstance(),parts,new File(svg.getAbsolutePath()+".png")).join(); } catch (InterruptedException e) { // Auto-generated catch block e.printStackTrace(); @@ -165,7 +166,7 @@ public void adversarial() throws IOException { ArrayListparts =run(s); try { ThumbnailImage.setCullFaceValue(CullFace.NONE); - ThumbnailImage.writeImage(parts,new File(svg.getAbsolutePath()+".png")).join(); + ThumbnailImage.writeImage(CSGDatabase.getInstance(),parts,new File(svg.getAbsolutePath()+".png")).join(); } catch (InterruptedException e) { // Auto-generated catch block e.printStackTrace(); diff --git a/src/test/java/eu/mihosoft/vrl/v3d/ServerClientTest.java b/src/test/java/eu/mihosoft/vrl/v3d/ServerClientTest.java index de479394..11b05d8c 100644 --- a/src/test/java/eu/mihosoft/vrl/v3d/ServerClientTest.java +++ b/src/test/java/eu/mihosoft/vrl/v3d/ServerClientTest.java @@ -8,6 +8,8 @@ import org.junit.Test; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import eu.mihosoft.vrl.v3d.parametrics.LengthParameter; public class ServerClientTest { @@ -47,8 +49,12 @@ public CSG prep(CSG incoming) { return incoming; } }); - LengthParameter param = new LengthParameter("parameter", (double) 35, new ArrayList()); - a.setParameter(param); + CSGDatabaseInstance instance = CSGDatabase.getInstance(); + + LengthParameter param = new LengthParameter(instance,"parameter", (double) 35, new ArrayList()); + + a.setParameter(CSGDatabase.getInstance(),param ); + instance.saveDatabase(); CSG b = new Cube(20, 30, 5).toCSG(); b.getBounds(); CSG c = new Cube(10, 10, 10).toCSG(); diff --git a/src/test/java/eu/mihosoft/vrl/v3d/StlLoadTest.java b/src/test/java/eu/mihosoft/vrl/v3d/StlLoadTest.java index 84eae98d..7c089c42 100644 --- a/src/test/java/eu/mihosoft/vrl/v3d/StlLoadTest.java +++ b/src/test/java/eu/mihosoft/vrl/v3d/StlLoadTest.java @@ -7,6 +7,7 @@ import org.junit.Test; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; import eu.mihosoft.vrl.v3d.thumbnail.ThumbnailImage; import javafx.scene.shape.CullFace; @@ -19,7 +20,7 @@ public void test() throws IOException { CSG loaded = STL.file(file.toPath()); try { ThumbnailImage.setCullFaceValue(CullFace.NONE); - ThumbnailImage.writeImage(loaded,new File(file.getAbsolutePath()+".png")).join(); + ThumbnailImage.writeImage(CSGDatabase.getInstance(),loaded,new File(file.getAbsolutePath()+".png")).join(); } catch (InterruptedException e) { // Auto-generated catch block e.printStackTrace();