--- /dev/null
+package org.simantics.g3d.vtk.common;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionChangedListener;\r
+import org.eclipse.jface.viewers.SelectionChangedEvent;\r
+import org.simantics.g3d.scenegraph.IG3DNode;\r
+import org.simantics.g3d.scenegraph.NodeHighlighter;\r
+import org.simantics.g3d.scenegraph.NodeHighlighter.HighlightEventType;\r
+import org.simantics.g3d.scenegraph.NodeHighlighter.HighlightObjectType;\r
+import org.simantics.g3d.scenegraph.base.INode;\r
+import org.simantics.g3d.tools.AdaptationUtils;\r
+import org.simantics.utils.threads.AWTThread;\r
+import org.simantics.utils.threads.ThreadUtils;\r
+\r
+import vtk.vtkActor;\r
+import vtk.vtkAlgorithm;\r
+import vtk.vtkAlgorithmOutput;\r
+import vtk.vtkFeatureEdges;\r
+import vtk.vtkMapper;\r
+import vtk.vtkPanel;\r
+import vtk.vtkProp;\r
+import vtk.vtkProperty;\r
+\r
+public class SelectionHighlighter implements ISelectionChangedListener{\r
+\r
+ \r
+ \r
+ vtkPanel panel;\r
+ VTKNodeMap nodeMap;\r
+ \r
+ List<IG3DNode> selectedNodes = new ArrayList<IG3DNode>();\r
+ List<vtkActor> selectedActors = new ArrayList<vtkActor>();\r
+ \r
+ HighlightObjectType type = HighlightObjectType.Node;\r
+ \r
+ public SelectionHighlighter(vtkPanel panel, VTKNodeMap nodeMap) {\r
+ this.panel = panel;\r
+ this.nodeMap = nodeMap;\r
+ }\r
+ \r
+ @Override\r
+ public void selectionChanged(SelectionChangedEvent event) {\r
+ final ISelection s = event.getSelection();\r
+ \r
+ if (Thread.currentThread().equals(AWTThread.getThreadAccess().getThread()))\r
+ highlight(s);\r
+ else {\r
+ ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ highlight(s);\r
+ //System.out.println(this.getClass().getName() + " highlight ");\r
+ panel.Render();\r
+ //panel.repaint();\r
+ }\r
+ });\r
+ }\r
+ \r
+ }\r
+ \r
+ protected void hilight(IG3DNode node, HighlightEventType type) {\r
+ if (node instanceof NodeHighlighter) {\r
+ ((NodeHighlighter)node).highlight(type);\r
+ return;\r
+ }\r
+ if (type == HighlightEventType.Selection) {\r
+ setSelectedColor(node); \r
+ } else if (type == HighlightEventType.ClearSelection) {\r
+ setDefaultColor(node);\r
+ }\r
+ }\r
+ \r
+ protected void hilight(vtkActor actor, HighlightEventType type) {\r
+ if (type == HighlightEventType.Selection) {\r
+ setColor(actor,false,new double[]{1,0,0});\r
+ setColor(actor,true,new double[]{1,0,1});\r
+ } else if (type == HighlightEventType.ClearSelection) {\r
+ setColor(actor,false,new double[]{1,1,0});\r
+ setColor(actor,true,new double[]{0,0,0});\r
+ }\r
+ }\r
+ \r
+ protected void highlight(ISelection s) {\r
+ highlight(s, HighlightEventType.Selection, HighlightEventType.ClearSelection);\r
+ }\r
+ \r
+ protected void highlight(ISelection s, HighlightEventType apply, HighlightEventType clear) {\r
+ \r
+ boolean changed = false;\r
+ if (type == HighlightObjectType.Node) {\r
+ Collection<IG3DNode> currentSelectedNodes = AdaptationUtils.adaptToCollection(s,IG3DNode.class);//getSelectedNodes(currentSelectedActors);\r
+ if (currentSelectedNodes.size() == 0) {\r
+ Collection<vtkProp> currentSelectedActors = AdaptationUtils.adaptToCollection(s, vtkProp.class);\r
+ currentSelectedNodes = getSelectedNodes(currentSelectedActors);\r
+ }\r
+ for (IG3DNode node : selectedNodes) {\r
+ if (!currentSelectedNodes.contains(node)) {\r
+ hilight(node, clear);\r
+ changed = true;\r
+ }\r
+ }\r
+ for (IG3DNode node : currentSelectedNodes) {\r
+ if (!selectedNodes.contains(node)) {\r
+ hilight(node, apply);\r
+ changed = true;\r
+ }\r
+ }\r
+ selectedNodes.clear();\r
+ selectedNodes.addAll(currentSelectedNodes);\r
+ //selectedNodes = currentSelectedNodes;\r
+ \r
+ } else {\r
+ \r
+ Collection<vtkActor> currentSelectedActors = AdaptationUtils.adaptToCollection(s, vtkActor.class);\r
+ \r
+ for (vtkActor act : selectedActors) {\r
+ if (!currentSelectedActors.contains(act)) {\r
+ hilight(act,clear);\r
+ changed = true;\r
+ }\r
+ }\r
+ for (vtkActor act : currentSelectedActors) {\r
+ if (!selectedActors.contains(act)) {\r
+ hilight(act,apply);\r
+ changed = true;\r
+ }\r
+ }\r
+ selectedActors.clear();\r
+ selectedActors.addAll(currentSelectedActors);\r
+ }\r
+ if (changed) {\r
+ panel.repaint();\r
+ }\r
+ }\r
+ \r
+ protected List<IG3DNode> getSelectedNodes(Collection<vtkProp> selectedActors) {\r
+ List<IG3DNode> currentSelectedNodes = new ArrayList<IG3DNode>();\r
+ \r
+ for (vtkProp a : selectedActors) {\r
+ INode node = nodeMap.getNode((vtkProp)a);\r
+ if (node == null || !(node instanceof IG3DNode))\r
+ continue;\r
+ if (!currentSelectedNodes.contains(node))\r
+ currentSelectedNodes.add((IG3DNode)node);\r
+ }\r
+ return currentSelectedNodes;\r
+ }\r
+ \r
+ protected void setDefaultColor(IG3DNode node) {\r
+ double color[] = new double[]{1,1,0};\r
+ setColor(node, false, color);\r
+ }\r
+ \r
+ protected void setSelectedColor(IG3DNode node) {\r
+ double color[] = new double[]{1,0,0};\r
+ setColor(node, false, color);\r
+ }\r
+ \r
+ \r
+ protected void setColor(IG3DNode node, boolean edge, double color[]) {\r
+ for (vtkProp prop : nodeMap.getRenderObjects(node)) {\r
+ if (prop instanceof vtkActor) {\r
+ vtkActor act = (vtkActor)prop;\r
+ setColor(act, edge, color);\r
+ }\r
+ }\r
+ }\r
+ \r
+ protected void setColor(vtkActor act, boolean edge, double color[]) {\r
+ \r
+ vtkMapper mapper = act.GetMapper();\r
+ vtkAlgorithmOutput out = mapper.GetInputConnection(0, 0);\r
+ vtkAlgorithm producer = out.GetProducer();\r
+ boolean isEdge = (producer instanceof vtkFeatureEdges);\r
+ producer.Delete();\r
+ if (isEdge == edge) {\r
+ vtkProperty property = act.GetProperty();\r
+ property.SetColor(color);\r
+ property.Delete();\r
+ }\r
+ out.Delete();\r
+ mapper.Delete();\r
+ }\r
+}\r