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.Objects; 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.common.VtkView; 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.vtkProp3D; import vtk.vtkProperty; public class GeometryComponent { private TopoDS_Shape solidModel; private vtkSolidObject solidObject; private Mesh mesh; private vtkMeshObject meshObject; private Map currentParameters; private Map calculatedParameters; private boolean parametersUpdated = true; private GeometryProvider geometryProvider; public GeometryComponent() { currentParameters = new HashMap<>(); calculatedParameters = new HashMap<>(); } public void visualize(VtkView 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 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 getParameterMap() { return Collections.unmodifiableMap(currentParameters); } public Map getCalculatedParameters() { return calculatedParameters; } public Map getTotalParameters() { Map params = new HashMap<>(); params.putAll(currentParameters); params.putAll(calculatedParameters); return params; } public void setParametersUpdated(boolean parametersUpdated) { this.parametersUpdated = parametersUpdated; } public Set setParameterMap(Map parameters) { Set ids = new HashSet(); for (String id : parameters.keySet()) { Object currentValue = currentParameters.get(id); Object newValue = parameters.get(id); if (Objects.equals(currentValue, newValue)) continue; if (newValue == null) { 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 getActors() { List list = new ArrayList(); 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.clearActorsVTK(); solidObject = null; } if (solidModel != null) { solidModel.delete(); solidModel = null; } if (meshObject != null) { meshObject.clearActorsVTK(); 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()) { prop.SetVisibility(hover ? 1 : 0); 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); // } } } }