void Membrane_MouseMove(Membrane sender, List<Intersection> intersections, System.Windows.Forms.MouseEventArgs e) { bool RedrawNeeded = false; Options.Viewport.AreUpdatesDisabled = true; IEnumerable<Intersection> TriangleIntersections = intersections.Where(i => i.Target.GetType() == typeof (Triangle)); IEnumerable<Intersection> PointIntersections = intersections.Where(i => i.Target.GetType() == typeof(SurfacePoint)); bool IsPointForemost = PointIntersections.Count() > 0 ? PointIntersections.First() == intersections.First() : false; if (TriangleIntersections.Count() > 0) { Triangle PickedTriangle = (Triangle)TriangleIntersections.First().Target; Vector3 Position = TriangleIntersections.First().Position; TextCursorPosition.Text = $"{Position.X:0.00}, {Position.Y:0.00}, {Position.Z:0.00} Å"; if (PickedTriangle != null && e.Button == System.Windows.Forms.MouseButtons.Left) // Extent triangle selection { if (KeyboardHelper.ShiftDown() && !KeyboardHelper.AltDown()) { sender.SelectTriangles(new[] { PickedTriangle }); RedrawNeeded = true; } else if (KeyboardHelper.AltDown() && !KeyboardHelper.ShiftDown()) { sender.DeselectTriangles(new[] { PickedTriangle }); RedrawNeeded = true; } } else if (KeyboardHelper.CtrlDown() && !IsPointForemost && !KeyboardHelper.ShiftDown() && !KeyboardHelper.AltDown()) // Show surface point preview { sender.PreviewGroup.CopyPropertiesFrom(sender.ActiveGroup); Vector3 PointPosition = Position; if (sender.PreviewGroup.Depiction == PointDepiction.LocalSurface && sender.TomogramTexture != null) // Discretize position in case of local isosurface { Vector3 TomoOffset = sender.TomogramTexture.Offset; float Scale = Options.PixelScale.X; PointPosition.X = (float)Math.Round((Position.X - TomoOffset.X) / Scale) * Scale + TomoOffset.X; PointPosition.Y = (float)Math.Round((Position.Y - TomoOffset.Y) / Scale) * Scale + TomoOffset.Y; PointPosition.Z = (float)Math.Round((Position.Z - TomoOffset.Z) / Scale) * Scale + TomoOffset.Z; } if (sender.PreviewGroup.Points.Count == 0 || (sender.PreviewGroup.Points[0].Position - PointPosition).Length > 0.1f) { float PsiDiff = 0; if (sender.PreviewGroup.Points.Count == 1) { OpenTK.Matrix3 OldFrame = sender.PreviewGroup.Points[0].TransformedMatrix; OpenTK.Matrix3 NewFrame = PickedTriangle.GetPlaneMatrix3(); OpenTK.Matrix3 DiffFrame = OpenTK.Matrix3.Transpose(OldFrame) * NewFrame; PsiDiff = (float)Math.Atan2(DiffFrame.Column0.Y, DiffFrame.Column0.X); } if (sender.PreviewGroup.Points.Count == 1) sender.PreviewGroup.Points.RemoveAt(0); else if (sender.PreviewGroup.Points.Count > 1) throw new Exception("Preview group has more than 1 point, but it really should not."); float Offset = (float)sender.SurfaceOffset * Options.PixelScale.X; Vector3 TriangleGlobal = Position - PickedTriangle.Normal * Offset; Vector3 TriangleLocal = PickedTriangle.ToBarycentric(TriangleGlobal); sender.PreviewGroup.Points.Add(new SurfacePoint(PointPosition, PickedTriangle, TriangleLocal, Offset, PsiDiff)); RedrawNeeded = true; } } else if (!KeyboardHelper.CtrlDown() || IsPointForemost) // Hide surface point preview { if (Options.Membrane.PreviewGroup.Points.Count == 1) { Options.Membrane.PreviewGroup.Points.RemoveAt(0); RedrawNeeded = true; } else if (Options.Membrane.PreviewGroup.Points.Count > 1) throw new Exception("Preview group has more than 1 point, but it really should not."); } if (KeyboardHelper.CtrlDown() && DraggingPoint != null && TriangleIntersections.Any()) { Vector3 PointPosition = Position; if (DraggingPoint.Group.Depiction == PointDepiction.LocalSurface && sender.TomogramTexture != null) { Vector3 TomoOffset = sender.TomogramTexture.Offset; float Scale = Options.PixelScale.X; PointPosition.X = (float)Math.Round((Position.X - TomoOffset.X) / Scale) * Scale + TomoOffset.X; PointPosition.Y = (float)Math.Round((Position.Y - TomoOffset.Y) / Scale) * Scale + TomoOffset.Y; PointPosition.Z = (float)Math.Round((Position.Z - TomoOffset.Z) / Scale) * Scale + TomoOffset.Z; } float PsiDiff = 0; OpenTK.Matrix3 OldFrame = DraggingPoint.TransformedMatrix; OpenTK.Matrix3 NewFrame = PickedTriangle.GetPlaneMatrix3(); OpenTK.Matrix3 DiffFrame = OpenTK.Matrix3.Transpose(OldFrame) * NewFrame; PsiDiff = (float)Math.Atan2(DiffFrame.Column0.Y, DiffFrame.Column0.X); float Offset = (float)sender.SurfaceOffset * Options.PixelScale.X; Vector3 TriangleGlobal = Position - PickedTriangle.Normal * Offset; Vector3 TriangleLocal = PickedTriangle.ToBarycentric(TriangleGlobal); DraggingPoint.OriginalMatrix = NewFrame; DraggingPoint.Position = PointPosition; DraggingPoint.SurfaceOffset = Offset; DraggingPoint.Psi = PsiDiff; DraggingPoint.Face = PickedTriangle; DraggingPoint.BarycentricCoords = TriangleLocal; DraggingPoint.Group.PointCloud.UpdateBuffers(); if (DraggingPoint.Group.Depiction == PointDepiction.LocalSurface) // Only local surface has to be updated when position changes DraggingPoint.Group.UpdateDepiction(); RedrawNeeded = true; } } Options.Viewport.AreUpdatesDisabled = false; if (RedrawNeeded) Options.Viewport.Redraw(); }
void Membrane_MouseClick(Membrane sender, List<Intersection> intersections, System.Windows.Forms.MouseEventArgs e) { IEnumerable<Intersection> TriangleIntersections = intersections.Where(i => i.Target.GetType() == typeof(Triangle)); IEnumerable<Intersection> PointIntersections = intersections.Where(i => i.Target.GetType() == typeof(SurfacePoint)); bool IsPointForemost = PointIntersections.Count() > 0 ? PointIntersections.First() == intersections.First() : false; if (KeyboardHelper.ShiftDown() || KeyboardHelper.AltDown() || KeyboardHelper.CtrlDown()) { if (TriangleIntersections.Count() > 0 && !IsPointForemost) { Triangle ClickedTriangle = (Triangle)TriangleIntersections.First().Target; if (KeyboardHelper.ShiftDown() && !KeyboardHelper.AltDown() && !KeyboardHelper.CtrlDown()) // Select triangles { sender.SelectTriangles(new[] { ClickedTriangle }); } else if (KeyboardHelper.AltDown() && !KeyboardHelper.ShiftDown() && !KeyboardHelper.CtrlDown()) // Deselect triangles { sender.DeselectTriangles(new[] { ClickedTriangle }); } else if (KeyboardHelper.CtrlDown() && !KeyboardHelper.ShiftDown() && !KeyboardHelper.AltDown()) // Create a surface point { if (sender.PreviewGroup.Points.Count == 1) // If there is already a preview point, keep it for its possibly non-default Psi { SurfacePoint PreviewPoint = sender.PreviewGroup.Points[0]; sender.PreviewGroup.Points.RemoveAt(0); sender.ActiveGroup.Points.Add(PreviewPoint); } else // If no preview points, create one from scratch with Psi = 0 { Vector3 Position = TriangleIntersections.First().Position; float Offset = (float)sender.SurfaceOffset * Options.PixelScale.X; Vector3 TriangleGlobal = Position - ClickedTriangle.Normal * Offset; Vector3 TriangleLocal = ClickedTriangle.ToBarycentric(TriangleGlobal); sender.ActiveGroup.Points.Add(new SurfacePoint(Position, ClickedTriangle, TriangleLocal, Offset, 0)); } Options.Viewport.Redraw(); } } } }