コード例 #1
0
        private void UpdateContourLines()
        {
            double minValue = AxesBox.ZAxis1.MinimumValue;
            double maxValue = AxesBox.ZAxis1.MaximumValue;

            // First define values for each contour line
            var contourLineValues = SetupContourLineValues(minValue, maxValue, step: (maxValue - minValue) / 15);

            // Then use CreateContourLinePositions method to create positions for all contour lines and returns them in one Point3DCollection.
            var contourLinePositions = HeightMap1.CreateContourLinePositions(contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map

            ContourLinesVisual3D.Positions = contourLinePositions;


            BottomContourLinesVisual3D.Children.Clear();
            AxesBox.ShowBottomConnectionLines = false;

            // Show flattened contour lines at the bottom of the graph
            if (ShowBottomGridCheckBox.IsChecked ?? false)
            {
                if (ContourLinesRadioButton.IsChecked ?? false)
                {
                    // Get bottom y position of the AxesBox
                    double yPosition = AxesBox.CenterPosition.Y - AxesBox.Size.Y * 0.5;

                    // CreateContourLinePositions creates positions for individual contour lines and returns them in an array of Point3DCollection
                    // (each element in the array represents positions for contour lines each value in _contourLineValues).
                    var individualContourLinePositions = HeightMap1.CreateMultiContourLinePositions(contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map


                    for (var i = 0; i < contourLineValues.Length; i++)
                    {
                        // Update all position's Y value to yPosition
                        var positions = individualContourLinePositions[i];
                        for (var j = 0; j < positions.Count; j++)
                        {
                            positions[j] = new Point3D(positions[j].X, yPosition, positions[j].Z);
                        }

                        var color = HeightMap1.GetHeightTextureColor(contourLineValues[i]);

                        var multiLineVisual3D = new MultiLineVisual3D()
                        {
                            Positions     = positions,
                            LineThickness = 2,
                            LineColor     = color
                        };

                        BottomContourLinesVisual3D.Children.Add(multiLineVisual3D);
                    }
                }
                else if (WireframeRadioButton.IsChecked ?? false)
                {
                    AxesBox.ShowBottomConnectionLines = true;
                }
            }
        }
コード例 #2
0
        private void CreateEdgeLines(Color lineColor)
        {
            foreach (var wireframeVisual3D in RootModelVisual.Children.OfType <WireframeVisual3D>())
            {
                var edgeLinePositions = new Point3DCollection();
                EdgeLinesFactory.AddEdgeLinePositions(wireframeVisual3D.OriginalModel, edgeStartAngleInDegrees: 30, linePositions: edgeLinePositions);

                var multiLineVisual3D = new MultiLineVisual3D()
                {
                    Positions     = edgeLinePositions,
                    LineColor     = lineColor,
                    LineThickness = 2,
                    Transform     = wireframeVisual3D.Transform
                };

                EdgeLinesModelVisual.Children.Add(multiLineVisual3D);
            }
        }
コード例 #3
0
        private void AddLinesFan(ModelVisual3D parentModelVisual3D, Point3D startPosition, double lineThickness, double linesLength, string titleText = null)
        {
            if (titleText == null)
            {
                titleText = string.Format(System.Globalization.CultureInfo.InvariantCulture, "LineThickness {0:0.0}:", lineThickness);
            }


            var textBlockVisual3D = new TextBlockVisual3D()
            {
                Position         = startPosition + new Vector3D(-2, linesLength + 5, 0),
                PositionType     = PositionTypes.Bottom | PositionTypes.Left,
                FontSize         = 11,
                RenderBitmapSize = new Size(1024, 256),
                Text             = titleText
            };

            parentModelVisual3D.Children.Add(textBlockVisual3D);


            var linePositions = new Point3DCollection();

            for (int a = 0; a <= 90; a += 5)
            {
                Point3D endPosition = startPosition + new Vector3D(linesLength * Math.Cos(a / 180.0 * Math.PI), linesLength * Math.Sin(a / 180.0 * Math.PI), 0);

                linePositions.Add(startPosition);
                linePositions.Add(endPosition);
            }

            var multiLineVisual3D = new MultiLineVisual3D()
            {
                Positions     = linePositions,
                LineColor     = Colors.Black,
                LineThickness = lineThickness
            };

            parentModelVisual3D.Children.Add(multiLineVisual3D);
        }
        private MultiLineVisual3D AddTriangleFan(Point3D startPosition, double linesLength, double lineThickness)
        {
            var linePositions = new Point3DCollection();

            for (int a = 0; a <= 90; a += 5)
            {
                Point3D endPosition = startPosition + new Vector3D(linesLength * Math.Cos(a / 180.0 * Math.PI), linesLength * Math.Sin(a / 180.0 * Math.PI), 0);

                linePositions.Add(startPosition);
                linePositions.Add(endPosition);
            }

            var multiLineVisual3D = new MultiLineVisual3D()
            {
                Positions     = linePositions,
                LineColor     = Colors.Black,
                LineThickness = lineThickness
            };

            MainViewport.Children.Add(multiLineVisual3D);

            return(multiLineVisual3D);
        }
コード例 #5
0
        public TwoDimensionalCameraLineEditor()
        {
            InitializeComponent();

            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Create new line");


            // NOTE: TwoDimensionalCamera class is available with full source in this samples project in the Common folder.

            // Create an instance of TwoDimensionalCamera.
            // TwoDimensionalCamera will internally create a TargetPositionCamera and MouseCameraController (when mouseEventsSourceElement is not null).
            // They will be used to show the 2D scene.
            _twoDimensionalCamera = new TwoDimensionalCamera(MainDXViewportView,
                                                             mouseEventsSourceElement: ViewportBorder,   // if mouseEventsSourceElement is null, then MouseCameraController will not be created by TwoDimensionalCamera
                                                             useScreenPixelUnits: false,                 // when false, then the size in device independent units is used (as size of DXViewportView); when true size in screen pixels is used (see SharpHorizontalAndVerticalLines sample)
                                                             coordinateSystemType: TwoDimensionalCamera.CoordinateSystemTypes.CenterOfViewOrigin)
            {
                MoveCameraConditions       = MouseCameraController.MouseAndKeyboardConditions.RightMouseButtonPressed,
                QuickZoomConditions        = MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed | MouseCameraController.MouseAndKeyboardConditions.RightMouseButtonPressed,
                ShowCameraLight            = ShowCameraLightType.Always,
                IsMouseAndTouchZoomEnabled = true,
            };

            // You can access the create TargetPositionCamera with UsedCamera property
            // and MouseCameraController with UsedMouseCameraController property.
            MouseCameraControllerInfo1.MouseCameraController = _twoDimensionalCamera.UsedMouseCameraController;

            // If we want to use LeftMouseButton for mouse movement, then we can also start new line with the same button with setting MouseMoveThreshold:
            //// Set MouseMoveThreshold so that mouse move starts after the mouse is moved
            //// for at least 3 pixels. This way we can use mouse click to start / end line drawing.
            //_twoDimensionalCamera.UsedMouseCameraController.MouseMoveThreshold = 3;


            _twoDimensionalCamera.CameraChanged += delegate(object sender, EventArgs args)
            {
                // When zoom is changed, we need to update all line markers
                if (!MathUtils.IsSame(_lastZoomFactor, _twoDimensionalCamera.ZoomFactor))
                {
                    // Update line markers size (we want that at each zoom level their WPF size is _positionMarkerWpfSize
                    _positionMarkerHalfSize = _twoDimensionalCamera.GetViewSizeFromWpfSize(_positionMarkerWpfSize) * 0.5;

                    if (double.IsNaN(_snappedViewPosition.X)) // Check if _snappedViewPosition is actually set
                    {
                        return;
                    }

                    // Reuse last position
                    var mousePosition = _twoDimensionalCamera.ToWpfPosition(_snappedViewPosition);
                    CheckPositionMarkers(mousePosition, updateExistingPositionMarkers: true); // _positionMarkerHalfSize is changed so we need to update all shown position markers

                    _lastZoomFactor = _twoDimensionalCamera.ZoomFactor;
                }
            };


            _twoDimensionalCamera.UsedMouseCameraController.CameraMoveStarted += delegate(object sender, EventArgs args)
            {
                _isMouseButtonPressed = false; // when we started mouse camera movement, we need to prevent creating the line when the mouse button is released
            };

            _twoDimensionalCamera.UsedMouseCameraController.CameraQuickZoomStarted += delegate(object sender, EventArgs args)
            {
                _isMouseButtonPressed = false; // when we started quick zoom, we need to prevent creating the line when the mouse button is released
            };


            // We store lines in our List of Points.
            // The main purpose of this is that we can have a very fast access to line positions.
            // (if we would read the Positions from MultiLineVisual3D this would be much slower because accessing DependencyProperties and Point3DCollection is very slow).
            _allPositions = new List <Point>();

            // _positionMarkers is a list that stores all created line markers. The size of array is the same as the size of _allPositions
            _positionMarkers = new List <PolyLineVisual3D>();


            // One MultiLineVisual3D will show fully created 3D lines (this is the much faster then creating individual LineVisual3D objects)
            _multiLineVisual3D = new MultiLineVisual3D()
            {
                Positions     = new Point3DCollection(),
                LineColor     = Colors.Black,
                LineThickness = 1
            };

            MainViewport.Children.Add(_multiLineVisual3D);


            // _creatingLine will show the line that is currently being created - user has not placed the end position yet.
            _creatingLine = new LineVisual3D()
            {
                LineColor     = Colors.Gray,
                LineThickness = 1,
                IsVisible     = false
            };

            MainViewport.Children.Add(_creatingLine);


            // _snappedPositionMarker will be shown over standard gray position marker and will indicate with its black color that mouse position is snapped to the marked position.
            _snappedPositionMarker = new PolyLineVisual3D()
            {
                Positions     = new Point3DCollection(5),
                LineColor     = Colors.Black,
                LineThickness = 1,
                IsVisible     = false
            };

            MainViewport.Children.Add(_snappedPositionMarker);


            _positionMarkerHalfSize = _twoDimensionalCamera.GetViewSizeFromWpfSize(_positionMarkerWpfSize) * 0.5;

            AddAxisLines();

            AddRandomLines(10);

            _snappedViewPosition = new Point(double.NaN, double.NaN); // Mark as invalid


            // We use ViewportBorder to get our mouse events
            ViewportBorder.MouseLeftButtonDown += delegate(object o, MouseButtonEventArgs args)
            {
                _isMouseButtonPressed = true; // we will start the line on mouse up
            };

            ViewportBorder.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs args)
            {
                if (!_isMouseButtonPressed)
                {
                    return;
                }

                if (_creatingLine.IsVisible)
                {
                    CompleteNewLine();
                }
                else
                {
                    StartNewLine(_snappedViewPosition);
                }

                _isMouseButtonPressed = false;
            };

            ViewportBorder.MouseMove += delegate(object o, MouseEventArgs args)
            {
                var mousePosition = args.GetPosition(ViewportBorder);
                CheckPositionMarkers(mousePosition, updateExistingPositionMarkers: false);

                if (_creatingLine.IsVisible)
                {
                    UpdateLastLinePosition(_snappedViewPosition);
                }
            };


            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                MainDXViewportView.Dispose();
            };
        }
        private void LoadSampleLinesData(double lineThickness, Rect targetRect)
        {
            // Read many lines from a custom bin file format.
            // The bin file was created from a metafile (wmf) file that was read by Ab2d.ReaderWmf,
            // then the lines were grouped by color and saved to a custom bin file.

            Rect bounds;
            var  lines = ReadLineDataFromBin(AppDomain.CurrentDomain.BaseDirectory + @"Resources\palazz_sport.bin", out bounds);


            Point targetCenter = new Point(targetRect.X + targetRect.Width * 0.5, targetRect.Y + targetRect.Height * 0.5);

            double xScale = targetRect.Width / bounds.Width;
            double yScale = targetRect.Height / bounds.Height;

            double scale = Math.Min(xScale, yScale); // Preserve aspect ratio - so use the minimal scale

            double xOffset = targetCenter.X - bounds.Width * scale * 0.5;
            double yOffset = targetCenter.Y + bounds.Height * scale * 0.5; // targetCenter.Y - bounds.Height * scale * 0.5 + bounds.Height * scale // because we flipped y we need to offset by height


            var matrixTransform = new MatrixTransform(scale, 0,
                                                      0, -scale, // We also need to flip y axis because here y axis is pointing up
                                                      xOffset, yOffset);

            for (var i = 0; i < lines.Count; i++)
            {
                var oneLineData = lines[i];
                var positions   = oneLineData.Positions;

                var point3DCollection = new Point3DCollection(positions.Count);
                for (var j = 0; j < positions.Count; j++)
                {
                    var p = new Point(positions[j].X, positions[j].Y);
                    p = matrixTransform.Transform(p);

                    point3DCollection.Add(new Point3D(p.X, p.Y, 0));
                }

                if (oneLineData.IsLineStrip)
                {
                    var polyLineVisual3D = new PolyLineVisual3D()
                    {
                        Positions     = point3DCollection,
                        LineColor     = oneLineData.LineColor,
                        LineThickness = lineThickness < 0 ? oneLineData.LineThickness : lineThickness
                    };

                    RootLinesVisual3D.Children.Add(polyLineVisual3D);
                }
                else
                {
                    var multiLineVisual3D = new MultiLineVisual3D()
                    {
                        Positions     = point3DCollection,
                        LineColor     = oneLineData.LineColor,
                        LineThickness = lineThickness < 0 ? oneLineData.LineThickness : lineThickness
                    };

                    RootLinesVisual3D.Children.Add(multiLineVisual3D);
                }
            }
        }
        private void LoadModelWithEdgeLines(string fileName)
        {
            MainViewport.Children.Clear();

            // Create an instance of AssimpWpfImporter
            var assimpWpfImporter = new AssimpWpfImporter();
            var readModel3D       = assimpWpfImporter.ReadModel3D(fileName, texturesPath: null); // we can also define a textures path if the textures are located in some other directory (this is parameter can be skipped, but is defined here so you will know that you can use it)

            MainViewport.Children.Add(readModel3D.CreateModelVisual3D());


            // NOTES:
            // 1)
            // The source code for EdgeLinesFactory class is written below (in a comment at the end of this file).
            // You can change its source and create a new class that would suite your needs.
            //
            // 2)
            // With using AddEdgeLinePositions we will create STATIC lines from the current readModel3D.
            // If the readModel3D would be changed (any child transformation would be changed),
            // then the lines would not be correct any more.
            // See the DynamicEdgeLinesSample to see how to create dynamic edge lines.
            // If your object will not change, then it is better to create static edge lines for performance reasons
            // (having single MultiLineVisual3D for the whole instead of one MultiLineVisual3D for each GeometryModel3D).
            //
            // 3)
            // Multi-threading:
            // If you want to call AddEdgeLinePositions method on background threads, you will need to call Freeze on the readModel3D
            // (this will make the model and meshes immutable and this way they can be read on other threads).
            // You will also need to create Point3DCollection for each thread and after it is filled in AddEdgeLinePositions
            // call Freeze on it so it can be "send" to the main UI thread.
            // Another option (better) is to create a MeshAnalyzer class in each thread and for each MeshGeometry3D call CreateEdgeLines
            // (see source of the EdgeLinesFactory.GenerateEdgeLineIndices method).
            //
            // 4)
            // You can use wpf3d file format to save 3D models with embedded EdgeLineIndices data (and also with PolygonIndices data).
            // The source code for wpf3d file format is available in this project under Wpf3DFile folder (see sample in this folder for more info).
            // This way you can calculate model edges in a separate application and then save that into the wpf3d file
            // so that the application that requires models with EdgeLineIndices data will not need to calculate that.

            var edgeLinePositions = new Point3DCollection();

            EdgeLinesFactory.AddEdgeLinePositions(readModel3D, EdgeStartAngleSlider.Value, edgeLinePositions);

            _multiLineVisual3D = new MultiLineVisual3D()
            {
                Positions     = edgeLinePositions,
                LineColor     = Colors.Black,
                LineThickness = LineThicknessSlider.Value,
            };

            MainViewport.Children.Add(_multiLineVisual3D);


            if (_fileName != fileName) // Reset camera only when the file is loaded for the first time
            {
                _fileName = fileName;

                Camera1.TargetPosition = readModel3D.Bounds.GetCenterPosition();
                Camera1.Distance       = readModel3D.Bounds.GetDiagonalLength() * 1.2;
            }

            // Add ambient light
            var ambientLight = new AmbientLight(Color.FromRgb(100, 100, 100));

            MainViewport.Children.Add(ambientLight.CreateModelVisual3D());
        }
コード例 #8
0
        private void UpdateContourLines()
        {
            double minValue = AxesBox.ZAxis1.MinimumValue;
            double maxValue = AxesBox.ZAxis1.MaximumValue;

            // First define values for each contour line
            var contourLineValues = SetupContourLineValues(minValue, maxValue, step: (maxValue - minValue) / 15);

            // Then use CreateContourLinePositions method to create positions for all contour lines and returns them in one Point3DCollection.

            // No yOffset when rendered by DXEngine because we will use LineDepthBias instead (see a few lines below):
            //var contourLinePositions = HeightMap1.CreateContourLinePositions(contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map
            var contourLinePositions = HeightMap1.CreateContourLinePositions(contourLineValues);

            ContourLinesVisual3D.Positions = contourLinePositions;

            // With DXEngine it is possible to offset the 3D lines from the 3D models in the geometry shader
            // so that lines are always positioned towards the camera.
            // This efficiently prevents that lines or parts of lines are hidden by the 3D objects.
            ContourLinesVisual3D.SetDXAttribute(DXAttributeType.LineDepthBias, 0.5f);


            BottomContourLinesVisual3D.Children.Clear();
            AxesBox.ShowBottomConnectionLines = false;

            // Show flattened contour lines at the bottom of the graph
            if (ShowBottomGridCheckBox.IsChecked ?? false)
            {
                if (ContourLinesRadioButton.IsChecked ?? false)
                {
                    // Get bottom y position of the AxesBox
                    double yPosition = AxesBox.CenterPosition.Y - AxesBox.Size.Y * 0.5;

                    // CreateContourLinePositions creates positions for individual contour lines and returns them in an array of Point3DCollection
                    // (each element in the array represents positions for contour lines each value in _contourLineValues).
                    var individualContourLinePositions = HeightMap1.CreateMultiContourLinePositions(contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map


                    for (var i = 0; i < contourLineValues.Length; i++)
                    {
                        // Update all position's Y value to yPosition
                        var positions = individualContourLinePositions[i];
                        for (var j = 0; j < positions.Count; j++)
                        {
                            positions[j] = new Point3D(positions[j].X, yPosition, positions[j].Z);
                        }

                        var color = HeightMap1.GetHeightTextureColor(contourLineValues[i]);

                        var multiLineVisual3D = new MultiLineVisual3D()
                        {
                            Positions     = positions,
                            LineThickness = 2,
                            LineColor     = color
                        };

                        BottomContourLinesVisual3D.Children.Add(multiLineVisual3D);
                    }
                }
                else if (WireframeRadioButton.IsChecked ?? false)
                {
                    AxesBox.ShowBottomConnectionLines = true;
                }
            }
        }
コード例 #9
0
        private ModelVisual3D CreateScene()
        {
            var rootModelVisual3D = new ModelVisual3D();

            var showLineThicknesses = new double[4];

            showLineThicknesses[0] = 0.6;

            double screenPixelLineThickness = 1.0 / _dpiScale; // set line thickness so that it will take 1 pixel
            string screenPixelThickLineText;

            if (_dpiScale == 1)
            {
                // No DPI scaling is used
                showLineThicknesses[1] = 0.8;
                showLineThicknesses[2] = 1.0;
                showLineThicknesses[3] = 2.0;

                screenPixelThickLineText = null; // No special line title
            }
            else
            {
                // DPI scaling is used => show line with 1 screen pixel line thickness
                showLineThicknesses[1] = screenPixelLineThickness;
                showLineThicknesses[2] = 1.0;
                showLineThicknesses[3] = 2.0;

                screenPixelThickLineText = string.Format(System.Globalization.CultureInfo.InvariantCulture, "LineThickness {0:0.##} (1px *):", screenPixelLineThickness);
            }


            AddLinesFan(rootModelVisual3D, startPosition: new Point3D(-210, -5, 0), lineThickness: 0.6, linesLength: 100);
            AddLinesFan(rootModelVisual3D, startPosition: new Point3D(-50, -5, 0), lineThickness: 0.8, linesLength: 100, screenPixelThickLineText);

            AddLinesFan(rootModelVisual3D, startPosition: new Point3D(-210, -140, 0), lineThickness: 1, linesLength: 100);
            AddLinesFan(rootModelVisual3D, startPosition: new Point3D(-50, -140, 0), lineThickness: 2, linesLength: 100);


            // Add lines that start from vertical lines and then continue with slightly angled lines
            var linePositions = new Point3DCollection();

            double xPos = 100;

            for (int i = 0; i <= 16; i++)
            {
                var startPosition = new Point3D(xPos, -5.5, 0);

                linePositions.Add(startPosition);
                linePositions.Add(startPosition + new Vector3D(i, 100, 0));

                xPos += 6;
            }

            var multiLineVisual3D = new MultiLineVisual3D()
            {
                Positions     = linePositions,
                LineColor     = Colors.Black,
                LineThickness = screenPixelLineThickness
            };

            rootModelVisual3D.Children.Add(multiLineVisual3D);



            // Add line circles
            double radius = 10;

            while (radius <= 40)
            {
                var lineArcVisual3D = new LineArcVisual3D()
                {
                    Radius        = radius,
                    LineColor     = Colors.Black,
                    LineThickness = screenPixelLineThickness,
                    StartAngle    = 0,
                    EndAngle      = 360,
                    Segments      = 60,
                    CircleNormal  = new Vector3D(0, 0, 1),
                };

                var transform3DGroup = new Transform3DGroup();
                transform3DGroup.Children.Add(new ScaleTransform3D(1.5, 1, 1));
                transform3DGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), 45)));
                transform3DGroup.Children.Add(new TranslateTransform3D(150, -90.5, 0));
                lineArcVisual3D.Transform = transform3DGroup;

                radius += radius <= 20 ? 2 : 3;

                rootModelVisual3D.Children.Add(lineArcVisual3D);
            }

            return(rootModelVisual3D);
        }
コード例 #10
0
        private void CreateContourLines()
        {
            ContourLinesRootVisual3D.Children.Clear();

            // NOTE:
            // Here we use CreateContourLinePositions and CreateMultiContourLinePositions methods on the HeightMapVisual3D class.
            // Those methods use the MeshGeometry3D of the height map and also scale the contour lines by the size of the HeightMapVisual3D.
            //
            // If you want to create contour lines based on some other geometry, then use the Ab3d.Utilities.ContourLinesFactory class (internally used by HeightMapVisual3D).

            if (CombineAllContourLinesRadioButton.IsChecked ?? false)
            {
                // CreateContourLinePositions creates positions for all contour lines and returns them in one Point3DCollection.
                var contourLinePositions = HeightMap1.CreateContourLinePositions(_contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map

                var multiLineVisual3D = new MultiLineVisual3D()
                {
                    Positions     = contourLinePositions,
                    LineColor     = Colors.Black,
                    LineThickness = 1
                };

                ContourLinesRootVisual3D.Children.Add(multiLineVisual3D);

                _individualContourLinePositions = null;
                _individualContourLines         = null;
            }
            else
            {
                _individualContourLines = new List <MultiLineVisual3D>(_contourLineValues.Length);

                // CreateContourLinePositions creates positions for individual contour lines and returns them in an array of Point3DCollection
                // (each element in the array represents positions for contour lines each value in _contourLineValues).
                _individualContourLinePositions = HeightMap1.CreateMultiContourLinePositions(_contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map

                for (var i = 0; i < _individualContourLinePositions.Length; i++)
                {
                    var multiLineVisual3D = new MultiLineVisual3D()
                    {
                        Positions = _individualContourLinePositions[i],
                    };

                    // Set line thickness (each 5th line is thicker)
                    if ((i % 5) == 0)
                    {
                        multiLineVisual3D.LineThickness = 2;
                    }
                    else
                    {
                        multiLineVisual3D.LineThickness = 0.7;
                    }

                    // Set line color
                    if (ColoredContourLinesRadioButton.IsChecked ?? false)
                    {
                        var color = HeightMap1.GetHeightTextureColor(_contourLineValues[i]);
                        multiLineVisual3D.LineColor = color;
                    }
                    else
                    {
                        multiLineVisual3D.LineColor = Colors.Black;
                    }


                    ContourLinesRootVisual3D.Children.Add(multiLineVisual3D);

                    _individualContourLines.Add(multiLineVisual3D);
                }
            }
        }
コード例 #11
0
        private void LoadModelWithEdgeLines(string fileName)
        {
            _mainViewport3D.Children.Clear();

            // Create an instance of AssimpWpfImporter
            var assimpWpfImporter = new AssimpWpfImporter();
            var readModel3D       = assimpWpfImporter.ReadModel3D(fileName, texturesPath: null); // we can also define a textures path if the textures are located in some other directory (this is parameter can be skipped, but is defined here so you will know that you can use it)


            if (readModel3D == null)
            {
                MessageBox.Show("Cannot read file");
                return;
            }

            _mainViewport3D.Children.Add(readModel3D.CreateModelVisual3D());


            // NOTE:
            // EdgeLinesFactory from Ab3d.PowerToys library will be used to create 3D lines that define the edges of the 3D models.
            // The edges are created when the angle between two triangles is bigger then the specified edgeStartAngleInDegrees (set by EdgeStartAngleSlider).
            //
            // See Lines3D\StaticEdgeLinesCreationSample and Lines3D\DynamicEdgeLinesSample samples for more info.
            //
            //
            // ADDITIONAL NOTE:
            // It is possible to store edge lines into wpf3d file format (this way it is not needed to generate the edge lines after the file is read).
            // The source code to read and write wpf3d file is available with Ab3d.PowerToys library.



            // With using AddEdgeLinePositions we will create STATIC lines from the current readModel3D.
            // If the readModel3D would be changed (any child transformation would be changed),
            // then the lines would not be correct any more.
            // See the DynamicEdgeLinesSample to see how to create dynamic edge lines.
            // If your object will not change, then it is better to create static edge lines for performance reasons
            // (having single MultiLineVisual3D for the whole instead of one MultiLineVisual3D for each GeometryModel3D).

            var edgeLinePositions = new Point3DCollection();

            EdgeLinesFactory.AddEdgeLinePositions(readModel3D, EdgeStartAngleSlider.Value, edgeLinePositions);


            _edgeLinesVisual3D = new MultiLineVisual3D()
            {
                Positions     = edgeLinePositions,
                LineColor     = Colors.Black,
                LineThickness = LineThicknessSlider.Value,
                IsVisible     = ShowEdgeLinesCheckBox.IsChecked ?? false
            };

            if (LineDepthBiasCheckBox.IsChecked ?? false)
            {
                // Use line depth bias to move the line closer to the camera so the line is rendered on top of solid model and is not partially occluded by it.
                double depthBias = (double)DepthBiasComboBox.SelectedItem;
                _edgeLinesVisual3D.SetDXAttribute(DXAttributeType.LineDepthBias, depthBias);
            }

            _mainViewport3D.Children.Add(_edgeLinesVisual3D);


            if (_fileName != fileName) // Reset camera only when the file is loaded for the first time
            {
                _fileName = fileName;

                // Set both Distance and CameraWidth (this way we can change the CameraType with RadioButtons)
                // Distance is used when CameraType is PerspectiveCamera.
                // CameraWidth is used when CameraType is OrthographicCamera.
                Camera1.Distance    = readModel3D.Bounds.GetDiagonalLength() * 1.3;
                Camera1.CameraWidth = readModel3D.Bounds.SizeX * 2;

                Camera1.TargetPosition = readModel3D.Bounds.GetCenterPosition() + new Vector3D(0, readModel3D.Bounds.SizeY * 0.15, 0); // slightly move the object down so that the object is not shown over the title

                // Find best EdgeLine DepthBias
                double idealDepthBias = Camera1.Distance / 3000;

                double bestDistance = double.MaxValue;
                int    bestIndex    = -1;
                for (int i = 0; i < PossibleEdgeLineDepthBiases.Length; i++)
                {
                    double distance = Math.Abs(idealDepthBias - PossibleEdgeLineDepthBiases[i]);
                    if (distance < bestDistance)
                    {
                        bestDistance = distance;
                        bestIndex    = i;
                    }
                }

                DepthBiasComboBox.SelectedIndex = bestIndex;
            }

            // Add ambient light
            var ambientLight = new AmbientLight(Color.FromRgb(100, 100, 100));

            _mainViewport3D.Children.Add(ambientLight.CreateModelVisual3D());
        }