Пример #1
0
        /// <summary>
        /// Reads one 3D scene from a given file (containing text variant of Wavefront OBJ format).
        /// Can read GZipped files.
        /// </summary>
        /// <param name="fileName">File-name (ending by .gz for gzipped file)</param>
        /// <param name="scene">Scene to be modified</param>
        /// <returns>Number of faces read</returns>
        public int ReadBrep(string fileName, SceneBrep scene)
        {
            if (fileName == null ||
                fileName.Length == 0)
            {
                return(SceneBrep.NULL);
            }

            StreamReader reader;

            if (fileName.EndsWith(".gz"))
            {
                reader = new StreamReader(new GZipStream(new FileStream(fileName, FileMode.Open),
                                                         CompressionMode.Decompress));
            }
            else
            {
                reader = new StreamReader(new FileStream(fileName, FileMode.Open));
            }
            int faces = ReadBrep(reader, scene);

            reader.Close();

            return(faces);
        }
Пример #2
0
 void AddToScene(SceneBrep scene, List <Vector3> v, int total)
 {
     for (int i = total; i > total - v.Count + 1; i--)
     {
         scene.AddLine(i, i - 1);
     }
 }
Пример #3
0
        private void firstCircle(Vector3 v1, Vector3 v2, SceneBrep scene, Matrix4 m)
        {
            Vector3 dif  = (v2 - v1) * size;
            Vector3 rdif = (v2 - v1) * (1 - size);

            last_circle = createCircleAround(v1, v2);
            float s = radius / curve.current_count;

            last_circle     = Transforms.scale(last_circle, s, s, s);
            connect_indices = new int[cdetail];
            Vector3 center = getCenter(last_circle);

            for (int i = 0; i < cdetail; i++)
            {
                connect_indices[i] = scene.AddVertex(Vector3.TransformPosition(last_circle[i] + v1, m));
                scene.SetNormal(connect_indices[i], Vector3.TransformVector(last_circle[i] - center, m).Normalized());
                float r = (last_circle[i].X + v1.X + 1.1f) / 2.5f;
                float g = (last_circle[i].Y + v1.Y + 1.1f) / 2.5f;
                float b = (last_circle[i].Z + v1.Z + 1.1f) / 2.5f;
                scene.SetColor(connect_indices[i], new Vector3(r, g, b));
            }

            for (int i = 0; i < cdetail; i++)
            {
                last_circle[i] += v1 + rdif;
            }
        }
Пример #4
0
        /// <summary>
        /// Construct a new Brep solid (preferebaly closed = regular one).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="param">Shape parameters if needed</param>
        /// <returns>Number of generated faces (0 in case of failure)</returns>
        public int AddMesh(SceneBrep scene, Matrix4 m, string param)
        {
            parseParams(param);
            scene.Reserve(10000000);

            curve = Curve.createCurve(level);

            firstCircle(curve.current_vertices[0], curve.current_vertices[1], scene, m);
            int count = 0;

            for (int i = 1; i < curve.current_vertices.Length - 1; i++)
            {
                if (isBent(curve.current_vertices[i - 1], curve.current_vertices[i], curve.current_vertices[i + 1]))
                {
                    count += createBentPipe(scene, m, curve.current_vertices[i - 1], curve.current_vertices[i], curve.current_vertices[i + 1]);
                }
                else
                {
                    Vector3 dif = curve.current_vertices[i] - curve.current_vertices[i - 1];
                    for (int j = 0; j < cdetail; j++)
                    {
                        last_circle[j] = last_circle[j] + dif;
                    }
                }
            }

            int l = curve.current_vertices.Length;

            count += lastCircle(curve.current_vertices[l - 2], curve.current_vertices[l - 1], scene, m);

            return(count);
        }
Пример #5
0
        private int lastCircle(Vector3 v1, Vector3 v2, SceneBrep scene, Matrix4 m)
        {
            _ = createCircleAround(v1, v2);
            Vector3 center = getCenter(last_circle);
            Vector3 dif    = (v2 - v1) * size;

            _ = (v2 - v1) * (1 - size);
            int[] v = new int[cdetail];

            for (int i = 0; i < cdetail; i++)
            {
                v[i] = scene.AddVertex(Vector3.TransformPosition(last_circle[i] + dif, m));
                scene.SetNormal(v[i], Vector3.TransformVector(last_circle[i] - center, m).Normalized());
                float r = (last_circle[i].X + 1.1f) / 2.5f;
                float g = (last_circle[i].Y + 1.1f) / 2.5f;
                float b = (last_circle[i].Z + 1.1f) / 2.5f;
                scene.SetColor(v[i], new Vector3(r, g, b));
            }

            for (int i = 0; i < cdetail - 1; i++)
            {
                scene.AddTriangle(connect_indices[i], v[i], connect_indices[i + 1]);
                scene.AddTriangle(connect_indices[i + 1], v[i], v[i + 1]);
            }

            scene.AddTriangle(connect_indices[cdetail - 1], v[cdetail - 1], connect_indices[0]);
            scene.AddTriangle(connect_indices[0], v[cdetail - 1], v[0]);

            return(cdetail * 2);
        }
        private int drawKoch(SceneBrep scene, Matrix4 m, string param)
        {
            Vector3 A, B, C, D;
            int     one, two, three, four;

            //float a = 1.0f;
            A.X   = 0;
            A.Y   = 0;
            A.Z   = 0;
            one   = scene.AddVertex(Vector3.TransformPosition(A, m));
            B.X   = 1.0f;
            B.Y   = 1.0f;
            B.Z   = 0;
            two   = scene.AddVertex(Vector3.TransformPosition(B, m));
            C.X   = 0;
            C.Y   = 1.0f;
            C.Z   = 1.0f;
            three = scene.AddVertex(Vector3.TransformPosition(C, m));
            D.X   = 1.0f;
            D.Y   = 0;
            D.Z   = 1.0f;
            four  = scene.AddVertex(Vector3.TransformPosition(D, m));

            scene.AddLine(one, two);
            scene.AddLine(two, three);
            scene.AddLine(three, one);
            scene.AddLine(four, one);
            scene.AddLine(four, two);
            scene.AddLine(four, three);

            drawKochRecursive(depthParam, scene, m, param, A, B, C, D);

            return(segments + (int)Math.Pow(4, depthParam) + 1);
        }
        public SceneBrep Clone()
        {
            SceneBrep tmp = new SceneBrep();

            tmp.geometry = new List <Vector3>(geometry);
            if (normals != null)
            {
                tmp.normals = new List <Vector3>(normals);
            }
            if (colors != null)
            {
                tmp.colors = new List <Vector3>(colors);
            }
            if (txtCoords != null)
            {
                tmp.txtCoords = new List <Vector2>(txtCoords);
            }
            if (vertexPtr != null)
            {
                tmp.vertexPtr = new List <int>(vertexPtr);
            }
            if (oppositePtr != null)
            {
                tmp.oppositePtr = new List <int>(oppositePtr);
            }
            tmp.BuildCornerTable();
            return(tmp);
        }
        /// <summary>
        /// Construct a new Brep solid (preferebaly closed = regular one).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="param">Shape parameters if needed</param>
        /// <returns>Number of generated faces (0 in case of failure)</returns>
        public int AddMesh(SceneBrep scene, Matrix4 m, string param)
        {
            // {{ TODO: put your Mesh-construction code here

            parseParams(param);
            if (bezier)
            {
                return(drawBezier(scene, m, param));
            }
            if (tetrahedron)
            {
                return(drawTetrahedron(scene, m, param));
            }
            else if (koch)
            {
                return(drawKoch(scene, m, param));
            }
            else if (rose)
            {
                return(drawRose(scene, m, param));
            }
            else if (octahedron)
            {
                int    ret    = 0;
                double s      = 0.0;
                double ds     = 1.0 / depthParam;
                double period = paramAngle;
                double dtheta = period / depthParam;
                for (int i = 1; i <= depthParam; ++i)
                {
                    double theta           = i * dtheta;
                    System.Drawing.Color c = Raster.Draw.ColorRamp(0.5 * (s + 1.0));

                    ret += drawOctahedron(scene, m, param, i, new Vector3(c.R / 255.0f, c.G / 255.0f, c.B / 255.0f), s, theta);
                    s   += ds;
                }
                return(ret);
            }
            else if (spiral)
            {
                return(drawSpiral(scene, m, param));
            }
            else if (dragon)
            {
                if (depthParam > 15)
                {
                    depthParam = 15;
                }
                return(dragonCurve(scene, m, param));
            }
            else
            {
                return(drawDefault(scene, m, param));
            }



            // }}
        }
Пример #9
0
        /// <summary>
        /// Construct a new Brep solid (preferebaly closed = regular one).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="param">Shape parameters if needed</param>
        /// <returns>Number of generated faces (0 in case of failure)</returns>
        public int AddMesh(SceneBrep scene, Matrix4 m, string param)
        {
            // !!!{{ TODO: put your Mesh-construction code here

            return(CreateTetrahedron(scene, m, Vector3.Zero, 1.0f));

            // !!!}}
        }
Пример #10
0
        /// <summary>
        /// Construct a new Brep solid (preferebaly closed = regular one).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="variant">Shape variant if needed</param>
        /// <returns>Number of generated faces (0 in case of failure)</returns>
        public int AddMesh( SceneBrep scene, Matrix4 m, float variant )
        {
            // !!!{{ TODO: put your Mesh-construction code here

              return 0;

              // !!!}}
        }
Пример #11
0
        /// <summary>
        /// Construct a new Brep solid (preferebaly closed = regular one).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="variant">Shape variant if needed</param>
        /// <returns>Number of generated faces (0 in case of failure)</returns>
        public int AddMesh(SceneBrep scene, Matrix4 m, float variant)
        {
            // !!!{{ TODO: put your Mesh-construction code here

            return(0);

            // !!!}}
        }
Пример #12
0
        /// <summary>
        /// Reads one 3D scene from a given stream (containing text variant of Wavefront OBJ format).
        /// </summary>
        /// <param name="reader">Already open text reader</param>
        /// <param name="scene">Scene to be modified</param>
        /// <returns>Number of faces read</returns>
        public int ReadBrep( StreamReader reader, SceneBrep scene )
        {
            if ( reader == null ) return SceneBrep.NULL;

              Debug.Assert( scene != null );
              scene.Reset();
              return ReadBrep( reader, scene, Matrix4.Identity );
        }
        private int drawOctahedron(SceneBrep scene, Matrix4 m, string param, float sc, Vector3 color, double s, double theta)
        {
            int     one, two, three, four, five, six;
            float   localScale = (float)sc;
            Vector4 row1       = new Vector4((float)Math.Cos(theta), (float)-Math.Sin(theta), 0, 0);
            Vector4 row2       = new Vector4((float)Math.Sin(theta), (float)Math.Cos(theta), 0, 0);
            Vector4 row3       = new Vector4(0, 0, 1, 0);
            Vector4 row4       = new Vector4(0, 0, 0, 1);

            m = new Matrix4(row1, row2, row3, row4);

            Vector3 A = new Vector3(localScale, 0, 0);

            one   = scene.AddVertex(Vector3.TransformPosition(A, m));
            A     = new Vector3(0, localScale, 0);
            two   = scene.AddVertex(Vector3.TransformPosition(A, m));
            A     = new Vector3(-localScale, 0, 0);
            three = scene.AddVertex(Vector3.TransformPosition(A, m));
            A     = new Vector3(0, -localScale, 0);
            four  = scene.AddVertex(Vector3.TransformPosition(A, m));
            A     = new Vector3(0, 0, localScale);
            five  = scene.AddVertex(Vector3.TransformPosition(A, m));
            A     = new Vector3(0, 0, -localScale);
            six   = scene.AddVertex(Vector3.TransformPosition(A, m));

            scene.SetTxtCoord(one, new Vector2((float)s, (float)s));
            scene.SetTxtCoord(two, new Vector2((float)s, (float)s));
            scene.SetTxtCoord(three, new Vector2((float)s, (float)s));
            scene.SetTxtCoord(four, new Vector2((float)s, (float)s));
            scene.SetTxtCoord(five, new Vector2((float)s, (float)s));
            scene.SetTxtCoord(six, new Vector2((float)s, (float)s));

            scene.SetColor(one, color);
            scene.SetColor(two, color);
            scene.SetColor(three, color);
            scene.SetColor(four, color);
            scene.SetColor(five, color);
            scene.SetColor(six, color);


            scene.AddLine(one, two);
            scene.AddLine(two, three);
            scene.AddLine(three, four);
            scene.AddLine(four, one);

            scene.AddLine(five, one);
            scene.AddLine(five, two);
            scene.AddLine(five, three);
            scene.AddLine(five, four);

            scene.AddLine(six, one);
            scene.AddLine(six, two);
            scene.AddLine(six, three);
            scene.AddLine(six, four);


            return(6);
        }
Пример #14
0
        private int CreateTetrahedron(SceneBrep scene, Matrix4 m, Vector3 center, float size)
        {
            int[] v = new int[4];
            float z = (float)(size * Math.Sqrt(0.5));

            Vector3 A = new Vector3(size, 0.0f, -z);
            Vector3 B = new Vector3(-size, 0.0f, -z);
            Vector3 C = new Vector3(0.0f, size, z);
            Vector3 D = new Vector3(0.0f, -size, z);

            // vertices:
            v[0] = scene.AddVertex(Vector3.TransformPosition(A, m));
            v[1] = scene.AddVertex(Vector3.TransformPosition(B, m));
            v[2] = scene.AddVertex(Vector3.TransformPosition(C, m));
            v[3] = scene.AddVertex(Vector3.TransformPosition(D, m));

            // normal vectors:
            scene.SetNormal(v[0], Vector3.TransformVector(A, m).Normalized());
            scene.SetNormal(v[1], Vector3.TransformVector(B, m).Normalized());
            scene.SetNormal(v[2], Vector3.TransformVector(C, m).Normalized());
            scene.SetNormal(v[3], Vector3.TransformVector(D, m).Normalized());

            // texture coordinates:
            scene.SetTxtCoord(v[0], new Vector2(1.0f, 0.0f));
            scene.SetTxtCoord(v[1], new Vector2(0.0f, 0.0f));
            scene.SetTxtCoord(v[2], new Vector2(1.0f, 1.0f));
            scene.SetTxtCoord(v[3], new Vector2(0.0f, 1.0f));

            // colors:
            long seed = (long)Math.Min(long.MaxValue, (m.Row3.LengthSquared * 10000.0f));

            seed = RandomStatic.numericRecipes(seed);
            float r = (seed & 255) / 255.0f;

            seed = RandomStatic.numericRecipes(seed);
            float g = (seed & 255) / 255.0f;

            seed = RandomStatic.numericRecipes(seed);
            float b = (seed & 255) / 255.0f;

            scene.SetColor(v[0], new Vector3(r, g, b));
            r = Math.Min(r + 0.2f, 1.0f);
            scene.SetColor(v[1], new Vector3(r, g, b));
            g = Math.Min(g + 0.2f, 1.0f);
            scene.SetColor(v[2], new Vector3(r, g, b));
            b = Math.Min(b + 0.2f, 1.0f);
            scene.SetColor(v[3], new Vector3(r, g, b));

            // triangle faces:
            scene.AddTriangle(v[0], v[1], v[2]);
            scene.AddTriangle(v[2], v[1], v[3]);
            scene.AddTriangle(v[1], v[0], v[3]);
            scene.AddTriangle(v[2], v[3], v[0]);

            return(4);
        }
        /// <summary>
        /// Returns true if vertex lies on the edge of triangle mesh
        /// </summary>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public static bool IsOnEdge(Vector3 vertex, SceneBrep scene)
        {
            bool onEdge = false;

            var        handle      = scene.GetVertex(vertex);
            List <int> trianglePtr = new List <int>();

            // get triangles
            for (int i = 0; i < scene.vertexPtr.Count; i++)
            {
                if (scene.vertexPtr[i] == handle)
                {
                    if (i % 3 == 0)
                    {
                        trianglePtr.Add(i / 3);
                    }
                    else if (i % 3 == 1)
                    {
                        trianglePtr.Add((i - 1) / 3);
                    }
                    else if (i % 3 == 2)
                    {
                        trianglePtr.Add((i - 2) / 3);
                    }
                }
            }

            // is triangle on edge?

            foreach (var ptr in trianglePtr)
            {
                // get handle of corners of triangle
                var c1 = Scene3D.SceneBrep.tCorner(ptr);
                var c2 = c1 + 1;
                var c3 = c1 + 2;



                if (scene.cOpposite(c1) == -1)
                {
                    onEdge = true;
                }
                else if (scene.cOpposite(c2) == -1)
                {
                    onEdge = true;
                }
                else if (scene.cOpposite(c3) == -1)
                {
                    onEdge = true;
                }
            }

            return(onEdge);
        }
        /// <summary>
        /// Construct a new Brep solid (preferebaly closed = regular one).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="param">Shape parameters if needed</param>
        /// <returns>Number of generated faces (0 in case of failure)</returns>
        public int AddMesh(SceneBrep scene, Matrix4 m, string param)
        {
            // !!!{{ TODO: put your Mesh-construction code here

            // if there will be large number of new vertices, reserve space for them to save time:
            scene.Reserve(4);

            return(CreateTetrahedron(scene, m, Vector3.Zero, 1.0f));

            // !!!}}
        }
        private int drawRose(SceneBrep scene, Matrix4 m, string param)
        {
            int    number_of_points = segments;
            double period           = Math.PI * d;

            if ((n % 2 == 0) || (d % 2 == 0))
            {
                period *= 2;
            }

            double s  = 0.0;
            double ds = 1.0 / number_of_points;

            double     dtheta = period / number_of_points;
            List <int> points = new List <int>();
            double     k      = (double)n / d;

            for (int i = 0; i < number_of_points; i++)
            {
                double theta = i * dtheta;
                double r     = scale * Math.Cos(k * theta);
                float  x     = (float)(r * Math.Cos(theta * ratioX));
                float  y     = (float)(r * Math.Sin(theta * ratioY));
                float  z     = (float)(r * Math.Cos(theta * i * ratioZ));
                if (noRatioZ)
                {
                    z = (float)(r * Math.Cos(theta));
                }
                if (noRatioX)
                {
                    x = (float)(r * Math.Cos(theta));
                }
                if (noRatioY)
                {
                    y = (float)(r * Math.Sin(theta));
                }


                Vector3 A = new Vector3(x, y, z);
                int     v = scene.AddVertex(Vector3.TransformPosition(A, m));
                points.Add(v);
                scene.SetTxtCoord(v, new Vector2((float)s, (float)s));
                System.Drawing.Color c = Raster.Draw.ColorRamp(0.5 * (s + 1.0));
                scene.SetColor(v, new Vector3(c.R / 255.0f, c.G / 255.0f, c.B / 255.0f));
                s += ds;
            }

            for (int i = 0; i < number_of_points - 1; i++)
            {
                scene.AddLine(points[i], points[i + 1]);
            }
            scene.AddLine(points[0], points[points.Count - 1]);
            return(number_of_points);
        }
Пример #18
0
        /// <summary>
        /// Reads one 3D scene from a given stream (containing text variant of Wavefront OBJ format).
        /// </summary>
        /// <param name="reader">Already open text reader</param>
        /// <param name="scene">Scene to be modified</param>
        /// <returns>Number of faces read</returns>
        public int ReadBrep(StreamReader reader, SceneBrep scene)
        {
            if (reader == null)
            {
                return(SceneBrep.NULL);
            }

            Debug.Assert(scene != null);
            scene.Reset();
            return(ReadBrep(reader, scene, Matrix4.Identity));
        }
Пример #19
0
 internal void RenderSceneJustCurve(SceneBrep scene)
 {
     for (int i = 0; i < Vertices.Count; i++)
     {
         scene.AddVertex(Vertices[i]);
         if (i > 0)
         {
             scene.AddLine(i - 1, i);
         }
     }
     scene.AddLine(0, Vertices.Count - 1);
 }
Пример #20
0
        /// <summary>
        /// Construct a new Brep solid (preferebaly closed = regular one).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="param">Shape parameters if needed</param>
        /// <returns>Number of generated faces (0 in case of failure)</returns>
        public int AddMesh(SceneBrep scene, Matrix4 m, string param)
        {
            parseParams(param);
            scene.Reserve(10000000);
            Curve c = new Curve(xFreq, yFreq, zFreq, thickness, vertexFreq, circEdgeSize);

            c.GenerateThingsForScene(m);
            c.RenderSceneSimpleTube(scene);
            // c.RenderSceneJustCurve(scene);

            return(c.GeneratedFaces);
        }
Пример #21
0
        /// <summary>
        /// Construct a new Brep solid (preferebaly closed = regular one).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="param">Shape parameters if needed</param>
        /// <returns>Number of generated faces (0 in case of failure)</returns>
        public int AddMesh(SceneBrep scene, Matrix4 m, string param)
        {
            // {{ TODO: put your Mesh-construction code here

            parseParams(param);

            // If there will be large number of new vertices, reserve space for them to save time.
            scene.Reserve(segments + 1);

            double t  = 0.0;
            double dt = maxT / segments;
            double s  = 0.0; // for both texture coordinate & color ramp
            double ds = 1.0 / segments;

            int     vPrev = 0;
            Vector3 A;

            for (int i = 0; i <= segments; i++)
            {
                // New vertex's coordinates.
                A.X = (float)(radius * Math.Cos(kx * t + dx));
                A.Y = (float)(radius * Math.Cos(ky * t + dy));
                A.Z = (float)(radius * Math.Cos(kz * t + dz));

                // New vertex.
                int v = scene.AddVertex(Vector3.TransformPosition(A, m));

                // Vertex attributes.
                scene.SetTxtCoord(v, new Vector2((float)s, (float)s));
                System.Drawing.Color c = Raster.Draw.ColorRamp(0.5 * (s + 1.0));
                scene.SetColor(v, new Vector3(c.R / 255.0f, c.G / 255.0f, c.B / 255.0f));

                // New line?
                if (i > 0)
                {
                    scene.AddLine(vPrev, v);
                }

                // Next vertex.
                t    += dt;
                s    += ds;
                vPrev = v;
            }

            // Thick line (for rendering).
            scene.LineWidth = 3.0f;

            return(segments);

            // }}
        }
Пример #22
0
        /// <summary>
        /// Reads one 3D scene from a given file (containing text variant of Wavefront OBJ format).
        /// Can read GZipped files.
        /// </summary>
        /// <param name="fileName">File-name (ending by .gz for gzipped file)</param>
        /// <param name="scene">Scene to be modified</param>
        /// <returns>Number of faces read</returns>
        public int ReadBrep( String fileName, SceneBrep scene )
        {
            if ( fileName == null ||
               fileName.Length == 0 )
            return SceneBrep.NULL;

              StreamReader reader;
              if ( fileName.EndsWith( ".gz" ) )
            reader = new StreamReader( new GZipStream( new FileStream( fileName, FileMode.Open ), CompressionMode.Decompress ) );
              else
            reader = new StreamReader( new FileStream( fileName, FileMode.Open ) );
              int faces = ReadBrep( reader, scene );
              reader.Close();

              return faces;
        }
        private void drawTetrahedronRecursive(int depth, SceneBrep scene, Matrix4 m, string param, Vector3 a, Vector3 b, Vector3 c, Vector3 d)
        {
            if (depth == 0)
            {
                return;
            }
            Vector3 stand;

            stand.X = 0;
            stand.Y = 0;
            stand.Z = 0;
            int     ab, ac, ad, bc, bd, cd;
            Vector3 AB = stand, AC = stand, AD = stand;
            Vector3 BC = stand, BD = stand;
            Vector3 CD = stand;

            calculateMiddle(a, b, c, d, ref AB, ref AC, ref AD, ref BC, ref BD, ref CD);

            ab = scene.AddVertex(Vector3.TransformPosition(AB, m));
            ac = scene.AddVertex(Vector3.TransformPosition(AC, m));
            ad = scene.AddVertex(Vector3.TransformPosition(AD, m));
            bc = scene.AddVertex(Vector3.TransformPosition(BC, m));
            bd = scene.AddVertex(Vector3.TransformPosition(BD, m));
            cd = scene.AddVertex(Vector3.TransformPosition(CD, m));

            scene.AddLine(ab, ac);
            scene.AddLine(ac, bc);
            scene.AddLine(bc, ab);

            scene.AddLine(ab, bd);
            scene.AddLine(bd, ad);
            scene.AddLine(ad, ab);

            scene.AddLine(ac, ad);
            scene.AddLine(ad, cd);
            scene.AddLine(cd, ac);

            scene.AddLine(bc, cd);
            scene.AddLine(cd, bd);
            scene.AddLine(bd, bc);

            drawTetrahedronRecursive(depth - 1, scene, m, param, AB, b, BC, BD);
            drawTetrahedronRecursive(depth - 1, scene, m, param, a, AB, AC, AD);
            drawTetrahedronRecursive(depth - 1, scene, m, param, AC, BC, c, CD);
            drawTetrahedronRecursive(depth - 1, scene, m, param, AD, BD, CD, d);
        }
Пример #24
0
        /// <summary>
        /// Writes the whole B-rep scene to a given text stream (uses text variant of Wavefront OBJ format).
        /// </summary>
        /// <param name="writer">Already open text writer</param>
        /// <param name="scene">Scene to write</param>
        public void WriteBrep(StreamWriter writer, SceneBrep scene)
        {
            if (scene == null || scene.Triangles < 1)
            {
                return;
            }

            int i;

            for (i = 0; i < scene.Vertices; i++)
            {
                Vector3 v = scene.GetVertex(i);
                writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} {1} {2} {3}",
                                               new object[] { VERTEX, v.X, v.Y, v.Z }));
            }

            bool hasNormals = scene.Normals > 0;

            if (hasNormals)
            {
                for (i = 0; i < scene.Vertices; i++)
                {
                    Vector3 n = scene.GetNormal(i);
                    writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} {1} {2} {3}",
                                                   new object[] { VERTEX_NORMAL, n.X, n.Y, n.Z }));
                }
            }

            for (i = 0; i < scene.Triangles; i++)
            {
                int A, B, C;
                scene.GetTriangleVertices(i, out A, out B, out C);
                A++;
                B++;
                C++;
                if (hasNormals)
                {
                    writer.WriteLine("{0} {1}//{1} {2}//{2} {3}//{3}", FACE, A, B, C);
                }
                else
                {
                    writer.WriteLine("{0} {1} {2} {3}", FACE, A, B, C);
                }
            }
        }
Пример #25
0
        internal void RenderSceneSimpleTube(SceneBrep scene)
        {
            int total = -1;

            for (int i = 0; i < MeshVertices.Count; i++)
            {
                for (int j = 0; j < MeshVertices[i].Count; j++)
                {
                    scene.AddVertex(MeshVertices[i][j]);
                    total++;
                }
                //AddToScene(scene, MeshVertices[i], total);
                if (i > 0)
                {
                    ConnectTwoCircles(scene, MeshVertices, total, i);
                }
            }
            ConnectTwoCircles(scene, MeshVertices, total, 0);
        }
Пример #26
0
        void ConnectTwoCircles(SceneBrep scene, List <List <Vector3> > MeshV, int total, int index)
        {
            List <int> firstCirc = new List <int>();
            List <int> secCirc   = new List <int>();
            int        count     = MeshV[index].Count;

            if (index != 0)
            {
                for (int i = total; i > total - count; i--)
                {
                    firstCirc.Add(i);
                    secCirc.Add(i - count);
                }
                //for (int i = 0; i < firstCirc.Count; i++) {
                //  scene.AddLine(firstCirc[i], secCirc[i]);
                //  scene.AddLine(firstCirc[i], secCirc[(i + 1 == secCirc .Count ? 0 : i+1)]);
                //}
            }
            else
            {
                for (int i = total; i > total - count; i--)
                {
                    firstCirc.Add(i);
                    secCirc.Add(total - i + count);
                }
                //for (int i = 0; i < firstCirc.Count; i++) {
                //  scene.AddLine(firstCirc[i], secCirc[i]);
                //  scene.AddLine(firstCirc[i], secCirc[(i + 1 == secCirc.Count ? 0 : i+1)]);
                //}
            }

            for (int i = 0; i < firstCirc.Count; i++)
            {
                scene.AddTriangle(firstCirc[i], secCirc[i], secCirc[(i + 1 == secCirc.Count ? 0 : i + 1)]);
                this.GeneratedFaces++;
                scene.AddTriangle(
                    firstCirc[(i + 1 == firstCirc.Count ? 0 : i + 1)],
                    firstCirc[i],
                    secCirc[(i + 1 == secCirc.Count ? 0 : i + 1)]);
                this.GeneratedFaces++;
            }
        }
Пример #27
0
        public EarClipping(List <int> pointers, Scene3D.SceneBrep scene)
        {
            // Polygon has at least 3 vertices
            if (pointers.Count < 3)
            {
                return;
            }

            this.Scene = scene;

            // Get coordinates from vertex pointers
            PolygonVertices = new List <Vector3>();
            pointers.ForEach(x => PolygonVertices.Add(Scene.GetVertex(x)));

            PrepareNormal(PolygonVertices);
            polygon = new Polygon();
            copy    = new Polygon();
            CreatePolygon(polygon, PolygonVertices);
            CreatePolygon(copy, PolygonVertices);
        }
        private int drawTetrahedron(SceneBrep scene, Matrix4 m, string param)
        {
            segments = 4;
            scene.Reserve(segments + (int)Math.Pow(4, depthParam) + 1);

            /*c.Line(0, 0, 0, c.Height);
             * c.Line(0, c.Height, c.Width, c.Height / 2);
             * c.Line(c.Width, c.Height / 2, 0, 0);
             */
            Vector3 A, B, C, D;
            int     one, two, three, four;

            //float a = 1.0f;
            A.X   = 0;
            A.Y   = 0;
            A.Z   = 0;
            one   = scene.AddVertex(Vector3.TransformPosition(A, m));
            B.X   = 1.0f;
            B.Y   = 1.0f;
            B.Z   = 0;
            two   = scene.AddVertex(Vector3.TransformPosition(B, m));
            C.X   = 0;
            C.Y   = 1.0f;
            C.Z   = 1.0f;
            three = scene.AddVertex(Vector3.TransformPosition(C, m));
            D.X   = 1.0f;
            D.Y   = 0;
            D.Z   = 1.0f;
            four  = scene.AddVertex(Vector3.TransformPosition(D, m));

            scene.AddLine(one, two);
            scene.AddLine(two, three);
            scene.AddLine(three, one);
            scene.AddLine(four, one);
            scene.AddLine(four, two);
            scene.AddLine(four, three);

            drawTetrahedronRecursive(depthParam, scene, m, param, A, B, C, D);

            return(segments + (int)Math.Pow(4, depthParam) + 1);
        }
        private int drawLineBezier(SceneBrep scene, Matrix4 m, string param, Vector3 P0, Vector3 P1, Vector3 P2)
        {
            int segm = 200;

            float hun = 100.0f;


            List <int> pointsList = new List <int>();

            addCube(scene, m, param);


            //P0 -= delta; P1 -= delta;P2 -= delta;

            for (int i = 0; i <= 100; i++)
            {
                float   t = ((float)(i)) / hun;
                Vector3 P = (1 - t) * ((1 - t) * P0 + t * P1) + t * ((1 - t) * P1 + t * P2);
                //float x = (1-t)*(1-t)*x1 + 2*(1-t)*t*x2+t*t*x3;
                //float y = (1-t)*(1-t)*y1 + 2*(1-t)*t*y2+t*t*y3;
                pointsList.Add(scene.AddVertex(Vector3.TransformPosition(P, m)));
            }

            for (int i = 0; i < pointsList.Count - 1; i++)
            {
                scene.AddLine(pointsList[i], pointsList[i + 1]);
            }

            int p0, p1, p2;

            p0 = scene.AddVertex(Vector3.TransformPosition(P0, m));
            p1 = scene.AddVertex(Vector3.TransformPosition(P1, m));
            p2 = scene.AddVertex(Vector3.TransformPosition(P2, m));

            scene.AddLine(p0, p1);
            scene.AddLine(p1, p2);

            return(segm + 2);
        }
        private int drawSpiral(SceneBrep scene, Matrix4 m, string param)
        {
            int number_of_points = segments;

            double     period = Math.PI * scale;
            double     dtheta = period / number_of_points;
            List <int> points = new List <int>();
            double     ds     = 1.0 / (double)number_of_points;
            double     s      = 0.0;

            for (int i = 0; i < number_of_points; i++)
            {
                double theta = i * dtheta;
                float  x     = (float)(s * s * Math.Cos(theta * ratioX));
                float  y     = (float)(s * s * Math.Sin(theta * ratioY));
                float  z     = (float)(s * s);



                Vector3 A = new Vector3(x, y, z);
                int     v = scene.AddVertex(Vector3.TransformPosition(A, m));

                scene.SetTxtCoord(v, new Vector2((float)s, (float)s));
                System.Drawing.Color c = Raster.Draw.ColorRamp(0.5 * (s + 1.0));
                scene.SetColor(v, new Vector3(c.R / 255.0f, c.G / 255.0f, c.B / 255.0f));

                points.Add(v);
                s += ds;
            }

            for (int i = 0; i < number_of_points - 1; i++)
            {
                scene.AddLine(points[i], points[i + 1]);
            }
            //scene.AddLine(points[0], points[points.Count - 1]);
            return(number_of_points);
        }
Пример #31
0
        /// <summary>
        /// Do Loop subdivision of the input control triangle mesh.
        /// </summary>
        /// <param name="scene">Input scene (must not be changed).</param>
        /// <param name="epsilon">Reference error toleration (size of undivided triangle).</param>
        /// <param name="normals">Generate normals? (optional)</param>
        /// <param name="colors">Generate colors? (optional)</param>
        /// <param name="txtcoord">Generate texture coordinates? (optional)</param>
        /// <param name="time">Current time for animation (optional)</param>
        /// <param name="param">Optional additional parameters.</param>
        /// <returns>Number of generated points.</returns>
        public int Subdivide(SceneBrep scene, float epsilon, bool normals, bool colors, bool txtcoord, float time, string param)
        {
            result = scene.Clone();

            // !!!{{ TODO: put your Loop subdivision code here

            // pilot: do one (trivial) division
            int triangles = result.Triangles;
            int tr;

            for (tr = 0; tr < triangles; tr++)
            {
                int A, B, C;
                result.GetTriangleVertices(tr, out A, out B, out C);
                Vector3 vA = result.GetVertex(A);
                Vector3 vB = result.GetVertex(B);
                Vector3 vC = result.GetVertex(C);

                Vector3 vA2 = (vB + vC) * 0.5f;
                Vector3 vB2 = (vA + vC) * 0.5f;
                Vector3 vC2 = (vA + vB) * 0.5f;
                int     A2  = result.AddVertex(vA2);
                int     B2  = result.AddVertex(vB2);
                int     C2  = result.AddVertex(vC2);

                result.AddTriangle(B2, C2, A2);
                result.AddTriangle(B2, A2, C);
                result.AddTriangle(C2, B, A2);
                result.SetTriangleVertices(tr, A, C2, B2);
            }

            //result.BuildCornerTable();

            return(result.Vertices);

            // !!!}}
        }
Пример #32
0
        /// <summary>
        /// Construct a new control mesh for subdivision (formally the Brep solid..).
        /// </summary>
        /// <param name="scene">B-rep scene to be modified</param>
        /// <param name="m">Transform matrix (object-space to world-space)</param>
        /// <param name="time">Current time in seconds</param>
        /// <param name="param">Shape parameters if needed</param>
        public void ControlMesh(SceneBrep scene, Matrix4 m, float time, string param)
        {
            // !!!{{ TODO: put your Control-mesh-construction code here

            List <int> upper = new List <int>();

            upper.Add(scene.AddVertex(Vector3.TransformPosition(new Vector3(0, 1, 0), m)));
            upper.Add(scene.AddVertex(Vector3.TransformPosition(new Vector3(1, 1, 0), m)));
            upper.Add(scene.AddVertex(Vector3.TransformPosition(new Vector3(1, 1, 1), m)));
            upper.Add(scene.AddVertex(Vector3.TransformPosition(new Vector3(0, 1, 1), m)));

            List <int> lower = new List <int>();

            lower.Add(scene.AddVertex(Vector3.TransformPosition(new Vector3(0, 0, 0), m)));
            lower.Add(scene.AddVertex(Vector3.TransformPosition(new Vector3(1, 0, 0), m)));
            lower.Add(scene.AddVertex(Vector3.TransformPosition(new Vector3(1, 0, 1), m)));
            lower.Add(scene.AddVertex(Vector3.TransformPosition(new Vector3(0, 0, 1), m)));

            // Lower face
            scene.AddTriangle(lower[0], lower[1], lower[2]);
            scene.AddTriangle(lower[2], lower[3], lower[0]);

            // Upper face
            scene.AddTriangle(upper[2], upper[1], upper[0]);
            scene.AddTriangle(upper[0], upper[3], upper[2]);

            // Side faces
            for (int i = 0; i < upper.Count; i++)
            {
                int j = i < (upper.Count - 1) ? i + 1 : 0;
                scene.AddTriangle(upper[i], upper[j], lower[i]);
                scene.AddTriangle(lower[i], upper[j], lower[j]);
            }

            // !!!}}
        }
Пример #33
0
        /// <summary>
        /// Reads one 3D scene from a given stream (containing text variant of Wavefront OBJ format).
        /// </summary>
        /// <param name="reader">Already open text reader</param>
        /// <param name="scene">Scene to be modified</param>
        /// <param name="scene">Matrix for instancing</param>
        /// <returns>Number of faces read</returns>
        public int ReadBrep( StreamReader reader, SceneBrep scene, Matrix4 m )
        {
            if ( reader == null ) return SceneBrep.NULL;

              Debug.Assert( scene != null );
              int v0 = scene.Vertices;

              int faces = 0;
              List<Vector3> normals = new List<Vector3>( 256 );
              int[] f = new int[ 3 ];

              do
              {
            string line = reader.ReadLine();
            if ( line == null ) break;

            int commentPos = line.IndexOf( COMMENT );
            if ( commentPos >= 0 )
              line = line.Substring( 0, commentPos );

            string[] tokens = line.Split( ' ' );

            switch ( tokens[ 0 ] )
            {
              case VERTEX:
            if ( tokens.Length < 4 ) continue;

            Vector3 coord;
            if ( !float.TryParse( tokens[ 1 ], NumberStyles.Float, CultureInfo.InvariantCulture, out coord.X ) ||
                 !float.TryParse( tokens[ 2 ], NumberStyles.Float, CultureInfo.InvariantCulture, out coord.Y ) ||
                 !float.TryParse( tokens[ 3 ], NumberStyles.Float, CultureInfo.InvariantCulture, out coord.Z ) )
              continue;

            if ( MirrorConversion )
              coord.Z = -coord.Z;
            scene.AddVertex( Vector3.Transform( coord, m ) );
            break;

              case VERTEX_NORMAL:
            if ( tokens.Length < 4 ) continue;

            Vector3 norm;
            if ( !float.TryParse( tokens[ 1 ], NumberStyles.Float, CultureInfo.InvariantCulture, out norm.X ) ||
                 !float.TryParse( tokens[ 2 ], NumberStyles.Float, CultureInfo.InvariantCulture, out norm.Y ) ||
                 !float.TryParse( tokens[ 3 ], NumberStyles.Float, CultureInfo.InvariantCulture, out norm.Z ) )
              continue;

            if ( MirrorConversion )
              norm.Z = -norm.Z;
            normals.Add( Vector3.TransformNormal( norm, m ) );
            break;

              case FACE:
            if ( tokens.Length < 4 ) continue;
            int i;

            for ( i = 0; i < 3; i++ )
            {
              string[] vt = tokens[ i + 1 ].Split( '/' );
              int ti, ni;
              ti = ni = SceneBrep.NULL;
              // 0 .. vertex coord index
              if ( !int.TryParse( vt[ 0 ], out f[ i ] ) ) break;
              f[ i ] = v0 + f[ i ] - 1;
              if ( vt.Length >= 2 )
              {
                // 1 .. texture coord index (not yet)
                int.TryParse( vt[ 1 ], out ti );
                ti--;
                if ( vt.Length >= 3 )
                {
                  // 2 .. normal vector index
                  int.TryParse( vt[ 2 ], out ni );
                  ni--;
                }
              }
              if ( ni >= 0 && ni < normals.Count )
                scene.SetNormal( f[ i ], normals[ ni ] );
            }

            if ( i >= 3 )
            {
              scene.AddTriangle( f[ 0 ], f[ 1 ], f[ 2 ] );
              faces++;
            }

            break;
            }
              }
              while ( !reader.EndOfStream );

              return faces;
        }
Пример #34
0
        /// <summary>
        /// Reads one 3D scene from a given stream (containing text variant of Wavefront OBJ format).
        /// </summary>
        /// <param name="reader">Already open text reader</param>
        /// <param name="scene">Scene to be modified</param>
        /// <param name="scene">Matrix for instancing</param>
        /// <returns>Number of faces read</returns>
        public int ReadBrep( StreamReader reader, SceneBrep scene, Matrix4 m )
        {
            if ( reader == null ) return SceneBrep.NULL;

              Debug.Assert( scene != null );
              int v0 = scene.Vertices;
              int lastVertex = v0 - 1;

              int faces = 0;
              List<Vector3> normals = new List<Vector3>( 256 );
              int lastNormal = -1;
              int[] f = new int[ 3 ];

              do
              {
            string line = reader.ReadLine();
            if ( line == null ) break;

            int commentPos = line.IndexOf( COMMENT );
            if ( commentPos >= 0 )
              line = line.Substring( 0, commentPos );

            string[] tokens = line.Split( DELIMITERS , StringSplitOptions.RemoveEmptyEntries );
            if ( tokens.Length < 1 ) continue;

            switch ( tokens[ 0 ] )
            {
              case VERTEX:
            if ( tokens.Length < 4 ) continue;

            Vector3 coord;
            if ( !float.TryParse( tokens[ 1 ], NumberStyles.Float, CultureInfo.InvariantCulture, out coord.X ) ||
                 !float.TryParse( tokens[ 2 ], NumberStyles.Float, CultureInfo.InvariantCulture, out coord.Y ) ||
                 !float.TryParse( tokens[ 3 ], NumberStyles.Float, CultureInfo.InvariantCulture, out coord.Z ) )
              continue;

            if ( MirrorConversion )
              coord.Z = -coord.Z;
            lastVertex = scene.AddVertex( Vector3.Transform( coord, m ) );
            break;

              case VERTEX_NORMAL:
            if ( tokens.Length < 4 ) continue;

            Vector3 norm;
            if ( !float.TryParse( tokens[ 1 ], NumberStyles.Float, CultureInfo.InvariantCulture, out norm.X ) ||
                 !float.TryParse( tokens[ 2 ], NumberStyles.Float, CultureInfo.InvariantCulture, out norm.Y ) ||
                 !float.TryParse( tokens[ 3 ], NumberStyles.Float, CultureInfo.InvariantCulture, out norm.Z ) )
              continue;

            if ( MirrorConversion )
              norm.Z = -norm.Z;
            normals.Add( Vector3.TransformNormal( norm, m ) );
            lastNormal++;
            break;

              case FACE:
            if ( tokens.Length < 4 ) continue;
            int N = tokens.Length - 1;
            if ( f.Length < N )
              f = new int[ N ];
            int i;

            for ( i = 0; i < N; i++ )       // read indices for one vertex
            {
              string[] vt = tokens[ i + 1 ].Split( '/' );
              int ti, ni;
              ti = ni = 0;                  // 0 => value not present

              // 0 .. vertex coord index
              if ( !int.TryParse( vt[ 0 ], out f[ i ] ) ||
                   f[ i ] == 0 )
                break;

              if ( f[ i ] > 0 )
                f[ i ] = v0 + f[ i ] - 1;
              else
                f[ i ] = lastVertex + 1 - f[ i ];

              if ( vt.Length > 1 )
              {
                // 1 .. texture coord index (not yet)
                if ( !int.TryParse( vt[ 1 ], out ti ) ) ti = 0;

                if ( vt.Length > 2 )
                {
                  // 2 .. normal vector index
                  if ( !int.TryParse( vt[ 2 ], out ni ) ) ni = 0;
                }
              }
              // there was a normal..
              if ( ni != 0 )
              {
                if ( ni > 0 )
                  ni--;
                else
                  ni = lastNormal + 1 - ni;
                if ( ni >= 0 && ni < normals.Count )
                  scene.SetNormal( f[ i ], normals[ ni ] );
              }
            }

            N = i;
            for ( i = 1; i < N - 1; i++ )
            {
              scene.AddTriangle( f[ 0 ], f[ i ], f[ i + 1 ] );
              faces++;
            }

            break;
            }
              }
              while ( !reader.EndOfStream );

              return faces;
        }
Пример #35
0
        /// <summary>
        /// Writes the whole B-rep scene to a given text stream (uses text variant of Wavefront OBJ format).
        /// </summary>
        /// <param name="writer">Already open text writer</param>
        /// <param name="scene">Scene to write</param>
        public void WriteBrep( StreamWriter writer, SceneBrep scene )
        {
            if ( scene == null || scene.Triangles < 1 ) return;

              int i;
              for ( i = 0; i < scene.Vertices; i++ )
              {
            Vector3 v = scene.GetVertex( i );
            writer.WriteLine( String.Format( CultureInfo.InvariantCulture, "{0} {1} {2} {3}", new object[] { VERTEX, v.X, v.Y, v.Z } ) );
              }

              bool hasNormals = scene.Normals > 0;
              if ( hasNormals )
            for ( i = 0; i < scene.Vertices; i++ )
            {
              Vector3 n = scene.GetNormal( i );
              writer.WriteLine( String.Format( CultureInfo.InvariantCulture, "{0} {1} {2} {3}", new object[] { VERTEX_NORMAL, n.X, n.Y, n.Z } ) );
            }

              for ( i = 0; i < scene.Triangles; i++ )
              {
            int A, B, C;
            scene.GetTriangleVertices( i, out A, out B, out C );
            A++; B++; C++;
            if ( hasNormals )
              writer.WriteLine( "{0} {1}//{1} {2}//{2} {3}//{3}", FACE, A, B, C );
            else
              writer.WriteLine( "{0} {1} {2} {3}", FACE, A, B, C );
              }
        }
        private void drawKochRecursive(int depth, SceneBrep scene, Matrix4 m, string param, Vector3 a, Vector3 b, Vector3 c, Vector3 d)
        {
            if (depth == 0)
            {
                return;
            }

            Vector3 stand;

            stand.X = 0;
            stand.Y = 0;
            stand.Z = 0;
            int     ab, ac, ad, bc, bd, cd, headabc, headadb, headacd, headbdc;
            Vector3 AB = stand, AC = stand, AD = stand;
            Vector3 BC = stand, BD = stand;
            Vector3 CD = stand;

            calculateMiddle(a, b, c, d, ref AB, ref AC, ref AD, ref BC, ref BD, ref CD);
            float lengthOfSide = (float)Math.Sqrt((AB.X - BC.X) * (AB.X - BC.X) + (AB.Y - BC.Y) * (AB.Y - BC.Y) + (AB.Z - BC.Z) * (AB.Z - BC.Z));
            float height       = lengthOfSide * (float)Math.Sqrt(6) / 3.0f;

            Vector3 headABC = calculateHeightVertex(a, b, c, height);
            Vector3 headADB = calculateHeightVertex(a, d, b, height);
            Vector3 headACD = calculateHeightVertex(a, c, d, height);
            Vector3 headBDC = calculateHeightVertex(b, d, c, height);


            ab      = scene.AddVertex(Vector3.TransformPosition(AB, m));
            ac      = scene.AddVertex(Vector3.TransformPosition(AC, m));
            ad      = scene.AddVertex(Vector3.TransformPosition(AD, m));
            bc      = scene.AddVertex(Vector3.TransformPosition(BC, m));
            bd      = scene.AddVertex(Vector3.TransformPosition(BD, m));
            cd      = scene.AddVertex(Vector3.TransformPosition(CD, m));
            headabc = scene.AddVertex(Vector3.TransformPosition(headABC, m));
            headadb = scene.AddVertex(Vector3.TransformPosition(headADB, m));
            headacd = scene.AddVertex(Vector3.TransformPosition(headACD, m));
            headbdc = scene.AddVertex(Vector3.TransformPosition(headBDC, m));


            scene.AddLine(ab, ac);
            scene.AddLine(ac, bc);
            scene.AddLine(bc, ab);
            scene.AddLine(ab, headabc);
            scene.AddLine(ac, headabc);
            scene.AddLine(bc, headabc);


            scene.AddLine(ab, bd);
            scene.AddLine(bd, ad);
            scene.AddLine(ad, ab);
            scene.AddLine(ab, headadb);
            scene.AddLine(bd, headadb);
            scene.AddLine(ad, headadb);


            scene.AddLine(ac, ad);
            scene.AddLine(ad, cd);
            scene.AddLine(cd, ac);
            scene.AddLine(ac, headacd);
            scene.AddLine(ad, headacd);
            scene.AddLine(cd, headacd);


            scene.AddLine(bc, cd);
            scene.AddLine(cd, bd);
            scene.AddLine(bd, bc);
            scene.AddLine(bc, headbdc);
            scene.AddLine(bd, headbdc);
            scene.AddLine(cd, headbdc);

            drawKochRecursive(depth - 1, scene, m, param, AB, AC, BC, headABC);
            drawKochRecursive(depth - 1, scene, m, param, AB, BD, AD, headADB);
            drawKochRecursive(depth - 1, scene, m, param, AD, CD, AC, headACD);
            drawKochRecursive(depth - 1, scene, m, param, BD, BC, CD, headBDC);
        }
Пример #37
0
 public SceneBrep Clone()
 {
     SceneBrep tmp = new SceneBrep();
       tmp.geometry = new List<Vector3>( geometry );
       if ( normals != null ) tmp.normals = new List<Vector3>( normals );
       if ( colors != null ) tmp.colors = new List<Vector3>( colors );
       if ( txtCoords != null ) tmp.txtCoords = new List<Vector2>( txtCoords );
       if ( vertexPtr != null ) tmp.vertexPtr = new List<int>( vertexPtr );
       if ( oppositePtr != null ) tmp.oppositePtr = new List<int>( oppositePtr );
       tmp.BuildCornerTable();
       return tmp;
 }
Пример #38
0
        public void Render( Bitmap output, SceneBrep scene )
        {
            if ( output == null ||
               scene  == null ) return;

              // center of the object = point to look at:
              double cx = 0.0;
              double cy = 0.0;
              double cz = 0.0;
              float minx = float.MaxValue;
              float miny = float.MaxValue;
              float minz = float.MaxValue;
              float maxx = float.MinValue;
              float maxy = float.MinValue;
              float maxz = float.MinValue;
              int n = scene.Vertices;
              int i;

              for ( i = 0; i < n; i++ )
              {
            Vector3 vi = scene.GetVertex( i );
            cx += vi.X;
            cy += vi.Y;
            cz += vi.Z;
            if ( vi.X < minx ) minx = vi.X;
            if ( vi.Y < miny ) miny = vi.Y;
            if ( vi.Z < minz ) minz = vi.Z;
            if ( vi.X > maxx ) maxx = vi.X;
            if ( vi.Y > maxy ) maxy = vi.Y;
            if ( vi.Z > maxz ) maxz = vi.Z;
              }
              Vector3 center = new Vector3( (float)(cx / n),
                                    (float)(cy / n),
                                    (float)(cz / n) );
              float diameter = (float)Math.Sqrt( (maxx - minx) * (maxx - minx) +
                                         (maxy - miny) * (maxy - miny) +
                                         (maxz - minz) * (maxz - minz) );
              if ( Distance < diameter ) Distance = diameter;

              // and the rest of projection matrix goes here:
              int width    = output.Width;
              int height   = output.Height;
              float aspect = width / (float)height;
              double az    = Azimuth / 180.0 * Math.PI;
              double el    = Elevation / 180.0 * Math.PI;

              Vector3 eye   = new Vector3( (float)(center.X + Distance * Math.Sin( az ) * Math.Cos( el )),
                                   (float)(center.Y + Distance * Math.Sin( el )),
                                   (float)(center.Z + Distance * Math.Cos( az ) * Math.Cos( el )) );
              Matrix4 modelView = Matrix4.LookAt( eye, center, Vector3.UnitY );
              Matrix4 proj;

              if ( Perspective )
              {
            float vv = (float)(2.0 * Math.Atan2( diameter * 0.5, Distance ));
            proj = Matrix4.CreatePerspectiveFieldOfView( vv, aspect, 1.0f, 50.0f );
              }
              else
              {
            float vHalf = diameter * 0.52f;
            proj = Matrix4.CreateOrthographicOffCenter( -vHalf, vHalf,
                                                    -vHalf / aspect, vHalf / aspect,
                                                    1.0f, 50.0f );
              }

              Matrix4 compound = Matrix4.Mult( modelView, proj );
              Matrix4 viewport = Geometry.SetViewport( 0, 0, width, height );
              compound = Matrix4.Mult( compound, viewport );

              // wireframe rendering:
              Graphics gr = Graphics.FromImage( output );
              Pen pen = new Pen( Color.FromArgb( 255, 255, 80 ), 1.0f );
              n = scene.Triangles;
              for ( i = 0; i < n; i++ )
              {
            Vector4 A, B, C;
            scene.GetTriangleVertices( i, out A, out B, out C );
            A = Vector4.Transform( A, compound );
            B = Vector4.Transform( B, compound );
            C = Vector4.Transform( C, compound );
            Vector2 a = new Vector2( A.X / A.W, A.Y / A.W );
            Vector2 b = new Vector2( B.X / B.W, B.Y / B.W );
            Vector2 c = new Vector2( C.X / C.W, C.Y / C.W );
            gr.DrawLine( pen, a.X, a.Y, b.X, b.Y );
            gr.DrawLine( pen, b.X, b.Y, c.X, c.Y );
            gr.DrawLine( pen, c.X, c.Y, a.X, a.Y );
              }

              if ( DrawNormals && scene.Normals > 0 )
              {
            pen = new Pen( Color.FromArgb( 255, 80, 80 ), 1.0f );
            n = scene.Vertices;
            for ( i = 0; i < n; i++ )
            {
              Vector4 V = new Vector4( scene.GetVertex( i ), 1.0f );
              Vector3 N = scene.GetNormal( i );
              N.Normalize();
              N *= diameter * 0.03f;
              Vector4 W = V + new Vector4( N );
              V = Vector4.Transform( V, compound );
              W = Vector4.Transform( W, compound );
              Vector2 v = new Vector2( V.X / V.W, V.Y / V.W );
              Vector2 w = new Vector2( W.X / W.W, W.Y / W.W );
              gr.DrawLine( pen, v.X, v.Y, w.X, w.Y );
            }
              }
        }
Пример #39
0
        /// <summary>
        /// Generic OBJ-loading scene definition routine.
        /// </summary>
        /// <param name="dir">Viewing direction of a camera.</param>
        /// <param name="FoVy">Field of View in degrees.</param>
        /// <param name="correction">Value less than 1.0 brings camera nearer.</param>
        /// <param name="name">OBJ file-name.</param>
        /// <param name="names">Substitute file-name[s].</param>
        /// <returns>Number of triangles.</returns>
        protected static long SceneObj( IRayScene sc, Vector3d dir, double FoVy, double correction, string name, string[] names, double[] surfaceColor )
        {
            Debug.Assert( sc != null );

              Vector3 center = Vector3.Zero;   // center of the mesh
              dir.Normalize();                 // normalized viewing vector of the camera
              float diameter = 2.0f;           // default scene diameter
              int faces = 0;

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );

              // OBJ file to read:
              if ( names.Length == 0 ||
               names[ 0 ].Length == 0 )
            names = new string[] { name };

              string[] paths = Scenes.SmartFindFiles( names );
              if ( paths[ 0 ] == null || paths[ 0 ].Length == 0 )
              {
            for ( int i = 0; i < names.Length; i++ )
              if ( names[ i ].Length > 0 )
            names[ i ] += ".gz";
            paths = Scenes.SmartFindFiles( names );
              }
              if ( paths[ 0 ] == null || paths[ 0 ].Length == 0 )
            root.InsertChild( new Sphere(), Matrix4d.Identity );
              else
              {
            // B-rep scene construction:
            WavefrontObj objReader = new WavefrontObj();
            objReader.MirrorConversion = false;
            SceneBrep brep = new SceneBrep();
            faces = objReader.ReadBrep( paths[ 0 ], brep );
            brep.BuildCornerTable();
            diameter = brep.GetDiameter( out center );
            TriangleMesh m = new TriangleMesh( brep );
            root.InsertChild( m, Matrix4d.Identity );
              }

              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( surfaceColor, 0.2, 0.5, 0.4, 32 ) );
              root.SetAttribute( PropertyName.COLOR, surfaceColor );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 };

              // Camera:
              double dist = (0.5 * diameter * correction) / Math.Tan( MathHelper.DegreesToRadians( (float)(0.5 * FoVy) ) );
              Vector3d cam = (Vector3d)center - dist * dir;
              sc.Camera = new StaticCamera( cam, dir, FoVy );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 0.8 ) );
              Vector3d lightDir = Vector3d.TransformVector( dir, Matrix4d.CreateRotationY( -2.0 ) );
              lightDir = Vector3d.TransformVector( lightDir, Matrix4d.CreateRotationZ( -0.8 ) );
              sc.Sources.Add( new PointLightSource( (Vector3d)center + diameter * lightDir, 1.0 ) );

              return faces;
        }