private void AddHitLineArrow(Ray ray, DXRayHitTestResult hitResult, Point3D?referenceHitPosition = null, Point3D?rayEndPosition = null)
        {
            Ab3d.Visuals.LineVisual3D lineVisual3D;
            Point3D endPosition;

            if (hitResult != null)
            {
                endPosition = hitResult.HitPosition.ToWpfPoint3D();
            }
            else
            {
                endPosition = rayEndPosition ?? Camera1.TargetPosition + Camera1.Offset;
            }

            if (hitResult != null)
            {
                lineVisual3D = new Ab3d.Visuals.LineVisual3D()
                {
                    StartPosition = ray.Position.ToWpfPoint3D(),
                    EndPosition   = endPosition,
                    LineColor     = Colors.Green,
                    LineThickness = 1,
                    EndLineCap    = LineCap.ArrowAnchor
                };


                if (referenceHitPosition != null)
                {
                    var wireCrossVisual3D = new Ab3d.Visuals.WireCrossVisual3D()
                    {
                        Position      = referenceHitPosition.Value,
                        LineColor     = Colors.Red,
                        LineThickness = 1,
                        LinesLength   = 5
                    };

                    _hitLinesModelVisual3D.Children.Add(wireCrossVisual3D);
                }
            }
            else
            {
                lineVisual3D = new Ab3d.Visuals.LineVisual3D()
                {
                    StartPosition = ray.Position.ToWpfPoint3D(),
                    EndPosition   = endPosition,
                    LineColor     = Colors.Green,
                    LineThickness = 1
                };
            }

            _hitLinesModelVisual3D.Children.Add(lineVisual3D);
        }
Пример #2
0
        private void AddModel(Model3D originalModel3D, Point3D position, PositionTypes positionType, Size3D size, bool preserveAspectRatio = true)
        {
            // Create a new Model3DGroup that will hold the originalModel3D.
            // This allows us to have different transformation for each originalModel3D (transformation is on Model3DGroup)
            var model3DGroup = new Model3DGroup();

            model3DGroup.Children.Add(originalModel3D);

            Ab3d.Utilities.ModelUtils.PositionAndScaleModel3D(model3DGroup, position, positionType, size, preserveAspectRatio);

            // Add the model
            var modelVisual3D = new ModelVisual3D()
            {
                Content = model3DGroup
            };

            SolidObjectsVisual3D.Children.Add(modelVisual3D);



            // Now add red WireCrossVisual3D at the specified position
            var wireCrossVisual3D = new Ab3d.Visuals.WireCrossVisual3D()
            {
                Position    = position,
                LinesLength = 30,
                LineColor   = Colors.Red
            };

            SolidObjectsVisual3D.Children.Add(wireCrossVisual3D);


            // Now show a WireBoxVisual3D (box from 3D lines) that would represent the position, positionType and size.

            // To get the correct CenterPosition of the WireBoxVisual3D,
            // we start with creating a bounding box (Rect3D) that would be used when CenterPosition would be set to (0, 0, 0):
            var wireboxInitialBounds = new Point3D(-size.X * 0.5, -size.Y * 0.5, -size.Z * 0.5);

            // Then we use that bounding box and call GetModelTranslationVector3D method
            // that will tell us how much we need to move the bounding box so that it will be positioned at position and for positionType:
            var wireboxCenterOffset = Ab3d.Utilities.ModelUtils.GetModelTranslationVector3D(new Rect3D(wireboxInitialBounds, size), position, positionType);

            // Now we can use the result wireboxCenterOffset as a CenterPosition or a WireBoxVisual3D

            var wireBoxVisual3D = new WireBoxVisual3D()
            {
                CenterPosition = new Point3D(wireboxCenterOffset.X, wireboxCenterOffset.Y, wireboxCenterOffset.Z),
                Size           = size,
                LineColor      = Colors.Green,
                LineThickness  = 1
            };

            SolidObjectsVisual3D.Children.Add(wireBoxVisual3D);


            // Finally we add TextBlockVisual3D to show position and size information for this model
            // Note that the TextBlockVisual3D is added to the TransparentObjectsVisual3D.
            // The reason for this is that TextBlockVisual3D uses semi-transparent background.
            // To correctly show other object through semi-transparent, the semi-transparent must be added to the scene after solid objects.
            var infoText = string.Format("Position: {0:0}\r\nPositionType: {1}\r\nSize: {2:0}", position, positionType, size);

            if (!preserveAspectRatio)
            {
                infoText += "\r\npreserveAspectRatio: false";
            }

            var textBlockVisual3D = new TextBlockVisual3D()
            {
                Position      = new Point3D(model3DGroup.Bounds.GetCenterPosition().X, -15, 55), // Show so that X center position is the same as model center position
                PositionType  = PositionTypes.Center,
                TextDirection = new Vector3D(1, 0, 0),
                UpDirection   = new Vector3D(0, 1, -1), // angled at 45 degrees
                Size          = new Size(80, 0),        // y size will be calculated automatically based on x size (80) and size of the text

                Text            = infoText,
                BorderBrush     = Brushes.DimGray,
                BorderThickness = new Thickness(1, 1, 1, 1),
                Background      = new SolidColorBrush(Color.FromArgb(180, 200, 200, 200)),
                TextPadding     = new Thickness(5, 2, 5, 2)
            };

            TransparentObjectsVisual3D.Children.Add(textBlockVisual3D);
        }
        private void GetAllHitTestObjects()
        {
            var dxScene = MainDXViewportView.DXScene;

            if (dxScene == null) // NO DXEngine rendering
            {
                return;
            }



            _hitLinesModelVisual3D.Children.Clear();

            // After the 3D lines are cleared we need to call Update method to update SceneNodes before we call HitTest.
            // If this is not done manually, the SceneNodes would be updated before next rendering but after the HitTest and we could get hit the 3D line.
            MainDXViewportView.Update();


            // DXHitTestOptions.MeshPositionsCountForOctTreeGeneration:
            // Gets or sets an integer value that specifies number of positions in a mesh (DXMeshGeometry3D) at which a OctTree is generated to speed up hit testing
            // (e.g. if mesh has more positions then a value specified with this property, then OctTree will be generated for the mesh).
            // Default value is 512.
            //dxScene.DXHitTestOptions.MeshPositionsCountForOctTreeGeneration = 1;

            // When GetOnlyFrontFacingTriangles is true, then only triangles that are facing the camera will be hit
            dxScene.DXHitTestOptions.GetOnlyFrontFacingTriangles = OnlyFrontTrianglesCheckBox.IsChecked ?? false;

            // By default multiple hit results can be returned per one SceneNode.
            // This can be changed by setting GetOnlyOneHitPerSceneNode to true.
            //dxScene.DXHitTestOptions.GetOnlyOneHitPerSceneNode = false;

            // It is also possible to specify a hit test filter callback to skip testing some SceneNodes
            //dxScene.DXHitTestOptions.HitTestFilterCallback = delegate(SceneNode sceneNode)
            //{
            //    if (sceneNode == ...)
            //        return DXHitTestOptions.HitTestFilterResult.ContinueSkipSelfAndChildren;

            //    return DXHitTestOptions.HitTestFilterResult.Continue;
            //};

            // Hit test center of the MainDXViewportView (we could also use mouse position)
            var positionInViewport3D = new Point(MainDXViewportView.ActualWidth / 2, MainDXViewportView.ActualHeight / 2);
            var pickRay = dxScene.GetRayFromCamera((int)positionInViewport3D.X, (int)positionInViewport3D.Y);


            List <DXRayHitTestResult> allHitTests = dxScene.GetAllHitObjects(pickRay);

            if (allHitTests.Count == 0)
            {
                AddMessage("No object hit\r\n");
            }
            else
            {
                var sb = new StringBuilder();
                sb.AppendFormat("Ray.Start: {0:0.0}; Ray.Direction: {1:0.00}\r\n{2} hit results:\r\n",
                                pickRay.Position, pickRay.Direction, allHitTests.Count);

                for (var i = 0; i < allHitTests.Count; i++)
                {
                    var hitTest = allHitTests[i];
                    sb.AppendFormat("{0}. PointHit: {1:0.0};  Dist: {2:0};   SceneNode Id: {3}",
                                    i + 1,
                                    hitTest.HitPosition,
                                    hitTest.DistanceToRayOrigin,
                                    hitTest.HitSceneNode.Id);

                    if (!string.IsNullOrEmpty(hitTest.HitSceneNode.Name))
                    {
                        sb.AppendFormat(" ('{0}')", hitTest.HitSceneNode.Name);
                    }

                    var dxRayHitTestWpfModel3DResult = hitTest as DXRayHitTestWpfModel3DResult;
                    if (dxRayHitTestWpfModel3DResult != null && dxRayHitTestWpfModel3DResult.HitGeometryModel3D != null)
                    {
                        var name = dxRayHitTestWpfModel3DResult.HitGeometryModel3D.GetName();

                        if (!string.IsNullOrEmpty(name))
                        {
                            sb.Append("  GeometryModel3D.Name: ").Append(name);
                        }
                    }


                    sb.AppendLine();

                    //if (_showHitArrows)
                    //{
                    var wireCrossVisual3D = new Ab3d.Visuals.WireCrossVisual3D()
                    {
                        Position      = hitTest.HitPosition.ToWpfPoint3D(),
                        LineColor     = Colors.Red,
                        LineThickness = 1,
                        LinesLength   = 5
                    };

                    _hitLinesModelVisual3D.Children.Add(wireCrossVisual3D);
                    //}
                }

                sb.AppendLine();

                AddMessage(sb.ToString());
            }

            var lineVisual3D = new Ab3d.Visuals.LineVisual3D()
            {
                StartPosition = pickRay.Position.ToWpfPoint3D(),
                EndPosition   = pickRay.Position.ToWpfPoint3D() + pickRay.Direction.ToWpfVector3D() * dxScene.Camera.FarPlaneDistance,
                LineColor     = Colors.Green,
                LineThickness = 1,
                EndLineCap    = LineCap.ArrowAnchor
            };

            _hitLinesModelVisual3D.Children.Add(lineVisual3D);
        }