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 props; List 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 getGizmo() { List list = new ArrayList(); 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(); } }