surface selection

This commit is contained in:
Val Erastov 2014-08-11 21:53:54 -07:00
parent 29202bfa69
commit 435dd9f02c
4 changed files with 197 additions and 49 deletions

View file

@ -3,10 +3,12 @@ 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 {
@ -17,6 +19,12 @@ public class CSGNode extends MeshView {
super(mesh);
this.context = context;
setMaterial(Utils3D.DEFAULT_MATERIAL);
setOnMouseEntered(e -> {
context.highlightManger.selectExclusively(this);
});
setOnMouseExited(e -> {
context.highlightManger.getSelection().clear();
});
setOnMouseClicked(e -> {
context.clickOnNode(this, e);
});
@ -25,6 +33,10 @@ public class CSGNode extends MeshView {
private void highlight(Polygon poly) {
System.out.println(poly);
}
private void select(Polygon poly) {
System.out.println(poly);
}
public final Map<Surface, Sketch> sketches = new HashMap<>();

View file

@ -1,9 +1,13 @@
package cad.fx;
import cad.math.Vector;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.PickResult;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.MeshView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -11,8 +15,58 @@ public class CadContext {
public Sketcher sketcher;
public Selection selection;
public final SelectionManager selectionManger = new SelectionManager();
public final SelectionManager highlightManger = new SelectionManager();
class MaterialChangeListener implements SelectionManager.Listener {
public final PhongMaterial onSelect;
public final PhongMaterial onDeselect;
private SelectionManager dependency;
MaterialChangeListener(PhongMaterial onSelect, PhongMaterial onDeselect, SelectionManager dependency) {
this.onSelect = onSelect;
this.onDeselect = onDeselect;
this.dependency = dependency;
}
public void added(List<Node> nodes) {
if (dependency != null) {
nodes = filter(nodes, dependency);
}
setMaterial(nodes, onSelect);
}
public void removed(List<Node> nodes) {
if (dependency != null) {
nodes = filter(nodes, dependency);
}
setMaterial(nodes, onDeselect);
}
private List<Node> filter(List<Node> nodes, SelectionManager dependency) {
nodes = new ArrayList<>(nodes);
nodes.removeAll(selectionManger.getSelection());
return nodes;
}
}
{
selectionManger.addListener(new MaterialChangeListener(Utils3D.SELECTED_MATERIAL, Utils3D.DEFAULT_MATERIAL, null));
highlightManger.addListener(new MaterialChangeListener(Utils3D.HIGHLIGHTED_MATERIAL, Utils3D.DEFAULT_MATERIAL, selectionManger));
}
private void setMaterial(List<Node> nodes, PhongMaterial material) {
for (Node node : nodes) {
if (node instanceof MeshView) {
((MeshView) node).setMaterial(material);
}
}
}
public void clickOnNode(CSGNode csgNode, MouseEvent e) {
selectionManger.selectExclusively(csgNode);
PickResult pickResult = e.getPickResult();
int face = pickResult.getIntersectedFace();
CSGMesh csgMesh = (CSGMesh) csgNode.getMesh();
@ -64,8 +118,10 @@ public class CadContext {
Surface surface = new Surface(sketch.owner.normal, polygon, Collections.emptyList());
List<Surface> extruded = Surface.extrude(surface, dir);
sketch.drawLayer.getChildren().addAll(new CSGNode(Utils3D.getMesh(extruded), this)); // fixme
for (Surface s : extruded) {
sketch.drawLayer.getChildren().addAll(new CSGNode( Utils3D.getMesh(Collections.singletonList(s)), this)); // fixme
}
// CSG pad = Extrude.points(dir, polygon);
}
}

View file

@ -0,0 +1,66 @@
package cad.fx;
import com.sun.javafx.collections.TrackableObservableList;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import java.util.ArrayList;
import java.util.List;
public class SelectionManager {
private final List<Listener> listeners = new ArrayList<>();
public void addListener(Listener listener) {
listeners.add(listener);
}
private final ObservableList<Node> selection = new TrackableObservableList<Node>() {
protected void onChanged(ListChangeListener.Change<Node> c) {
while (c.next()) {
if (c.wasAdded()) {
List<Node> added = c.getAddedSubList();
added.forEach((n) -> {
ObservableList<String> styleClass = n.getStyleClass();
if (!styleClass.contains("selected")) {
styleClass.add("selected");
}
});
fireSelected(added);
} else if (c.wasRemoved()) {
List<Node> removed = c.getRemoved();
removed.forEach((n) -> n.getStyleClass().removeAll("selected"));
fireRemoved(removed);
}
}
}
};
private void fireRemoved(List<Node> removed) {
for (Listener l : listeners) {
l.removed(removed);
}
}
private void fireSelected(List<Node> added) {
for (Listener l : listeners) {
l.added(added);
}
}
public ObservableList<Node> getSelection() {
return selection;
}
public interface Listener {
void added(List<Node> nodes);
void removed(List<Node> nodes);
}
public void selectExclusively(Node node) {
selection.clear();
selection.add(node);
}
}

View file

@ -22,17 +22,26 @@ import java.util.List;
public class Utils3D {
public static final PhongMaterial DEFAULT_MATERIAL = new PhongMaterial();
public static final PhongMaterial SELECTED_MATERIAL = new PhongMaterial();
public static final PhongMaterial HIGHLIGHTED_MATERIAL = new PhongMaterial();
static {
// DEFAULT_MATERIAL.setDiffuseColor(Color.LIGHTBLUE);
// DEFAULT_MATERIAL.setSpecularColor(Color.WHITE);
DEFAULT_MATERIAL.setDiffuseColor(Color.LIGHTSTEELBLUE);
DEFAULT_MATERIAL.setSpecularColor(Color.LIGHTBLUE);
// DEFAULT_MATERIAL.setSpecularColor(Color.LIGHTBLUE);
SELECTED_MATERIAL.setDiffuseColor(Color.LIGHTSEAGREEN);
// SELECTED_MATERIAL.setSpecularColor(Color.SEAGREEN); //disable reflection
HIGHLIGHTED_MATERIAL.setDiffuseColor(Color.LIGHTGOLDENRODYELLOW);
// HIGHLIGHTED_MATERIAL.setSpecularColor(Color.GOLD);
// DEFAULT_MATERIAL.setDiffuseMap(new Image(Utils3D.class.getResource("tex.png").toExternalForm()));
}
public static CSGMesh getMesh(List<Surface> surfaces) {
CSGMesh mesh = new CSGMesh();
@ -45,46 +54,46 @@ public class Utils3D {
for (Vector[] triangle : surface.getTriangles()) {
mesh.getPoints().addAll(
(float) triangle[0].x,
(float) triangle[0].y,
(float) triangle[0].z
);
mesh.getPoints().addAll(
(float) triangle[0].x,
(float) triangle[0].y,
(float) triangle[0].z
);
mesh.getTexCoords().addAll(0); // texture (not covered)
mesh.getTexCoords().addAll(0);
mesh.getTexCoords().addAll(0); // texture (not covered)
mesh.getTexCoords().addAll(0);
mesh.getPoints().addAll(
(float) triangle[1].x,
(float) triangle[1].y,
(float) triangle[1].z
(float) triangle[1].x,
(float) triangle[1].y,
(float) triangle[1].z
);
mesh.getTexCoords().addAll(0); // texture (not covered)
mesh.getTexCoords().addAll(0);
mesh.getTexCoords().addAll(0); // texture (not covered)
mesh.getTexCoords().addAll(0);
mesh.getPoints().addAll(
(float) triangle[2].x,
(float) triangle[2].y,
(float) triangle[2].z
(float) triangle[2].x,
(float) triangle[2].y,
(float) triangle[2].z
);
mesh.getTexCoords().addAll(0); // texture (not covered)
mesh.getTexCoords().addAll(0);
mesh.getTexCoords().addAll(0); // texture (not covered)
mesh.getTexCoords().addAll(0);
int counter = faceCounter * 3;
mesh.getFaces().addAll(
counter, // first vertex
0, // texture (not covered)
counter + 1, // second vertex
0, // texture (not covered)
counter + 2, // third vertex
0 // texture (not covered)
);
mesh.polygons.put(faceCounter, surface);
++faceCounter;
int counter = faceCounter * 3;
mesh.getFaces().addAll(
counter, // first vertex
0, // texture (not covered)
counter + 1, // second vertex
0, // texture (not covered)
counter + 2, // third vertex
0 // texture (not covered)
);
mesh.polygons.put(faceCounter, surface);
++faceCounter;
} // end if #verts >= 3
@ -105,27 +114,27 @@ public class Utils3D {
TriangulationPoint firstVertex = p.points[0];
mesh.getPoints().addAll(
p.points[2].getXf(),
p.points[2].getYf(),
p.points[2].getZf()
p.points[2].getXf(),
p.points[2].getYf(),
p.points[2].getZf()
);
mesh.getTexCoords().addAll(0); // texture (not covered)
mesh.getTexCoords().addAll(0);
mesh.getPoints().addAll(
p.points[1].getXf(),
p.points[1].getYf(),
p.points[1].getZf()
p.points[1].getXf(),
p.points[1].getYf(),
p.points[1].getZf()
);
mesh.getTexCoords().addAll(0); // texture (not covered)
mesh.getTexCoords().addAll(0);
mesh.getPoints().addAll(
p.points[0].getXf(),
p.points[0].getYf(),
p.points[0].getZf()
p.points[0].getXf(),
p.points[0].getYf(),
p.points[0].getZf()
);
mesh.getTexCoords().addAll(0); // texture (not covered)
@ -133,12 +142,12 @@ public class Utils3D {
int counter = faceCounter * 3;
mesh.getFaces().addAll(
counter, // first vertex
0, // texture (not covered)
counter + 1, // second vertex
0, // texture (not covered)
counter + 2, // third vertex
0 // texture (not covered)
counter, // first vertex
0, // texture (not covered)
counter + 1, // second vertex
0, // texture (not covered)
counter + 2, // third vertex
0 // texture (not covered)
);
// mesh.polygons.put(faceCounter, p);
++faceCounter;
@ -148,15 +157,20 @@ 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 Surface createSquare(double width) {
width /= 2;
List<Vector> shell = Arrays.asList(
new Vector(-width, -width),
new Vector(width, -width),
new Vector(width, width, 0),
new Vector(-width, width, 0)
new Vector(-width, -width),
new Vector(width, -width),
new Vector(width, width, 0),
new Vector(-width, width, 0)
);
// width /= 3;