+package org.simantics.plant3d.gizmo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+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.VtkView;
+import org.simantics.g3d.vtk.gizmo.vtkGizmo;
+import org.simantics.g3d.vtk.utils.vtkUtil;
+import org.simantics.plant3d.Activator;
+
+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 ConstraintPointGizmo extends vtkGizmo {
+
+ List<vtkTexturedActor2D> props;
+ List<Vector3d> positions;
+
+ VtkView panel;
+
+ private RenderListener listener;
+
+ public ConstraintPointGizmo(VtkView panel) {
+ this.panel = panel;
+ props = new ArrayList<>();
+ positions = new ArrayList<>();
+
+ this.listener = new RenderListener() {
+
+ @Override
+ public void preRender() {
+ for (int i = 0; i < positions.size(); i++) {
+ Vector3d pos = positions.get(i);
+ vtkTexturedActor2D prop = props.get(i);
+ Point2d p = vtkUtil.getScreenCoordinates(getRenderer(), pos);
+ prop.SetDisplayPosition((int)p.x, (int)p.y);
+ }
+ }
+
+ @Override
+ public void postRender() {
+
+
+ }
+ };
+
+ }
+
+ vtkRenderer getRenderer() {
+ return panel.getRenderer();
+ }
+
+
+ @Override
+ public void attach(VtkView renderingPart) {
+
+ panel.addListener(listener);
+
+ super.attach(renderingPart);
+
+ }
+
+ @Override
+ public Collection<vtkProp> getGizmo() {
+ List<vtkProp> list = new ArrayList<vtkProp>();
+ for (vtkTexturedActor2D p : props) {
+ list.add(p);
+ }
+ return list;
+ }
+
+ protected void attachActors() {
+ panel.lock();
+ vtkRenderer ren = getRenderer();
+ while (props.size() < positions.size())
+ props.add(createActor());
+ for (int i = 0; i < positions.size(); i++) {
+ vtkTexturedActor2D p = props.get(i);
+ ren.AddActor2D(p);
+ }
+ panel.unlock();
+ }
+
+ @Override
+ protected void deattachActors() {
+ panel.removeListener(listener);
+ panel.lock();
+ vtkRenderer ren = getRenderer();
+ for (vtkTexturedActor2D p : props) {
+ ren.RemoveActor2D(p);
+ }
+ panel.unlock();
+ }
+
+
+ public void addPosition(Vector3d position) {
+ positions.add(position);
+ }
+
+ public void clearPositions() {
+ positions.clear();
+ }
+
+ vtkPolyDataMapper2D mapper;
+ vtkTexture plusTex;
+
+ double pw = 8;
+
+ private vtkTexturedActor2D createActor() {
+ if (mapper == null) {
+ loadData();
+ }
+ vtkTexturedActor2D nextProp = new vtkTexturedActor2D();
+
+ nextProp.SetMapper(mapper);
+ nextProp.SetTexture(plusTex);
+ nextProp.SetPickable(0);
+ nextProp.SetWidth(pw);
+ nextProp.SetHeight(pw);
+ nextProp.GetProperty().SetColor(new double[] {255.0,0.0,255.0});
+ nextProp.GetProperty().Delete();
+
+ panel.addDeletable(nextProp);
+
+ return nextProp;
+ }
+
+ public void dispose() {
+
+ }
+
+
+ private void loadData() {
+ String plusTexFile = PluginTools.getAbsolutePath(Activator.getDefault().getBundle(), "icons/crosshair.png");
+ if (plusTexFile == null)
+ throw new RuntimeException("Cannot resolve required image files.");
+
+ vtkPoints points = new vtkPoints();
+ points.InsertNextPoint(-pw, -pw, 0.0);
+ points.InsertNextPoint( pw, -pw, 0.0);
+ points.InsertNextPoint( pw, pw, 0.0);
+ points.InsertNextPoint(-pw, pw, 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 plusReader = new vtkPNGReader();
+ plusReader.SetFileName(plusTexFile);
+
+ plusTex = new vtkTexture();
+ plusTex.SetInputConnection(plusReader.GetOutputPort());
+ plusTex.SetInterpolate(1);
+
+ mapper = new vtkPolyDataMapper2D();
+ mapper.SetInputData(quad);
+
+ panel.addDeletable(mapper);
+ panel.addDeletable(plusTex);
+
+
+ plusReader.GetOutputPort().Delete();
+ plusReader.Delete();
+ quad.GetPointData().Delete();
+ quad.Delete();
+ points.Delete();
+ polygon.GetPointIds().Delete();
+ polygon.Delete();
+ cellArray.Delete();
+ texCoords.Delete();
+
+ }
+
+
+
+
+}