--- /dev/null
+package org.simantics.plant3d.scenegraph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.jcae.opencascade.jni.TopoDS_Shape;
+import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.scenegraph.GeometryProvider;
+import org.simantics.g3d.scenegraph.MeshProvider;
+import org.simantics.g3d.scenegraph.NodeHighlighter.HighlightEventType;
+import org.simantics.g3d.scenegraph.ParametricGeometryProvider;
+import org.simantics.g3d.shape.Mesh;
+import org.simantics.g3d.vtk.shape.MeshActor;
+import org.simantics.g3d.vtk.shape.vtkMeshObject;
+import org.simantics.opencascade.OccTriangulator;
+import org.simantics.opencascade.SolidModelProvider;
+import org.simantics.opencascade.vtk.vtkSolidObject;
+
+import vtk.vtkActor;
+import vtk.vtkPanel;
+import vtk.vtkProp3D;
+import vtk.vtkProperty;
+
+public class GeometryComponent {
+
+ private TopoDS_Shape solidModel;
+ private vtkSolidObject solidObject;
+ private Mesh mesh;
+ private vtkMeshObject meshObject;
+
+ private Map<String,Object> currentParameters;
+ private Map<String,Object> calculatedParameters;
+
+ private boolean parametersUpdated = true;
+
+ private GeometryProvider geometryProvider;
+
+ public GeometryComponent() {
+ currentParameters = new HashMap<String, Object>();
+ calculatedParameters = new HashMap<String, Object>();
+ }
+
+ public void visualize(vtkPanel panel) {
+ if (geometryProvider != null) {
+ updateParameters();
+
+ if (geometryProvider instanceof SolidModelProvider) {
+ SolidModelProvider solidModelProvider = (SolidModelProvider)geometryProvider;
+ if (solidModel == null || parametersUpdated) {
+ createGeometry(solidModelProvider);
+ }
+ if ((solidObject == null || parametersUpdated) && solidModel != null) {
+ solidObject = new vtkSolidObject(panel, solidModel);
+ }
+ if (solidObject != null) {
+ solidObject.visualizeSolid(true,true, false,false);
+ updateVisuals(true, true);
+ }
+ } else if (geometryProvider instanceof MeshProvider) {
+ MeshProvider provider = (MeshProvider)geometryProvider;
+ if (mesh == null || parametersUpdated) {
+ mesh = provider.getMesh();
+ }
+ if ((meshObject== null || parametersUpdated) && mesh != null) {
+ meshObject = new vtkMeshObject(panel, mesh);
+
+ }
+ if (meshObject != null) {
+ meshObject.visualizeMesh();
+ updateVisuals(true, true);
+ }
+ }
+ }
+
+ parametersUpdated = false;
+
+ }
+
+ public void updateParameters() {
+ //if (parametersUpdated && geometryProvider instanceof ParametricGeometryProvider) {
+ if (geometryProvider instanceof ParametricGeometryProvider) {
+ ((ParametricGeometryProvider)geometryProvider).setProperties(currentParameters);
+ ((ParametricGeometryProvider)geometryProvider).updateCalculatedProperties(calculatedParameters);
+ }
+ }
+
+ private void createGeometry(SolidModelProvider solidModelProvider) {
+ Collection<TopoDS_Shape> shapes;
+ try {
+ shapes = solidModelProvider.getModel();
+ if (shapes.size() == 1) {
+ solidModel = shapes.iterator().next();
+ } else {
+ solidModel = OccTriangulator.makeCompound(shapes.toArray(new TopoDS_Shape[shapes.size()]));
+ for (TopoDS_Shape shape : shapes) {
+ shape.delete();
+ }
+ }
+// shapes.clear();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public Map<String, Object> getParameterMap() {
+ return Collections.unmodifiableMap(currentParameters);
+ }
+
+ public Map<String, Object> getCalculatedParameters() {
+ return calculatedParameters;
+ }
+
+ public void setParametersUpdated(boolean parametersUpdated) {
+ this.parametersUpdated = parametersUpdated;
+ }
+
+ public Set<String> setParameterMap(Map<String, Object> parameters) {
+ Set<String> ids = new HashSet<String>();
+ for (String id : parameters.keySet()) {
+ Object currentValue = currentParameters.get(id);
+ Object newValue = parameters.get(id);
+ if (currentValue == newValue)
+ continue;
+ if (currentValue instanceof Double) {
+ if (Math.abs((Double)currentValue-(Double)newValue) < MathTools.NEAR_ZERO)
+ continue;
+ }
+ currentParameters.put(id, newValue);
+ parametersUpdated = true;
+ ids.add(id);
+ }
+ return ids;
+ }
+
+ public GeometryProvider getGeometry() {
+ return geometryProvider;
+ }
+
+ public void setGeometry(final GeometryProvider provider) {
+ if (provider != null && provider.equals(geometryProvider))
+ return;
+
+ if (geometryProvider != null) {
+ deleteData();
+ }
+ geometryProvider = provider;
+ }
+
+ private void deleteData() {
+ geometryProvider = null;
+ if (solidObject != null) {
+ solidObject.clearActors();
+ solidObject = null;
+ }
+ if (solidModel != null) {
+ solidModel.delete();
+ solidModel = null;
+ }
+ if (meshObject != null) {
+ meshObject.clearActors();
+ meshObject = null;
+ }
+ if (mesh != null)
+ mesh = null;
+
+ }
+
+ public Collection<vtkProp3D> getActors() {
+ List<vtkProp3D> list = new ArrayList<vtkProp3D>();
+ if (solidObject != null)
+ list.addAll(solidObject.getActors());
+ if (meshObject != null && meshObject.getActor() != null)
+ list.add(meshObject.getActor());
+ return list;
+ }
+
+ public void stopVisualize() {
+ if (solidObject != null) {
+ solidObject.clearActorsAWT();
+ solidObject = null;
+ }
+ if (solidModel != null) {
+ solidModel.delete();
+ solidModel = null;
+ }
+ if (meshObject != null) {
+ meshObject.clearActorsAWT();
+ meshObject = null;
+ }
+ if (mesh != null)
+ mesh = null;
+
+ }
+
+ private boolean selected = false;
+ private boolean hover = false;
+
+ public void highlight(HighlightEventType type) {
+ if (type == HighlightEventType.Selection || type == HighlightEventType.ClearSelection) {
+ selected = type == HighlightEventType.Selection;
+// hingeA.visualizeSolid(selected,true,false);
+// hingeB.visualizeSolid(selected,true,false);
+ updateVisuals(true, false);
+// update(null);
+ } else {
+ hover = type == HighlightEventType.Hover;
+ updateVisuals(false, true);
+ }
+
+
+ }
+
+ protected double[] getSelectedColor() {
+ return new double[]{1,0,0};
+ }
+
+ protected double[] getColor() {
+ return new double[]{1,1,0};
+ }
+
+ public void updateVisuals(boolean s, boolean h) {
+ if (solidObject != null) {
+ if (s) {
+ double color[];
+ if (selected) {
+ color = getSelectedColor();
+
+ } else {
+ color = getColor();
+
+ }
+ for (vtkProp3D prop : solidObject.getSolid()) {
+ vtkProperty property = ((vtkActor)prop).GetProperty();
+ property.SetColor(color);
+ property.Delete();
+ }
+ }
+ if (h) {
+ double color[] = new double[]{0,0,0};
+ if (hover)
+ color = new double[]{1,0,1};
+ for (vtkProp3D prop : solidObject.getEdges()) {
+ vtkProperty property = ((vtkActor)prop).GetProperty();
+ property.SetColor(color);
+ property.Delete();
+ }
+
+ }
+ } else if (meshObject != null) {
+ if (s) {
+ double color[];
+ if (selected) {
+ color = getSelectedColor();
+
+ } else {
+ color = getColor();
+
+ }
+ vtkProp3D prop = meshObject.getActor();
+ if (prop != null) {
+ vtkProperty property = ((vtkActor)prop).GetProperty();
+ property.SetColor(color);
+ property.Delete();
+ }
+
+ }
+ if (h) {
+ double color[] = new double[]{0,0,0};
+ MeshActor actor = meshObject.getActor();
+ if (actor != null) {
+ vtkProperty property = actor.GetProperty();
+ if (hover) {
+ color = new double[]{1,0,1};
+ property.SetEdgeVisibility(1);
+ property.SetEdgeColor(color);
+ } else {
+ property.SetEdgeVisibility(0);
+ property.SetEdgeColor(color);
+ }
+ property.Delete();
+ }
+ }
+ } else {
+// if (s) {
+// axes.addToRenderer();
+// axes.setAxesVisibility(selected);
+// }
+ }
+ }
+}