Пример #1
0
        private void FrameSkeleton()
        {
            // position camera at average center position of skeleton
            if (this.Skeleton == null || this.Skeleton.Bones == null || this.Skeleton.Bones.Count <= 0)
            {
                return;
            }

            Rect3D bounds = default;

            Vector3D pos = this.Skeleton.Bones.First().ViewModel.Position.ToMedia3DVector();

            foreach (BoneVisual3d visual in this.Skeleton.Bones)
            {
                pos += visual.ViewModel.Position.ToMedia3DVector();

                Point3D point = visual.ViewModel.Position.ToMedia3DPoint();
                bounds.Union(point);
            }

            pos /= this.Skeleton.Bones.Count;

            double  d      = Math.Max(Math.Max(bounds.SizeX, bounds.SizeY), bounds.SizeZ);
            Point3D center = new Point3D(pos.X, pos.Y, pos.Z - (d + 3));

            this.camera.Position = center;

            foreach (BoneVisual3d visual in this.Skeleton.Bones)
            {
                visual.SphereRadius = d / 128;
            }
        }
Пример #2
0
        //MESHES & MATERIALS

        public void SetMeshes(List <wMesh> MeshSet)
        {
            Meshes.Clear();
            Materials.Clear();

            for (int i = 0; i < MeshSet.Count; i++)
            {
                Meshes.Add(MeshSet[i].WpfMesh);

                if (i == 0)
                {
                    Bound3D = MeshSet[i].WpfMesh.Bounds;
                }
                else
                {
                    Bound3D.Union(MeshSet[i].WpfMesh.Bounds);
                }

                MaterialGroup MatGroup = new MaterialGroup();
                MatGroup.Children.Add(new DiffuseMaterial(new SolidColorBrush(MeshSet[i].Material.DiffuseColor.ToMediaColor())));
                MatGroup.Children.Add(new SpecularMaterial(new SolidColorBrush(MeshSet[i].Material.SpecularColor.ToMediaColor()), 1.0 - MeshSet[i].Material.SpecularValue));
                MatGroup.Children.Add(new EmissiveMaterial(new SolidColorBrush(MeshSet[i].Material.EmissiveColor.ToMediaColor())));

                Materials.Add(MatGroup);
            }
            Origin = new Point3D(Bound3D.Location.X + Bound3D.SizeX / 2.0, Bound3D.Location.Y + Bound3D.SizeX / 2.0, Bound3D.Location.Z + Bound3D.SizeX / 2.0);
        }
Пример #3
0
        void btn_ZoomAll(object sender, RoutedEventArgs e)
        {
            Rect3D rect = new Rect3D();

            foreach (Visual3D v in _dict.Values1)
            {
                Rect3D r = v.FindBounds(Transform3D.Identity);
                rect.Union(r);
            }
            hv.ZoomExtents(rect, 10);
        }
Пример #4
0
        internal static Camera CreateEnclosingPerspectiveCamera(double horizontalFieldOfView, double aspectRatio, List <Model3D> models)
        {
            Rect3D empty = Rect3D.Empty;

            foreach (Model3D model3D in models)
            {
                if (model3D != null)
                {
                    empty.Union(model3D.Bounds);
                }
            }
            return(Helper3D.CreateEnclosingPerspectiveCamera(horizontalFieldOfView, aspectRatio, empty, 0.8));
        }
Пример #5
0
        /// <summary>
        /// Find the bounds of the children of a visual NOT including this visual's Transform.
        /// </summary>
        public static Rect3D GetChildrenBounds(Visual3D visual)
        {
            Rect3D bounds = Rect3D.Empty;

            if (visual is ModelVisual3D)
            {
                foreach (Visual3D v in ((ModelVisual3D)visual).Children)
                {
                    bounds.Union(GetChildrenBoundsRecursive((ModelVisual3D)v, Matrix3D.Identity));
                }
            }

            return(bounds);
        }
Пример #6
0
        // Fit the meshes to the indicated box.
        public void FitToBox(Rect3D box)
        {
            // Get the combined bounds of all meshes.
            Rect3D bounds = Meshes[0].Bounds;

            for (int i = 1; i < Meshes.Count; i++)
            {
                bounds.Union(Meshes[i].Bounds);
            }

            // Get the transformation.
            Transform3DGroup group = MeshExtensions.GetBoxMapping(bounds, box);

            // Apply the transformation to all meshes.
            foreach (MeshGeometry3D mesh in Meshes)
            {
                mesh.ApplyTransformation(group);
            }
        }
Пример #7
0
        private static Rect3D GetChildrenBoundsRecursive(ModelVisual3D visual, Matrix3D tx)
        {
            Rect3D   bounds           = Rect3D.Empty;
            Matrix3D currentTransform = MatrixUtils.Multiply(MatrixUtils.Value(visual.Transform), tx);

            if (visual.Content != null)
            {
                bounds = ModelBounder.CalculateBounds(visual.Content, currentTransform);
            }

            foreach (Visual3D v in visual.Children)
            {
                if (v is ModelVisual3D)
                {
                    bounds.Union(GetChildrenBoundsRecursive((ModelVisual3D)v, currentTransform));
                }
            }

            return(bounds);
        }
Пример #8
0
        /// <summary>
        /// Find the bounds of a model taking into account its Transform * (some arbitrary transform - e.g. Projection)
        /// </summary>
        public static Rect3D CalculateBounds(Model3D model, Matrix3D tx)
        {
            if (model == null)
            {
                return(Rect3D.Empty);
            }

            Rect3D bounds = Rect3D.Empty;

            model = model.CloneCurrentValue();
            Matrix3D newTx = MatrixUtils.Multiply(MatrixUtils.Value(model.Transform), tx);

            if (model is Model3DGroup)
            {
                foreach (Model3D m in ObjectUtils.GetChildren((Model3DGroup)model))
                {
                    bounds.Union(CalculateBounds(m, newTx));
                }
            }
            else if (model is GeometryModel3D)
            {
                bounds = CalculateBounds((GeometryModel3D)model, newTx);
            }
#if SSL
            else if (model is ScreenSpaceLines3D)
            {
                bounds = CalculateBounds((ScreenSpaceLines3D)model, tx);
            }
#endif
            else if (model is Light)
            {
                // Do nothing.  Light has no bounds.
            }
            else
            {
                throw new NotSupportedException("I do not calculate bounds on Model3D of type: " + model.GetType());
            }

            return(bounds);
        }
Пример #9
0
        /// <summary>
        /// The expand.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="transformation">
        /// The transformation.
        /// </param>
        private void Expand(GeometryModel3D model, Transform3D transformation)
        {
            Transform3D ot;

            if (this.originalTransforms.ContainsKey(model))
            {
                ot = this.originalTransforms[model];
            }
            else
            {
                ot = model.Transform;
                this.originalTransforms.Add(model, ot);
            }

            Transform3D totalTransform = Transform3DHelper.CombineTransform(transformation, ot);

            var mesh = model.Geometry as MeshGeometry3D;

            if (mesh == null)
            {
                return;
            }

            var bounds = new Rect3D();

            foreach (int i in mesh.TriangleIndices)
            {
                bounds.Union(totalTransform.Transform(mesh.Positions[i]));
            }

            Point3D  p = bounds.Location;
            Vector3D d = p - this.actualExpandOrigin;

            d *= this.Expansion;
            Point3D p2 = this.actualExpandOrigin + d;
            var     t  = new TranslateTransform3D(p2 - p);

            model.Transform = Transform3DHelper.CombineTransform(ot, t);
        }
Пример #10
0
        private void PreRender(double?time = null)
        {
            if (!time.HasValue)
            {
                for (double tick = 0; tick < animation.DurationInTicks; tick++)
                {
                    TransformNode(tick, aiScene.RootNode, globalInverseTransform);

                    var model = Render(tick);

                    cache.Add(tick, model);

                    Bounds = Rect3D.Union(Bounds, model.Bounds);
                }
            }
            else
            {
                TransformNode(time.Value, aiScene.RootNode, globalInverseTransform);

                var model = Render(time.Value);

                cache.Add(time.Value, model);
            }
        }
Пример #11
0
        public StreamLinesSample()
        {
            InitializeComponent();


            // We will set the tube path position color based on the Density
            string colorColumnName  = "Density"; // "AngularVelocity"
            bool   invertColorValue = false;     // This needs to be set to true when using AngularVelocity


            // First create a gradient legend and texture
            var gradientStopCollection = new GradientStopCollection();

            gradientStopCollection.Add(new GradientStop(Colors.Red, 1));
            gradientStopCollection.Add(new GradientStop(Colors.Yellow, 0.75));
            gradientStopCollection.Add(new GradientStop(Colors.Lime, 0.5));
            gradientStopCollection.Add(new GradientStop(Colors.Aqua, 0.25));
            gradientStopCollection.Add(new GradientStop(Colors.Blue, 0));

            var linearGradientBrush = new LinearGradientBrush(gradientStopCollection,
                                                              new System.Windows.Point(0, 1),  // startPoint (offset == 0) - note that y axis is down (so 1 is bottom)
                                                              new System.Windows.Point(0, 0)); // endPoint (offset == 1)

            // Create Legend control
            var gradientColorLegend = new GradientColorLegend()
            {
                Width  = 70,
                Height = 200,
                Margin = new Thickness(5, 5, 5, 5)
            };

            gradientColorLegend.GradientBrush = linearGradientBrush;

            var gradientTexture = gradientColorLegend.RenderToTexture(size: 256, isHorizontal: true);

            var imageBrush = new ImageBrush(gradientTexture);

            // IMPORTANT:
            // When texture coordinates have one components (for example y) always set to 0,
            // we need to change the ViewportUnits from the default RelativeToBoundingBox to Absolute.
            imageBrush.ViewportUnits = BrushMappingMode.Absolute;

            var gradientMaterial = new DiffuseMaterial(imageBrush);


            // Now load sample data
            // Sample data was created by using ParaView application and exporting the streamlines into csv file.
            string sampleDataFileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources\\Streamlines.csv");


            // Create csv file reader that can read data from a csv file
            var csvDataReader = new CsvDataReader();

            csvDataReader.ReadFile(sampleDataFileName);


            float minValue, maxValue;

            csvDataReader.GetValuesRange(colorColumnName, out minValue, out maxValue);

            float dataRange = maxValue - minValue;


            var streamlineIndexes = csvDataReader.IndividualObjectIndexes;


            // Create the streamlines
            var allStreamlineBounds = new Rect3D();

            for (var i = 0; i < csvDataReader.IndividualObjectIndexes.Length - 1; i++)
            {
                Rect3D bounds;

                int startIndex = streamlineIndexes[i];
                int endIndex   = streamlineIndexes[i + 1] - 1;

                int dataCount = endIndex - startIndex;

                if (dataCount < 2) // Skip streamlines without any positions or with less then 2 positions
                {
                    continue;
                }

                var positions = csvDataReader.GetPositions(startIndex, dataCount, out bounds);

                allStreamlineBounds.Union(bounds);

                var pathPositions = new Point3DCollection(positions);


                float[] dataValues = csvDataReader.GetValues(colorColumnName, startIndex, dataCount);

                // Generate texture coordinates for each path position
                // Because our texture is one dimensional gradient image (size 256 x 1)
                // we set the x coordinate in range from 0 to 1 (0 = first gradient color; 1 = last gradient color).
                //
                // Note:
                // If we would only set x texture coordinate and preserve y at 0,
                // WPF would not render the texture because the y size would be 0
                // and because by default the ViewportUnits is set to RelativeToBoundingBox,
                // WPF "thinks" the texture is empty.
                // Therefore we need to set the imageBrush.ViewportUnits to Absolute.
                var positionsCount     = pathPositions.Count;
                var textureCoordinates = new PointCollection(positionsCount);
                for (int j = 0; j < dataCount; j++)
                {
                    float relativeDataValue = (dataValues[j] - minValue) / dataRange;

                    if (invertColorValue)
                    {
                        relativeDataValue = 1.0f - relativeDataValue;
                    }

                    textureCoordinates.Add(new Point(relativeDataValue, 0));
                }


                var tubePathMesh3D = new Ab3d.Meshes.TubePathMesh3D(
                    pathPositions: pathPositions,
                    pathPositionTextureCoordinates: textureCoordinates,
                    radius: 0.03,
                    isTubeClosed: true,
                    isPathClosed: false,
                    segments: 8);


                var geometryModel3D = new GeometryModel3D(tubePathMesh3D.Geometry, gradientMaterial);
                //var geometryModel3D = new GeometryModel3D(tubePathMesh3D.Geometry, new DiffuseMaterial(Brushes.Red));
                geometryModel3D.BackMaterial = new DiffuseMaterial(Brushes.DimGray);

                var modelVisual3D = new ModelVisual3D()
                {
                    Content = geometryModel3D
                };

                MainViewport.Children.Add(modelVisual3D);
            }

            Camera1.TargetPosition = allStreamlineBounds.GetCenterPosition();
            Camera1.Distance       = allStreamlineBounds.GetDiagonalLength();


            // Add legend control:
            int legendValuesCount = 5;

            for (int i = 0; i < legendValuesCount; i++)
            {
                float t        = (float)i / (float)(legendValuesCount - 1);
                float oneValue = minValue + t * (maxValue - minValue);

                string valueLegendText = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00}", oneValue);
                gradientColorLegend.LegendLabels.Add(new GradientColorLegend.LegendLabel(t, valueLegendText));
            }


            var legendTitleTextBlock = new TextBlock()
            {
                Text                = colorColumnName,
                FontSize            = 14,
                FontWeight          = FontWeights.Bold,
                Foreground          = Brushes.Black,
                HorizontalAlignment = HorizontalAlignment.Center
            };


            var stackPanel = new StackPanel()
            {
                Orientation         = Orientation.Vertical,
                VerticalAlignment   = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Right,
                Margin = new Thickness(0, 0, 5, 5)
            };

            stackPanel.Children.Add(legendTitleTextBlock);
            stackPanel.Children.Add(gradientColorLegend);

            RootGrid.Children.Add(stackPanel);
        }
        private void UpdateScene()
        {
            _originalModelVisual3D = null;
            _originalModel3D       = null;
            _originalMesh3D        = null;
            _model3DFor2DSlice     = null;

            RootModelVisual3D.Children.Clear();

            WireframeModels1.OriginalModel = null;
            WireframeModels2.OriginalModel = null;


            if (Model1RadioButton.IsChecked ?? false)
            {
                // Use ObjModelVisual3D to load robotarm.obj and then read its Content to get Model3D
                var objModelVisual3D = new ObjModelVisual3D()
                {
                    Source       = new Uri("pack://application:,,,/Ab3d.PowerToys.Samples;component/Resources/ObjFiles/robotarm.obj", UriKind.Absolute),
                    SizeX        = 100,
                    Position     = new Point3D(0, 0, 0),
                    PositionType = ObjModelVisual3D.VisualPositionType.BottomCenter
                };

                _originalModel3D = objModelVisual3D.Content;
                _modelBounds     = _originalModel3D.Bounds;
            }
            else if (Model2RadioButton.IsChecked ?? false)
            {
                _originalMesh3D = new Ab3d.Meshes.SphereMesh3D(new Point3D(0, 0, 0), 50, 20).Geometry;
                _modelBounds    = _originalMesh3D.Bounds;
            }
            else if (Model3RadioButton.IsChecked ?? false)
            {
                _originalModelVisual3D = new ModelVisual3D();

                _originalModelVisual3D.Children.Add(new Ab3d.Visuals.PyramidVisual3D()
                {
                    BottomCenterPosition = new Point3D(-280, -60, 0), Size = new Size3D(120, 120, 120), Material = new DiffuseMaterial(Brushes.Green)
                });
                _originalModelVisual3D.Children.Add(new Ab3d.Visuals.BoxVisual3D()
                {
                    CenterPosition = new Point3D(-100, 0, 0), Size = new Size3D(120, 120, 60), Material = new DiffuseMaterial(Brushes.Green)
                });
                _originalModelVisual3D.Children.Add(new Ab3d.Visuals.TubeVisual3D()
                {
                    BottomCenterPosition = new Point3D(80, -60, 0), InnerRadius = 40, OuterRadius = 60, Height = 120, Material = new DiffuseMaterial(Brushes.Green)
                });
                _originalModelVisual3D.Children.Add(new Ab3d.Visuals.SphereVisual3D()
                {
                    CenterPosition = new Point3D(240, 0, 0), Radius = 60, Material = new DiffuseMaterial(Brushes.Green)
                });

                _modelBounds = new Rect3D();
                foreach (var visual3D in _originalModelVisual3D.Children.OfType <ModelVisual3D>())
                {
                    _modelBounds.Union(visual3D.Content.Bounds);
                }
            }

            _rootModelSize   = Math.Sqrt(_modelBounds.SizeX * _modelBounds.SizeX + _modelBounds.SizeY * _modelBounds.SizeY + _modelBounds.SizeZ * _modelBounds.SizeZ);
            Camera1.Distance = 2 * _rootModelSize;
        }