From: Marko Luukkainen Date: Wed, 2 Sep 2020 11:18:41 +0000 (+0300) Subject: OcTree implementation X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F20%2F4420%2F1;p=simantics%2F3d.git OcTree implementation Created a separate plugin, so that 3D data structures remain independent of G3D framework. gitlab #140 Change-Id: Ia40bb149baff2c8f887a2c1be2f515679393a6c7 --- diff --git a/org.simantics.g3d.datastructures/.classpath b/org.simantics.g3d.datastructures/.classpath new file mode 100644 index 00000000..eca7bdba --- /dev/null +++ b/org.simantics.g3d.datastructures/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.simantics.g3d.datastructures/.gitignore b/org.simantics.g3d.datastructures/.gitignore new file mode 100644 index 00000000..ae3c1726 --- /dev/null +++ b/org.simantics.g3d.datastructures/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/org.simantics.g3d.datastructures/.project b/org.simantics.g3d.datastructures/.project new file mode 100644 index 00000000..dce8db1f --- /dev/null +++ b/org.simantics.g3d.datastructures/.project @@ -0,0 +1,28 @@ + + + org.simantics.g3d.datastructures + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.simantics.g3d.datastructures/.settings/org.eclipse.jdt.core.prefs b/org.simantics.g3d.datastructures/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..0c68a61d --- /dev/null +++ b/org.simantics.g3d.datastructures/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/org.simantics.g3d.datastructures/META-INF/MANIFEST.MF b/org.simantics.g3d.datastructures/META-INF/MANIFEST.MF new file mode 100644 index 00000000..07e18e5a --- /dev/null +++ b/org.simantics.g3d.datastructures/META-INF/MANIFEST.MF @@ -0,0 +1,10 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: G3D Datastructures +Bundle-SymbolicName: org.simantics.g3d.datastructures +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Semantum +Automatic-Module-Name: org.simantics.g3d.datastructures +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: javax.vecmath;bundle-version="1.5.2" +Export-Package: org.simantics.g3d.datastructures diff --git a/org.simantics.g3d.datastructures/build.properties b/org.simantics.g3d.datastructures/build.properties new file mode 100644 index 00000000..34d2e4d2 --- /dev/null +++ b/org.simantics.g3d.datastructures/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.simantics.g3d.datastructures/pom.xml b/org.simantics.g3d.datastructures/pom.xml new file mode 100644 index 00000000..7e06a4d6 --- /dev/null +++ b/org.simantics.g3d.datastructures/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + org.simantics.g3d + org.simantics.g3d.root + 1.0.0-SNAPSHOT + + + org.simantics.g3d.datastructures + eclipse-plugin + 1.0.0-SNAPSHOT + + diff --git a/org.simantics.g3d.datastructures/src/org/simantics/g3d/datastructures/Box.java b/org.simantics.g3d.datastructures/src/org/simantics/g3d/datastructures/Box.java new file mode 100644 index 00000000..ebe44e3b --- /dev/null +++ b/org.simantics.g3d.datastructures/src/org/simantics/g3d/datastructures/Box.java @@ -0,0 +1,32 @@ +package org.simantics.g3d.datastructures; + +import javax.vecmath.Point3d; + +public class Box { + + Point3d min; + Point3d max; + + public Point3d getMin() { + return min; + } + public Point3d getMax() { + return max; + } + + public Box(Point3d min, Point3d max) { + this.max = max; + this.min = min; + } + + public Box(double minx, double miny, double minz, double maxx, double maxy, double maxz) { + min = new Point3d(minx, miny, minz); + max = new Point3d(maxx, maxy, maxz); + } + + public Box(double min[], double max[]) { + this.min = new Point3d(min); + this.max = new Point3d(max); + } + +} diff --git a/org.simantics.g3d.datastructures/src/org/simantics/g3d/datastructures/OcTree.java b/org.simantics.g3d.datastructures/src/org/simantics/g3d/datastructures/OcTree.java new file mode 100644 index 00000000..671570c0 --- /dev/null +++ b/org.simantics.g3d.datastructures/src/org/simantics/g3d/datastructures/OcTree.java @@ -0,0 +1,196 @@ +package org.simantics.g3d.datastructures; + +import java.util.HashSet; +import java.util.Set; + +import javax.vecmath.Point3d; + +public class OcTree { + + Point3d center; + Set contains; + double dx,dy,dz; + + boolean leaf; + + OcTree[] children; + + /** + * Creates a octree + * @param center center of the octree area + * @param dx size of the area along x-axis. + * @param dy size of the area along y-axis. + * @param dz size of the area along z-axis. + * @param depth depth of the tree structure. + */ + public OcTree(Point3d center, double dx, double dy, double dz, int depth) { + this.center = center; + this.dx = dx; + this.dy = dy; + this.dz = dz; + this.leaf = true; + split(depth); + } + + private OcTree(Point3d center, double dx, double dy, double dz) { + this.center = center; + this.dx = dx; + this.dy = dy; + this.dz = dz; + this.leaf = true; + } + + /** + * Insets an object into the tree + * @param object + * @param bounds + */ + public void insert(T object, Box bounds) { + if (leaf) { + contains.add(object); + } else { + + boolean ins[] = getAccessArr(bounds); + for (int i = 0; i < 8; i++) { + if (ins[i]) + children[i].insert(object, bounds); + } + } + } + + private boolean[] getAccessArr(Box bounds) { + boolean pX = bounds.getMin().getX() > center.getX(); + boolean nX = bounds.getMax().getX() < center.getX(); + boolean pY = bounds.getMin().getY() > center.getY(); + boolean nY = bounds.getMax().getY() < center.getY(); + boolean pZ = bounds.getMin().getZ() > center.getZ(); + boolean nZ = bounds.getMax().getZ() < center.getZ(); + + boolean ins[] = new boolean[8]; + for (int i = 0; i < 8; i++) + ins[i] = true; + + if (pX) { + for (int i = 1; i < 8; i+=2) { + ins[i] = false; + } + } else if (nX) { + for (int i = 0; i < 8; i+=2) { + ins[i] = false; + } + } + + if (pY) { + for (int i = 2; i < 8; ) { + ins[i++] = false; + ins[i++] = false; + i+=2; + } + } else if (nY) { + for (int i = 0; i < 8; ) { + ins[i++] = false; + ins[i++] = false; + i+=2; + } + } + + if (pZ) { + for (int i = 4; i < 8; i++) { + ins[i] = false; + } + } else if (nZ) { + for (int i = 0; i < 4; i++) { + ins[i] = false; + } + } + return ins; + } + + /** + * Removes an object from the tree + * @param object + */ + public void remove(T object) { + if (leaf) { + contains.remove(object); + } else { + for (OcTree n : children) { + n.remove(object); + } + } + } + + /** + * Returns objects within the given area. + * @param bounds + * @param set + */ + public void get(Box bounds, Set set) { + if (leaf) { + set.addAll(contains); + } else { + + boolean ins[] = getAccessArr(bounds); + for (int i = 0; i < 8; i++) { + if (ins[i]) + children[i].get(bounds, set); + } + } + } + + public void clear() { + if (leaf) { + contains.clear(); + } else { + for (OcTree n : children) + n.clear(); + } + } + + private void split(int depth) { + if (!leaf) { + throw new IllegalStateException("Node is already split"); + } + if (depth <= 0) { + this.contains = new HashSet<>(); + return; + } + split(); + depth--; + for (OcTree n : children) { + n.split(depth); + } + } + + + private void split() { + double _dx = dx * 0.5; + double _dy = dy * 0.5; + double _dz = dz * 0.5; + double xd2 = _dx * 0.5; + double yd2 = _dy * 0.5; + double zd2 = _dz * 0.5; + children = new OcTree[8]; + children[0] = new OcTree(new Point3d(center.x+xd2, center.y+yd2, center.z+zd2),_dx,_dy,_dz); + children[1] = new OcTree(new Point3d(center.x-xd2, center.y+yd2, center.z+zd2),_dx,_dy,_dz); + children[2] = new OcTree(new Point3d(center.x+xd2, center.y-yd2, center.z+zd2),_dx,_dy,_dz); + children[3] = new OcTree(new Point3d(center.x-xd2, center.y-yd2, center.z+zd2),_dx,_dy,_dz); + children[4] = new OcTree(new Point3d(center.x+xd2, center.y+yd2, center.z-zd2),_dx,_dy,_dz); + children[5] = new OcTree(new Point3d(center.x-xd2, center.y+yd2, center.z-zd2),_dx,_dy,_dz); + children[6] = new OcTree(new Point3d(center.x+xd2, center.y-yd2, center.z-zd2),_dx,_dy,_dz); + children[7] = new OcTree(new Point3d(center.x-xd2, center.y-yd2, center.z-zd2),_dx,_dy,_dz); + leaf = false; + } + + + public void dispose() { + if (leaf) { + this.contains = null; + } else { + for (OcTree n : children) { + n.dispose(); + } + children = null; + } + } + } diff --git a/org.simantics.g3d.feature/feature.xml b/org.simantics.g3d.feature/feature.xml index f094a076..ee9976b0 100644 --- a/org.simantics.g3d.feature/feature.xml +++ b/org.simantics.g3d.feature/feature.xml @@ -181,4 +181,11 @@ This Agreement is governed by the laws of the State of New York and the intellec version="0.0.0" unpack="false"/> + + diff --git a/pom.xml b/pom.xml index 75f7af22..4e93b310 100644 --- a/pom.xml +++ b/pom.xml @@ -169,6 +169,7 @@ org.simantics.g3d.csg.ontology org.simantics.g3d.ontology org.simantics.g3d.vtk + org.simantics.g3d.datastructures org.simantics.opencascade org.simantics.opencascade.vtk