예제 #1
0
        /// <summary>
        /// For each mesh object in the viewport, this method calculates the vertex that when mapped to 2D is closest to the given 2D point on the screen
        /// </summary>
        /// <param name="pointToHitTest"> The point in screen coordinates to calculate the closest vertices for. </param>
        /// <returns> A ClosestVertexResult containing the distance to the 2D point and the closest 3D vertex point for each geometry/model </returns>
        public IEnumerable <ClosestVertexResult> FindClosestHits(Point pointToHitTest)
        {
            ProjectionCamera camera = mViewPort3D.Camera as ProjectionCamera;

            if (camera == null)
            {
                throw new InvalidOperationException("No projection camera defined. Cannot find rectangle hits.");
            }

            List <ClosestVertexResult> results = new List <ClosestVertexResult>();

            mViewPort3D.Children.Traverse <GeometryModel3D>(
                (model, transform) =>
            {
                MeshGeometry3D geometry = model.Geometry as MeshGeometry3D;
                if (geometry == null || geometry.Positions == null || geometry.TriangleIndices == null)
                {
                    return;
                }

                Point3D[] point3Ds;
                if (geometry.Positions.Count <= mMaximumVerticesPerMesh)
                {
                    point3Ds = geometry.Positions.Select(transform.Transform).ToArray();
                }
                else
                {
                    Rect3D bounds = geometry.Bounds;
                    point3Ds      = GetBoundaryPointsBoundingBox(bounds).Select(transform.Transform).ToArray();
                }

                // transform the positions of the mesh to screen coordinates
                Point[] point2Ds = mViewPort3D.Point3DtoPoint2D(point3Ds).ToArray();

                double minSquaredDistanceToPoint = double.PositiveInfinity;

                Point3D closestPoint   = point3Ds[0];
                Point closestPointIn2D = point2Ds[0];

                for (int i = 0; i < point2Ds.Length; i++)
                {
                    Point point            = point2Ds[i];
                    double xDiff           = point.X - pointToHitTest.X;
                    double yDiff           = point.Y - pointToHitTest.Y;
                    double squaredDistance = xDiff * xDiff + yDiff * yDiff;
                    if (squaredDistance < minSquaredDistanceToPoint)
                    {
                        minSquaredDistanceToPoint = squaredDistance;
                        closestPoint     = point3Ds[i];
                        closestPointIn2D = point;
                    }
                }

                ClosestVertexResult hitTestResult = new ClosestVertexResult(model, geometry, closestPoint,
                                                                            closestPointIn2D, Math.Sqrt(minSquaredDistanceToPoint));
                results.Add(hitTestResult);
            });

            return(results);
        }
예제 #2
0
        public TranslatePartGizmo(Viewport3D viewport)
        {
            this.viewport = viewport;
            x             = new TranslatePartVisual3D();
            y             = new TranslatePartVisual3D();
            x1            = new TranslationVisual3D(new Point3D(0, 0, 0), new Vector3D(1, 0, 0));
            y1            = new TranslationVisual3D(new Point3D(0, 0, 0), new Vector3D(1, 0, 0));
            x2            = new TranslationVisual3D(new Point3D(0, 0, 0), new Vector3D(-1, 0, 0));
            y2            = new TranslationVisual3D(new Point3D(0, 0, 0), new Vector3D(-1, 0, 0));

            containerX = new ContainerUIElement3D();
            containerX.Children.Add(x);
            containerY = new ContainerUIElement3D();
            containerY.Children.Add(y);

            containerX1 = new ContainerUIElement3D();
            containerY1 = new ContainerUIElement3D();
            containerX1.Children.Add(x1);
            containerY1.Children.Add(y1);

            containerX2 = new ContainerUIElement3D();
            containerY2 = new ContainerUIElement3D();
            containerX2.Children.Add(x2);
            containerY2.Children.Add(y2);



            x.Material  = new DiffuseMaterial(Brushes.LightCoral.MakeTransparent(0.6));
            y.Material  = new DiffuseMaterial(Brushes.LightSkyBlue.MakeTransparent(0.6));
            x1.Material = new DiffuseMaterial(Brushes.Red);
            y1.Material = new DiffuseMaterial(Brushes.Blue);
            x2.Material = new DiffuseMaterial(Brushes.Red);
            y2.Material = new DiffuseMaterial(Brushes.Blue);

            var scales     = new[] { x, y };
            var containers = new[] { containerX, containerY };

            for (int i = 0; i < 2; i++)
            {
                int iCopy     = i;
                var scale     = scales[i];
                var container = containers[i];
                var curMat    = scale.Material;
                container.MouseEnter += (sender, args) =>
                {
                    scale.Material = new DiffuseMaterial(Brushes.Yellow);
                };
                container.MouseLeave += (sender, args) =>
                {
                    scale.Material = curMat;
                };
                container.MouseDown += (sender, args) =>
                {
                    Mouse.Capture(container);
                    whichAxis    = iCopy + 1;
                    lastPosition = args.GetPosition(container);
                };
                container.MouseMove += (sender, args) =>
                {
                    if (whichAxis != 0)
                    {
                        Point curPosition = args.GetPosition(container);
                        //  double dy = Math.Pow(2,(curPosition.Y - lastPosition.Y)/200);
                        //  double dx = Math.Pow(2, (curPosition.X - lastPosition.X)/200);

                        Point screenCenter = viewport.Point3DtoPoint2D(center);
                        Viewport3DHelper.Point3DtoPoint2D(viewport, center);
                        Vector sX = viewport.Point3DtoPoint2D(center + xAxis) - screenCenter;
                        Vector sY = viewport.Point3DtoPoint2D(center + yAxis) - screenCenter;

                        ScaleTransform scaling = null;
                        if (whichAxis == 1)
                        {
                            //scale along x
                            Vector offset = curPosition - lastPosition;
                            double proj   = sX * offset / sX.Length;
                            scaling = new ScaleTransform(0.4 * proj, 0);
                        }
                        else if (whichAxis == 2)
                        {
                            //scale along y
                            Vector offset = curPosition - lastPosition;
                            double proj   = sY * offset / sY.Length;
                            scaling = new ScaleTransform(0, 0.4 * proj);
                        }


                        if (Scaled != null)
                        {
                            Scaled(scaling);
                        }

                        lastPosition = curPosition;
                    }
                };
                container.MouseUp += (sender, args) =>
                {
                    Mouse.Capture(null);
                    whichAxis = 0;
                };
            }
        }