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; } }
//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); }
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); }
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)); }
/// <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); }
// 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); } }
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); }
/// <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); }
/// <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); }
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); } }
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; }