public SurfacePatch(Membrane membrane, string name, Color color, IEnumerable <Triangle> triangles) { Membrane = membrane; Name = name; Color = color; Dictionary <Vertex, Vertex> VertexToTransformed = new Dictionary <Vertex, Vertex>(); List <Triangle> NewTriangles = new List <Triangle>(triangles.Count()); foreach (var t in triangles) { foreach (var v in t.Vertices) { if (!VertexToTransformed.ContainsKey(v)) { VertexToTransformed.Add(v, new Vertex(v.VolumePosition, v.VolumeNormal)); } } Triangle NewTriangle = new Triangle(t.ID, VertexToTransformed[t.V0], VertexToTransformed[t.V1], VertexToTransformed[t.V2]); NewTriangles.Add(NewTriangle); OriginalToTransformed.Add(t, NewTriangle); TransformedToOriginal.Add(NewTriangle, t); } SurfaceMesh = new Mesh(); SurfaceMesh.Vertices.AddRange(VertexToTransformed.Values); SurfaceMesh.Triangles.AddRange(OriginalToTransformed.Values); SurfaceMesh.UpdateGraph(); SurfaceMesh.UpdateVertexIDs(); TurnUpsideUp(); // Don't update buffers because there is no OpenGL context yet. UpdateStats(); UpdatePlanarizationStats(); Membrane.DisplayedPatches.CollectionChanged += MembraneDisplayedPatches_CollectionChanged; Membrane.PointGroups.CollectionChanged += MembranePointGroups_CollectionChanged; MembranePointGroups_CollectionChanged(null, null); }
public SurfacePatch(Membrane membrane, string name, Color color, IEnumerable<Triangle> triangles) { Membrane = membrane; Name = name; Color = color; Dictionary<Vertex, Vertex> VertexToTransformed = new Dictionary<Vertex, Vertex>(); List<Triangle> NewTriangles = new List<Triangle>(triangles.Count()); foreach (var t in triangles) { foreach (var v in t.Vertices) if (!VertexToTransformed.ContainsKey(v)) VertexToTransformed.Add(v, new Vertex(v.VolumePosition, v.VolumeNormal)); Triangle NewTriangle = new Triangle(t.ID, VertexToTransformed[t.V0], VertexToTransformed[t.V1], VertexToTransformed[t.V2]); NewTriangles.Add(NewTriangle); OriginalToTransformed.Add(t, NewTriangle); TransformedToOriginal.Add(NewTriangle, t); } SurfaceMesh = new Mesh(); SurfaceMesh.Vertices.AddRange(VertexToTransformed.Values); SurfaceMesh.Triangles.AddRange(OriginalToTransformed.Values); SurfaceMesh.UpdateGraph(); SurfaceMesh.UpdateVertexIDs(); TurnUpsideUp(); // Don't update buffers because there is no OpenGL context yet. UpdateStats(); UpdatePlanarizationStats(); Membrane.DisplayedPatches.CollectionChanged += MembraneDisplayedPatches_CollectionChanged; Membrane.PointGroups.CollectionChanged += MembranePointGroups_CollectionChanged; MembranePointGroups_CollectionChanged(null, null); }
void Membrane_TriangleSelectionChanged(Membrane sender, List<Triangle> selection) { float Area = selection.Sum(t => t.GetVolumeArea()); TextSelectionStats.Text = String.Format("{0} faces, {1:0.0} Ų.", selection.Count, Area); }
private void Membrane_MouseWheel(Membrane membrane, 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; bool RedrawNeeded = false; if (KeyboardHelper.CtrlDown() && IsPointForemost) // Rotate closest point overlapping with cursor { float Mult = KeyboardHelper.ShiftDown() ? 30f : 3f; ((SurfacePoint)PointIntersections.First().Target).Psi -= e.Delta / 120f * Mult / 180f * (float)Math.PI; ((SurfacePoint)PointIntersections.First().Target).Group.PointCloud.UpdateBuffers(); RedrawNeeded = true; } if (KeyboardHelper.CtrlDown() && membrane.PreviewGroup.Points.Count == 1) // Rotate preview point { float Mult = KeyboardHelper.ShiftDown() ? 30f : 3f; membrane.PreviewGroup.Points[0].Psi -= e.Delta / 120f * Mult / 180f * (float)Math.PI; membrane.PreviewGroup.Points[0].Group.PointCloud.UpdateBuffers(); Options.Viewport.Redraw(); RedrawNeeded = true; } if (RedrawNeeded) Options.Viewport.Redraw(); }
void Membrane_MouseUp(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; DraggingPoint = null; }
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_MouseLeave(Membrane sender, System.Windows.Forms.MouseEventArgs arg2) { TextCursorPosition.Text = ""; DraggingPoint = null; if (Options.Membrane.PreviewGroup.Points.Count == 1) { Options.Membrane.PreviewGroup.Points.RemoveAt(0); Options.Viewport.Redraw(); } else if (Options.Membrane.PreviewGroup.Points.Count > 1) throw new Exception("Preview group has more than 1 point, but it really should not."); }
void Membrane_MouseEnter(Membrane sender, List<Intersection> arg1, System.Windows.Forms.MouseEventArgs arg2) { }
void Membrane_MouseDown(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 (IsPointForemost && KeyboardHelper.CtrlDown()) DraggingPoint = (SurfacePoint)PointIntersections.First().Target; }
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(); } } } }