rename surface to plane

This commit is contained in:
Val Erastov 2014-08-12 20:36:37 -07:00
parent 8f89af7beb
commit 25acb0ff6f
8 changed files with 125 additions and 115 deletions

View file

@ -1,19 +1,16 @@
package cad;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.FPSAnimator;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.AWTGLAutoDrawable;
import javax.media.opengl.awt.GLJPanel;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.media.opengl.Threading;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener {
@ -24,7 +21,9 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
private static GLWindow window;
public static void main(String[] args) {
ExecutorService updater = Executors.newSingleThreadExecutor();
public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException {
// Get the default OpenGL profile, reflecting the best for your running platform
GLProfile glp = GLProfile.getDefault();
@ -34,42 +33,41 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
window = GLWindow.create(caps);
// Create a animator that drives canvas' display() at the specified FPS.
final FPSAnimator animator = new FPSAnimator(window, 60, true);
// final FPSAnimator animator = new FPSAnimator(window, 60, true);
//// final Animator animator = new Animator(window);
window.addWindowListener(new com.jogamp.newt.event.WindowAdapter() {
@Override
public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent arg0) {
// Use a dedicate thread to run the stop() to ensure that the
// animator stops before program exits.
new Thread() {
@Override
public void run() {
if (animator.isStarted())
animator.stop(); // stop the animator loop
}
}.start();
}
});
// window.addWindowListener(new com.jogamp.newt.event.WindowAdapter() {
// @Override
// public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent arg0) {
// // Use a dedicate thread to run the stop() to ensure that the
// // animator stops before program exits.
// new Thread() {
// @Override
// public void run() {
// if (animator.isStarted())
// animator.stop(); // stop the animator loop
// }
// }.start();
// }
// });
window.addGLEventListener(new Cad());
window.setSize(640, 480);
window.setTitle("CAD");
window.setVisible(true);
new Thread(new Runnable() {
public void run() {
final Object monitor = new Object();
synchronized (monitor) {
while (true)
try {
Executors.newSingleThreadExecutor().execute(() -> {
Object monitor = new Object();
while (true) {
try {
synchronized (monitor) {
monitor.wait();
} catch (InterruptedException e) {
}
} catch (InterruptedException e) {
}
}
}).start();
});
// animator.start();
}
@ -143,20 +141,15 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
public void display(GLAutoDrawable drawable) {
// Turn the gears' teeth
angle += 2.0f;
// angle += 2.0f;
// Get the GL corresponding to the drawable we are animating
GL2 gl = drawable.getGL().getGL2();
// Special handling for the case where the GLJPanel is translucent
// and wants to be composited with other Java 2D content
if ((drawable instanceof GLJPanel) &&
!((GLJPanel) drawable).isOpaque() &&
((GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) {
gl.glClear(GL2.GL_DEPTH_BUFFER_BIT);
} else {
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
}
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
// Rotate the entire assembly of gears based on how the user
// dragged the mouse around
@ -167,7 +160,7 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
// Place the first gear and call its display list
gl.glPushMatrix();
gl.glTranslatef(-3.0f, -2.0f, 0.0f);
gl.glTranslatef(1.0f, 1.0f, 0.0f);
gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);
gl.glCallList(gear1);
gl.glPopMatrix();
@ -339,6 +332,41 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
view_rotx += thetaX;
view_roty += thetaY;
update(window::display);
}
volatile boolean updating = false;
private void update(Runnable op) {
if (updating) {
return;
}
Threading.invokeOnOpenGLThread(false, new Runnable() {
@Override
public void run() {
try {
updating = true;
op.run();
} finally {
updating = false;
}
}
});
// updater.execute(() -> {
// try {
// updating = true;
//
// op.run();
// } finally {
// updating = false;
// }
// });
}
@Override

View file

@ -36,7 +36,7 @@ public class AppCtrl implements Initializable {
}
private void setInitObject(Group parent) {
List<Surface> cube = Utils3D.createCube(100);
List<Plane> cube = Utils3D.createCube(100);
parent.getChildren().addAll(cadContext.toNodes(cube));
//
// CSG init = new Cube(100).toCSG().difference(new Cylinder(30, 100, 10).toCSG());

View file

@ -1,12 +1,11 @@
package cad.fx;
import eu.mihosoft.vrl.v3d.Polygon;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import javafx.scene.shape.TriangleMesh;
public class CSGMesh extends TriangleMesh {
public final TIntObjectMap<Surface> polygons = new TIntObjectHashMap<>();
public final TIntObjectMap<Plane> polygons = new TIntObjectHashMap<>();
}

View file

@ -1,14 +1,10 @@
package cad.fx;
import eu.mihosoft.vrl.v3d.CSG;
import eu.mihosoft.vrl.v3d.Polygon;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.shape.MeshView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CSGNode extends MeshView {
@ -38,14 +34,14 @@ public class CSGNode extends MeshView {
System.out.println(poly);
}
public final Map<Surface, Sketch> sketches = new HashMap<>();
public final Map<Plane, Sketch> sketches = new HashMap<>();
public Sketch getSketch(Surface surface) {
Sketch sketch = sketches.get(surface);
public Sketch getSketch(Plane plane) {
Sketch sketch = sketches.get(plane);
if (sketch == null) {
sketch = new Sketch(surface);
sketch = new Sketch(plane);
((Group) getParent()).getChildren().add(sketch.drawLayer);
sketches.put(surface, sketch);
sketches.put(plane, sketch);
}
return sketch;
}

View file

@ -10,9 +10,6 @@ import javafx.scene.shape.MeshView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
@ -75,20 +72,20 @@ public class CadContext {
PickResult pickResult = e.getPickResult();
int face = pickResult.getIntersectedFace();
CSGMesh csgMesh = (CSGMesh) csgNode.getMesh();
Surface surface = csgMesh.polygons.get(face);
System.out.println(surface);
if (surface != null) {
Plane plane = csgMesh.polygons.get(face);
System.out.println(plane);
if (plane != null) {
if (selection != null) {
boolean isSameNode = selection.sameTo(csgNode, surface);
boolean isSameNode = selection.sameTo(csgNode, plane);
if (sketcher == null && !isSameNode) {
selection = new Selection(csgNode, surface);
selection = new Selection(csgNode, plane);
}
if (sketcher != null && isSameNode) {
sketcher.addPoint(pickResult.getIntersectedPoint());
}
} else {
if (sketcher == null) {
selection = new Selection(csgNode, surface);
selection = new Selection(csgNode, plane);
}
}
}
@ -98,7 +95,7 @@ public class CadContext {
if (sketcher != null || selection == null) {
return;
}
sketcher = new Sketcher(selection.csgNode.getSketch(selection.surface));
sketcher = new Sketcher(selection.csgNode.getSketch(selection.plane));
}
public void endSketching() {
@ -114,43 +111,43 @@ public class CadContext {
return;
}
Sketch sketch = selection.csgNode.getSketch(selection.surface);
Sketch sketch = selection.csgNode.getSketch(selection.plane);
Vector dir = sketch.owner.normal.scale(height);
for (List<Vector> polygon : sketch.polygons) {
if (polygon.isEmpty()) {
continue;
}
Surface surface = new Surface(sketch.owner.normal, polygon, Collections.emptyList());
List<Surface> extruded = Surface.extrude(surface, dir);
Plane plane = new Plane(sketch.owner.normal, polygon, Collections.emptyList());
List<Plane> extruded = Plane.extrude(plane, dir);
for (Surface s : extruded) {
for (Plane s : extruded) {
sketch.drawLayer.getChildren().addAll(toNodes(extruded));// fixme
}
// CSG pad = Extrude.points(dir, polygon);
}
}
public List<CSGNode> toNodes(List<Surface> extruded) {
public List<CSGNode> toNodes(List<Plane> extruded) {
return extruded.stream().map(this::toNode).collect(toList());
}
public CSGNode toNode(Surface surface) {
return new CSGNode(Utils3D.getMesh(Collections.singletonList(surface)), this);
public CSGNode toNode(Plane plane) {
return new CSGNode(Utils3D.getMesh(Collections.singletonList(plane)), this);
}
public static class Selection {
public final CSGNode csgNode;
public final Surface surface;
public final Plane plane;
public Selection(CSGNode csgNode, Surface surface) {
public Selection(CSGNode csgNode, Plane plane) {
this.csgNode = csgNode;
this.surface = surface;
this.plane = plane;
}
public boolean sameTo(CSGNode csgNode, Surface surface) {
return this.csgNode.equals(csgNode) && this.surface.equals(surface);
public boolean sameTo(CSGNode csgNode, Plane plane) {
return this.csgNode.equals(csgNode) && this.plane.equals(plane);
}
}
}

View file

@ -15,7 +15,7 @@ import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
public class Surface {
public class Plane {
public final Vector normal;
public final List<Vector> shell;
@ -23,15 +23,15 @@ public class Surface {
private List<Vector[]> triangles;
public Surface(List<Vector> shell) {
public Plane(List<Vector> shell) {
this(shell, Collections.emptyList());
}
public Surface(List<Vector> shell, List<List<Vector>> holes) {
public Plane(List<Vector> shell, List<List<Vector>> holes) {
this(normalOfCCWSeq(shell.get(0), shell.get(1), shell.get(2)), shell, holes);
}
public Surface(Vector normal, List<Vector> shell, List<List<Vector>> holes) {
public Plane(Vector normal, List<Vector> shell, List<List<Vector>> holes) {
this.normal = normal.normalize();
this.shell = shell;
this.holes = holes;
@ -43,11 +43,11 @@ public class Surface {
}
}
public Surface fixCCW() {
public Plane fixCCW() {
if (!normal.slightlyEqualTo(normalOfCCWSeq(shell.get(0), shell.get(1), shell.get(2)))) {
List<Vector> shell = new ArrayList<>(this.shell);
Collections.reverse(shell);
return new Surface(normal, shell, holes);
return new Plane(normal, shell, holes);
}
return this;
}
@ -128,11 +128,11 @@ public class Surface {
triangle[2] = first;
}
public Surface flip() {
return new Surface(normal.negate(), shell, holes);
public Plane flip() {
return new Plane(normal.negate(), shell, holes);
}
public static List<Surface> extrude(Surface source, Vector target) {
public static List<Plane> extrude(Plane source, Vector target) {
double dotProduct = target.normalize().dot(source.normal);
if (dotProduct == 0) {
@ -143,22 +143,22 @@ public class Surface {
}
source = source.fixCCW();
List<Surface> surfaces = new ArrayList<>();
surfaces.add(source);
List<Plane> planes = new ArrayList<>();
planes.add(source);
Surface lid = source.shift(target).flip();
surfaces.add(lid);
Plane lid = source.shift(target).flip();
planes.add(lid);
for (int i = 0; i < source.shell.size(); i++) {
Surface face = new Surface(Arrays.asList(
Plane face = new Plane(Arrays.asList(
get(source.shell, i - 1),
get(lid.shell, i - 1),
get(lid.shell, i),
get(source.shell, i)
));
surfaces.add(face);
planes.add(face);
}
return surfaces;
return planes;
}
private static <T> T get(List<T> list, int i) {
@ -169,12 +169,12 @@ public class Surface {
return list.get(i);
}
public Surface shift(Vector target) {
public Plane shift(Vector target) {
List<Vector> shell = this.shell.stream().map(vector -> vector.plus(target)).collect(toList());
List<List<Vector>> holes = new ArrayList<>();
for (List<Vector> hole : this.holes) {
holes.add(hole.stream().map(vector -> vector.plus(target)).collect(toList()));
}
return new Surface(normal, shell, holes);
return new Plane(normal, shell, holes);
}
}

View file

@ -8,11 +8,11 @@ import java.util.List;
public class Sketch {
public final Surface owner;
public final Plane owner;
public final List<List<Vector>> polygons = new ArrayList<>();
public final Group drawLayer = new Group();
public Sketch(Surface owner) {
public Sketch(Plane owner) {
this.owner = owner;
}
}

View file

@ -1,18 +1,8 @@
package cad.fx;
import cad.math.Vector;
import eu.mihosoft.vrl.v3d.CSG;
import eu.mihosoft.vrl.v3d.MeshContainer;
import eu.mihosoft.vrl.v3d.Polygon;
import eu.mihosoft.vrl.v3d.Vector3d;
import eu.mihosoft.vrl.v3d.Vertex;
import eu.mihosoft.vrl.v3d.ext.org.poly2tri.PolygonUtil;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.TriangleMesh;
import org.poly2tri.Poly2Tri;
import org.poly2tri.geometry.polygon.PolygonPoint;
import org.poly2tri.triangulation.TriangulationPoint;
import org.poly2tri.triangulation.delaunay.DelaunayTriangle;
@ -42,16 +32,16 @@ public class Utils3D {
}
public static CSGMesh getMesh(List<Surface> surfaces) {
public static CSGMesh getMesh(List<Plane> planes) {
CSGMesh mesh = new CSGMesh();
int faceCounter = 0;
for (Surface surface : surfaces) {
for (Plane plane : planes) {
for (Vector[] triangle : surface.getTriangles()) {
for (Vector[] triangle : plane.getTriangles()) {
mesh.getPoints().addAll(
@ -92,7 +82,7 @@ public class Utils3D {
counter + 2, // third vertex
0 // texture (not covered)
);
mesh.polygons.put(faceCounter, surface);
mesh.polygons.put(faceCounter, plane);
++faceCounter;
} // end if #verts >= 3
@ -157,12 +147,12 @@ public class Utils3D {
return mesh;
}
public static List<Surface> createCube(double width) {
Surface square = createSquare(width);
return Surface.extrude(square, square.normal.scale(width));
public static List<Plane> createCube(double width) {
Plane square = createSquare(width);
return Plane.extrude(square, square.normal.scale(width));
}
public static Surface createSquare(double width) {
public static Plane createSquare(double width) {
width /= 2;
@ -183,6 +173,6 @@ public class Utils3D {
//
// polygon.addHole(hole);
return new Surface(shell);
return new Plane(shell);
}
}