private static Visual3D MakeModelVisual3D(VoxelizedSolid vs) { var positions = new Point3DCollection(); var normals = new Vector3DCollection(); var s = vs.VoxelSideLength; for (var i = 0; i < vs.numVoxelsX; i++) { for (var j = 0; j < vs.numVoxelsY; j++) { for (var k = 0; k < vs.numVoxelsZ; k++) { if (!vs[i, j, k]) { continue; } var neighbors = vs.GetNeighbors(i, j, k).ToList(); if (neighbors.All(n => n != null)) { continue; } var x = i * s + vs.Offset[0]; var y = j * s + vs.Offset[1]; var z = k * s + vs.Offset[2]; for (var m = 0; m < 12; m++) { if (neighbors[m / 2] != null) { continue; } for (var n = 0; n < 3; n++) { positions.Add(new Point3D(x + coordOffsets[m][n][0] * s, y + coordOffsets[m][n][1] * s, z + coordOffsets[m][n][2] * s)); normals.Add(new Vector3D(normalsTemplate[m][0], normalsTemplate[m][1], normalsTemplate[m][2])); } } } } } return(new ModelVisual3D { Content = new GeometryModel3D { Geometry = new MeshGeometry3D { Positions = positions, Normals = normals }, Material = MaterialHelper.CreateMaterial( new System.Windows.Media.Color { A = 255, //vs.SolidColor.A, B = vs.SolidColor.B, G = vs.SolidColor.G, R = vs.SolidColor.R }) } }); }
protected virtual void PropertyChanged(DependencyPropertyChangedEventArgs args) { Point3DCollection vertices; Vector3DCollection normals; Int32Collection indices; PointCollection textures; if (!IsWireFrame || args.Property == IsWireFrameProperty && !(bool)args.OldValue) { // Obtain the MeshGeometry3D. MeshGeometry3D mesh = Geometry; // Get all four collectiona. vertices = mesh.Positions; normals = mesh.Normals; indices = mesh.TriangleIndices; textures = mesh.TextureCoordinates; // Set the MeshGeometry3D collections to null while updating. mesh.Positions = null; mesh.Normals = null; mesh.TriangleIndices = null; mesh.TextureCoordinates = null; } else { // Get properties from WireFrame object vertices = wireframe.Positions; normals = wireframe.Normals; indices = wireframe.TriangleIndices; textures = wireframe.TextureCoordinates; wireframe.Positions = null; wireframe.Normals = null; wireframe.TriangleIndices = null; wireframe.TextureCoordinates = null; } // If args.Property not IsWireFrame OR Algorithmic transforms if (args.Property != AlgorithmicTransformsProperty && args.Property != IsWireFrameProperty) { // Call the abstract method to fill the collections. Triangulate(args, vertices, normals, indices, textures); // Transfer vertices and normals to internal collections. verticesPreTransform.Clear(); normalsPreTransform.Clear(); foreach (Point3D vertex in vertices) { verticesPreTransform.Add(vertex); } foreach (Vector3D normal in normals) { normalsPreTransform.Add(normal); } } if (args.Property == AlgorithmicTransformsProperty) { vertices.Clear(); normals.Clear(); normalsAsPoints.Clear(); // Transfer saved vertices and normals. foreach (Point3D vertex in verticesPreTransform) { vertices.Add(vertex); } foreach (Vector3D normal in normalsPreTransform) { normalsAsPoints.Add((Point3D)normal); } } if (args.Property != IsWireFrameProperty) { foreach (AlgorithmicTransform xform in AlgorithmicTransforms) { xform.Transform(vertices); xform.Transform(normalsAsPoints); } foreach (Point3D point in normalsAsPoints) { normals.Add((Vector3D)point); } } if (IsWireFrame) { // Set stuff to WireFrame object, and create it if necessary if (wireframe == null) { wireframe = new WireFrame(); Children.Add(wireframe); // do we want to remove it when it's no longer used? } wireframe.TextureCoordinates = textures; wireframe.TriangleIndices = indices; wireframe.Normals = normals; wireframe.Positions = vertices; } else { // Obtain the MeshGeometry3D. MeshGeometry3D mesh = Geometry; // Set the updated collections to the MeshGeometry3D. mesh.TextureCoordinates = textures; mesh.TriangleIndices = indices; mesh.Normals = normals; mesh.Positions = vertices; } }
private void CreateSurface() { if (this.Points != null && this.TextureBuilder != null) { Material texture = this.TextureBuilder.CreateTexture(); int xWidth = this.Points.GetLength(0); int yWidth = this.Points.GetLength(1); int capacity = (xWidth - 1) * (yWidth - 1); Point3DCollection positions = new Point3DCollection(capacity); Int32Collection indices = new Int32Collection(capacity); PointCollection texCoords = new PointCollection(capacity); Vector3DCollection normals = new Vector3DCollection(capacity); int indiceCount = 0; for (int ix = 0; ix < xWidth - 1; ix++) { if (!double.IsNaN(this.Points[ix, 0].Z)) { if (!double.IsNaN(this.Points[ix + 1, 0].Z)) { for (int iy = 0; iy < yWidth - 1; iy++) { // V0-----V3 // | | // | | // V1-----V2 //Add Triangle V0--V1--V2 positions.Add(this.Points[ix, iy]); positions.Add(this.Points[ix + 1, iy]); positions.Add(this.Points[ix + 1, iy + 1]); double middleZ = (this.Points[ix, iy].Z + this.Points[ix + 1, iy].Z + this.Points[ix + 1, iy + 1].Z + this.Points[ix, iy + 1].Z) / 4.0; Point texturePt = this.TextureBuilder.GetTextureMapping(middleZ); texCoords.Add(texturePt); texCoords.Add(texturePt); texCoords.Add(texturePt); indices.Add(indiceCount++); indices.Add(indiceCount++); indices.Add(indiceCount++); Vector3D normal = MathHelper.CalculateNormal(this.Points[ix + 1, iy + 1], this.Points[ix + 1, iy], this.Points[ix, iy]); normals.Add(normal); normals.Add(normal); normals.Add(normal); //Add Triangle V2--V3-V0 positions.Add(this.Points[ix + 1, iy + 1]); positions.Add(this.Points[ix, iy + 1]); positions.Add(this.Points[ix, iy]); texCoords.Add(texturePt); texCoords.Add(texturePt); texCoords.Add(texturePt); indices.Add(indiceCount++); indices.Add(indiceCount++); indices.Add(indiceCount++); Vector3D normal2 = MathHelper.CalculateNormal(this.Points[ix, iy], this.Points[ix, iy + 1], this.Points[ix + 1, iy + 1]); normals.Add(normal2); normals.Add(normal2); normals.Add(normal2); } } } } positions.Freeze(); _mesh.Positions = positions; indices.Freeze(); _mesh.TriangleIndices = indices; texCoords.Freeze(); _mesh.TextureCoordinates = texCoords; normals.Freeze(); _mesh.Normals = normals; _model3D.Material = texture; _model3D.BackMaterial = texture; } }
/*Применяет произвольное 3D-преобразование к изображению*/ public static void ApplyTransform(string input, string output, Matrix3D matr) { Viewport3D myViewport3D; BitmapImage image = new BitmapImage(new Uri(input)); // Declare scene objects. myViewport3D = new Viewport3D(); Model3DGroup myModel3DGroup = new Model3DGroup(); GeometryModel3D myGeometryModel = new GeometryModel3D(); ModelVisual3D myModelVisual3D = new ModelVisual3D(); // Defines the camera used to view the 3D object. In order to view the 3D object, // the camera must be positioned and pointed such that the object is within view // of the camera. PerspectiveCamera myPCamera = new PerspectiveCamera(); // Specify where in the 3D scene the camera is. myPCamera.Position = new Point3D(0, 0, Math.Max(image.PixelWidth, image.PixelHeight) * 2); // Specify the direction that the camera is pointing. myPCamera.LookDirection = new Vector3D(0, 0, -1); // Define camera's horizontal field of view in degrees. myPCamera.FieldOfView = 60; // Asign the camera to the viewport myViewport3D.Camera = myPCamera; // Define the lights cast in the scene. Without light, the 3D object cannot // be seen. Note: to illuminate an object from additional directions, create // additional lights. AmbientLight al = new AmbientLight(Colors.White); myModel3DGroup.Children.Add(al); // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet // is created. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); // Create a collection of normal vectors for the MeshGeometry3D. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myMeshGeometry3D.Normals = myNormalCollection; // Create a collection of vertex positions for the MeshGeometry3D. Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(-image.PixelWidth / 2.0, -image.PixelHeight / 2.0, 0.5)); myPositionCollection.Add(new Point3D(image.PixelWidth / 2.0, -image.PixelHeight / 2.0, 0.5)); myPositionCollection.Add(new Point3D(image.PixelWidth / 2.0, image.PixelHeight / 2.0, 0.5)); myPositionCollection.Add(new Point3D(image.PixelWidth / 2.0, image.PixelHeight / 2.0, 0.5)); myPositionCollection.Add(new Point3D(-image.PixelWidth / 2.0, image.PixelHeight / 2.0, 0.5)); myPositionCollection.Add(new Point3D(-image.PixelWidth / 2.0, -image.PixelHeight / 2.0, 0.5)); myMeshGeometry3D.Positions = myPositionCollection; // Create a collection of texture coordinates for the MeshGeometry3D. PointCollection myTextureCoordinatesCollection = new PointCollection(); Point p5 = new Point(0, 0); Point p34 = new Point(1, 0); Point p2 = new Point(1, 1); Point p16 = new Point(0, 1); myTextureCoordinatesCollection.Add(p16); myTextureCoordinatesCollection.Add(p2); myTextureCoordinatesCollection.Add(p34); myTextureCoordinatesCollection.Add(p34); myTextureCoordinatesCollection.Add(p5); myTextureCoordinatesCollection.Add(p16); myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection; // Create a collection of triangle indices for the MeshGeometry3D. Int32Collection myTriangleIndicesCollection = new Int32Collection(); myTriangleIndicesCollection.Add(0); myTriangleIndicesCollection.Add(1); myTriangleIndicesCollection.Add(2); myTriangleIndicesCollection.Add(3); myTriangleIndicesCollection.Add(4); myTriangleIndicesCollection.Add(5); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; // Apply the mesh to the geometry model. myGeometryModel.Geometry = myMeshGeometry3D; // The material specifies the material applied to the 3D object. ImageBrush br = new ImageBrush(image); // Define material and apply to the mesh geometries. DiffuseMaterial myMaterial = new DiffuseMaterial(br); myGeometryModel.Material = myMaterial; myGeometryModel.BackMaterial = myMaterial; MatrixTransform3D transform = new MatrixTransform3D(matr); myGeometryModel.Transform = transform; // Add the geometry model to the model group. myModel3DGroup.Children.Add(myGeometryModel); // Add the group of models to the ModelVisual3d. myModelVisual3D.Content = myModel3DGroup; myViewport3D.Children.Add(myModelVisual3D); //render Viewport3D into bitmap int width = image.PixelWidth; int height = image.PixelHeight; myViewport3D.Width = width; myViewport3D.Height = height; myViewport3D.Measure(new Size(width, height)); myViewport3D.Arrange(new Rect(0, 0, width, height)); RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); rtb.Render(myViewport3D); //Save bitmap to file using (var fileStream = new FileStream(output, FileMode.Create)) { BitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(rtb)); encoder.Save(fileStream); } }
/// <summary> /// /// </summary> /// <param name="args"></param> /// <param name="vertices"></param> /// <param name="normals"></param> /// <param name="indices"></param> /// <param name="textures"></param> protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { // Clear all four collections. vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); double x, y, z; int indexBase = 0; // Front side. // ----------- z = Depth / 2; // Fill the vertices, normals, textures collections. for (int stack = 0; stack <= Stacks; stack++) { y = Height / 2 - stack * Height / Stacks; for (int slice = 0; slice <= Slices; slice++) { x = -Width / 2 + slice * Width / Slices; Point3D point = new Point3D(x, y, z); vertices.Add(point); normals.Add(point - new Point3D(x, y, 0)); textures.Add(new Point((double)slice / Slices, (double)stack / Stacks)); } } // Fill the indices collection. for (int stack = 0; stack < Stacks; stack++) { for (int slice = 0; slice < Slices; slice++) { indices.Add((stack + 0) * (Slices + 1) + slice); indices.Add((stack + 1) * (Slices + 1) + slice); indices.Add((stack + 0) * (Slices + 1) + slice + 1); indices.Add((stack + 0) * (Slices + 1) + slice + 1); indices.Add((stack + 1) * (Slices + 1) + slice); indices.Add((stack + 1) * (Slices + 1) + slice + 1); } } // Rear side. // ----------- indexBase = vertices.Count; z = -Depth / 2; // Fill the vertices, normals, textures collections. for (int stack = 0; stack <= Stacks; stack++) { y = Height / 2 - stack * Height / Stacks; for (int slice = 0; slice <= Slices; slice++) { x = Width / 2 - slice * Width / Slices; Point3D point = new Point3D(x, y, z); vertices.Add(point); normals.Add(point - new Point3D(x, y, 0)); textures.Add(new Point((double)slice / Slices, (double)stack / Stacks)); } } // Fill the indices collection. for (int stack = 0; stack < Stacks; stack++) { for (int slice = 0; slice < Slices; slice++) { indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice); indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice); indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice + 1); indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice + 1); indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice); indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice + 1); } } // Left side. // ----------- indexBase = vertices.Count; x = -Width / 2; // Fill the vertices, normals, textures collections. for (int stack = 0; stack <= Stacks; stack++) { y = Height / 2 - stack * Height / Stacks; for (int layer = 0; layer <= Layers; layer++) { z = -Depth / 2 + layer * Depth / Layers; Point3D point = new Point3D(x, y, z); vertices.Add(point); normals.Add(point - new Point3D(0, y, z)); textures.Add(new Point((double)layer / Layers, (double)stack / Stacks)); } } // Fill the indices collection. for (int stack = 0; stack < Stacks; stack++) { for (int layer = 0; layer < Layers; layer++) { indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer); indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer); indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer + 1); indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer + 1); indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer); indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer + 1); } } // Right side. // ----------- indexBase = vertices.Count; x = Width / 2; // Fill the vertices, normals, textures collections. for (int stack = 0; stack <= Stacks; stack++) { y = Height / 2 - stack * Height / Stacks; for (int layer = 0; layer <= Layers; layer++) { z = Depth / 2 - layer * Depth / Layers; Point3D point = new Point3D(x, y, z); vertices.Add(point); normals.Add(point - new Point3D(0, y, z)); textures.Add(new Point((double)layer / Layers, (double)stack / Stacks)); } } // Fill the indices collection. for (int stack = 0; stack < Stacks; stack++) { for (int layer = 0; layer < Layers; layer++) { indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer); indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer); indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer + 1); indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer + 1); indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer); indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer + 1); } } // Top side. // ----------- indexBase = vertices.Count; y = Height / 2; // Fill the vertices, normals, textures collections. for (int layer = 0; layer <= Layers; layer++) { z = -Depth / 2 + layer * Depth / Layers; for (int slice = 0; slice <= Slices; slice++) { x = -Width / 2 + slice * Width / Slices; Point3D point = new Point3D(x, y, z); vertices.Add(point); normals.Add(point - new Point3D(x, 0, z)); textures.Add(new Point((double)slice / Slices, (double)layer / Layers)); } } // Fill the indices collection. for (int layer = 0; layer < Layers; layer++) { for (int slice = 0; slice < Slices; slice++) { indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice); indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice); indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice + 1); indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice + 1); indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice); indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice + 1); } } // Bottom side. // ----------- indexBase = vertices.Count; y = -Height / 2; // Fill the vertices, normals, textures collections. for (int layer = 0; layer <= Layers; layer++) { z = Depth / 2 - layer * Depth / Layers; for (int slice = 0; slice <= Slices; slice++) { x = -Width / 2 + slice * Width / Slices; Point3D point = new Point3D(x, y, z); vertices.Add(point); normals.Add(point - new Point3D(x, 0, z)); textures.Add(new Point((double)slice / Slices, (double)layer / Layers)); } } // Fill the indices collection. for (int layer = 0; layer < Layers; layer++) { for (int slice = 0; slice < Slices; slice++) { indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice); indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice); indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice + 1); indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice + 1); indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice); indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice + 1); } } }
public void GenerateSkyDome() { //use blender model SkyBrush = new ImageBrush(); SkyBrush.ViewportUnits = BrushMappingMode.Absolute; SkyBrush.ImageSource = new BitmapImage(new Uri("gfx/SkyDome.png", UriKind.Relative)); material = new DiffuseMaterial(SkyBrush); SkyDomeMesh = new MeshGeometry3D(); SkyDomeModel = new GeometryModel3D(); PositionBuffer = SkyDomeMesh.Positions; NormalBuffer = SkyDomeMesh.Normals; TexcoordBuffer = SkyDomeMesh.TextureCoordinates; IndexBuffer = SkyDomeMesh.TriangleIndices; int SkyDomeDist = ApplicationSettings.chunkSize * ApplicationSettings.renderDistance + ApplicationSettings.chunkSize; //int SkyDomeDist = 500; Vector3D Normal = new Vector3D(0, 0, -1); Point[] tex = new Point[14]; tex[0] = new Point(0.2505, 0.005); tex[1] = new Point(0.4995, 0.005); tex[2] = new Point(0, 0.3383); tex[3] = new Point(0.250, 0.3383); tex[4] = new Point(0.5, 0.3383); tex[5] = new Point(0.75, 0.3383); tex[6] = new Point(1, 0.3383); tex[7] = new Point(0, 0.6661); tex[8] = new Point(0.25, 0.6661); tex[9] = new Point(0.5, 0.6661); tex[10] = new Point(0.75, 0.6661); tex[11] = new Point(1, 0.6661); tex[12] = new Point(0.2505, 0.995); tex[13] = new Point(0.4995, 0.995); Point3D[] pos = new Point3D[8]; pos[0] = new Point3D(-SkyDomeDist, -SkyDomeDist, -SkyDomeDist); pos[1] = new Point3D(-SkyDomeDist, SkyDomeDist, -SkyDomeDist); pos[2] = new Point3D(SkyDomeDist, -SkyDomeDist, -SkyDomeDist); pos[3] = new Point3D(SkyDomeDist, SkyDomeDist, -SkyDomeDist); pos[4] = new Point3D(-SkyDomeDist, -SkyDomeDist, SkyDomeDist); pos[5] = new Point3D(-SkyDomeDist, SkyDomeDist, SkyDomeDist); pos[6] = new Point3D(SkyDomeDist, -SkyDomeDist, SkyDomeDist); pos[7] = new Point3D(SkyDomeDist, SkyDomeDist, SkyDomeDist); //front PositionBuffer.Add(pos[1]); PositionBuffer.Add(pos[0]); PositionBuffer.Add(pos[2]); PositionBuffer.Add(pos[2]); PositionBuffer.Add(pos[3]); PositionBuffer.Add(pos[1]); //right PositionBuffer.Add(pos[3]); PositionBuffer.Add(pos[2]); PositionBuffer.Add(pos[6]); PositionBuffer.Add(pos[6]); PositionBuffer.Add(pos[7]); PositionBuffer.Add(pos[3]); //back PositionBuffer.Add(pos[7]); PositionBuffer.Add(pos[6]); PositionBuffer.Add(pos[4]); PositionBuffer.Add(pos[4]); PositionBuffer.Add(pos[5]); PositionBuffer.Add(pos[7]); //left PositionBuffer.Add(pos[5]); PositionBuffer.Add(pos[4]); PositionBuffer.Add(pos[0]); PositionBuffer.Add(pos[0]); PositionBuffer.Add(pos[1]); PositionBuffer.Add(pos[5]); //top PositionBuffer.Add(pos[3]); PositionBuffer.Add(pos[7]); PositionBuffer.Add(pos[5]); PositionBuffer.Add(pos[5]); PositionBuffer.Add(pos[1]); PositionBuffer.Add(pos[3]); //bottom PositionBuffer.Add(pos[0]); PositionBuffer.Add(pos[4]); PositionBuffer.Add(pos[6]); PositionBuffer.Add(pos[6]); PositionBuffer.Add(pos[2]); PositionBuffer.Add(pos[0]); for (int i = 0; i < SkyDomeMesh.Positions.Count; i++) { IndexBuffer.Add(i); NormalBuffer.Add(Normal); } //front TexcoordBuffer.Add(tex[3]); TexcoordBuffer.Add(tex[8]); TexcoordBuffer.Add(tex[9]); TexcoordBuffer.Add(tex[9]); TexcoordBuffer.Add(tex[4]); TexcoordBuffer.Add(tex[3]); //right TexcoordBuffer.Add(tex[4]); TexcoordBuffer.Add(tex[9]); TexcoordBuffer.Add(tex[10]); TexcoordBuffer.Add(tex[10]); TexcoordBuffer.Add(tex[5]); TexcoordBuffer.Add(tex[4]); //back TexcoordBuffer.Add(tex[5]); TexcoordBuffer.Add(tex[10]); TexcoordBuffer.Add(tex[11]); TexcoordBuffer.Add(tex[11]); TexcoordBuffer.Add(tex[6]); TexcoordBuffer.Add(tex[5]); //left TexcoordBuffer.Add(tex[2]); TexcoordBuffer.Add(tex[7]); TexcoordBuffer.Add(tex[8]); TexcoordBuffer.Add(tex[8]); TexcoordBuffer.Add(tex[3]); TexcoordBuffer.Add(tex[2]); //top TexcoordBuffer.Add(tex[0]); TexcoordBuffer.Add(tex[3]); TexcoordBuffer.Add(tex[4]); TexcoordBuffer.Add(tex[4]); TexcoordBuffer.Add(tex[1]); TexcoordBuffer.Add(tex[0]); //bottom TexcoordBuffer.Add(tex[8]); TexcoordBuffer.Add(tex[12]); TexcoordBuffer.Add(tex[13]); TexcoordBuffer.Add(tex[13]); TexcoordBuffer.Add(tex[9]); TexcoordBuffer.Add(tex[8]); SkyDomeModel = new GeometryModel3D(); SkyDomeModel.Geometry = SkyDomeMesh; SkyDomeModel.Material = material; MainWindow.AttachGeometry(SkyDomeModel, "SkyDome"); }
/// <summary> /// /// </summary> /// <param name="args"></param> /// <param name="vertices"></param> /// <param name="normals"></param> /// <param name="indices"></param> /// <param name="textures"></param> protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { // Clear all four collections. vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); // Begin at the top end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double y = Length / 2; double radius = stack * Radius / EndStacks; int top = (stack + 0) * (Slices + 1); int bot = (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -radius *Math.Sin(theta); double z = -radius *Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(0, 1, 0)); textures.Add(new Point((double)slice / Slices, Fold * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { if (stack != 0) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); } indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } int offset = vertices.Count; // Length of the cylinder: Fill in the collections. for (int stack = 0; stack <= Stacks; stack++) { double y = Length - stack * Length / Stacks - Length / 2; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -Radius *Math.Sin(theta); double z = -Radius *Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(x, 0, z)); textures.Add(new Point((double)slice / Slices, Fold + (1 - 2 * Fold) * stack / Stacks)); if (stack < Stacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } offset = vertices.Count; // Finish with the bottom end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double y = -Length / 2; double radius = (EndStacks - stack) * Radius / EndStacks; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -radius *Math.Sin(theta); double z = -radius *Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(0, -1, 0)); textures.Add(new Point((double)slice / Slices, (1 - Fold) + Fold * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); if (stack != EndStacks - 1) { indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } } }
private void CreateRenderMeshes() { List <GeometryModel3D> geoModels = new List <GeometryModel3D>(); BoundingBox bbox = BoundingBox.Empty; var backFaceMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.Black)); foreach (var file3dmObject in File3dm.Objects) { // skip if not mesh (until we find out how to extract render meshes) var objectType = file3dmObject.Geometry.ObjectType; if (objectType != ObjectType.Mesh && objectType != ObjectType.Brep) { continue; } // create new empty geometry model var geoModel = new GeometryModel3D(); // create guid property geoModel.SetValue(IdKey, file3dmObject.Id); // convert mesh to meshGeo MeshGeometry3D mesh = new MeshGeometry3D(); if (objectType == ObjectType.Mesh) { mesh = (file3dmObject.Geometry as Mesh).ToMeshGeometry3D(); } if (objectType == ObjectType.Brep) { var tempMesh = new Mesh(); foreach (var face in (file3dmObject.Geometry as Brep).Faces) { tempMesh.Append(face.GetMesh(MeshType.Render)); } tempMesh.Normals.ComputeNormals(); tempMesh.Compact(); mesh = tempMesh.ToMeshGeometry3D(); } geoModel.Geometry = mesh; // create material var material = new DiffuseMaterial(new SolidColorBrush(File3dm.AllLayers .FindIndex(file3dmObject.Attributes.LayerIndex).Color.ToMediaColor())); geoModel.Material = material; geoModel.BackMaterial = backFaceMaterial; geoModels.Add(geoModel); // union bbox bbox.Union(file3dmObject.Geometry.GetBoundingBox(Plane.WorldXY)); } bbox.Inflate(2); SceneBbox = bbox; // set up camera from bbox //var position = bbox.Corner(true, true, false); //Camera = new PerspectiveCamera(position.ToPoint3D(), (bbox.Center - position).ToVector3D(), // new Vector3D(0, 0, 1), 60); var myGeometryModel = new GeometryModel3D(); // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet // is created. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); // Create a collection of normal vectors for the MeshGeometry3D. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myMeshGeometry3D.Normals = myNormalCollection; // Create a collection of vertex positions for the MeshGeometry3D. Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myMeshGeometry3D.Positions = myPositionCollection; // Create a collection of texture coordinates for the MeshGeometry3D. PointCollection myTextureCoordinatesCollection = new PointCollection(); myTextureCoordinatesCollection.Add(new Point(0, 0)); myTextureCoordinatesCollection.Add(new Point(1, 0)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(0, 1)); myTextureCoordinatesCollection.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection; // Create a collection of triangle indices for the MeshGeometry3D. Int32Collection myTriangleIndicesCollection = new Int32Collection(); myTriangleIndicesCollection.Add(0); myTriangleIndicesCollection.Add(1); myTriangleIndicesCollection.Add(2); myTriangleIndicesCollection.Add(3); myTriangleIndicesCollection.Add(4); myTriangleIndicesCollection.Add(5); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; // Apply the mesh to the geometry model. myGeometryModel.Geometry = myMeshGeometry3D; // The material specifies the material applied to the 3D object. In this sample a // linear gradient covers the surface of the 3D object. // Create a horizontal linear gradient with four stops. LinearGradientBrush myHorizontalGradient = new LinearGradientBrush(); myHorizontalGradient.StartPoint = new Point(0, 0.5); myHorizontalGradient.EndPoint = new Point(1, 0.5); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); // Define material and apply to the mesh geometries. DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient); myGeometryModel.Material = myMaterial; // Apply a transform to the object. In this sample, a rotation transform is applied, // rendering the 3D object rotated. RotateTransform3D myRotateTransform3D = new RotateTransform3D(); AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D(); myAxisAngleRotation3d.Axis = new Vector3D(0, 3, 0); myAxisAngleRotation3d.Angle = 40; myRotateTransform3D.Rotation = myAxisAngleRotation3d; myGeometryModel.Transform = myRotateTransform3D; geoModels.Add(myGeometryModel); RenderMeshes = geoModels.ToArray(); }
protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); Point3D[,] faces = Faces; PointCollection texturesBase = TextureCoordinates; int indexTextures = 0; for (int face = 0; face < faces.GetLength(0); face++) { Vector3D normal = Vector3D.CrossProduct(faces[face, 1] - faces[face, 0], faces[face, 2] - faces[face, 0]); // For faces that are triangles. if (faces.GetLength(1) == 3) { int indexBase = vertices.Count; for (int i = 0; i < 3; i++) { vertices.Add(faces[face, i]); normals.Add(normal); indices.Add(indexBase + i); if (texturesBase != null && texturesBase.Count > 0) { textures.Add(texturesBase[indexTextures]); indexTextures = (indexTextures + 1) % texturesBase.Count; } } if (Slices > 1) { TriangleSubdivide(vertices, normals, indices, textures); } } // For faces that are not triangles. else { for (int i = 0; i < faces.GetLength(1) - 1; i++) { int indexBase = vertices.Count; int num = faces.GetLength(1) - 1; vertices.Add(faces[face, 0]); vertices.Add(faces[face, i + 1]); vertices.Add(faces[face, (i + 1) % num + 1]); if (texturesBase != null && texturesBase.Count >= faces.GetLength(1)) { textures.Add(texturesBase[indexTextures + 0]); textures.Add(texturesBase[indexTextures + i + 1]); textures.Add(texturesBase[indexTextures + (i + 1) % num + 1]); } normals.Add(normal); normals.Add(normal); normals.Add(normal); indices.Add(indexBase + 0); indices.Add(indexBase + 1); indices.Add(indexBase + 2); if (Slices > 1) { TriangleSubdivide(vertices, normals, indices, textures); } } if (texturesBase != null && texturesBase.Count > 0) { indexTextures = (indexTextures + faces.GetLength(1)) % texturesBase.Count; } } } }
public MainWindow() { InitializeComponent(); Draw3D draw = new Draw3D(mainCanvas); Point3D p0 = new Point3D(0, 0, 0); Point3D p1 = new Point3D(10, 0, 0); draw.shapes.AddLine(p0, p1); draw.shapes.AddSphere(p0, 10, 12); draw.IsOnZoomPan_WheelScroll = true; draw.RegenerateShapes_ModelVisual3ds(); draw.RedrawShapes(); //Example_CanvasText(); draw.ViewTop(); // Declare scene objects. Viewport3D myViewport3D = new Viewport3D(); Model3DGroup myModel3DGroup = new Model3DGroup(); GeometryModel3D myGeometryModel = new GeometryModel3D(); ModelVisual3D myModelVisual3D = new ModelVisual3D(); // Defines the camera used to view the 3D object. In order to view the 3D object, // the camera must be positioned and pointed such that the object is within view // of the camera. PerspectiveCamera myPCamera = new PerspectiveCamera(); // Specify where in the 3D scene the camera is. myPCamera.Position = new Point3D(0, 0, 2); // Specify the direction that the camera is pointing. myPCamera.LookDirection = new Vector3D(0, 0, -1); // Define camera's horizontal field of view in degrees. myPCamera.FieldOfView = 60; // Asign the camera to the viewport myViewport3D.Camera = myPCamera; // Define the lights cast in the scene. Without light, the 3D object cannot // be seen. Note: to illuminate an object from additional directions, create // additional lights. DirectionalLight myDirectionalLight = new DirectionalLight(); myDirectionalLight.Color = Colors.White; myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61); myModel3DGroup.Children.Add(myDirectionalLight); // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet // is created. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); // Create a collection of normal vectors for the MeshGeometry3D. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myMeshGeometry3D.Normals = myNormalCollection; // Create a collection of vertex positions for the MeshGeometry3D. Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myMeshGeometry3D.Positions = myPositionCollection; // Create a collection of texture coordinates for the MeshGeometry3D. PointCollection myTextureCoordinatesCollection = new PointCollection(); myTextureCoordinatesCollection.Add(new Point(0, 0)); myTextureCoordinatesCollection.Add(new Point(1, 0)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(0, 1)); myTextureCoordinatesCollection.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection; // Create a collection of triangle indices for the MeshGeometry3D. Int32Collection myTriangleIndicesCollection = new Int32Collection(); myTriangleIndicesCollection.Add(0); myTriangleIndicesCollection.Add(1); myTriangleIndicesCollection.Add(2); myTriangleIndicesCollection.Add(3); myTriangleIndicesCollection.Add(4); myTriangleIndicesCollection.Add(5); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; // Apply the mesh to the geometry model. myGeometryModel.Geometry = myMeshGeometry3D; // The material specifies the material applied to the 3D object. In this sample a // linear gradient covers the surface of the 3D object. // Create a horizontal linear gradient with four stops. LinearGradientBrush myHorizontalGradient = new LinearGradientBrush(); myHorizontalGradient.StartPoint = new Point(0, 0.5); myHorizontalGradient.EndPoint = new Point(1, 0.5); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); // Define material and apply to the mesh geometries. DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient); myGeometryModel.Material = myMaterial; // Apply a transform to the object. In this sample, a rotation transform is applied, // rendering the 3D object rotated. RotateTransform3D myRotateTransform3D = new RotateTransform3D(); AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D(); myAxisAngleRotation3d.Axis = new Vector3D(0, 3, 0); myAxisAngleRotation3d.Angle = 40; myRotateTransform3D.Rotation = myAxisAngleRotation3d; myGeometryModel.Transform = myRotateTransform3D; // Add the geometry model to the model group. myModel3DGroup.Children.Add(myGeometryModel); // Add the group of models to the ModelVisual3d. myModelVisual3D.Content = myModel3DGroup; // myViewport3D.Children.Add(myModelVisual3D); // Apply the viewport to the page so it will be rendered. Content = myViewport3D; }
public static Model3D CreateModel3D(List <Mesh> meshGroups, BitmapSource texture, AnimData pose, int frame) { var model = new GeometryModel3D(); var mesh3D = new MeshGeometry3D(); var numVertices = 0; foreach (var meshGroup in meshGroups) { numVertices += meshGroup.Positions.Count; } var triangleIndices = new Int32Collection(); var positions = new Point3DCollection(numVertices); var normals = new Vector3DCollection(numVertices); var uvCoords = new PointCollection(numVertices); var vstart = 0; foreach (var meshGroup in meshGroups) { var hasVertexWeights = meshGroup.vertexWeights.Count > 0; var vwNum = 0; var vw = new VertexWeight(); if (meshGroup.vertexWeights.Count > 0) { vw = meshGroup.vertexWeights[vwNum]; } var vnum = 0; foreach (var vertex in meshGroup.Positions) { var point = vertex; if (frame >= 0 && pose != null) { if (vw.endVertex < vnum) { ++vwNum; vw = meshGroup.vertexWeights[vwNum]; if (vnum < vw.startVertex || vnum > vw.endVertex) { Debug.Fail("Vertex " + vnum + " out of range of bone weights " + vw.startVertex + " -> " + vw.endVertex); } } var bone1No = vw.bone1; var bindingPos1 = pose.bindingPose[bone1No]; var bone1Pose = pose.perFrameFKPoses[frame, bone1No]; var joint1Pos = bone1Pose.Position; if (vw.bone2 == 0xFF) { if (bone1No == 1) { bone1No = 1; } var m = Matrix3D.Identity; m.Translate(new Vector3D(-bindingPos1.X, -bindingPos1.Y, -bindingPos1.Z)); // Inverse binding matrix m.Rotate(bone1Pose.Rotation); m.Translate(new Vector3D(bone1Pose.Position.X, bone1Pose.Position.Y, bone1Pose.Position.Z)); point = m.Transform(point); } else { // multi-bone var bone2No = vw.bone2; var bindingPos2 = pose.bindingPose[bone2No]; var bone2Pose = pose.perFrameFKPoses[frame, bone2No]; double boneSum = vw.boneWeight1 + vw.boneWeight2; var bone1Coeff = vw.boneWeight1 / boneSum; var bone2Coeff = vw.boneWeight2 / boneSum; var m = Matrix3D.Identity; m.Translate(new Vector3D(-bindingPos1.X, -bindingPos1.Y, -bindingPos1.Z)); // Inverse binding matrix m.Rotate(bone1Pose.Rotation); m.Translate(new Vector3D(bone1Pose.Position.X, bone1Pose.Position.Y, bone1Pose.Position.Z)); var point1 = m.Transform(point); // Now rotate var m2 = Matrix3D.Identity; m2.Translate(new Vector3D(-bindingPos2.X, -bindingPos2.Y, -bindingPos2.Z)); // Inverse binding matrix m2.Rotate(bone2Pose.Rotation); m2.Translate(new Vector3D(bone2Pose.Position.X, bone2Pose.Position.Y, bone2Pose.Position.Z)); var point2 = m2.Transform(point); point = new Point3D(point1.X * bone1Coeff + point2.X * bone2Coeff, point1.Y * bone1Coeff + point2.Y * bone2Coeff, point1.Z * bone1Coeff + point2.Z * bone2Coeff); } } positions.Add(point); ++vnum; } foreach (var normal in meshGroup.Normals) { normals.Add(normal); } foreach (var ti in meshGroup.TriangleIndices) { triangleIndices.Add(ti + vstart); } foreach (var uv in meshGroup.TextureCoordinates) { uvCoords.Add(uv); } vstart += meshGroup.Positions.Count; } mesh3D.TriangleIndices = triangleIndices; mesh3D.Positions = positions; mesh3D.TextureCoordinates = uvCoords; mesh3D.Normals = normals; model.Geometry = mesh3D; var dm = new DiffuseMaterial(); if (texture != null && texture.Width > 0 && texture.Height > 0) { var ib = new ImageBrush(texture) { ViewportUnits = BrushMappingMode.Absolute }; // May be needed at a later point //ib.TileMode = TileMode.Tile; dm.Brush = ib; } else { var dg = new DrawingGroup(); // Background dg.Children.Add(new GeometryDrawing() { Brush = new SolidColorBrush(Colors.Black), Geometry = new RectangleGeometry(new Rect(0, 0, 2, 2)) }); // Tiles dg.Children.Add(new GeometryDrawing() { Brush = new SolidColorBrush(Colors.Violet), Geometry = new RectangleGeometry(new Rect(0, 0, 1, 1)) }); dg.Children.Add(new GeometryDrawing() { Brush = new SolidColorBrush(Colors.Violet), Geometry = new RectangleGeometry(new Rect(1, 1, 1, 1)) }); dm.Brush = new DrawingBrush(dg) { TileMode = TileMode.Tile, Transform = new ScaleTransform(0.1, 0.1) }; } model.Material = dm; return(model); }
protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); // vectRearRadius points towards -Z (when possible). Vector3D vectCylinder = Point2 - Point1; Vector3D vectRearRadius; if (vectCylinder.X == 0 && vectCylinder.Y == 0) { // Special case: set rear-radius vector vectRearRadius = new Vector3D(0, -1, 0); } else { // Find vector axis 90 degrees from cylinder where Z == 0 rotate.Axis = Vector3D.CrossProduct(vectCylinder, new Vector3D(0, 0, 1)); rotate.Angle = -90; // Rotate cylinder 90 degrees to find radius vector vectRearRadius = vectCylinder * xform.Value; vectRearRadius.Normalize(); } // Will rotate radius around cylinder axis rotate.Axis = -vectCylinder; // Begin at the top end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double radius = stack * Radius1 / EndStacks; Vector3D vectRadius = radius * vectRearRadius; int top = (stack + 0) * (Slices + 1); int bot = (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { rotate.Angle = slice * 360.0 / Slices; vertices.Add(Point1 + vectRadius * xform.Value); normals.Add(-vectCylinder); textures.Add(new Point((double)slice / Slices, Fold1 * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { if (stack != 0) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); } indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } int offset = vertices.Count; // Go down length of cylinder and fill in the collections. for (int stack = 0; stack <= Stacks; stack++) { double radius = ((Stacks - stack) * Radius1 + stack * Radius2) / Stacks; Vector3D vectRadius = radius * vectRearRadius; Point3D center = (Point3D)(Point1 + stack * vectCylinder / Stacks); int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { rotate.Angle = slice * 360.0 / Slices; Vector3D normal = vectRadius * xform.Value; normals.Add(normal); vertices.Add(center + normal); textures.Add(new Point((double)slice / Slices, Fold1 + (Fold2 - Fold1) * stack / Stacks)); if (stack < Stacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } offset = vertices.Count; // Finish with bottom. for (int stack = 0; stack <= EndStacks; stack++) { double radius = Radius2 * (1 - (double)stack / EndStacks); Vector3D vectRadius = radius * vectRearRadius; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { rotate.Angle = slice * 360.0 / Slices; vertices.Add(Point2 + vectRadius * xform.Value); normals.Add(vectCylinder); textures.Add(new Point((double)slice / Slices, Fold2 + (1 - Fold2) * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); if (stack != EndStacks - 1) { indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } } }
void PropertyChanged(DependencyPropertyChangedEventArgs args) { // Get reference to Geometry property for local ease. MeshGeometry3D mesh = Geometry; // Get references to all four collections. Point3DCollection vertices = mesh.Positions; Vector3DCollection normals = mesh.Normals; Int32Collection indices = mesh.TriangleIndices; PointCollection textures = mesh.TextureCoordinates; // Set the MeshGeometry3D properties to null to inhibit notifications. mesh.Positions = null; mesh.Normals = null; mesh.TriangleIndices = null; mesh.TextureCoordinates = null; // Clear the four collections. vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); // Fill the vertices, normals, and textures collections. for (int stack = 0; stack <= Stacks; stack++) { double phi = Math.PI / 2 - stack * Math.PI / Stacks; double y = Radius * Math.Sin(phi); double scale = -Radius *Math.Cos(phi); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = scale * Math.Sin(theta); double z = scale * Math.Cos(theta); Vector3D normal = new Vector3D(x, y, z); normals.Add(normal); vertices.Add(normal + Center); textures.Add(new Point((double)slice / Slices, (double)stack / Stacks)); } } // Fill the indices collection. for (int stack = 0; stack < Stacks; stack++) { int top = (stack + 0) * (Slices + 1); int bot = (stack + 1) * (Slices + 1); for (int slice = 0; slice < Slices; slice++) { if (stack != 0) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); } if (stack != Stacks - 1) { indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } // Set the collections back to the properties mesh.TextureCoordinates = textures; mesh.TriangleIndices = indices; mesh.Normals = normals; mesh.Positions = vertices; }
/// <summary> /// /// </summary> /// <param name="args"> /// The DependencyPropertyChangedEventArgs object originally /// passed to the PropertyChanged handler that initiated this /// recalculation. /// </param> /// <param name="vertices"> /// The Point3DCollection corresponding to the Positions property /// of the MeshGeometry3D. /// </param> /// <param name="normals"> /// The Vector3DCollection corresponding to the Normals property /// of the MeshGeometry3D. /// </param> /// <param name="indices"> /// The Int32Collection corresponding to the TriangleIndices /// property of the MeshGeometry3D. /// </param> /// <param name="textures"> /// The PointCollection corresponding to the TextureCoordinates /// property of the MeshGeometry3D. /// </param> protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { // Clear all four collections. vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); // Loop for outside (side = 1) and inside (side = -1). for (int side = 1; side >= -1; side -= 2) { int offset = vertices.Count; // Begin at the top end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double y = Length; double radius = Radius + side * stack * Thickness / 2 / EndStacks; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -radius *Math.Sin(theta); double z = -radius *Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(0, side, 0)); textures.Add(new Point((double)slice / Slices, Fold * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } offset = vertices.Count; // Length of the tube: Fill in the collections. for (int stack = 0; stack <= Stacks; stack++) { double y = Length - stack * Length / Stacks; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -(Radius + side * Thickness / 2) * Math.Sin(theta); double z = -(Radius + side * Thickness / 2) * Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(side * x, 0, side * z)); textures.Add(new Point((double)slice / Slices, Fold + (1 - 2 * Fold) * stack / Stacks)); if (stack < Stacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } offset = vertices.Count; // Finish with the bottom end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double y = 0; double radius = Radius + side * Thickness / 2 * (1 - (double)stack / EndStacks); int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -radius *Math.Sin(theta); double z = -radius *Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(0, -side, 0)); textures.Add(new Point((double)slice / Slices, (1 - Fold) + Fold * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } } }
// Create a DrawingVisual that contains a 3D object. private DrawingVisual Create3DVisualObject() { // Declare scene objects. // The Viewport3DVisual is used instead of the Viewport3D object because this 3D // object is drawn directly to the WPF visual layer. Using Viepwor3dVisual can provide // performance benefits over using Viewport3D although it does not support many of the // features that Viewport3D does. Viewport3DVisual myViewport3D = new Viewport3DVisual(); Model3DGroup myModel3DGroup = new Model3DGroup(); GeometryModel3D myGeometryModel = new GeometryModel3D(); ModelVisual3D myModelVisual3D = new ModelVisual3D(); // Defines the camera used to view the 3D object. In order to view the 3D object, // the camera must be positioned and pointed such that the object is within view // of the camera. PerspectiveCamera myPCamera = new PerspectiveCamera(); // Specify where in the 3D scene the camera is. myPCamera.Position = new Point3D(0, 0, 2); // Specify the direction that the camera is pointing. myPCamera.LookDirection = new Vector3D(0, 0, -1); // Define camera's horizontal field of view in degrees. myPCamera.FieldOfView = 60; // Asign the camera to the viewport myViewport3D.Camera = myPCamera; // Define the lights cast in the scene. Without light, the 3D object cannot // be seen. Note: to illuminate an object from additional directions, create // additional lights. DirectionalLight myDirectionalLight = new DirectionalLight(); myDirectionalLight.Color = Colors.White; myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61); myModel3DGroup.Children.Add(myDirectionalLight); // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet // is created. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); // Create a collection of normal vectors for the MeshGeometry3D. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myMeshGeometry3D.Normals = myNormalCollection; // Create a collection of vertex positions for the MeshGeometry3D. Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myMeshGeometry3D.Positions = myPositionCollection; // Create a collection of texture coordinates for the MeshGeometry3D. PointCollection myTextureCoordinatesCollection = new PointCollection(); myTextureCoordinatesCollection.Add(new Point(0, 0)); myTextureCoordinatesCollection.Add(new Point(1, 0)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(0, 1)); myTextureCoordinatesCollection.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection; // Create a collection of triangle indices for the MeshGeometry3D. Int32Collection myTriangleIndicesCollection = new Int32Collection(); myTriangleIndicesCollection.Add(0); myTriangleIndicesCollection.Add(1); myTriangleIndicesCollection.Add(2); myTriangleIndicesCollection.Add(3); myTriangleIndicesCollection.Add(4); myTriangleIndicesCollection.Add(5); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; // Apply the mesh to the geometry model. myGeometryModel.Geometry = myMeshGeometry3D; // The material specifies the material applied to the 3D object. In this sample a // linear gradient covers the surface of the 3D object. // Create a horizontal linear gradient with four stops. LinearGradientBrush myHorizontalGradient = new LinearGradientBrush(); myHorizontalGradient.StartPoint = new Point(0, 0.5); myHorizontalGradient.EndPoint = new Point(1, 0.5); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); // Define material and apply to the mesh geometries. DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient); myGeometryModel.Material = myMaterial; // Apply a transform to the object. In this sample, a rotation transform is applied, // rendering the 3D object rotated. RotateTransform3D myRotateTransform3D = new RotateTransform3D(); AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D(); myAxisAngleRotation3d.Axis = new Vector3D(0, 3, 0); myAxisAngleRotation3d.Angle = 40; myRotateTransform3D.Rotation = myAxisAngleRotation3d; myGeometryModel.Transform = myRotateTransform3D; // Add the geometry model to the model group. myModel3DGroup.Children.Add(myGeometryModel); // Add the group of models to the ModelVisual3d. myModelVisual3D.Content = myModel3DGroup; // Create a rectangle to view the 3D object in. Rect myRectangle = new Rect(); myRectangle.Location = new Point(10, 5); myRectangle.Size = new Size(900, 900); myViewport3D.Children.Add(myModelVisual3D); myViewport3D.Viewport = myRectangle; DrawingVisual dv = new DrawingVisual(); dv.Children.Add(myViewport3D); return(dv); }
// // CONSTRUCTOR // public MosaicFootprint(BitmapImage image, double xmin, double ymin, double xmax, double ymax, double height, ModelVisual3D highlightlines, ModelVisual3D selectedlines) { // this.Attributes = new Dictionary <string, object>(); this.Image = image; this.XMin = xmin; this.YMin = ymin; this.XMax = xmax; this.YMax = ymax; this.Height = height; this.HighlightLines = highlightlines; this.SelectedLines = selectedlines; // Define normals Vector3DCollection normals = new Vector3DCollection(); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); // Define vertex positions Point3DCollection positions = new Point3DCollection(); positions.Add(new Point3D(this.XMin, this.YMin, this.Height)); positions.Add(new Point3D(this.XMin, this.YMax, this.Height)); positions.Add(new Point3D(this.XMax, this.YMax, this.Height)); positions.Add(new Point3D(this.XMax, this.YMin, this.Height)); // Define textures PointCollection textureCoordinates = new PointCollection(); textureCoordinates.Add(new Point(0, 1)); textureCoordinates.Add(new Point(0, 0)); textureCoordinates.Add(new Point(1, 0)); textureCoordinates.Add(new Point(1, 1)); // Define triangles Int32Collection triangleIndices = new Int32Collection(); triangleIndices.Add(0); triangleIndices.Add(3); triangleIndices.Add(2); triangleIndices.Add(2); triangleIndices.Add(1); triangleIndices.Add(0); // Create Border (up facing) with image texture this.Element = new Border() { Cursor = Cursors.Hand, Height = 100, Width = 100, Background = new ImageBrush() { ImageSource = this.Image, Stretch = Stretch.Fill } }; this.Element.MouseEnter += (s, e) => { this.IsMouseOver = true; }; this.Element.MouseLeave += (s, e) => { this.IsMouseOver = false; }; // Create Viewport2DVisual3D from Border Viewport2DVisual3D top = new Viewport2DVisual3D() { Geometry = new MeshGeometry3D() { Normals = normals, Positions = positions, TextureCoordinates = textureCoordinates, TriangleIndices = triangleIndices }, Material = new DiffuseMaterial() { Brush = new SolidColorBrush() { Color = Colors.White }, AmbientColor = Colors.White }, Visual = this.Element }; Viewport2DVisual3D.SetIsVisualHostMaterial(top.Material, true); // Create down facing texture ModelUIElement3D bottom = new ModelUIElement3D() { IsHitTestVisible = true, Model = new GeometryModel3D() { Geometry = new MeshGeometry3D() { Normals = normals, Positions = positions, TextureCoordinates = textureCoordinates, TriangleIndices = triangleIndices }, BackMaterial = new DiffuseMaterial() { Brush = new SolidColorBrush() { Color = Colors.LightGray } } } }; // Create Model ModelVisual3D model = new ModelVisual3D(); model.Children.Add(top); model.Children.Add(bottom); this.ModelVisual = model; }
public static MeshGeometry3D SaifToMesh(string directory) { Point3DCollection verts = new Point3DCollection(); Int32Collection tris = new Int32Collection(); Vector3DCollection normals = new Vector3DCollection(); PointCollection textureCoordinates = new PointCollection(); StreamReader reader = new StreamReader(directory); string line; while ((line = reader.ReadLine()) != null) { string IdentifiedChar = line.Substring(0, 3); string[] CurrentLine; switch (IdentifiedChar) { case "Ver": try { string vertices = line; CurrentLine = vertices.Split(' '); for (int i = 1; i < CurrentLine.Length - 1; i++) { string[] vertStr = CurrentLine[i].Split(','); Point3D vert = new Point3D() { X = double.Parse(vertStr[0].ToString()), Y = double.Parse(vertStr[1].ToString()), Z = double.Parse(vertStr[2].ToString()), }; verts.Add(vert); } } catch (Exception e) { MessageBox.Show(e.ToString()); Environment.Exit(0); } break; case "Tri": try { string triangles = line; CurrentLine = triangles.Split(' '); for (int i = 1; i < CurrentLine.Length - 1; i++) { tris.Add(int.Parse(CurrentLine[i])); } } catch (Exception e) { MessageBox.Show(e.ToString()); Environment.Exit(0); } break; case "Nor": try { string normalz = line; CurrentLine = normalz.Split(' '); for (int i = 1; i < CurrentLine.Length - 1; i++) { string[] normStr = CurrentLine[i].Split(','); Vector3D norm = new Vector3D() { X = double.Parse(normStr[0].ToString()), Y = double.Parse(normStr[1].ToString()), Z = double.Parse(normStr[2].ToString()), }; normals.Add(norm); } } catch (Exception e) { MessageBox.Show(e.ToString()); Environment.Exit(0); } break; case "Tex": try { string textCoords = line; CurrentLine = textCoords.Split(' '); for (int i = 1; i < CurrentLine.Length - 1; i++) { string[] coordStr = CurrentLine[i].Split(','); Point coord = new Point() { X = double.Parse(coordStr[0]), Y = double.Parse(coordStr[1]) }; textureCoordinates.Add(coord); } } catch (Exception e) { MessageBox.Show(e.ToString()); Environment.Exit(0); } break; default: break; } } reader.Close(); MeshGeometry3D loadedMesh = new MeshGeometry3D() { Positions = verts, TriangleIndices = tris, Normals = normals, TextureCoordinates = textureCoordinates }; return(loadedMesh); }
/// <summary> /// The add face. /// </summary> /// <param name="values"> /// The values. /// </param> private void AddFace(string values) { // A polygonal face. The numbers are indexes into the arrays of vertex positions, // texture coordinates, and normals respectively. A number may be omitted if, // for example, texture coordinates are not being defined in the model. // There is no maximum number of vertices that a single polygon may contain. // The .obj file specification says that each face must be flat and convex. var fields = values.SplitOnWhitespace(); var points = new Point3DCollection(); var textureCoordinates = new PointCollection(); var normals = new Vector3DCollection(); foreach (var field in fields) { if (string.IsNullOrEmpty(field)) { continue; } var ff = field.Split('/'); int vi = int.Parse(ff[0]); int vti = ff.Length > 1 && ff[1].Length > 0 ? int.Parse(ff[1]) : int.MaxValue; int vni = ff.Length > 2 && ff[2].Length > 0 ? int.Parse(ff[2]) : int.MaxValue; if (vi < 0) { vi = this.Points.Count + vi; } if (vti < 0) { vti = this.TexCoords.Count + vti; } if (vni < 0) { vni = this.Normals.Count + vni; } if (vi - 1 < this.Points.Count) { points.Add(this.Points[vi - 1]); } if (vti < int.MaxValue && vti - 1 < this.TexCoords.Count) { textureCoordinates.Add(this.TexCoords[vti - 1]); } if (vni < int.MaxValue && vni - 1 < this.Normals.Count) { normals.Add(this.Normals[vni - 1]); } } if (textureCoordinates.Count == 0) { textureCoordinates = null; } if (normals.Count == 0) { normals = null; } if (normals == null) { // turn off normals in the mesh builder //this.CurrentGroup.MeshBuilder.Normals = null; } if (textureCoordinates == null) { // turn off texture coordinates in the mesh builder //this.CurrentGroup.MeshBuilder.TextureCoordinates = null; } // TRIANGLE if (points.Count == 3) { this.CurrentGroup.MeshBuilder.AddTriangles(points, normals, textureCoordinates); return; } // QUAD if (points.Count == 4) { this.CurrentGroup.MeshBuilder.AddQuads(points, normals, textureCoordinates); return; } // POLYGONS (flat and convex) { var poly3D = new Polygon3D(points); // Transform the polygon to 2D var poly2D = poly3D.Flatten(); // Triangulate var triangleIndices = poly2D.Triangulate(); if (triangleIndices != null) { // Add the triangle indices with the 3D points this.CurrentGroup.MeshBuilder.Append(points, triangleIndices, normals, textureCoordinates); } } }
public static void DrawLibGGraphicItem(NodeModel node, object geom, RenderDescription rd, Octree.OctreeSearch.Octree octree) { var selected = DynamoSelection.Instance.Selection.Contains(node); var g = geom as GraphicItem; if (g is CoordinateSystem) { #region draw coordinate systems var line_strip_vertices = g.line_strip_vertices_threadsafe(); for (int i = 0; i < line_strip_vertices.Count; i += 6) { var p1 = new Point3D( line_strip_vertices[i], line_strip_vertices[i + 1], line_strip_vertices[i + 2]); var p2 = new Point3D( line_strip_vertices[i + 3], line_strip_vertices[i + 4], line_strip_vertices[i + 5]); if (i < 6) { rd.XAxisPoints.Add(p1); rd.XAxisPoints.Add(p2); } else if (i >= 6 && i < 12) { rd.YAxisPoints.Add(p1); rd.YAxisPoints.Add(p2); } else { rd.ZAxisPoints.Add(p1); rd.ZAxisPoints.Add(p2); } } #endregion } else { #region draw points var point_vertices = g.point_vertices_threadsafe(); for (int i = 0; i < point_vertices.Count; i += 3) { if (selected) { rd.SelectedPoints.Add(new Point3D(point_vertices[i], point_vertices[i + 1], point_vertices[i + 2])); } else { rd.Points.Add(new Point3D(point_vertices[i], point_vertices[i + 1], point_vertices[i + 2])); } } #endregion #region draw lines SizeTList num_line_strip_vertices = g.num_line_strip_vertices_threadsafe(); FloatList line_strip_vertices = g.line_strip_vertices_threadsafe(); int counter = 0; foreach (uint num_verts in num_line_strip_vertices) { for (int i = 0; i < num_verts; ++i) { var p = new Point3D( line_strip_vertices[counter], line_strip_vertices[counter + 1], line_strip_vertices[counter + 2]); if (selected) { rd.SelectedLines.Add(p); } else { rd.Lines.Add(p); } counter += 3; if (i == 0 || i == num_verts - 1) { continue; } if (selected) { rd.SelectedLines.Add(p); } else { rd.Lines.Add(p); } } } #endregion #region draw surface //var sw = new Stopwatch(); //sw.Start(); var builder = new MeshBuilder(); var points = new Point3DCollection(); var tex = new PointCollection(); var norms = new Vector3DCollection(); var tris = new List <int>(); FloatList triangle_vertices = g.triangle_vertices_threadsafe(); FloatList triangle_normals = g.triangle_normals_threadsafe(); for (int i = 0; i < triangle_vertices.Count; i += 3) { var new_point = new Point3D(triangle_vertices[i], triangle_vertices[i + 1], triangle_vertices[i + 2]); var normal = new Vector3D(triangle_normals[i], triangle_normals[i + 1], triangle_normals[i + 2]); //find a matching point //compare the angle between the normals //to discern a 'break' angle for adjacent faces //int foundIndex = -1; //for (int j = 0; j < points.Count; j++) //{ // var testPt = points[j]; // var testNorm = norms[j]; // var ang = Vector3D.AngleBetween(normal, testNorm); // if (new_point.X == testPt.X && // new_point.Y == testPt.Y && // new_point.Z == testPt.Z && // ang > 90.0000) // { // foundIndex = j; // break; // } //} //if (foundIndex != -1) //{ // tris.Add(foundIndex); // continue; //} tris.Add(points.Count); points.Add(new_point); norms.Add(normal); tex.Add(new System.Windows.Point(0, 0)); octree.AddNode(new_point.X, new_point.Y, new_point.Z, node.GUID.ToString()); } //builder.AddTriangles(points, norms, tex); builder.Append(points, tris, norms, tex); //sw.Stop(); //Debug.WriteLine(string.Format("{0} elapsed for drawing geometry.", sw.Elapsed)); //don't add empty meshes if (builder.Positions.Count > 0) { if (selected) { rd.SelectedMeshes.Add(builder.ToMesh(true)); } else { rd.Meshes.Add(builder.ToMesh(true)); } } #endregion } }
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) { Viewport3D myViewport3D = new Viewport3D(); Model3DGroup myModel3DGroup = new Model3DGroup(); GeometryModel3D myGeometryModel = new GeometryModel3D(); ModelVisual3D myModelVisual3D = new ModelVisual3D(); OrthographicCamera myOCamera = new OrthographicCamera(new Point3D(0, 0, 6), new Vector3D(0, 0, -1), new Vector3D(0, 1, 0), 8); myViewport3D.Camera = myOCamera; AmbientLight myDirectionalLight = new AmbientLight(); myDirectionalLight.Color = Colors.White; //myDirectionalLight.Direction = new Vector3D(0, 0, -3); myModel3DGroup.Children.Add(myDirectionalLight); MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myMeshGeometry3D.Normals = myNormalCollection; Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(0.0, 1.0, 1.0)); myPositionCollection.Add(new Point3D(1.0, 1.0, 1.0)); myPositionCollection.Add(new Point3D(1.0, 1.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 1.0, 0.0)); myPositionCollection.Add(new Point3D(0.0, 1.0, 0.0)); myPositionCollection.Add(new Point3D(0.0, 1.0, 1.0)); //2 myPositionCollection.Add(new Point3D(0.0, 0.0, 1.0)); myPositionCollection.Add(new Point3D(0.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 0.0, 1.0)); myPositionCollection.Add(new Point3D(0.0, 0.0, 1.0)); //3 myPositionCollection.Add(new Point3D(0.0, 1.0, 1.0)); myPositionCollection.Add(new Point3D(0.0, 0.0, 1.0)); //4 myPositionCollection.Add(new Point3D(1.0, 0.0, 1.0)); myPositionCollection.Add(new Point3D(1.0, 0.0, 1.0)); myPositionCollection.Add(new Point3D(1.0, 1.0, 1.0)); myPositionCollection.Add(new Point3D(0.0, 1.0, 1.0)); //4 myPositionCollection.Add(new Point3D(1.0, 1.0, 1.0)); myPositionCollection.Add(new Point3D(1.0, 0.0, 1.0)); myPositionCollection.Add(new Point3D(1.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 1.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 1.0, 1.0)); //5 myPositionCollection.Add(new Point3D(1.0, 1.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(0.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(0.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(0.0, 1.0, 0.0)); myPositionCollection.Add(new Point3D(1.0, 1.0, 0.0)); //6 myPositionCollection.Add(new Point3D(0.0, 1.0, 1.0)); myPositionCollection.Add(new Point3D(0.0, 1.0, 0.0)); myPositionCollection.Add(new Point3D(0.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(0.0, 0.0, 0.0)); myPositionCollection.Add(new Point3D(0.0, 0.0, 1.0)); myPositionCollection.Add(new Point3D(0.0, 1.0, 1.0)); myMeshGeometry3D.Positions = myPositionCollection; Int32Collection myTriangleIndicesCollection = new Int32Collection(); for (int i = 0; i < myTriangleIndicesCollection.Count; i++) { myTriangleIndicesCollection.Add(i); } myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 1)); myMeshGeometry3D.TextureCoordinates.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates.Add(new Point(1, 0)); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; myGeometryModel.Geometry = myMeshGeometry3D; BitmapImage bm1 = new BitmapImage(); bm1.BeginInit(); bm1.UriSource = new Uri("dog.jpg", UriKind.RelativeOrAbsolute); bm1.EndInit(); ImageBrush imgBrush = new ImageBrush(bm1); var brush = new SolidColorBrush(Color.FromRgb(100, 200, 100)); DiffuseMaterial myMaterial = new DiffuseMaterial(imgBrush); myGeometryModel.Material = myMaterial; RotateTransform3D myRotateTransform3D = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 1, 0), 0), new Point3D(0, 0, 0)); Transform3DGroup trGrp = new Transform3DGroup(); RotateTransform3D nrt1 = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), 45)); RotateTransform3D nrt2 = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 45)); TranslateTransform3D trs = new TranslateTransform3D(new Vector3D(0, 0, 0)); trGrp.Children.Clear(); trGrp.Children.Add(nrt1); trGrp.Children.Add(nrt2); trGrp.Children.Add(myRotateTransform3D); trGrp.Children.Add(trs); myGeometryModel.Transform = trGrp; DoubleAnimation rotAnimaion = new DoubleAnimation(0, 360, new Duration(TimeSpan.FromSeconds(2))); rotAnimaion.RepeatBehavior = RepeatBehavior.Forever; myRotateTransform3D.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, rotAnimaion); myModel3DGroup.Children.Add(myGeometryModel); myModelVisual3D.Content = myModel3DGroup; myViewport3D.Children.Add(myModelVisual3D); this.Content = myViewport3D; }
/// <summary> /// Convert a Revit mesh to a Helix mesh for visualization. /// In order to merge mesh vertices, this method uses a dictionary with a string key formed as x:y:z of the point. /// This assumes that where vertices are the "same" in the Revit mesh, they will have the same coordinates. This /// is NOT a safe strategy to use in other mesh-processing contexts where vertices might have small discrepancies. /// </summary> /// <param name="rmesh"></param> /// <param name="octree"></param> /// <param name="node"></param> /// <returns></returns> private static MeshGeometry3D RevitMeshToHelixMesh(Mesh rmesh, Octree.OctreeSearch.Octree octree, NodeModel node) { var builder = new MeshBuilder(); var points = new Point3DCollection(); var tex = new PointCollection(); var norms = new Vector3DCollection(); var tris = new List <int>(); //A dictionary which will contain a point, a normal, and an index //keyed on the location of the point as a hash var pointDict = new Dictionary <string, PointData>(); for (int i = 0; i < rmesh.NumTriangles; ++i) { var tri = rmesh.get_Triangle(i); //calculate the face normal by //getting the cross product of two edges var a = tri.get_Vertex(0); var b = tri.get_Vertex(1); var c = tri.get_Vertex(2); var e1 = b - a; var e2 = c - a; var normXYZ = e1.CrossProduct(e2).Normalize(); var normal = new Vector3D(normXYZ.X, normXYZ.Y, normXYZ.Z); for (int j = 0; j < 3; j++) { var pt = RevitPointToWindowsPoint(tri.get_Vertex(j)); var key = pt.X + ":" + pt.Y + ":" + pt.Z; if (!pointDict.ContainsKey(key)) { //if the dictionary doesn't contain the key var pd = new PointData(pt.X, pt.Y, pt.Z); pd.Normals.Add(normal); pd.Index = pointDict.Count; pointDict.Add(key, pd); tris.Add(pd.Index); } else { //add an index to our tris array //add a normal to our internal collection //for post processing var data = pointDict[key]; tris.Add(data.Index); data.Normals.Add(normal); } } } var lst = pointDict.ToList(); lst.ForEach(x => points.Add(x.Value.Position)); lst.ForEach(x => octree.AddNode(x.Value.Position.X, x.Value.Position.Y, x.Value.Position.Z, node.GUID.ToString())); lst.ForEach(x => tex.Add(x.Value.Tex)); //merge the normals foreach (var pd in lst) { var avg = new Vector3D(); var nList = pd.Value.Normals; foreach (var n in nList) { avg.X += n.X; avg.Y += n.Y; avg.Z += n.Z; } avg.X = avg.X / nList.Count; avg.Y = avg.Y / nList.Count; avg.Z = avg.Z / nList.Count; norms.Add(avg); } builder.Append(points, tris, norms, tex); Debug.WriteLine(string.Format("Mesh had {0} faces coming in and {1} faces going out.", rmesh.NumTriangles, builder.TriangleIndices.Count / 3)); return(builder.ToMesh(true)); }
public Renderer() { InitializeComponent(); Loaded += LoadedHandler; //GotFocus += (object sender, RoutedEventArgs e) => { Debug.Write("renderer got focus\n"); }; //LostFocus += (object sender, RoutedEventArgs e) => { Debug.Write("renderer lost focus\n"); }; // TODO add focusing to all windows Focusable = true; MouseDown += (object sender, MouseButtonEventArgs e) => { Focus(); }; // Declare scene objects. Viewport3D myViewport3D = new Viewport3D(); Model3DGroup myModel3DGroup = new Model3DGroup(); GeometryModel3D myGeometryModel = new GeometryModel3D(); ModelVisual3D myModelVisual3D = new ModelVisual3D(); Camera camera = new Camera(myViewport3D); KeyDown += camera.OnKeyDownHandler; KeyUp += camera.OnKeyUpHandler; // Define the lights cast in the scene. Without light, the 3D object cannot // be seen. Note: to illuminate an object from additional directions, create // additional lights. DirectionalLight myDirectionalLight = new DirectionalLight(); myDirectionalLight.Color = Colors.White; myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61); myModel3DGroup.Children.Add(myDirectionalLight); // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet // is created. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); // Create a collection of normal vectors for the MeshGeometry3D. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myMeshGeometry3D.Normals = myNormalCollection; // Create a collection of vertex positions for the MeshGeometry3D. Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myMeshGeometry3D.Positions = myPositionCollection; // Create a collection of texture coordinates for the MeshGeometry3D. PointCollection myTextureCoordinatesCollection = new PointCollection(); myTextureCoordinatesCollection.Add(new Point(0, 0)); myTextureCoordinatesCollection.Add(new Point(1, 0)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(0, 1)); myTextureCoordinatesCollection.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection; // Create a collection of triangle indices for the MeshGeometry3D. Int32Collection myTriangleIndicesCollection = new Int32Collection(); myTriangleIndicesCollection.Add(0); myTriangleIndicesCollection.Add(1); myTriangleIndicesCollection.Add(2); myTriangleIndicesCollection.Add(3); myTriangleIndicesCollection.Add(4); myTriangleIndicesCollection.Add(5); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; // Apply the mesh to the geometry model. myGeometryModel.Geometry = myMeshGeometry3D; // The material specifies the material applied to the 3D object. In this sample a // linear gradient covers the surface of the 3D object. // Create a horizontal linear gradient with four stops. LinearGradientBrush myHorizontalGradient = new LinearGradientBrush(); myHorizontalGradient.StartPoint = new Point(0, 0.5); myHorizontalGradient.EndPoint = new Point(1, 0.5); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); // Define material and apply to the mesh geometries. DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient); myGeometryModel.Material = myMaterial; // Apply a transform to the object. In this sample, a rotation transform is applied, // rendering the 3D object rotated. RotateTransform3D myRotateTransform3D = new RotateTransform3D(); AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D(); myAxisAngleRotation3d.Axis = new Vector3D(0, 3, 0); myAxisAngleRotation3d.Angle = 40; myRotateTransform3D.Rotation = myAxisAngleRotation3d; myGeometryModel.Transform = myRotateTransform3D; // Add the geometry model to the model group. myModel3DGroup.Children.Add(myGeometryModel); Grid grid = new Grid(myModel3DGroup); // Add the group of models to the ModelVisual3d. myModelVisual3D.Content = myModel3DGroup; // myViewport3D.Children.Add(myModelVisual3D); // Apply the viewport to the page so it will be rendered. this.Content = myViewport3D; }
public EmissiveMaterialExample() { // Declare scene objects. Viewport3D myViewport3D = new Viewport3D(); Model3DGroup myModel3DGroup = new Model3DGroup(); GeometryModel3D myGeometryModel = new GeometryModel3D(); ModelVisual3D myModelVisual3D = new ModelVisual3D(); // Defines the camera used to view the 3D object. In order to view the 3D object, // the camera must be positioned and pointed such that the object is within view // of the camera. PerspectiveCamera myPCamera = new PerspectiveCamera(); // Specify where in the 3D scene the camera is. myPCamera.Position = new Point3D(0, 0, 2); // Specify the direction that the camera is pointing. myPCamera.LookDirection = new Vector3D(0, 0, -1); // Define camera's horizontal field of view in degrees. myPCamera.FieldOfView = 60; // Asign the camera to the viewport myViewport3D.Camera = myPCamera; // Define the lights cast in the scene. Without light, the 3D object cannot // be seen. Note: to illuminate an object from additional directions, create // additional lights. DirectionalLight myDirectionalLight = new DirectionalLight(); myDirectionalLight.Color = Colors.White; myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61); myModel3DGroup.Children.Add(myDirectionalLight); // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet // is created. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); // Create a collection of normal vectors for the MeshGeometry3D. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myMeshGeometry3D.Normals = myNormalCollection; // Create a collection of vertex positions for the MeshGeometry3D. Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myMeshGeometry3D.Positions = myPositionCollection; // Create a collection of texture coordinates for the MeshGeometry3D. PointCollection myTextureCoordinatesCollection = new PointCollection(); myTextureCoordinatesCollection.Add(new Point(0, 0)); myTextureCoordinatesCollection.Add(new Point(1, 0)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(0, 1)); myTextureCoordinatesCollection.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection; // Create a collection of triangle indices for the MeshGeometry3D. Int32Collection myTriangleIndicesCollection = new Int32Collection(); myTriangleIndicesCollection.Add(0); myTriangleIndicesCollection.Add(1); myTriangleIndicesCollection.Add(2); myTriangleIndicesCollection.Add(3); myTriangleIndicesCollection.Add(4); myTriangleIndicesCollection.Add(5); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; // Apply the mesh to the geometry model. myGeometryModel.Geometry = myMeshGeometry3D; // <SnippetEmissiveMaterialCodeExampleInline1> // The material property of GeometryModel3D specifies the material applied to the 3D object. // In this sample the material applied to the 3D object is made up of two materials layered // on top of each other - a DiffuseMaterial (gradient brush) with an EmissiveMaterial // layered on top (blue SolidColorBrush). The EmmisiveMaterial alters the appearance of // the gradient toward blue. // Create a horizontal linear gradient with four stops. LinearGradientBrush myHorizontalGradient = new LinearGradientBrush(); myHorizontalGradient.StartPoint = new Point(0, 0.5); myHorizontalGradient.EndPoint = new Point(1, 0.5); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); // Define material that will use the gradient. DiffuseMaterial myDiffuseMaterial = new DiffuseMaterial(myHorizontalGradient); // Add this gradient to a MaterialGroup. MaterialGroup myMaterialGroup = new MaterialGroup(); myMaterialGroup.Children.Add(myDiffuseMaterial); // Define an Emissive Material with a blue brush. Color c = new Color(); c.ScA = 1; c.ScB = 255; c.ScR = 0; c.ScG = 0; EmissiveMaterial myEmissiveMaterial = new EmissiveMaterial(new SolidColorBrush(c)); // Add the Emmisive Material to the Material Group. myMaterialGroup.Children.Add(myEmissiveMaterial); // Add the composite material to the 3D model. myGeometryModel.Material = myMaterialGroup; // </SnippetEmissiveMaterialCodeExampleInline1> // Apply a transform to the object. In this sample, a rotation transform is applied, // rendering the 3D object rotated. RotateTransform3D myRotateTransform3D = new RotateTransform3D(); AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D(); myAxisAngleRotation3d.Axis = new Vector3D(0, 3, 0); myAxisAngleRotation3d.Angle = 40; myRotateTransform3D.Rotation = myAxisAngleRotation3d; myGeometryModel.Transform = myRotateTransform3D; // Add the geometry model to the model group. myModel3DGroup.Children.Add(myGeometryModel); // Add the group of models to the ModelVisual3d. myModelVisual3D.Content = myModel3DGroup; myViewport3D.Children.Add(myModelVisual3D); // Apply the viewport to the page so it will be rendered. this.Content = myViewport3D; }
private Model3DGroup GenerateTileStitching(PointCloudTileSource tileSource, TileInfo3D tileInfo) { PointCloudTile tile = tileInfo.Tile; MeshGeometry3D mesh = GetTileMeshGeometry(tileInfo.CurrentGeometry); Grid <float> grid = tileInfo.CurrentGrid; //Model3DGroup stitchingGroup = new Model3DGroup(); bool hasTop = false; bool hasLeft = false; Point3D topCornerPoint = default(Point3D); Point3D leftCornerPoint = default(Point3D); Vector3D topCornerNormal = default(Vector3D); Vector3D leftCornerNormal = default(Vector3D); // connect to left tile (if available) if (tile.Col > 0) { PointCloudTile leftTile = tileSource.TileSet.GetTile(tile.Row, tile.Col - 1); TileInfo3D leftTileInfo = null; if (leftTile != null && m_tileInfo.TryGetValue(leftTile, out leftTileInfo) && leftTileInfo.CurrentGrid == grid) { MeshGeometry3D leftMesh = GetTileMeshGeometry(leftTileInfo.CurrentGeometry); int leftPositionsStart = leftMesh.Positions.Count - grid.SizeY; hasLeft = true; leftCornerPoint = leftMesh.Positions[leftPositionsStart]; leftCornerNormal = leftMesh.Normals[leftPositionsStart]; if (!tileInfo.HasStitching(TileStitchingEdge.Left)) { MeshGeometry3D stitchingMesh = new MeshGeometry3D(); int positionCount = grid.SizeY * 2; Point3DCollection positions = new Point3DCollection(positionCount); Vector3DCollection normals = new Vector3DCollection(positionCount); for (int edgePosition = 0; edgePosition < grid.SizeY; edgePosition++) { positions.Add(leftMesh.Positions[leftPositionsStart + edgePosition]); normals.Add(leftMesh.Normals[leftPositionsStart + edgePosition]); positions.Add(mesh.Positions[edgePosition]); normals.Add(mesh.Normals[edgePosition]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection((grid.SizeY - 1) * 6); for (int i = 0; i < grid.SizeY - 1; i++) { int j = 2 * i; indices.Add(j); indices.Add(j + 1); indices.Add(j + 2); indices.Add(j + 2); indices.Add(j + 1); indices.Add(j + 3); } stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, leftTileInfo.CurrentGrid, TileStitchingEdge.Left); //stitchingGroup.Children.Add(stitchingModel); } } } // connect to top tile (if available) if (tile.Row > 0) { PointCloudTile topTile = tileSource.TileSet.GetTile(tile.Row - 1, tile.Col); TileInfo3D topTileInfo = null; if (topTile != null && m_tileInfo.TryGetValue(topTile, out topTileInfo) && topTileInfo.CurrentGrid == grid) { MeshGeometry3D topMesh = GetTileMeshGeometry(topTileInfo.CurrentGeometry); hasTop = true; topCornerPoint = topMesh.Positions[grid.SizeY - 1]; topCornerNormal = topMesh.Normals[grid.SizeY - 1]; if (!tileInfo.HasStitching(TileStitchingEdge.Top)) { MeshGeometry3D stitchingMesh = new MeshGeometry3D(); int positionCount = grid.SizeX * 2; Point3DCollection positions = new Point3DCollection(positionCount); Vector3DCollection normals = new Vector3DCollection(positionCount); for (int edgePosition = 0; edgePosition < mesh.Positions.Count; edgePosition += grid.SizeY) { positions.Add(topMesh.Positions[edgePosition + grid.SizeY - 1]); normals.Add(topMesh.Normals[edgePosition + grid.SizeY - 1]); positions.Add(mesh.Positions[edgePosition]); normals.Add(mesh.Normals[edgePosition]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection((grid.SizeX - 1) * 6); for (int i = 0; i < grid.SizeX - 1; i++) { int j = 2 * i; indices.Add(j); indices.Add(j + 2); indices.Add(j + 1); indices.Add(j + 2); indices.Add(j + 3); indices.Add(j + 1); } stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, topTileInfo.CurrentGrid, TileStitchingEdge.Top); //stitchingGroup.Children.Add(stitchingModel); } } } // connect to top left tile (if available) if (hasTop && hasLeft && !tileInfo.HasStitching(TileStitchingEdge.TopLeft)) { PointCloudTile topleftTile = tileSource.TileSet.GetTile(tile.Row - 1, tile.Col - 1); TileInfo3D topleftTileInfo = null; if (topleftTile != null && m_tileInfo.TryGetValue(topleftTile, out topleftTileInfo)) { MeshGeometry3D topleftMesh = GetTileMeshGeometry(topleftTileInfo.CurrentGeometry); MeshGeometry3D stitchingMesh = new MeshGeometry3D(); Point3DCollection positions = new Point3DCollection(4); Vector3DCollection normals = new Vector3DCollection(4); { positions.Add(topleftMesh.Positions[topleftMesh.Positions.Count - 1]); normals.Add(topleftMesh.Normals[topleftMesh.Positions.Count - 1]); positions.Add(topCornerPoint); normals.Add(topCornerNormal); positions.Add(leftCornerPoint); normals.Add(leftCornerNormal); positions.Add(mesh.Positions[0]); normals.Add(mesh.Normals[0]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection(6); indices.Add(0); indices.Add(1); indices.Add(2); indices.Add(2); indices.Add(1); indices.Add(3); stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, topleftTileInfo.CurrentGrid, TileStitchingEdge.TopLeft); //stitchingGroup.Children.Add(stitchingModel); } } return(tileInfo.GetNewStitching()); }
/// <summary> /// /// </summary> /// <param name="vertices"></param> /// <param name="normals"></param> /// <param name="indices"></param> /// <param name="textures"></param> protected void TriangleSubdivide(Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { for (int i = 0; i < 3; i++) { verticesBase[2 - i] = vertices[vertices.Count - 1]; normalsBase[2 - i] = normals[vertices.Count - 1]; texturesBase[2 - i] = textures[vertices.Count - 1]; vertices.RemoveAt(vertices.Count - 1); normals.RemoveAt(normals.Count - 1); indices.RemoveAt(indices.Count - 1); textures.RemoveAt(textures.Count - 1); } int indexStart = vertices.Count; for (int slice = 0; slice <= Slices; slice++) { double weight = (double)slice / Slices; Point3D vertex1 = Point3DWeight(verticesBase[0], verticesBase[1], weight); Point3D vertex2 = Point3DWeight(verticesBase[0], verticesBase[2], weight); Vector3D normal1 = Vector3DWeight(normalsBase[0], normalsBase[1], weight); Vector3D normal2 = Vector3DWeight(normalsBase[0], normalsBase[2], weight); Point texture1 = PointWeight(texturesBase[0], texturesBase[1], weight); Point texture2 = PointWeight(texturesBase[0], texturesBase[2], weight); for (int i = 0; i <= slice; i++) { weight = (double)i / slice; if (Double.IsNaN(weight)) { weight = 0; } vertices.Add(Point3DWeight(vertex1, vertex2, weight)); normals.Add(Vector3DWeight(normal1, normal2, weight)); textures.Add(PointWeight(texture1, texture2, weight)); } } for (int slice = 0; slice < Slices; slice++) { int base1 = (slice + 1) * slice / 2; int base2 = base1 + slice + 1; for (int i = 0; i <= 2 * slice; i++) { int half = i / 2; if ((i & 1) == 0) // even { indices.Add(indexStart + base1 + half); indices.Add(indexStart + base2 + half); indices.Add(indexStart + base2 + half + 1); } else // odd { indices.Add(indexStart + base1 + half); indices.Add(indexStart + base2 + half + 1); indices.Add(indexStart + base1 + half + 1); } } } }
private void AddFace(string values) { // A polygonal face. The numbers are indexes into the arrays of vertex positions, // texture coordinates, and normals respectively. A number may be omitted if, // for example, texture coordinates are not being defined in the model. // There is no maximum number of vertices that a single polygon may contain. // The .obj file specification says that each face must be flat and convex. var fields = values.Split(' '); var pts = new Point3DCollection(); var tex = new PointCollection(); var norm = new Vector3DCollection(); foreach (var field in fields) { if (String.IsNullOrEmpty(field)) { continue; } var ff = field.Split('/'); int vi = int.Parse(ff[0]); int vti = ff.Length > 1 && ff[1].Length > 0 ? int.Parse(ff[1]) : -1; int vni = ff.Length > 2 && ff[2].Length > 0 ? int.Parse(ff[2]) : -1; pts.Add(Points[vi - 1]); if (vti >= 0) { tex.Add(TexCoords[vti - 1]); } if (vni >= 0) { norm.Add(Normals[vni - 1]); } } if (tex.Count == 0) { tex = null; } if (norm.Count == 0) { norm = null; } // QUAD if (pts.Count == 4) { CurrentGroup.MeshBuilder.AddQuads(pts, norm, tex); return; } // TRIANGLE if (pts.Count == 3) { CurrentGroup.MeshBuilder.AddTriangles(pts, norm, tex); return; } // POLYGONS (flat and convex) var poly3D = new Polygon3D(pts); // Transform the polygon to 2D var poly2D = poly3D.Flatten(); // Triangulate var tri = poly2D.Triangulate(); if (tri != null) { // Add the triangle indices with the 3D points var mesh = new MeshBuilder(); mesh.Append(pts, tri); CurrentGroup.MeshBuilder.Append(mesh); } }
private GeometryModel3D CreateSquare(Point3D offset, System.Windows.Media.Color theColor, double sizeX = 0.5, double sizeY = 0.5) { GeometryModel3D myGeometryModel = new GeometryModel3D(); // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet is created. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); float zVal = 1; // Create a collection of normal vectors for the MeshGeometry3D. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, zVal)); myNormalCollection.Add(new Vector3D(0, 0, zVal)); myNormalCollection.Add(new Vector3D(0, 0, zVal)); myNormalCollection.Add(new Vector3D(0, 0, zVal)); myNormalCollection.Add(new Vector3D(0, 0, zVal)); myNormalCollection.Add(new Vector3D(0, 0, zVal)); myMeshGeometry3D.Normals = myNormalCollection; // Create a collection of vertex positions for the MeshGeometry3D. Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(-sizeX + offset.X, -sizeY + offset.Y, offset.Z)); myPositionCollection.Add(new Point3D(sizeX + offset.X, -sizeY + offset.Y, offset.Z)); myPositionCollection.Add(new Point3D(sizeX + offset.X, sizeY + offset.Y, offset.Z)); myPositionCollection.Add(new Point3D(sizeX + offset.X, sizeY + offset.Y, offset.Z)); myPositionCollection.Add(new Point3D(-sizeX + offset.X, sizeY + offset.Y, offset.Z)); myPositionCollection.Add(new Point3D(-sizeX + offset.X, -sizeY + offset.Y, offset.Z)); myMeshGeometry3D.Positions = myPositionCollection; // Create a collection of texture coordinates for the MeshGeometry3D. PointCollection myTextureCoordinatesCollection = new PointCollection(); myTextureCoordinatesCollection.Add(new System.Windows.Point(0, 0)); myTextureCoordinatesCollection.Add(new System.Windows.Point(1, 0)); myTextureCoordinatesCollection.Add(new System.Windows.Point(1, 1)); myTextureCoordinatesCollection.Add(new System.Windows.Point(1, 1)); myTextureCoordinatesCollection.Add(new System.Windows.Point(0, 1)); myTextureCoordinatesCollection.Add(new System.Windows.Point(0, 0)); myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection; // Create a collection of triangle indices for the MeshGeometry3D. Int32Collection myTriangleIndicesCollection = new Int32Collection(); myTriangleIndicesCollection.Add(0); myTriangleIndicesCollection.Add(1); myTriangleIndicesCollection.Add(2); myTriangleIndicesCollection.Add(3); myTriangleIndicesCollection.Add(4); myTriangleIndicesCollection.Add(5); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; // Apply the mesh to the geometry model. myGeometryModel.Geometry = myMeshGeometry3D; SolidColorBrush theBrush = new SolidColorBrush(theColor); // Define material and apply to the mesh geometries. //DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient); DiffuseMaterial myMaterial = new DiffuseMaterial(theBrush); myGeometryModel.Material = myMaterial; myGeometryModel.BackMaterial = myMaterial; return(myGeometryModel); }
public bool Read(String data, XbimMatrix3D?tr = null) { using (StringReader sr = new StringReader(data)) { Matrix3D? m3d = null; RotateTransform3D r = new RotateTransform3D(); if (tr.HasValue) //set up the windows media transforms { m3d = new Matrix3D(tr.Value.M11, tr.Value.M12, tr.Value.M13, tr.Value.M14, tr.Value.M21, tr.Value.M22, tr.Value.M23, tr.Value.M24, tr.Value.M31, tr.Value.M32, tr.Value.M33, tr.Value.M34, tr.Value.OffsetX, tr.Value.OffsetY, tr.Value.OffsetZ, tr.Value.M44); r = tr.Value.GetRotateTransform3D(); } Point3DCollection vertexList = new Point3DCollection(); //holds the actual positions of the vertices in this data set in the mesh Vector3DCollection normalList = new Vector3DCollection(); //holds the actual normals of the vertices in this data set in the mesh String line; // Read and display lines from the data until the end of // the data is reached. while ((line = sr.ReadLine()) != null) { string[] tokens = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length > 1) //we need a command and some data { string command = tokens[0].Trim().ToUpper(); switch (command) { case "P": int pointCount = 512; int faceCount = 128; int triangleCount = 256; int normalCount = 512; if (tokens.Length > 1) { pointCount = Int32.Parse(tokens[2]); } if (tokens.Length > 2) { faceCount = Int32.Parse(tokens[3]); } if (tokens.Length > 3) { triangleCount = Int32.Parse(tokens[4]); } if (tokens.Length > 4) { normalCount = Math.Max(Int32.Parse(tokens[5]), pointCount); //can't really have less normals than points } vertexList = new Point3DCollection(pointCount); normalList = new Vector3DCollection(normalCount); //for efficienciency avoid continual regrowing //this.Mesh.Positions = this.Mesh.Positions.GrowBy(pointCount); //this.Mesh.Normals = this.Mesh.Normals.GrowBy(normalCount); //this.Mesh.TriangleIndices = this.Mesh.TriangleIndices.GrowBy(triangleCount*3); break; case "F": break; case "V": //process vertices for (int i = 1; i < tokens.Length; i++) { string[] xyz = tokens[i].Split(','); Point3D p = new Point3D(Convert.ToDouble(xyz[0], CultureInfo.InvariantCulture), Convert.ToDouble(xyz[1], CultureInfo.InvariantCulture), Convert.ToDouble(xyz[2], CultureInfo.InvariantCulture)); if (m3d.HasValue) { p = m3d.Value.Transform(p); } vertexList.Add(p); } break; case "N": //processes normals for (int i = 1; i < tokens.Length; i++) { string[] xyz = tokens[i].Split(','); Vector3D v = new Vector3D(Convert.ToDouble(xyz[0], CultureInfo.InvariantCulture), Convert.ToDouble(xyz[1], CultureInfo.InvariantCulture), Convert.ToDouble(xyz[2], CultureInfo.InvariantCulture)); normalList.Add(v); } break; case "T": //process triangulated meshes Vector3D currentNormal = new Vector3D(); //each time we start a new mesh face we have to duplicate the vertices to ensure that we get correct shading of planar and non planar faces Dictionary <int, int> writtenVertices = new Dictionary <int, int>(); for (int i = 1; i < tokens.Length; i++) { string[] triangleIndices = tokens[i].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (triangleIndices.Length != 3) { throw new Exception("Invalid triangle definition"); } for (int t = 0; t < 3; t++) { string[] indexNormalPair = triangleIndices[t].Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (indexNormalPair.Length > 1) //we have a normal defined { string normalStr = indexNormalPair[1].Trim(); switch (normalStr) { case "F": //Front currentNormal = new Vector3D(0, -1, 0); break; case "B": //Back currentNormal = new Vector3D(0, 1, 0); break; case "L": //Left currentNormal = new Vector3D(-1, 0, 0); break; case "R": //Right currentNormal = new Vector3D(1, 0, 0); break; case "U": //Up currentNormal = new Vector3D(0, 0, 1); break; case "D": //Down currentNormal = new Vector3D(0, 0, -1); break; default: //it is an index number int normalIndex = int.Parse(indexNormalPair[1]); currentNormal = normalList[normalIndex]; break; } if (tr.HasValue) { currentNormal = r.Transform(currentNormal); } } //now add the index int index = int.Parse(indexNormalPair[0]); int alreadyWrittenAt = index; //in case it is the first mesh if (!writtenVertices.TryGetValue(index, out alreadyWrittenAt)) //if we haven't written it in this mesh pass, add it again unless it is the first one which we know has been written { //all vertices will be unique and have only one normal writtenVertices.Add(index, this.PositionCount); this.Mesh.TriangleIndices.Add(this.PositionCount); this.Mesh.Positions.Add(vertexList[index]); this.Mesh.Normals.Add(currentNormal); } else //just add the index reference { this.Mesh.TriangleIndices.Add(alreadyWrittenAt); } } } break; default: throw new Exception("Invalid Geometry Command"); } } } } return(true); }
public MultipleTransformationsExample() { // Declare scene objects. Viewport3D myViewport3D = new Viewport3D(); Model3DGroup myModel3DGroup = new Model3DGroup(); GeometryModel3D myGeometryModel = new GeometryModel3D(); ModelVisual3D myModelVisual3D = new ModelVisual3D(); // Defines the camera used to view the 3D object. In order to view the 3D object, // the camera must be positioned and pointed such that the object is within view // of the camera. PerspectiveCamera myPCamera = new PerspectiveCamera(); // Specify where in the 3D scene the camera is. myPCamera.Position = new Point3D(0, 0, 2); // Specify the direction that the camera is pointing. myPCamera.LookDirection = new Vector3D(0, 0, -1); // Define camera's horizontal field of view in degrees. myPCamera.FieldOfView = 60; // Asign the camera to the viewport myViewport3D.Camera = myPCamera; // Define the lights cast in the scene. Without light, the 3D object cannot // be seen. Note: to illuminate an object from additional directions, create // additional lights. DirectionalLight myDirectionalLight = new DirectionalLight(); myDirectionalLight.Color = Colors.White; myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61); myModel3DGroup.Children.Add(myDirectionalLight); // The geometry specifies the shape of the 3D plane. In this sample, a flat sheet // is created. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D(); // Create a collection of normal vectors for the MeshGeometry3D. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 0, 1)); myMeshGeometry3D.Normals = myNormalCollection; // Create a collection of vertex positions for the MeshGeometry3D. Point3DCollection myPositionCollection = new Point3DCollection(); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5)); myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5)); myMeshGeometry3D.Positions = myPositionCollection; // Create a collection of texture coordinates for the MeshGeometry3D. PointCollection myTextureCoordinatesCollection = new PointCollection(); myTextureCoordinatesCollection.Add(new Point(0, 0)); myTextureCoordinatesCollection.Add(new Point(1, 0)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(1, 1)); myTextureCoordinatesCollection.Add(new Point(0, 1)); myTextureCoordinatesCollection.Add(new Point(0, 0)); myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection; // Create a collection of triangle indices for the MeshGeometry3D. Int32Collection myTriangleIndicesCollection = new Int32Collection(); myTriangleIndicesCollection.Add(0); myTriangleIndicesCollection.Add(1); myTriangleIndicesCollection.Add(2); myTriangleIndicesCollection.Add(3); myTriangleIndicesCollection.Add(4); myTriangleIndicesCollection.Add(5); myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection; // Apply the mesh to the geometry model. myGeometryModel.Geometry = myMeshGeometry3D; // The material specifies the material applied to the 3D object. In this sample a // linear gradient covers the surface of the 3D object. // Create a horizontal linear gradient with four stops. LinearGradientBrush myHorizontalGradient = new LinearGradientBrush(); myHorizontalGradient.StartPoint = new Point(0, 0.5); myHorizontalGradient.EndPoint = new Point(1, 0.5); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); // Define material and apply to the mesh geometries. DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient); myGeometryModel.Material = myMaterial; // <SnippetMultiple3DTransformationsCodeExampleInline1> // Apply multiple transformations to the object. In this sample, a rotation and scale // transform is applied. // Create and apply a transformation that rotates the object. RotateTransform3D myRotateTransform3D = new RotateTransform3D(); AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D(); myAxisAngleRotation3d.Axis = new Vector3D(0, 3, 0); myAxisAngleRotation3d.Angle = 40; myRotateTransform3D.Rotation = myAxisAngleRotation3d; // Add the rotation transform to a Transform3DGroup Transform3DGroup myTransform3DGroup = new Transform3DGroup(); myTransform3DGroup.Children.Add(myRotateTransform3D); // Create and apply a scale transformation that stretches the object along the local x-axis // by 200 percent and shrinks it along the local y-axis by 50 percent. ScaleTransform3D myScaleTransform3D = new ScaleTransform3D(); myScaleTransform3D.ScaleX = 2; myScaleTransform3D.ScaleY = 0.5; myScaleTransform3D.ScaleZ = 1; // Add the scale transform to the Transform3DGroup. myTransform3DGroup.Children.Add(myScaleTransform3D); // Set the Transform property of the GeometryModel to the Transform3DGroup which includes // both transformations. The 3D object now has two Transformations applied to it. myGeometryModel.Transform = myTransform3DGroup; // </SnippetMultiple3DTransformationsCodeExampleInline1> // Add the geometry model to the model group. myModel3DGroup.Children.Add(myGeometryModel); // Add the group of models to the ModelVisual3d. myModelVisual3D.Content = myModel3DGroup; myViewport3D.Children.Add(myModelVisual3D); // Apply the viewport to the page so it will be rendered. this.Content = myViewport3D; }
/// <summary> /// /// </summary> /// <param name="args"></param> /// <param name="vertices"></param> /// <param name="normals"></param> /// <param name="indices"></param> /// <param name="textures"></param> protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); Vector3D normal = new Vector3D(0, 0, 1); double angleInner = 2 * Math.PI / Sides; double radius = Length / 2 / Math.Sin(angleInner / 2); double angle = 3 * Math.PI / 2 + angleInner / 2; double xMin = 0, xMax = 0, yMin = 0, yMax = 0; for (int side = 0; side < Sides; side++) { double x = Math.Cos(angle); double y = Math.Sin(angle); xMin = Math.Min(xMin, x); xMax = Math.Max(xMax, x); yMin = Math.Min(yMin, y); yMax = Math.Max(yMax, y); angle += angleInner; } angle = 3 * Math.PI / 2 + angleInner / 2; for (int side = 0; side < Sides; side++) { vertices.Add(new Point3D(0, 0, 0)); textures.Add(new Point(-xMin / (xMax - xMin), yMax / (yMax - yMin))); normals.Add(normal); double x = Math.Cos(angle); double y = Math.Sin(angle); vertices.Add(new Point3D(x, y, 0)); textures.Add(new Point((x - xMin) / (xMax - xMin), (yMax - y) / (yMax - yMin))); normals.Add(normal); angle += angleInner; x = Math.Cos(angle); y = Math.Sin(angle); vertices.Add(new Point3D(x, y, 0)); textures.Add(new Point((x - xMin) / (xMax - xMin), (yMax - y) / (yMax - yMin))); normals.Add(normal); int index = vertices.Count - 3; indices.Add(index); indices.Add(index + 1); indices.Add(index + 2); if (Slices > 1) { TriangleSubdivide(vertices, normals, indices, textures); } } }