private void BuildTextures(OptFile opt) { this.nullTexture = null; this.textures = null; if (opt == null) { return; } this.nullTexture = new DiffuseMaterial(Brushes.White); this.textures = new Dictionary <string, Material>(); foreach (var texture in opt.Textures.Values) { var image = CreateTexture(opt, texture.Name); image.Freeze(); var brush = new ImageBrush(image) { ViewportUnits = BrushMappingMode.Absolute, Stretch = Stretch.Fill, TileMode = TileMode.Tile, Opacity = texture.HasAlpha ? 0.999 : 1.0 }; brush.Freeze(); var material = new DiffuseMaterial(brush); material.Freeze(); this.textures.Add(texture.Name, material); } }
protected Viewport2DBillboardBase() { Material material = new DiffuseMaterial(Brushes.White); Viewport2DVisual3D.SetIsVisualHostMaterial(material, true); material.Freeze(); viewport2DVisual.Material = material; Children.Add(viewport2DVisual); meshGeometry.TextureCoordinates.Add(new Point(0, 1)); meshGeometry.TextureCoordinates.Add(new Point(1, 1)); meshGeometry.TextureCoordinates.Add(new Point(0, 0)); meshGeometry.TextureCoordinates.Add(new Point(1, 0)); meshGeometry.TriangleIndices.Add(0); meshGeometry.TriangleIndices.Add(1); meshGeometry.TriangleIndices.Add(3); meshGeometry.TriangleIndices.Add(0); meshGeometry.TriangleIndices.Add(3); meshGeometry.TriangleIndices.Add(2); viewport2DVisual.Geometry = meshGeometry; }
private Model3DGroup Create3DScene(Point3D center, int xCount, int yCount, int zCount, float modelSize) { var semiTransparentBrush = new SolidColorBrush(Color.FromArgb(64, 200, 200, 200)); // alpha = 1/4 var diffuseMaterial = new DiffuseMaterial(semiTransparentBrush); diffuseMaterial.Freeze(); // This will significantly speed up the creation of objects var modelSizeWithMargin = modelSize * 1.2; var size = new Size3D(xCount * modelSizeWithMargin, yCount * modelSizeWithMargin, zCount * modelSizeWithMargin); var instancedData = InstancedMeshGeometry3DTest.CreateInstancesData(center, size, modelSize, xCount, yCount, zCount, false); var model3DGroup = new Model3DGroup(); var boxMesh3D = new Ab3d.Meshes.BoxMesh3D(new Point3D(0, 0, 0), new Size3D(1, 1, 1), 1, 1, 1).Geometry; for (int i = 0; i < instancedData.Length; i++) { var geometryModel3D = new GeometryModel3D(boxMesh3D, diffuseMaterial); geometryModel3D.BackMaterial = diffuseMaterial; geometryModel3D.Transform = new MatrixTransform3D(instancedData[i].World.ToWpfMatrix3D()); model3DGroup.Children.Add(geometryModel3D); } var modelVisual3D = new ModelVisual3D(); modelVisual3D.Content = model3DGroup; MainViewport3D.Children.Add(modelVisual3D); return(model3DGroup); }
private void CreateTestScene() { _standardBoxMaterial = new DiffuseMaterial(Brushes.Silver); _standardBoxMaterial.Freeze(); _mouseOverBoxMaterial = new DiffuseMaterial(Brushes.Orange); _mouseOverBoxMaterial.Freeze(); _selectedBoxMaterial = new DiffuseMaterial(Brushes.Red); _selectedBoxMaterial.Freeze(); // 5 x 3 boxes for (int x = 0; x < 5; x++) { for (int y = 0; y < 3; y++) { var boxVisual3D = new BoxVisual3D() { CenterPosition = new Point3D(-40 + x * 20, 5, -30 + y * 30), Size = new Size3D(10, 10, 10), Material = _standardBoxMaterial }; BoxesRootVisual3D.Children.Add(boxVisual3D); } } }
/// <summary> /// Updates the material when the texture changes. /// </summary> protected void TextureChanged() { var w = 256; var h = 256; var bitmap = new RenderTargetBitmap(opacityLevels * w, h, 96, 96, PixelFormats.Pbgra32); for (int i = 0; i < opacityLevels; i++) { var rect = new Rectangle { Opacity = 1 - ((double)i / opacityLevels), Fill = this.Texture, Width = w, Height = h }; rect.Arrange(new Rect(w * i, 0, w, h)); bitmap.Render(rect); } var brush = new ImageBrush(bitmap) { ViewportUnits = BrushMappingMode.Absolute }; brush.Freeze(); var material = new DiffuseMaterial(brush) { AmbientColor = Colors.White }; material.Freeze(); this.model.Material = material; }
protected static Material GetDefaultBackMaterial() { var backMaterial = new DiffuseMaterial { Brush = BACK_BRUSH }; backMaterial.Freeze(); return(backMaterial); }
private void OnBrushChanged() { var model = (GeometryModel3D)Content; var material = new DiffuseMaterial { Brush = this.Brush }; material.Freeze(); model.Material = material; }
private void initSource() //初始化资源 { darkc[0] = Colors.Red; darkc[1] = Colors.Blue; darkc[2] = Colors.DarkGreen; darkc[3] = Color.FromRgb(0x66, 0x00, 0xFF); darkc[4] = Color.FromRgb(0x99, 0x66, 0x00); darkc[5] = Colors.Red; darkc[6] = Colors.Gold; darkc[7] = Color.FromRgb(0x00, 0x00, 0xFF); darkc[8] = Colors.Green; darkc[9] = Color.FromRgb(0x66, 0x00, 0x66); darkc[10] = Color.FromRgb(0xFF, 0x99, 0x00); darkc[11] = Color.FromRgb(0xFF, 0xCC, 0xFF); // 设置资源 Color[] ac = new Color[12]; ac[0] = Color.FromRgb(0xFF, 0x66, 0x66); ac[1] = Color.FromRgb(0x00, 0x66, 0xFF); ac[2] = Color.FromRgb(0x66, 0xCC, 0x00); ac[3] = Color.FromRgb(0xCC, 0x00, 0xFF); ac[4] = Color.FromRgb(0x99, 0x66, 0x00); ac[5] = Colors.Pink; ac[6] = Color.FromRgb(0xFF, 0xFF, 0x00); ac[7] = Color.FromRgb(0x00, 0x00, 0xFF); ac[8] = Colors.Green; ac[9] = Color.FromRgb(0x66, 0x00, 0x66); ac[10] = Color.FromRgb(0xFF, 0x99, 0x00); ac[11] = Color.FromRgb(0xFF, 0xCC, 0xFF); MaterialGroup matg; DiffuseMaterial mat; for (int i = 0; i < 12; i++) { matg = new MaterialGroup(); matg.Children.Add(new DiffuseMaterial(new SolidColorBrush(ac[i]))); matg.Children.Add(new SpecularMaterial(Brushes.White, 90)); if (this.TryFindResource("matslice" + i.ToString()) == null) { this.Resources.Add("matslice" + i.ToString(), matg); } ac[i].A = 128; mat = new DiffuseMaterial(new LinearGradientBrush(ac[i], Colors.Transparent, 90)); mat.Freeze(); if (this.TryFindResource("matcone" + i.ToString()) == null) { this.Resources.Add("matcone" + i.ToString(), mat); } } //MeshGeometry3D cubep = Model3DHelper.genTextPlaneMesh(); //cubep.Freeze(); //this.Resources.Add("meshText", cubep); }
private IEnumerable <Material> GetMaterials(IGeometryModel model) { var indexes = model.Meshes.SelectMany(m => m.Submeshes) .Select(s => s.MaterialIndex).Distinct().ToArray(); var bitmapLookup = new Dictionary <int, DiffuseMaterial>(); for (short i = 0; i < model.Materials.Count; i++) { if (!indexes.Contains(i)) { yield return(null); continue; } var mat = model.Materials[i]; DiffuseMaterial material; try { var diffuse = mat.Submaterials.First(m => m.Usage == MaterialUsage.Diffuse); if (!bitmapLookup.ContainsKey(diffuse.Bitmap.Id)) { var dds = diffuse.Bitmap.ToDds(0); var brush = new ImageBrush(dds.ToBitmapSource(new DdsOutputArgs(DecompressOptions.Bgr24))) { ViewportUnits = BrushMappingMode.Absolute, TileMode = TileMode.Tile, Viewport = new Rect(0, 0, 1f / Math.Abs(diffuse.Tiling.X), 1f / Math.Abs(diffuse.Tiling.Y)) }; brush.Freeze(); material = new DiffuseMaterial(brush); material.Freeze(); bitmapLookup[diffuse.Bitmap.Id] = material; } else { material = bitmapLookup[diffuse.Bitmap.Id]; } } catch { material = ErrorMaterial; } yield return(material); } }
private Material GetOrCreateMaterial(Color color) { // Reuse and freeze material for better performance. Material material; if (!this.colorToMaterialDict.TryGetValue(color, out material)) { material = new DiffuseMaterial(new SolidColorBrush(color)); material.Freeze(); this.colorToMaterialDict[color] = material; } return(material); }
/// <summary> /// Creates a material from the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="opacity">The opacity value.</param> /// <param name="freeze">Freeze the material if set to <c>true</c>.</param> /// <returns>The image material.</returns> public static Material CreateImageMaterial(BitmapImage image, double opacity, bool freeze = true) { var brush = new ImageBrush(image) { Opacity = opacity }; var material = new DiffuseMaterial(brush); if (freeze) { material.Freeze(); } return(material); }
public MouseSelectionAndRotation() { InitializeComponent(); _standardBoxMaterial = new DiffuseMaterial(Brushes.Silver); _standardBoxMaterial.Freeze(); _mouseOverBoxMaterial = new DiffuseMaterial(Brushes.Orange); _mouseOverBoxMaterial.Freeze(); _selectedBoxMaterial = new DiffuseMaterial(Brushes.Red); _selectedBoxMaterial.Freeze(); var eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport); // IMPORTANT !!! // To allow EventManager3D and MouseCameraController to both work with left mouse button, // we need to set UsePreviewEvents on EventManager3D to true. // This will make EventManager3D subscribe to Preview... events (PreviewMouseMove instead of MouseMove) // and therefore EventManager3D will get the mouse events before they can be handled by the MouseCameraController. eventManager3D.UsePreviewEvents = true; // 5 x 3 boxes for (int x = 0; x < 5; x++) { for (int y = 0; y < 3; y++) { var boxVisual3D = new BoxVisual3D() { CenterPosition = new Point3D(-40 + x * 20, 5, -30 + y * 30), Size = new Size3D(10, 10, 10), Material = _standardBoxMaterial }; MainViewport.Children.Add(boxVisual3D); // Register mouse events on boxVisual3D RegisterMouseEventsOnBoxVisual(boxVisual3D, eventManager3D); } } MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Select Box"); }
protected Section3DChartBase() { border.Color = DefaultColor; Material material = new DiffuseMaterial { Brush = new SolidColorBrush(Color.FromArgb(0x7F, 0x4C, 0x88, 0xFF)) }; material.Freeze(); billboard.Material = material; billboard.BackMaterial = material; Children.Add(billboard); Children.Add(border); UpdateUI(); }
static GeometryModel3D createGeometryModel3D(Point3DCollection meshPositions, ImageSource sliceImage, Matrix genMatrix, PointCollection textureCoordinates) { MeshGeometry3D meshGeometry = new MeshGeometry3D(); meshGeometry.Positions = meshPositions; GeometryModel3D sliceGeometryModel = new GeometryModel3D(); sliceGeometryModel.Geometry = meshGeometry; meshGeometry.TextureCoordinates = textureCoordinates; ImageBrush imageBrushTransformed = new ImageBrush(sliceImage); imageBrushTransformed.RelativeTransform = new MatrixTransform(genMatrix); DiffuseMaterial imageMaterial = new DiffuseMaterial(imageBrushTransformed); imageMaterial.Freeze(); sliceGeometryModel.BackMaterial = imageMaterial; meshGeometry.Freeze(); sliceGeometryModel.Freeze(); return(sliceGeometryModel); }
public void SetCard(SetCard card) { if (m_card != card) { m_card = card; if (m_card != null) { Drawing drawing = SetCardDrawingFactory.GetFullCardDrawing(m_card); DrawingBrush brush = new DrawingBrush(drawing); DiffuseMaterial material = new DiffuseMaterial(brush); material.Freeze(); m_geometry.Material = material; } else { m_geometry.Material = new DiffuseMaterial(Brushes.Transparent); } } }
private void UpdateUI() { Children.Clear(); var grid = GridSource; if (grid == null) { return; } double sphereRadius = SphereRadius; Material sphereMaterial = new DiffuseMaterial(Brushes.Cyan); sphereMaterial.Freeze(); for (int k = 0; k < grid.Depth; k++) { int kLocal = k; Dispatcher.BeginInvoke(() => { for (int i = 0; i < grid.Width; i++) { for (int j = 0; j < grid.Height; j++) { Point3D position = grid.Grid[i, j, kLocal]; Sphere sphere = new Sphere { Radius = sphereRadius, Center = position, Material = sphereMaterial, Slices = 4, Stacks = 2 }; Children.Add(sphere); } } }, DispatcherPriority.Background); } }
public void LoadTileImageAsync(MapTileVisual tile, int x, int y, int zoom) { Task.Run(() => { ImageSource image = TileService.GetTileImage(zoom, x, y); ImageBrush imageBrush = new ImageBrush(); DiffuseMaterial material = new DiffuseMaterial(); material.Brush = imageBrush; imageBrush.ImageSource = image; imageBrush.Freeze(); material.Freeze(); //var foo = ImageWpfToGDI(image); // We've already set the Source to null before calling this method. if (image != null && imageBrush != null) { tile.Dispatcher.Invoke(() => { tile.Material = material; }); } }); }
///<summary>生成3D模型</summary> public void genModel() { //数据初始化 //定义参数 double maxX3D = parent.para.Limit.X, maxY3D = parent.para.Limit.Y, maxZ3D = parent.para.Limit.Z; // 3D场景最大坐标 int xcount = 12, zcount = 24, xcountData, zcountData = 25; // x y 方向数目,x为月数,z为小时数,其中,xcount表征月分,xcountData为数据的x方向个数 //zcount为0-23点,但zcountData为0-24点,多一个数据,同理,xcount中,增加一个数,全年下为12.31日 xcountData = samplePoints.GroupBy(p => p.zDate.Date).Count(); MeshGeometry3D mesh = new MeshGeometry3D(); double devx = maxX3D / (xcount), devy = maxY3D / parent.maxYValue, devz = maxZ3D / (zcount); allpoint = new Point3D[xcountData, zcountData]; double tx, tz; int di, dj; di = 0; DateTime olddate = samplePoints.OrderBy(p => p.zDate).First().zDate.Date; foreach (var e in samplePoints.OrderBy(p => p.zDate)) { //di = e.zDate.Month - 1; if (e.zDate.Date != olddate) { di++; olddate = e.zDate.Date; } dj = e.zDate.Hour; allpoint[di, dj] = new Point3D((double)((e.zDate - parent.startDate).TotalDays - 1) / ((parent.endDate - parent.startDate).TotalDays - 1) * maxX3D, devy * (double)e.zValue, -devz * dj); if (dj == 0) //赋第24点,以本日0代替 { allpoint[di, zcountData - 1] = new Point3D((double)((e.zDate - parent.startDate).TotalDays - 1) / ((parent.endDate - parent.startDate).TotalDays - 1) * maxX3D, devy * (double)e.zValue, -devz * (zcountData - 1)); } } allpoint = insertZPoint(allpoint, 2); //z插点 allpoint = insertXPoint(allpoint, 2); //x插点 for (int i = 0; i < allpoint.GetLength(0); i++) //加positions { for (int j = 0; j < allpoint.GetLength(1); j++) { mesh.Positions.Add(allpoint[i, j]); tx = 1.0 * i / allpoint.GetLength(0); tz = 1.0 * j / allpoint.GetLength(1); mesh.TextureCoordinates.Add(new Point(tx, tz)); } } for (int i = 0; i < allpoint.GetLength(0) - 1; i++) // 加三角索引 { for (int j = 0; j < allpoint.GetLength(1) - 1; j++) { mesh.TriangleIndices.Add(j + i * allpoint.GetLength(1)); mesh.TriangleIndices.Add(j + (i + 1) * allpoint.GetLength(1)); mesh.TriangleIndices.Add(j + 1 + i * allpoint.GetLength(1)); mesh.TriangleIndices.Add(j + 1 + i * allpoint.GetLength(1)); mesh.TriangleIndices.Add(j + (i + 1) * allpoint.GetLength(1)); mesh.TriangleIndices.Add(j + 1 + (i + 1) * allpoint.GetLength(1)); } } //=============== 曲面材质 Canvas panelLine = new Canvas(); panelLine.Width = devx * (parent.endDate - parent.startDate).TotalDays; panelLine.Height = devz * 23 * 30; //色变化说明:最高255,0,0最低0,255,0;从低到高变化顺序1:R 0->255,2:G 255->0; double x, y, maxy = 10, miny = 0, maxh = panelLine.Height, maxw = panelLine.Width; double w = maxw / (allpoint.GetLength(0) - 1), h = maxh / (allpoint.GetLength(1) - 1); double v; Color c1, c2; byte cr, cg, cb = 0; maxy = 0; miny = 10000; for (int i = 0; i < allpoint.GetLength(0) - 1; i++) { for (int j = 0; j < allpoint.GetLength(1) - 1; j++) { if (allpoint[i, j].Y > maxy) { maxy = allpoint[i, j].Y; } if (allpoint[i, j].Y < miny) { miny = allpoint[i, j].Y; } } } Point3D lastpoint = allpoint[allpoint.GetLength(0) - 1, allpoint.GetLength(1) - 1]; for (int i = 0; i < allpoint.GetLength(0) - 1; i++) { for (int j = 0; j < allpoint.GetLength(1) - 1; j++) { x = allpoint[i, j].X / lastpoint.X * maxw; y = allpoint[i, j].Z / lastpoint.Z * maxh; w = (allpoint[i + 1, j].X - allpoint[i, j].X) / lastpoint.X * maxw; double temp = 1;// .2;//新疆怪需求,人为加大最大值,以避免纯红 v = (allpoint[i, j].Y - miny) / (maxy * temp - miny) * 511; cr = v > 255 ? (byte)255 : (byte)v; cg = v > 255 ? (byte)(255 - (v - 256)) : (byte)255; c1 = Color.FromRgb(cr, cg, cb); v = (allpoint[i + 1, j + 1].Y - miny) / (maxy * temp - miny) * 511; cr = v > 255 ? (byte)255 : (byte)v; cg = v > 255 ? (byte)(255 - (v - 256)) : (byte)255; c2 = Color.FromRgb(cr, cg, cb); RectangleGeometry rect = new RectangleGeometry(new Rect(x, y, w, h)); rect.Freeze(); Path pr = new Path(); pr.Data = rect; LinearGradientBrush cbrush = new LinearGradientBrush(c1, c2, new Point(0, 0), new Point(1, 1)); pr.Fill = cbrush; pr.StrokeThickness = 0; panelLine.Children.Add(pr); } } panelLine.Measure(new System.Windows.Size(h, w)); panelLine.Arrange(new Rect(0, 0, h, w)); System.Windows.Media.Imaging.RenderTargetBitmap renderTarget = new System.Windows.Media.Imaging.RenderTargetBitmap((int)panelLine.Width, (int)panelLine.Height, 96, 96, PixelFormats.Pbgra32); renderTarget.Render(panelLine); renderTarget.Freeze(); curveBrush = new ImageBrush(renderTarget); DiffuseMaterial mat = new DiffuseMaterial(curveBrush); mat.Freeze(); model = new GeometryModel3D(mesh, mat); model.BackMaterial = mat; }
internal static GeometryModel3D MakeLine3D(Vector3D start, Vector3D end, Brush brush, double scale = 0.01) { MeshGeometry3D mesh = new MeshGeometry3D(); var length = (end - start).Length; var positions = new List <Point3D>(); positions.Add(new Point3D(-scale, +scale, 0)); positions.Add(new Point3D(-scale, +scale, +length)); positions.Add(new Point3D(+scale, +scale, +length)); positions.Add(new Point3D(+scale, +scale, 0)); positions.Add(new Point3D(-scale, -scale, 0)); positions.Add(new Point3D(-scale, -scale, +length)); positions.Add(new Point3D(+scale, -scale, +length)); positions.Add(new Point3D(+scale, -scale, 0)); var segment = end - start; var defaultAxis = new Vector3D(0, 0, length); var rot = Vector3D.AngleBetween(defaultAxis, segment); var rotAxis = Vector3D.CrossProduct(defaultAxis.NormalizeTo(), segment.NormalizeTo()); var matRot = new Matrix3D(); if (rotAxis.Length > 0.0) { matRot.Rotate(new Quaternion(rotAxis, rot)); } foreach (var pos in positions) { mesh.Positions.Add(matRot.Transform(pos) + start); } // top mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(1); // bottom mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(5); // left mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(1); // right mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(2); mesh.Freeze(); var diffuse = new DiffuseMaterial(Brushes.Black); var emissive = new EmissiveMaterial(brush); diffuse.Freeze(); emissive.Freeze(); var material = new MaterialGroup(); material.Children.Add(diffuse); material.Children.Add(emissive); material.Freeze(); return(new GeometryModel3D(mesh, material) { BackMaterial = material }); }
public void CreateScene(bool createExtremlyComplexScene) { // This is called in background thread var rootVisual3D = new ModelVisual3D(); var floorBox = new BoxVisual3D() { CenterPosition = new Point3D(0, -0.05, 0), Size = new Size3D(15, 0.1, 15), Material = new DiffuseMaterial(Brushes.Green) }; rootVisual3D.Children.Add(floorBox); double centerX = 0; double centerZ = 0; double boxesHeight = 1.4; double bigCircleRadius = 2; double singleSphereRadius = 0.1; int circleElementsCount; double spheresStartRadius; double spheresEndRadius; int yObjectsCount; if (createExtremlyComplexScene) { // This will create a 3D scene with almost 6000 3D objects // This will put a big load on GPU and especially on the CPU (the DirectX API and driver). // // NOTE: // When rendering many instances of the same object, it is possible to render the same scene // much much more efficiently with using InstancedMeshGeometryVisual3D. boxesHeight = 3; circleElementsCount = 40; spheresStartRadius = bigCircleRadius * 0.3; spheresEndRadius = bigCircleRadius; yObjectsCount = 30; } else { boxesHeight = 1.4; circleElementsCount = 18; spheresStartRadius = bigCircleRadius; spheresEndRadius = bigCircleRadius; yObjectsCount = 1; } var boxMaterial = new DiffuseMaterial(Brushes.Gray); var sphereMaterial = new MaterialGroup(); sphereMaterial.Children.Add(new DiffuseMaterial(Brushes.Gold)); sphereMaterial.Children.Add(new SpecularMaterial(Brushes.White, 16)); // IMPORTANT: // Freezing materials speeds up object creation by a many times !!! boxMaterial.Freeze(); sphereMaterial.Freeze(); for (int y = 0; y < yObjectsCount; y++) { double oneBoxHeight; double oneBoxHeightSpace = boxesHeight / yObjectsCount; if (yObjectsCount == 1) { oneBoxHeight = oneBoxHeightSpace; } else { oneBoxHeight = oneBoxHeightSpace * 0.7; } for (int a = 0; a < 360; a += (int)(Math.Ceiling(360.0 / circleElementsCount))) { double rad = SharpDX.MathUtil.DegreesToRadians(a); double sin = Math.Sin(rad); double cos = Math.Cos(rad); double x = sin * bigCircleRadius + centerX; double z = cos * bigCircleRadius + centerZ; var boxVisual3D = new BoxVisual3D() { CenterPosition = new Point3D(x, (y + 0.5) * oneBoxHeightSpace, z), Size = new Size3D(0.2, oneBoxHeight, 0.2), Material = boxMaterial }; rootVisual3D.Children.Add(boxVisual3D); for (double radius = spheresStartRadius; radius <= spheresEndRadius; radius += singleSphereRadius * 2) { x = sin * radius + centerX; z = cos * radius + centerZ; var sphereVisual3D = new SphereVisual3D() { CenterPosition = new Point3D(x, boxesHeight + singleSphereRadius * (y + 0.5) * 2, z), Radius = singleSphereRadius, Material = sphereMaterial }; rootVisual3D.Children.Add(sphereVisual3D); } } } wpfViewport3D.Children.Clear(); wpfViewport3D.Children.Add(rootVisual3D); // Add lights var lightsVisual3D = new ModelVisual3D(); var lightsGroup = new Model3DGroup(); var directionalLight = new DirectionalLight(Colors.White, new Vector3D(1, -0.3, 0)); lightsGroup.Children.Add(directionalLight); var ambientLight = new AmbientLight(System.Windows.Media.Color.FromRgb(60, 60, 60)); lightsGroup.Children.Add(ambientLight); lightsVisual3D.Content = lightsGroup; wpfViewport3D.Children.Add(lightsVisual3D); if (_targetPositionCamera != null) { if (createExtremlyComplexScene) { _targetPositionCamera.TargetPosition = new Point3D(0, 2, 0); _targetPositionCamera.Attitude = -30; _targetPositionCamera.Distance = 15; } else { _targetPositionCamera.TargetPosition = new Point3D(0, 0.5, 0); _targetPositionCamera.Attitude = -10; _targetPositionCamera.Distance = 8; } } isSceneDirty = true; }
private void OnBackgroundDoWork(object sender, DoWorkEventArgs e) { PointCloudTileSource tileSource = e.Argument as PointCloudTileSource; Jacere.Core.Geometry.Extent3D extent = tileSource.Extent; m_overviewTextureBrush = new ImageBrush(tileSource.Preview.Image); m_overviewTextureBrush.ViewportUnits = BrushMappingMode.Absolute; m_overviewTextureBrush.Freeze(); m_overviewMaterial = new DiffuseMaterial(m_overviewTextureBrush); m_overviewMaterial.Freeze(); if (tileSource != null) { previewImageGrid.MouseMove -= OnViewportGridMouseMove; Action <string> logAction = value => Context.WriteLine(value); m_progressManager = new BackgroundWorkerProgressManager(m_backgroundWorker, e, logAction, null); m_gridDimensionLowRes = (ushort)Math.Sqrt(VERTEX_COUNT_FAST / tileSource.TileSet.ValidTileCount); //m_gridDimensionHighRes = (ushort)Math.Sqrt(VERTEX_COUNT_LARGE / tileSource.TileSet.ValidTileCount); m_gridDimensionHighRes = (ushort)(Math.Sqrt(tileSource.TileSet.Density.MedianTileCount) / 3); //m_gridDimensionLowRes = (ushort)20; //m_gridDimensionHighRes = (ushort)40; Jacere.Core.Geometry.Point3D centerOfMass = tileSource.CenterOfMass; m_overallCenteredExtent = new Rect3D(extent.MinX - extent.MidpointX, extent.MinY - extent.MidpointY, extent.MinZ - centerOfMass.Z, extent.RangeX, extent.RangeY, extent.RangeZ); // load tiles KeyValuePair <Grid <int>, Grid <float> > gridsLowRes = tileSource.GenerateGrid(m_gridDimensionLowRes); m_gridLowRes = gridsLowRes.Value; m_quantizedGridLowRes = gridsLowRes.Key; KeyValuePair <Grid <int>, Grid <float> > gridsHighRes = tileSource.GenerateGrid(m_gridDimensionHighRes); m_gridHighRes = gridsHighRes.Value; m_quantizedGridHighRes = gridsHighRes.Key; foreach (PointCloudTile tile in tileSource.TileSet) { tileSource.LoadTileGrid(tile, m_buffer, m_gridLowRes, m_quantizedGridLowRes); if (ENABLE_HEIGHT_EXAGGERATION) { m_gridLowRes.Multiply(m_heightExaggerationFactor, (float)centerOfMass.Z); } Jacere.Core.Geometry.Extent3D tileExtent = tile.Extent; MeshGeometry3D mesh = tileSource.GenerateMesh(m_gridLowRes, tileExtent); DiffuseMaterial material = new DiffuseMaterial(); if (USE_LOW_RES_TEXTURE) { material.Brush = m_overviewTextureBrush; mesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(mesh, m_overallCenteredExtent, MathUtils.ZAxis); } else { material.Brush = m_solidBrush; } material.Freeze(); GeometryModel3D geometryModel = new GeometryModel3D(mesh, material); geometryModel.Freeze(); TileInfo3D tileInfo = new TileInfo3D(tile, geometryModel, m_gridLowRes); m_tileInfo.Add(tile, tileInfo); // add mappings m_meshTileMap.Add(geometryModel, tile); //m_lowResMap.Add(tile, geometryModel); if (!m_progressManager.Update(tile, geometryModel)) { break; } } //// test //foreach (double level in new double[] { centerOfMass.Z }) //{ // Grid<float> grid0 = new Grid<float>(20, 20, extent, false); // grid0.FillVal = (float)level; // grid0.Reset(); // grid0.FillVal = float.MinValue; // MeshGeometry3D mesh0 = tileSource.GenerateMesh(grid0, extent); // DiffuseMaterial material0 = new DiffuseMaterial(m_solidBrush); // material0.Freeze(); // GeometryModel3D geometryModel0 = new GeometryModel3D(mesh0, material0); // geometryModel0.Freeze(); // m_progressManager.Update(1.0f, geometryModel0); //} if (ENABLE_STITCHING) { int validStitchingIndex = 0; foreach (PointCloudTile tile in tileSource.TileSet) { TileInfo3D tileInfo = m_tileInfo[tile]; Model3DGroup stitchingGroup = GenerateTileStitching(tileSource, tileInfo); if (stitchingGroup != null) { ++validStitchingIndex; } if (!m_progressManager.Update(1.0f, stitchingGroup)) { break; } } } } }
private void UpdateCurrentTile(PointCloudTile tile) { if (tile == null) { return; } List <PointCloudTile> tilesToLoad = new List <PointCloudTile>(); int pointsToLoad = 0; Model3DGroup emptyModelGroup = new Model3DGroup(); emptyModelGroup.Freeze(); bool isDirty = false; int radius = 2; int xMin = Math.Max(0, tile.Col - radius); int xMax = Math.Min(tile.Col + radius + 1, CurrentTileSource.TileSet.Cols); int yMin = Math.Max(0, tile.Row - radius); int yMax = Math.Min(tile.Row + radius + 1, CurrentTileSource.TileSet.Rows); for (int x = xMin; x < xMax; x++) { for (int y = yMin; y < yMax; y++) { PointCloudTile currentTile = CurrentTileSource.TileSet.GetTile(y, x); if (currentTile != null) { if (!m_loadedTiles.ContainsKey(currentTile)) { tilesToLoad.Add(currentTile); pointsToLoad += currentTile.PointCount; isDirty = true; } } } } PointCloudTile[] loadedTiles = m_loadedTiles.Keys.ToArray(); SortByDistanceFromTile(loadedTiles, tile); Array.Reverse(loadedTiles); // drop loaded tiles that are the farthest from the center int totalAllowedPoints = MAX_BUFFER_SIZE_BYTES / CurrentTileSource.PointSizeBytes; int loadedPoints = loadedTiles.Sum(t => t.PointCount); int potentialTotalPoints = loadedPoints + pointsToLoad; Dictionary <PointCloudTile, TileInfo3D> alteredTiles = new Dictionary <PointCloudTile, TileInfo3D>(); if (potentialTotalPoints > totalAllowedPoints) { int pointsToDrop = potentialTotalPoints - totalAllowedPoints; int i = 0; while (pointsToDrop > 0) { PointCloudTile currentTile = loadedTiles[i]; TileInfo3D tileInfo = m_tileInfo[currentTile]; GeometryModel3D model = m_loadedTiles[currentTile]; m_meshTileMap.Remove(model); m_loadedTiles.Remove(currentTile); //m_loadedTileBuffers.Remove(currentTile); // replace high-res tile with low-res geometry int modelIndex = tileInfo.Tile.ValidIndex; m_tileModelCollection[modelIndex] = tileInfo.LowResGeometry; // clear stitching m_stitchingModelCollection[modelIndex] = emptyModelGroup; tileInfo.ClearGeometry(); alteredTiles.Add(currentTile, tileInfo); pointsToDrop -= currentTile.PointCount; ++i; } } Jacere.Core.Geometry.Point3D centerOfMass = CurrentTileSource.CenterOfMass; PointCloudTile[] tilesToLoadArray = tilesToLoad.ToArray(); #warning sort so that disk reads are in order? or make a tile cache SortByDistanceFromTile(tilesToLoadArray, tile); foreach (PointCloudTile currentTile in tilesToLoadArray) { TileInfo3D tileInfo = m_tileInfo[currentTile]; CurrentTileSource.LoadTileGrid(currentTile, m_buffer, m_gridHighRes, m_quantizedGridHighRes); if (ENABLE_HEIGHT_EXAGGERATION) { m_gridHighRes.Multiply(m_heightExaggerationFactor, (float)centerOfMass.Z); } Jacere.Core.Geometry.Extent3D tileExtent = currentTile.Extent; MeshGeometry3D mesh = CurrentTileSource.GenerateMesh(m_gridHighRes, tileExtent); DiffuseMaterial material = new DiffuseMaterial(); if (USE_HIGH_RES_TEXTURE) { material.Brush = m_overviewTextureBrush; mesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(mesh, m_overallCenteredExtent, MathUtils.ZAxis); } else { material.Brush = m_solidBrush; } material.Freeze(); GeometryModel3D geometryModel = new GeometryModel3D(mesh, material); geometryModel.Freeze(); // replace low-res tile with high-res geometry int modelIndex = tileInfo.Tile.ValidIndex; m_tileModelCollection[modelIndex] = geometryModel; // clear stitching m_stitchingModelCollection[modelIndex] = emptyModelGroup; tileInfo.UpdateGeometry(geometryModel, m_gridHighRes); alteredTiles.Add(currentTile, tileInfo); m_meshTileMap.Add(geometryModel, currentTile); m_loadedTiles.Add(currentTile, geometryModel); //m_loadedTileBuffers.Add(currentTile, inputBuffer); } // in the future, I could have a list of which tiles need to be checked for stitching updates // go through the stitching groups and replace any empty ones with the appropriate stitching if (ENABLE_STITCHING && isDirty) { PointCloudTile[] alteredTileArray = alteredTiles.Keys.ToArray(); foreach (PointCloudTile currentTile in alteredTileArray) { // this amount of clearing is excessive. I only want to clear one of the edges if (currentTile.Col < CurrentTileSource.TileSet.Cols - 1) { PointCloudTile adjacentTile = CurrentTileSource.TileSet.GetTile(currentTile.Row, currentTile.Col + 1); if (adjacentTile != null && m_tileInfo.ContainsKey(adjacentTile)) { TileInfo3D adjacentTileInfo = m_tileInfo[adjacentTile]; if (!alteredTiles.ContainsKey(adjacentTile)) { alteredTiles.Add(adjacentTile, adjacentTileInfo); } m_stitchingModelCollection[adjacentTileInfo.Tile.ValidIndex] = emptyModelGroup; adjacentTileInfo.UpdateStitching(null, null, TileStitchingEdge.Left); } } if (currentTile.Row < CurrentTileSource.TileSet.Rows - 1) { PointCloudTile adjacentTile = CurrentTileSource.TileSet.GetTile(currentTile.Row + 1, currentTile.Col); if (adjacentTile != null && m_tileInfo.ContainsKey(adjacentTile)) { TileInfo3D adjacentTileInfo = m_tileInfo[adjacentTile]; if (!alteredTiles.ContainsKey(adjacentTile)) { alteredTiles.Add(adjacentTile, adjacentTileInfo); } m_stitchingModelCollection[adjacentTileInfo.Tile.ValidIndex] = emptyModelGroup; adjacentTileInfo.UpdateStitching(null, null, TileStitchingEdge.Top); } } if (currentTile.Col < CurrentTileSource.TileSet.Cols - 1 && currentTile.Row < CurrentTileSource.TileSet.Rows - 1) { PointCloudTile adjacentTile = CurrentTileSource.TileSet.GetTile(currentTile.Row + 1, currentTile.Col + 1); if (adjacentTile != null && m_tileInfo.ContainsKey(adjacentTile)) { TileInfo3D adjacentTileInfo = m_tileInfo[adjacentTile]; if (!alteredTiles.ContainsKey(adjacentTile)) { alteredTiles.Add(adjacentTile, adjacentTileInfo); } m_stitchingModelCollection[adjacentTileInfo.Tile.ValidIndex] = emptyModelGroup; adjacentTileInfo.UpdateStitching(null, null, TileStitchingEdge.TopLeft); } } } foreach (KeyValuePair <PointCloudTile, TileInfo3D> kvp in alteredTiles) { int i = kvp.Value.Tile.ValidIndex; Model3DGroup stitchingGroup = m_stitchingModelCollection[i] as Model3DGroup; if (stitchingGroup.Children.Count == 0) { GeometryModel3D geometryModel = m_tileModelCollection[i] as GeometryModel3D; Model3DGroup newStitchingGroup = GenerateTileStitching(CurrentTileSource, kvp.Value); if (newStitchingGroup.Children.Count > 0) { m_stitchingModelCollection[i] = newStitchingGroup; } } } //for (int i = 0; i < m_stitchingModelCollection.Count; i++) //{ // Model3DGroup stitchingGroup = m_stitchingModelCollection[i] as Model3DGroup; // // this is an incorrect condition, but it won't be apparent until I get multi-res stitching // if (stitchingGroup.Children.Count < 3) // { // GeometryModel3D geometryModel = m_tileModelCollection[i] as GeometryModel3D; // PointCloudTile currentTile = m_meshTileMap[geometryModel]; // TileInfo3D currentTileInfo = m_tileInfo[currentTile]; // Model3DGroup newStitchingGroup = GenerateTileStitching(CurrentTileSource, currentTileInfo); // if (newStitchingGroup.Children.Count > 0) // m_stitchingModelCollection[i] = newStitchingGroup; // } //} } }
private Model3D ConvertVisualToModel3D(Visual visual, ref double z) { Model3D model = null; Rect bounds = VisualTreeHelper.GetContentBounds(visual); Viewport3D viewport = visual as Viewport3D; if (viewport != null) { bounds = new Rect(viewport.RenderSize); } if (this.includeEmptyVisuals) { bounds.Union(VisualTreeHelper.GetDescendantBounds(visual)); } if (!bounds.IsEmpty && bounds.Width > 0 && bounds.Height > 0) { MeshGeometry3D 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.Freeze(); Brush brush = this.MakeBrushFromVisual(visual, bounds); DiffuseMaterial material = new DiffuseMaterial(brush); material.Freeze(); model = new GeometryModel3D(mesh, material); ((GeometryModel3D)model).BackMaterial = material; z -= 1; } int childrenCount = VisualTreeHelper.GetChildrenCount(visual); if (childrenCount > 0) { Model3DGroup group = new Model3DGroup(); if (model != null) { group.Children.Add(model); } for (int i = 0; i < childrenCount; i++) { Visual childVisual = VisualTreeHelper.GetChild(visual, i) as Visual; if (childVisual != null) { Model3D childModel = this.ConvertVisualToModel3D(childVisual, ref z); if (childModel != null) { group.Children.Add(childModel); } } } model = group; } if (model != null) { Transform transform = VisualTreeHelper.GetTransform(visual); Matrix matrix = (transform == null ? Matrix.Identity : transform.Value); Vector offset = VisualTreeHelper.GetOffset(visual); matrix.Translate(offset.X, offset.Y); if (!matrix.IsIdentity) { Matrix3D 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.Freeze(); model.Transform = transform3D; } model.Freeze(); } return(model); }
private GeometryModel3D createSingleImageMesh(Point3D[,] slicedGrid, int dim, Matrix genMatrix, Color borderColor, ImageSource image, BitmapSource blankImage) { try { ImageSource sliceImage = image; Rect sliceImageRect = new Rect(0, 0, sliceImage.Width, sliceImage.Height); DrawingGroup dg = new DrawingGroup(); if (blankImage != null) { dg.Children.Add(new ImageDrawing(blankImage, sliceImageRect)); } dg.Children.Add(new ImageDrawing(sliceImage, sliceImageRect)); RectangleGeometry rGeometry = new RectangleGeometry(sliceImageRect); dg.Children.Add(new GeometryDrawing(null, new Pen(new SolidColorBrush(borderColor), 1), rGeometry)); dg.ClipGeometry = new RectangleGeometry(sliceImageRect); if (dim == 0) { if (CurrentShape != null && CurrentShape.PathPoints != null) { GeometryDrawing gd; if (CurrentShape.PathPoints.Count > 0) { gd = DrawRegion(CurrentShape); } else { gd = null; } if (gd != null) { dg.Children.Add(gd); } } } sliceImage = new DrawingImage(dg); Point3D p0 = slicedGrid[dim, 0]; Point3D p1 = slicedGrid[dim, 1]; Point3D p2 = slicedGrid[dim, 2]; Point3D p3 = slicedGrid[dim, 3]; Point3DCollection positionsFront = new Point3DCollection() { p0, p1, p3, p3, p1, p2 }; MeshGeometry3D meshGeometry3DFront = new MeshGeometry3D(); meshGeometry3DFront.Positions = positionsFront; GeometryModel3D sliceGeometryModelFront = new GeometryModel3D(); sliceGeometryModelFront.Geometry = meshGeometry3DFront; meshGeometry3DFront.TextureCoordinates = texturePointsFront; ImageBrush imageBrushTransformed = new ImageBrush(sliceImage); imageBrushTransformed.RelativeTransform = new MatrixTransform(genMatrix); DiffuseMaterial imageMaterial = new DiffuseMaterial(imageBrushTransformed); imageMaterial.Freeze(); sliceGeometryModelFront.Material = imageMaterial; sliceGeometryModelFront.BackMaterial = imageMaterial; meshGeometry3DFront.Freeze(); sliceGeometryModelFront.Freeze(); return(sliceGeometryModelFront); } catch { return(null); } }