public FastTriangleMesh(SceneBrep m) : base(m) { // !!!{{ TODO: prepare acceleration structure for the mesh // !!!}} }
public TriangleMesh(SceneBrep m) { mesh = m; ShellMode = false; Smooth = true; // !!!{{ TODO: prepare acceleration structure for the mesh // !!!}} }
public void AssignObjects(SceneBrep aFirst, SceneBrep aSecond) { mFirstObject = aFirst; mSecondObject = aSecond; if (aFirst == null || aSecond == null || aFirst.Vertices != aSecond.Vertices) { mInterpolatedObject = null; return; } mInterpolatedObject = mFirstObject.Clone(); // !!!{{ TODO: put your initialization code here // !!!}} }
/// <summary> /// Creates default ray-rendering scene. /// </summary> public RayScene(SceneBrep mesh) { // scene: TriangleMesh root = new TriangleMesh(mesh); root.SetAttribute(PropertyName.REFLECTANCE_MODEL, new PhongModel()); root.SetAttribute(PropertyName.MATERIAL, new PhongMaterial(new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.5, 0.4, 12)); root.SetAttribute(PropertyName.COLOR, new double[] { 1.0, 0.6, 0.0 }); Intersectable = root; // background color: BackgroundColor = new double[] { 0.0, 0.15, 0.2 }; // camera: Camera = new StaticCamera(new Vector3d(0.5, 2.0, -5.0), new Vector3d(0.1, -0.2, 0.9), 60.0); // light sources: Sources = new LinkedList <ILightSource>(); Sources.Add(new AmbientLightSource(0.8)); Sources.Add(new PointLightSource(new Vector3d(-20.0, 12.0, -12.0), 1.0)); }
private void loadButtonPressed(object sender, EventArgs e) { SceneBrep brep = new SceneBrep(); if (sender == buttonLoadFirst) { mFirstObject = brep; } else if (sender == buttonLoadSecond) { mSecondObject = brep; } else { return; } OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "Open Scene File"; ofd.Filter = "Wavefront OBJ Files|*.obj;*.obj.gz" + "|All scene types|*.obj"; ofd.FilterIndex = 1; ofd.FileName = ""; if (ofd.ShowDialog() != DialogResult.OK) { return; } if (mWavefrontObj.ReadBrep(ofd.FileName, brep) < 0) { MessageBox.Show(this, "Loading failed"); } mMorph.AssignObjects(mFirstObject, mSecondObject); mMorph.Interpolate(((float)trackBar1.Value) / trackBar1.Maximum); redrawAll(); }
/// <summary> /// Initialize ray-scene and image function (good enough for single samples). /// </summary> public static IImageFunction getImageFunction(out IRayScene scene, SceneBrep brepScene) { // default constructor of the RayScene .. custom scene scene = new RayScene(brepScene); return(new RayTracing(scene)); }
public static long TestScene(IRayScene sc, string[] names) { Debug.Assert(sc != null); Vector3 center = Vector3.Zero; // center of the mesh Vector3d dir = new Vector3d(0.1, -0.3, 0.9); dir.Normalize(); // normalized viewing vector of the camera float diameter = 2.0f; // default scene diameter double FoVy = 60.0; // Field of View in degrees 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[] { "teapot.obj" } } ; 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 FastTriangleMesh(brep); root.InsertChild(m, Matrix4d.Identity); } root.SetAttribute(PropertyName.REFLECTANCE_MODEL, new PhongModel()); root.SetAttribute(PropertyName.MATERIAL, new PhongMaterial(new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.5, 0.4, 12)); root.SetAttribute(PropertyName.COLOR, new double[] { 1.0, 0.6, 0.0 }); sc.Intersectable = root; // Background color: sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 }; // Camera: double dist = (0.6 * diameter) / 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)); sc.Sources.Add(new PointLightSource(new Vector3d(-20.0, 12.0, -12.0), 1.0)); return(faces); } }
/// <summary> /// Parses one object from input .obj file. /// </summary> /// <param name="reader">Reader with current position in .obj file.</param> /// <returns> /// Triangle mesh with name of the associated material. /// If material name is an empty string, no material was used. /// </returns> private Tuple <string, FastTriangleMesh> parseObject(StreamReader reader, ref int verticesCount, ref int txtCoordsCount, ref int normalsCount) { SceneBrep scene = new SceneBrep(); string materialName = ""; 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]; while (!reader.EndOfStream) { // Check if there is defined "o" tag, if yes, it is the end of definition of one object // and return this object. if ((char)reader.Peek() == 'o') { break; } string line = reader.ReadLine(); string[] tokens = line.Split(); if (tokens.Length == 0) { continue; } switch (tokens[0]) { case "v": if (tokens.Length != 4) { throw new Exception("Incorrect .obj file."); } // Add vertex. float x, y, z; if (!float.TryParse(tokens[1], NumberStyles.Float, CultureInfo.InvariantCulture, out x) || !float.TryParse(tokens[2], NumberStyles.Float, CultureInfo.InvariantCulture, out y) || !float.TryParse(tokens[3], NumberStyles.Float, CultureInfo.InvariantCulture, out z)) { throw new Exception("Incorrect .obj file."); } lastVertex = scene.AddVertex(new Vector3(x, y, z)); break; case "vt": if (tokens.Length != 3) { throw new Exception("Incorrect .obj file."); } // Add vertex. float u, v; if (!float.TryParse(tokens[1], NumberStyles.Float, CultureInfo.InvariantCulture, out u) || !float.TryParse(tokens[2], NumberStyles.Float, CultureInfo.InvariantCulture, out v)) { throw new Exception("Incorrect .obj file."); } txtCoords.Add(new Vector2(u, v)); ++lastTxtCoord; break; case "vn": if (tokens.Length != 4) { throw new Exception("Incorrect .obj file."); } // Add vertex. float nx, ny, nz; if (!float.TryParse(tokens[1], NumberStyles.Float, CultureInfo.InvariantCulture, out nx) || !float.TryParse(tokens[2], NumberStyles.Float, CultureInfo.InvariantCulture, out ny) || !float.TryParse(tokens[3], NumberStyles.Float, CultureInfo.InvariantCulture, out nz)) { throw new Exception("Incorrect .obj file."); } normals.Add(new Vector3(nx, ny, nz)); break; case "usemtl": // Set name of the material used for this object. if (tokens.Length != 2) { throw new Exception("Incorrect .obj file."); } materialName = tokens[1]; break; case "f": // Face must be formed by at least three vertices. if (tokens.Length < 4) { continue; } // Number of vertices. int N = tokens.Length - 1; // Reuse same array for each face and resize it if needed. if (f.Length < N) { f = new int[N]; } // Shrink it if less vertices is used. if (N < f.Length) { 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 - verticesCount; } 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 = ti - txtCoordsCount - 1; } 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 = ni - normalsCount - 1; } 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; } } // Update count of vertices, txt coords and normals. verticesCount += scene.Vertices; txtCoordsCount += txtCoords.Count; normalsCount += normals.Count; scene.BuildCornerTable(); scene.BuildBoundingBox(); return(new Tuple <string, FastTriangleMesh>(materialName, new FastTriangleMesh(scene))); }
public FastTriangleMesh(SceneBrep m) : base(m) { }
private void RenderScene(SceneBrep scene) { if (scene != null && scene.Triangles > 0) { if (scene.HasNormals() && scene.Normals > 0) { GL.Begin(PrimitiveType.Triangles); for (int i = 0; i < scene.Triangles; ++i) { int v1, v2, v3; scene.GetTriangleVertices(i, out v1, out v2, out v3); GL.Normal3(scene.GetNormal(v1)); GL.Vertex3(scene.GetVertex(v1)); GL.Normal3(scene.GetNormal(v2)); GL.Vertex3(scene.GetVertex(v2)); GL.Normal3(scene.GetNormal(v3)); GL.Vertex3(scene.GetVertex(v3)); } GL.End(); } else { GL.End(); GL.Begin(PrimitiveType.Triangles); for (int i = 0; i < scene.Triangles; ++i) { Vector3 v1, v2, v3; scene.GetTriangleVertices(i, out v1, out v2, out v3); GL.Vertex3(v1); GL.Vertex3(v2); GL.Vertex3(v3); } GL.End(); } } else // color cube (JB) { GL.Begin(PrimitiveType.Quads); GL.Color3(0.0f, 1.0f, 0.0f); // Set The Color To Green GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Top) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Top) GL.Vertex3(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top) GL.Vertex3(1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top) GL.Color3(1.0f, 0.5f, 0.0f); // Set The Color To Orange GL.Vertex3(1.0f, -1.0f, 1.0f); // Top Right Of The Quad (Bottom) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Top Left Of The Quad (Bottom) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Bottom) GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Bottom) GL.Color3(1.0f, 0.0f, 0.0f); // Set The Color To Red GL.Vertex3(1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front) GL.Vertex3(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Quad (Front) GL.Vertex3(1.0f, -1.0f, 1.0f); // Bottom Right Of The Quad (Front) GL.Color3(1.0f, 1.0f, 0.0f); // Set The Color To Yellow GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Back) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Back) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Back) GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Back) GL.Color3(0.0f, 0.0f, 1.0f); // Set The Color To Blue GL.Vertex3(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Left) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Left) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Quad (Left) GL.Color3(1.0f, 0.0f, 1.0f); // Set The Color To Violet GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Right) GL.Vertex3(1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right) GL.Vertex3(1.0f, -1.0f, 1.0f); // Bottom Left Of The Quad (Right) GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Right) GL.End(); } }