--- /dev/null
+package org.simantics.plant3d.gizmo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import javax.vecmath.Point2d;
+import javax.vecmath.Vector3d;
+
+import org.simantics.g3d.scenegraph.RenderListener;
+import org.simantics.g3d.tools.PluginTools;
+import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.gizmo.vtkGizmo;
+import org.simantics.g3d.vtk.utils.vtkUtil;
+import org.simantics.plant3d.Activator;
+import org.simantics.plant3d.scenegraph.InlineComponent;
+import org.simantics.plant3d.scenegraph.PipelineComponent;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
+
+import vtk.vtkCellArray;
+import vtk.vtkFloatArray;
+import vtk.vtkPNGReader;
+import vtk.vtkPoints;
+import vtk.vtkPolyData;
+import vtk.vtkPolyDataMapper2D;
+import vtk.vtkPolygon;
+import vtk.vtkProp;
+import vtk.vtkRenderer;
+import vtk.vtkTexture;
+import vtk.vtkTexturedActor2D;
+
+public class TerminalSelectionGizmo extends vtkGizmo {
+
+
+
+ vtkTexturedActor2D prevProp;
+ vtkTexturedActor2D nextProp;
+ vtkTexturedActor2D middleProp;
+
+ boolean showPrev = false;
+ boolean showNext = false;
+ boolean showMiddle = false;
+
+ Vector3d middle = new Vector3d();
+ Vector3d prev = new Vector3d();
+ Vector3d next = new Vector3d();
+
+ InteractiveVtkPanel panel;
+
+ private RenderListener listener;
+ public TerminalSelectionGizmo(InteractiveVtkPanel panel) {
+ this.panel = panel;
+ this.listener = new RenderListener() {
+
+ @Override
+ public void preRender() {
+
+ if (showMiddle) {
+ Point2d p = vtkUtil.getScreenCoordinates(getRenderer(), middle);
+ middleProp.SetDisplayPosition((int)p.x, (int)p.y);
+ }
+ if (showPrev) {
+ Point2d p = vtkUtil.getScreenCoordinates(getRenderer(), prev);
+ prevProp.SetDisplayPosition((int)p.x, (int)p.y);
+ }
+ if (showNext) {
+ Point2d p = vtkUtil.getScreenCoordinates(getRenderer(), next);
+ nextProp.SetDisplayPosition((int)p.x, (int)p.y);
+ }
+ }
+
+ @Override
+ public void postRender() {
+
+
+ }
+ };
+ }
+
+ @Override
+ public void attach(Object renderingPart) {
+ if (nextProp == null) {
+ loadData();
+
+ }
+ panel.addListener(listener);
+
+ super.attach(renderingPart);
+
+ }
+
+ @Override
+ public Collection<vtkProp> getGizmo() {
+ List<vtkProp> list = new ArrayList<vtkProp>();
+ if (showPrev) {
+ list.add(prevProp);
+ }
+ if (showNext) {
+ list.add(nextProp);
+
+ }
+ if (showMiddle) {
+ list.add(middleProp);
+ }
+ return list;
+ }
+
+ protected void attachActors() {
+ vtkRenderer ren = getRenderer();
+ if (showPrev) {
+ ren.AddActor(prevProp);
+ }
+ if (showNext) {
+ ren.AddActor(nextProp);
+ }
+ if (showMiddle) {
+ ren.AddActor(middleProp);
+ }
+
+ }
+
+ @Override
+ protected void deattachActors() {
+ panel.removeListener(listener);
+ vtkRenderer ren = getRenderer();
+ ren.RemoveActor(prevProp);
+ ren.RemoveActor(nextProp);
+ ren.RemoveActor(middleProp);
+ }
+
+ public void setComponent(PipelineComponent component, Set<PositionType> allowed) {
+// showPrev = component.getPrevious() == null;
+// showNext = component.getNext() == null;
+// showMiddle = (component instanceof InlineComponent) && !component.getControlPoint().isFixed();
+ showPrev = allowed.contains(PositionType.PREVIOUS);
+ showNext = allowed.contains(PositionType.NEXT);
+ showMiddle = allowed.contains(PositionType.SPLIT);
+
+ middle = component.getControlPoint().getWorldPosition();
+ component.getControlPoint().getControlPointEnds(prev, next);
+
+ }
+
+ private void loadData() {
+ String middleTexFile = PluginTools.getAbsolutePath(Activator.getDefault().getBundle(), "icons/middle.png");
+ String plusTexFile = PluginTools.getAbsolutePath(Activator.getDefault().getBundle(), "icons/plus.png");
+ if (middleTexFile == null || plusTexFile == null)
+ throw new RuntimeException("Cannot resolve required image files.");
+
+ vtkPoints points = new vtkPoints();
+ points.InsertNextPoint(-8, -8, 0.0);
+ points.InsertNextPoint( 8, -8, 0.0);
+ points.InsertNextPoint( 8, 8, 0.0);
+ points.InsertNextPoint(-8, 8, 0.0);
+
+
+ vtkCellArray cellArray = new vtkCellArray();
+ vtkPolygon polygon = new vtkPolygon();
+ polygon.GetPointIds().SetNumberOfIds(4);
+ polygon.GetPointIds().SetId(0, 0);
+ polygon.GetPointIds().SetId(1, 1);
+ polygon.GetPointIds().SetId(2, 2);
+ polygon.GetPointIds().SetId(3, 3);
+
+ cellArray.InsertNextCell(polygon);
+
+ vtkPolyData quad = new vtkPolyData();
+ quad.SetPoints(points);
+ quad.SetPolys(cellArray);
+
+ vtkFloatArray texCoords = new vtkFloatArray();
+
+ texCoords.SetNumberOfComponents(2);
+
+ texCoords.InsertNextTuple2(0.0, 0.0);
+ texCoords.InsertNextTuple2(1.0, 0.0);
+ texCoords.InsertNextTuple2(1.0, 1.0);
+ texCoords.InsertNextTuple2(0.0, 1.0);
+
+ quad.GetPointData().SetTCoords(texCoords);
+
+ vtkPNGReader middleReader = new vtkPNGReader();
+ middleReader.SetFileName(middleTexFile);
+
+ vtkPNGReader plusReader = new vtkPNGReader();
+ plusReader.SetFileName(plusTexFile);
+
+ vtkTexture middleTex = new vtkTexture();
+ middleTex.SetInputConnection(middleReader.GetOutputPort());
+ middleTex.SetInterpolate(1);
+
+ vtkTexture plusTex = new vtkTexture();
+ plusTex.SetInputConnection(plusReader.GetOutputPort());
+ plusTex.SetInterpolate(1);
+
+ vtkPolyDataMapper2D mapper = new vtkPolyDataMapper2D();
+ mapper.SetInput(quad);
+
+ nextProp = new vtkTexturedActor2D();
+ prevProp = new vtkTexturedActor2D();
+ middleProp = new vtkTexturedActor2D();
+
+ nextProp.SetMapper(mapper);
+ nextProp.SetTexture(plusTex);
+ nextProp.SetPickable(1);
+
+ prevProp.SetMapper(mapper);
+ prevProp.SetTexture(plusTex);
+ prevProp.SetPickable(1);
+
+ middleProp.SetMapper(mapper);
+ middleProp.SetTexture(middleTex);
+ middleProp.SetPickable(1);
+
+
+ plusReader.GetOutputPort().Delete();
+ plusReader.Delete();
+ middleReader.GetOutputPort().Delete();
+ middleReader.Delete();
+ middleTex.Delete();
+ plusTex.Delete();
+
+ mapper.Delete();
+ quad.GetPointData().Delete();
+ quad.Delete();
+ points.Delete();
+ polygon.GetPointIds().Delete();
+ polygon.Delete();
+ cellArray.Delete();
+ texCoords.Delete();
+
+ }
+
+
+ public PositionType getPickedPosition(vtkProp[] picked) {
+ if (picked == null)
+ return null;
+ for (vtkProp p : picked) {
+ if (p.equals(middleProp))
+ return PositionType.SPLIT;
+ if (p.equals(nextProp))
+ return PositionType.NEXT;
+ if (p.equals(prevProp))
+ return PositionType.PREVIOUS;
+ }
+ return null;
+ }
+
+
+}