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); }
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); }
/// <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); // }} }
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); }
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); }
public int ReadBrep(string fileName, SceneBrep scene) { Debug.Assert(scene != null); this.scene = scene; scene.Reset(); if (fileName == null || fileName.Length == 0) { throw new IOException("Invalid file name"); } if (fileName.EndsWith(".gz")) { headerReader = new StreamReader(new GZipStream(new FileStream(fileName, FileMode.Open), CompressionMode.Decompress)); } else { var fs = new FileStream(fileName, FileMode.Open); headerReader = new StreamReader(fs); } // prepare buffers for data filling if (!ParseHeader()) { return(-1); } // read vertices var vertexReader = GetReader("vertex"); var element = vertexReader.ReadElement(); List <Vector2> txtCoords = new List <Vector2>(256); int[] f = new int[3]; int v0 = scene.Vertices; int lastVertex = v0 - 1; while (element != null) { lastVertex = scene.AddVertex(Vector3.TransformPosition(element.GetVertex(), matrix)); if (DoNormals) { Vector3.TransformNormal(element.GetNormal(), matrix); scene.SetNormal(lastVertex, element.GetNormal()); } if (DoTxtCoords) { scene.SetTxtCoord(lastVertex, element.GetTextureCoordinate()); } if (DoColors) { scene.SetColor(lastVertex, element.GetVertexColor()); } element = vertexReader.ReadElement(); } // read triangles var faceReader = GetReader("face"); element = faceReader.ReadElement(); while (element != null) { int A, B, C; element.GetTriangleVertices(out A, out B, out C); scene.AddTriangle(A, B, C); element = faceReader.ReadElement(); } headerReader.Close(); vertexReader.Close(); faceReader.Close(); return(scene.Triangles); }
/// <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 <Vector2> txtCoords = new List <Vector2>(256); List <Vector3> normals = new List <Vector3>(256); int lastTxtCoord = -1; 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.TransformPosition(coord, m)); break; case VERTEX_TEXTURE: if (tokens.Length < 3) { continue; } Vector2 txtCoord; if (!float.TryParse(tokens[1], NumberStyles.Float, CultureInfo.InvariantCulture, out txtCoord.X) || !float.TryParse(tokens[2], NumberStyles.Float, CultureInfo.InvariantCulture, out txtCoord.Y)) { continue; } if (TextureUpsideDown) { txtCoord.Y = 1.0f - txtCoord.Y; } txtCoords.Add(txtCoord); lastTxtCoord++; 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 texture coord.. if (ti != 0) { if (ti > 0) { ti--; } else { ti = lastTxtCoord + 1 - ti; } if (ti >= 0 && ti < txtCoords.Count) { scene.SetTxtCoord(f[i], txtCoords[ti]); } } // 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); }