private Model3D ConvertVisualToModel3D(Visual visual, int dpi, ref double z) { Model3D model = null; var bounds = VisualTreeHelper.GetContentBounds(visual); if (visual is Viewport3D viewport3D) { bounds = new Rect(viewport3D.RenderSize); } if (this.includeEmptyVisuals) { bounds.Union(VisualTreeHelper.GetDescendantBounds(visual)); } if (!bounds.IsEmpty && bounds.Width > 0 && bounds.Height > 0) { var mesh = new MeshGeometry3D(); mesh.Positions.Add(new Point3D(bounds.Left, bounds.Top, z)); mesh.Positions.Add(new Point3D(bounds.Right, bounds.Top, z)); mesh.Positions.Add(new Point3D(bounds.Right, bounds.Bottom, z)); mesh.Positions.Add(new Point3D(bounds.Left, bounds.Bottom, z)); mesh.TextureCoordinates.Add(new Point(0, 0)); mesh.TextureCoordinates.Add(new Point(1, 0)); mesh.TextureCoordinates.Add(new Point(1, 1)); mesh.TextureCoordinates.Add(new Point(0, 1)); mesh.Normals.Add(new Vector3D(0, 0, 1)); mesh.Normals.Add(new Vector3D(0, 0, 1)); mesh.Normals.Add(new Vector3D(0, 0, 1)); mesh.Normals.Add(new Vector3D(0, 0, 1)); mesh.TriangleIndices = new Int32Collection(new int[] { 0, 1, 2, 2, 3, 0 }); mesh.FreezeIfPossible(); var brush = this.MakeBrushFromVisual(visual, bounds, dpi); var material = new DiffuseMaterial(brush); material.FreezeIfPossible(); model = new GeometryModel3D(mesh, material); ((GeometryModel3D)model).BackMaterial = material; z -= 1; } var childrenCount = VisualTreeHelper.GetChildrenCount(visual); if (childrenCount > 0) { var group = new Model3DGroup(); if (model != null) { group.Children.Add(model); } for (var i = 0; i < childrenCount; i++) { if (VisualTreeHelper.GetChild(visual, i) is Visual childVisual) { var childModel = this.ConvertVisualToModel3D(childVisual, dpi, ref z); if (childModel != null) { group.Children.Add(childModel); } } } model = group; } if (model != null) { var transform = VisualTreeHelper.GetTransform(visual); var matrix = transform?.Value ?? Matrix.Identity; var offset = VisualTreeHelper.GetOffset(visual); matrix.Translate(offset.X, offset.Y); if (!matrix.IsIdentity) { var matrix3D = new Matrix3D(matrix.M11, matrix.M12, 0, 0, matrix.M21, matrix.M22, 0, 0, 0, 0, 1, 0, matrix.OffsetX, matrix.OffsetY, 0, 1); Transform3D transform3D = new MatrixTransform3D(matrix3D); transform3D.FreezeIfPossible(); model.Transform = transform3D; } model.FreezeIfPossible(); } return(model); }