Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
                    }
                }
            }
        }