コード例 #1
0
 public WLineRenderData(ScreenSpaceLineNode _node, LineSelectorData _selectData,
                        PositionColoredLineMaterial mtl, List <SharpDX.Color4> _colors)
 {
     node       = _node;
     selectData = _selectData;
     material   = mtl;
     colors     = _colors;
 }
コード例 #2
0
        void CreateColoredPolyLine(int count, int layer)
        {
            Vector3 preV    = new Vector3(0, layer, 0);
            Color4  preC    = Color4.White;
            var     points  = new List <Point3D>();
            var     vectors = new List <Vector3>();
            var     colors  = new List <SharpDX.Color4>();

            for (int i = 0; i < count; i++)
            {
                float   max = 1f;
                Vector3 v   = new Vector3(1, layer, 0);
                v.X += preV.X;
                //Console.WriteLine("{0} : {1} {2} {3}", i, v.X, v.Y, v.Z);
                colors.Add(preC);
                points.Add(new Point3D((double)v.X, (double)v.Y, (double)v.Z));
                vectors.Add(v);
                preV = v;
            }

            DisposeList disposables   = new DisposeList();
            float       lineThickness = 5;
            bool        isPolyLine    = false;
            var         lineMaterial  = new PositionColoredLineMaterial()
            {
                LineColor      = Color4.White, // When PositionColors are used, then LineColor is used as a mask - each color is multiplied by LineColor - use White to preserve PositionColors
                LineThickness  = lineThickness,
                PositionColors = colors.ToArray(),
                IsPolyLine     = isPolyLine
            };

            // NOTE: When rendering multi-lines we need to set isLineStrip to false
            var screenSpaceLineNode = new ScreenSpaceLineNode(vectors.ToArray(), isLineClosed: false, isLineStrip: true, lineMaterial: lineMaterial);

            if (disposables != null)
            {
                disposables.Add(screenSpaceLineNode);
                disposables.Add(lineMaterial);
            }

            var sceneNodeVisual = new SceneNodeVisual3D(screenSpaceLineNode);

            MainViewport.Children.Add(sceneNodeVisual);
            bool isVisualConnected;
            var  lineSelectorData = new LineSelectorData(points, true);

            lineSelectorData.PositionsTransform3D = Ab3d.Utilities.TransformationsHelper.GetVisual3DTotalTransform(sceneNodeVisual, true, out isVisualConnected);
            _lineSelectorData.Add(lineSelectorData);
            var _data = new WLineRenderData(screenSpaceLineNode, lineSelectorData, lineMaterial, colors);

            lrData.Add(_data);
        }
コード例 #3
0
        public LinesSelector()
        {
            InitializeComponent();

            // LineSelectorData is a utility class that can be used to get the closest distance
            // of a specified screen position to the 3D line.
            _lineSelectorData = new List <LineSelectorData>();

            for (int i = 0; i < 15; i++)
            {
                // Create random 3D lines
                var randomColor  = GetRandomColor();
                var lineVisual3D = GenerateRandomLine(randomColor, 10);

                // Create LineSelectorData from each line.
                // When adjustLineDistanceWithLineThickness is true, then distance is measured from line edge.
                // If adjustLineDistanceWithLineThickness is false, then distance is measured from center of the line.
                var lineSelectorData = new LineSelectorData(lineVisual3D, Camera1, adjustLineDistanceWithLineThickness: true);

                // LineSelectorData transform the line positions when there is any transformation set to the lineVisual3D's Transform property
                // (in this case the lineSelectorData.PositionsTransform3D is set to the used transformation).
                //
                // But when the lineVisual3D is added to a parent Visual3D that has its own transformation,
                // then LineSelectorData is not "aware" of that transformation.
                // To demonstrate that, the lineVisual3D in this sample is added to a RootVisual3D that has TranslateTransform3D with OffsetX = 20.
                //
                // Because we know the organization of objects in this sample, we could simple write the following to support that:
                // lineSelectorData.PositionsTransform3D = RootVisual3D.Transform;
                //
                // But there is a more general way that can be used.
                // With help of TransformationsHelper.GetVisual3DTotalTransform it is possible
                // to get the combined (total) transformation from Viewport3D to the lineVisual3D.
                // This also includes the transformation on lineVisual3D (second parameter in GetVisual3DTotalTransform is true).
                //
                // This methods can be also used to check if specified Visual3D is connected to Viewport3D (it sets an out parameter isVisualConnected).
                // There is also another override of this method that takes two Visual3D objects and gets the transformation from the first to the second.

                bool isVisualConnected; // This will be set to true if lineVisual3D is connected to Viewport3D (always true in our case).
                lineSelectorData.PositionsTransform3D = Ab3d.Utilities.TransformationsHelper.GetVisual3DTotalTransform(lineVisual3D, true, out isVisualConnected);


                _lineSelectorData.Add(lineSelectorData);
            }



            _isCameraChanged = true; // When true, the CalculateScreenSpacePositions method is called before calculating line distances

            Camera1.CameraChanged += delegate(object sender, CameraChangedRoutedEventArgs e)
            {
                _isCameraChanged = true;
                UpdateClosestLine();
            };

            this.MouseMove += delegate(object sender, MouseEventArgs e)
            {
                _lastMousePosition = e.GetPosition(MainBorder);
                UpdateClosestLine();
            };

            Camera1.StartRotation(20, 0);
        }
コード例 #4
0
        private void UpdateClosestLine()
        {
            if (_lineSelectorData == null || _lineSelectorData.Count == 0)
            {
                return;
            }

            if (_isCameraChanged)
            {
                // Each time camera is changed, we need to call CalculateScreenSpacePositions method.
                // This will update the 2D screen positions of the 3D lines.

                // IMPORTANT:
                // Before calling CalculateScreenSpacePositions it is highly recommended to call Refresh method on the camera.
                Camera1.Refresh();

                if (MultiThreadedCheckBox.IsChecked ?? false)
                {
                    // This code demonstrates how to use call CalculateScreenSpacePositions from multiple threads.
                    // This significantly improves performance when many 3D lines are used (thousands)
                    // but is not needed when using only a few lines (as in this demo).
                    //
                    // When calling CalculateScreenSpacePositions we need to prepare all the data
                    // from WPF properties before calling the method because those properties
                    // are not accessible from the other thread.
                    // We need worldToViewportMatrix and
                    // the _lineSelectorData[i].Camera and _lineSelectorData[i].UsedLineThickness need to be set
                    // (in this sample they are set in the LineSelectorData constructor).

                    var  worldToViewportMatrix        = new Matrix3D();
                    bool isWorldToViewportMatrixValid = Camera1.GetWorldToViewportMatrix(ref worldToViewportMatrix, forceMatrixRefresh: false);

                    if (isWorldToViewportMatrixValid)
                    {
                        Parallel.For(0, _lineSelectorData.Count,
                                     i => _lineSelectorData[i].CalculateScreenSpacePositions(ref worldToViewportMatrix, transform: null));
                    }
                }
                else
                {
                    for (var i = 0; i < _lineSelectorData.Count; i++)
                    {
                        _lineSelectorData[i].CalculateScreenSpacePositions(Camera1);
                    }
                }

                _isCameraChanged = false;
            }


            // Now we can call the GetClosestDistance method.
            // This method calculates the closest distance from the _lastMousePosition to the line that was used to create the LineSelectorData.
            // GetClosestDistance also sets the LastDistance, LastLinePositionIndex properties on the LineSelectorData.

            if (MultiThreadedCheckBox.IsChecked ?? false)
            {
                Parallel.For(0, _lineSelectorData.Count,
                             i => _lineSelectorData[i].GetClosestDistance(_lastMousePosition));
            }
            else
            {
                for (var i = 0; i < _lineSelectorData.Count; i++)
                {
                    _lineSelectorData[i].GetClosestDistance(_lastMousePosition);
                }
            }


            // Get the closest line
            IEnumerable <LineSelectorData> usedLineSelectors;

            // If we limit the distance of the specified position to the line, then we can filter all the line with Where
            if (_maxSelectionDistance >= 0)
            {
                usedLineSelectors = _lineSelectorData.Where(l => l.LastDistance <= _maxSelectionDistance).ToList();
            }
            else
            {
                usedLineSelectors = _lineSelectorData;
            }


            List <LineSelectorData> orderedLineSelectors;

            if (OrderByDistanceCheckBox.IsChecked ?? false)
            {
                // Order by camera distance
                orderedLineSelectors = usedLineSelectors.OrderBy(l => l.LastDistanceFromCamera).ToList();
            }
            else
            {
                // Order by distance to the specified position
                orderedLineSelectors = usedLineSelectors.OrderBy(l => l.LastDistance).ToList();
            }

            // Get the closest LineSelectorData
            LineSelectorData closestLineSelector;

            if (orderedLineSelectors.Count > 0)
            {
                closestLineSelector = orderedLineSelectors[0];
            }
            else
            {
                closestLineSelector = null;
            }


            // It is possible to get the positions of the line segment that is closest to the mouse position
            //var closestPolyLine = (PolyLineVisual3D)closestLineSelector.LineVisual;
            //Point3D firstSegmentPosition = closestPolyLine.Positions[closestLineSelector.LastLinePositionIndex];
            //Point3D secondSegmentPosition = closestPolyLine.Positions[closestLineSelector.LastLinePositionIndex + 1];

            // To get the actual position on the line that is closest to the mouse position, use the LastClosestPositionOnLine
            //closestLineSelector.LastClosestPositionOnLine;


            // The closest position on the line is shown with a SphereVisual3D
            if (_closestPositionSphereVisual3D == null)
            {
                _closestPositionSphereVisual3D = new SphereVisual3D()
                {
                    Radius   = 2,
                    Material = new DiffuseMaterial(Brushes.Red)
                };

                MainViewport.Children.Add(_closestPositionSphereVisual3D);
            }

            if (closestLineSelector == null)
            {
                ClosestDistanceValue.Text  = "";
                LineSegmentIndexValue.Text = "";
                _closestPositionSphereVisual3D.IsVisible = false;
            }
            else
            {
                ClosestDistanceValue.Text  = string.Format("{0:0.0}", closestLineSelector.LastDistance);
                LineSegmentIndexValue.Text = closestLineSelector.LastLinePositionIndex.ToString();

                _closestPositionSphereVisual3D.CenterPosition = closestLineSelector.LastClosestPositionOnLine;
                _closestPositionSphereVisual3D.IsVisible      = true;
            }


            // Show the closest line as red
            if (!ReferenceEquals(_lastSelectedLineSelector, closestLineSelector))
            {
                if (_lastSelectedLineSelector != null)
                {
                    _lastSelectedLineSelector.LineVisual3D.LineColor = _savedLineColor;
                }

                if (closestLineSelector != null)
                {
                    _savedLineColor = closestLineSelector.LineVisual3D.LineColor;
                    closestLineSelector.LineVisual3D.LineColor = Colors.Red;
                }

                _lastSelectedLineSelector = closestLineSelector;
            }
        }