X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.g3d.vtk%2Fsrc%2Forg%2Fsimantics%2Fg3d%2Fvtk%2Fcommon%2FSelectionHighlighter.java;fp=org.simantics.g3d.vtk%2Fsrc%2Forg%2Fsimantics%2Fg3d%2Fvtk%2Fcommon%2FSelectionHighlighter.java;h=0cbcac2d7cc96664d7bbf41cbe5a903fbbf549e5;hb=87b3241ec277ba3d8e414b26186a032c9cdcaeed;hp=0000000000000000000000000000000000000000;hpb=1f0bcd66274375f2278d2e6c486cb28257a5f7b2;p=simantics%2F3d.git diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/SelectionHighlighter.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/SelectionHighlighter.java new file mode 100644 index 00000000..0cbcac2d --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/SelectionHighlighter.java @@ -0,0 +1,188 @@ +package org.simantics.g3d.vtk.common; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.simantics.g3d.scenegraph.IG3DNode; +import org.simantics.g3d.scenegraph.NodeHighlighter; +import org.simantics.g3d.scenegraph.NodeHighlighter.HighlightEventType; +import org.simantics.g3d.scenegraph.NodeHighlighter.HighlightObjectType; +import org.simantics.g3d.scenegraph.base.INode; +import org.simantics.g3d.tools.AdaptationUtils; +import org.simantics.utils.threads.AWTThread; +import org.simantics.utils.threads.ThreadUtils; + +import vtk.vtkActor; +import vtk.vtkAlgorithm; +import vtk.vtkAlgorithmOutput; +import vtk.vtkFeatureEdges; +import vtk.vtkMapper; +import vtk.vtkPanel; +import vtk.vtkProp; +import vtk.vtkProperty; + +public class SelectionHighlighter implements ISelectionChangedListener{ + + + + vtkPanel panel; + VTKNodeMap nodeMap; + + List selectedNodes = new ArrayList(); + List selectedActors = new ArrayList(); + + HighlightObjectType type = HighlightObjectType.Node; + + public SelectionHighlighter(vtkPanel panel, VTKNodeMap nodeMap) { + this.panel = panel; + this.nodeMap = nodeMap; + } + + @Override + public void selectionChanged(SelectionChangedEvent event) { + final ISelection s = event.getSelection(); + + if (Thread.currentThread().equals(AWTThread.getThreadAccess().getThread())) + highlight(s); + else { + ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() { + @Override + public void run() { + highlight(s); + //System.out.println(this.getClass().getName() + " highlight "); + panel.Render(); + //panel.repaint(); + } + }); + } + + } + + protected void hilight(IG3DNode node, HighlightEventType type) { + if (node instanceof NodeHighlighter) { + ((NodeHighlighter)node).highlight(type); + return; + } + if (type == HighlightEventType.Selection) { + setSelectedColor(node); + } else if (type == HighlightEventType.ClearSelection) { + setDefaultColor(node); + } + } + + protected void hilight(vtkActor actor, HighlightEventType type) { + if (type == HighlightEventType.Selection) { + setColor(actor,false,new double[]{1,0,0}); + setColor(actor,true,new double[]{1,0,1}); + } else if (type == HighlightEventType.ClearSelection) { + setColor(actor,false,new double[]{1,1,0}); + setColor(actor,true,new double[]{0,0,0}); + } + } + + protected void highlight(ISelection s) { + highlight(s, HighlightEventType.Selection, HighlightEventType.ClearSelection); + } + + protected void highlight(ISelection s, HighlightEventType apply, HighlightEventType clear) { + + boolean changed = false; + if (type == HighlightObjectType.Node) { + Collection currentSelectedNodes = AdaptationUtils.adaptToCollection(s,IG3DNode.class);//getSelectedNodes(currentSelectedActors); + if (currentSelectedNodes.size() == 0) { + Collection currentSelectedActors = AdaptationUtils.adaptToCollection(s, vtkProp.class); + currentSelectedNodes = getSelectedNodes(currentSelectedActors); + } + for (IG3DNode node : selectedNodes) { + if (!currentSelectedNodes.contains(node)) { + hilight(node, clear); + changed = true; + } + } + for (IG3DNode node : currentSelectedNodes) { + if (!selectedNodes.contains(node)) { + hilight(node, apply); + changed = true; + } + } + selectedNodes.clear(); + selectedNodes.addAll(currentSelectedNodes); + //selectedNodes = currentSelectedNodes; + + } else { + + Collection currentSelectedActors = AdaptationUtils.adaptToCollection(s, vtkActor.class); + + for (vtkActor act : selectedActors) { + if (!currentSelectedActors.contains(act)) { + hilight(act,clear); + changed = true; + } + } + for (vtkActor act : currentSelectedActors) { + if (!selectedActors.contains(act)) { + hilight(act,apply); + changed = true; + } + } + selectedActors.clear(); + selectedActors.addAll(currentSelectedActors); + } + if (changed) { + panel.repaint(); + } + } + + protected List getSelectedNodes(Collection selectedActors) { + List currentSelectedNodes = new ArrayList(); + + for (vtkProp a : selectedActors) { + INode node = nodeMap.getNode((vtkProp)a); + if (node == null || !(node instanceof IG3DNode)) + continue; + if (!currentSelectedNodes.contains(node)) + currentSelectedNodes.add((IG3DNode)node); + } + return currentSelectedNodes; + } + + protected void setDefaultColor(IG3DNode node) { + double color[] = new double[]{1,1,0}; + setColor(node, false, color); + } + + protected void setSelectedColor(IG3DNode node) { + double color[] = new double[]{1,0,0}; + setColor(node, false, color); + } + + + protected void setColor(IG3DNode node, boolean edge, double color[]) { + for (vtkProp prop : nodeMap.getRenderObjects(node)) { + if (prop instanceof vtkActor) { + vtkActor act = (vtkActor)prop; + setColor(act, edge, color); + } + } + } + + protected void setColor(vtkActor act, boolean edge, double color[]) { + + vtkMapper mapper = act.GetMapper(); + vtkAlgorithmOutput out = mapper.GetInputConnection(0, 0); + vtkAlgorithm producer = out.GetProducer(); + boolean isEdge = (producer instanceof vtkFeatureEdges); + producer.Delete(); + if (isEdge == edge) { + vtkProperty property = act.GetProperty(); + property.SetColor(color); + property.Delete(); + } + out.Delete(); + mapper.Delete(); + } +}