Пример #1
0
        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
                    })
                }
            });
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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;
            }
        }
Пример #4
0
        /*Применяет произвольное 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);
            }
        }
Пример #5
0
        /// <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);
                }
            }
        }
Пример #6
0
        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");
        }
Пример #7
0
        /// <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();
        }
Пример #9
0
        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;
                    }
                }
            }
        }
Пример #10
0
        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;
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
                        }
                    }
                }
            }
        }
Пример #13
0
        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;
        }
Пример #14
0
        /// <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);
                        }
                    }
                }
            }
        }
Пример #15
0
        // 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);
        }
Пример #16
0
        //
        // 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;
        }
Пример #17
0
        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);
        }
Пример #18
0
        /// <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);
                }
            }
        }
Пример #19
0
        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;
        }
Пример #21
0
        /// <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));
        }
Пример #22
0
        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;
        }
Пример #24
0
        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());
        }
Пример #25
0
        /// <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);
                    }
                }
            }
        }
Пример #26
0
        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);
            }
        }
Пример #27
0
        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);
        }
Пример #28
0
        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);
        }
Пример #29
0
        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;
        }
Пример #30
0
        /// <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);
                }
            }
        }