package org.simantics.plant3d.scenegraph; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jcae.opencascade.jni.TopoDS_Shape; import org.simantics.g3d.math.MathTools; import org.simantics.g3d.scenegraph.NodeHighlighter; import org.simantics.g3d.vtk.utils.vtkUtil; import org.simantics.objmap.graph.annotations.RelatedGetObj; import org.simantics.objmap.graph.annotations.RelatedSetObj; import org.simantics.opencascade.OccTriangulator; import org.simantics.opencascade.ParametricSolidModelProvider; import org.simantics.opencascade.SolidModelProvider; import org.simantics.opencascade.vtk.vtkSolidObject; import org.simantics.plant3d.ontology.Plant3D; import vtk.vtkActor; import vtk.vtkPanel; import vtk.vtkProp3D; import vtk.vtkProperty; import vtk.vtkRenderer; public class P3DParentGeometryNode extends P3DParentNode implements ParameterizedNode, NodeHighlighter{ private TopoDS_Shape solidModel; private vtkSolidObject solidObject; private Map currentParameters; private Map calculatedParameters; private boolean parametersUpdated = true; public P3DParentGeometryNode() { currentParameters = new HashMap(); calculatedParameters = new HashMap(); } @Override public void visualize(vtkPanel ren) { if (solidModelProvider != null) { updateParameters(); if (solidModel == null || parametersUpdated) { createGeometry(); } } if ((solidObject == null || parametersUpdated) && solidModel != null) { solidObject = new vtkSolidObject(ren, solidModel); } if (solidObject != null) { solidObject.visualizeSolid(true,true, false,false); updateVisuals(true, true); } parametersUpdated = false; } public void updateParameters() { if (solidModelProvider instanceof ParametricSolidModelProvider) { ((ParametricSolidModelProvider)solidModelProvider).setProperties(currentParameters); ((ParametricSolidModelProvider)solidModelProvider).updateCalculatedProperties(calculatedParameters); } } private void createGeometry() { 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 void setParameterMap(Map parameters) { 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; firePropertyChanged(id); } } private SolidModelProvider solidModelProvider; @RelatedGetObj(Plant3D.URIs.hasGeometry) public SolidModelProvider getGeometry() { return solidModelProvider; } @RelatedSetObj(Plant3D.URIs.hasGeometry) public void setGeometry(final SolidModelProvider provider) { if (provider != null && provider.equals(solidModelProvider)) return; if (solidModelProvider != null) { deleteData(); } solidModelProvider = provider; firePropertyChanged(Plant3D.URIs.hasGeometry); } private void deleteData() { solidModelProvider = null; if (solidObject != null) { solidObject.clearActors(); solidObject = null; } if (solidModel != null) { solidModel.delete(); solidModel = null; } } @Override public Collection getActors() { List list = new ArrayList(); if (solidObject != null) list.addAll(solidObject.getActors()); return list; } @Override public void stopVisualize() { if (solidObject != null) { solidObject.clearActorsAWT(); solidObject = null; } if (solidModel != null) { solidModel.delete(); solidModel = null; } } private boolean selected = false; private boolean hover = false; @Override 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}; } private 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 (s) { // axes.addToRenderer(); // axes.setAxesVisibility(selected); // } } } public void update(vtkRenderer ren) { vtkUtil.updateTransform(getActors(), getWorldPosition(), getWorldOrientation()); } public TopoDS_Shape getSolidModel() { return solidModel; } }