public static void WriteV3fArrayAsAara(string filePath, V3f[] elements, V2i sizeV) { var file = File.Open(filePath, FileMode.Create); using (var writer = new BinaryWriter(file, Encoding.UTF8)) { string typeName = "V3f"; byte dimensions = (byte)2; int[] size = { sizeV.X, sizeV.Y }; writer.Write(typeName); writer.Write(dimensions); writer.Write(size[0]); writer.Write(size[1]); for (int i = 0; i < elements.Length; i++) { writer.Write(elements[i].X); writer.Write(elements[i].Y); writer.Write(elements[i].Z); } writer.Flush(); } file.Dispose(); }
public static C4b[] ComputeColorMap(V2i size) { var length = size.X * size.Y; var indexArray = new C4b[length]; var stepX = 255 / (double)size.X; var stepY = 255 / (double)size.Y; //var currColor = C4b.Black; for (int j = 0; j < size.Y; j++) { for (int i = 0; i < size.X; i++) { int index = j * size.X + i; var newR = (byte)(stepX * i); var newG = (byte)(stepY * j); indexArray[index] = new C4b(newR, newG, (byte)128); indexArray[index].Opacity = 255; } } indexArray[0] = C4b.Red; indexArray[length - 1] = C4b.Blue; return(indexArray); }
public static C4b[] DefaultColor(V2i size) { var length = size.X * size.Y; var indexArray = new C4b[length].Set(C4b.White); return(indexArray); }
public static int[] GetIndexArray(V2i size, List <int> invalidPoints) { if (invalidPoints != null) { return(OpcIndices.ComputeIndexArray(size, invalidPoints)); } if (s_indexArrayTable == null) { s_indexArrayTable = new ConcurrentDictionary <V2i, int[]>(); } lock (s_indexArrayTable) { int[] indices; s_indexArrayTable.TryGetValue(size, out indices); if (indices != null) { return(indices); } else { Report.Begin("Computing Index Array Table for {0}", size); indices = OpcIndices.ComputeIndexArray(size, invalidPoints); if (!s_indexArrayTable.ContainsKey(size)) { s_indexArrayTable.TryAdd(size, indices); } Report.End(); return(indices); } } }
/// <summary> /// Returns a subregion of an IEnumerable, which is expected to be a grid in the given resolution. /// </summary> /// <param name="origin">upper left corner in the subpatch</param> /// <param name="size">dimensions in number of entries</param> /// <param name="resolution">Resolution of the expected grid</param> public static IEnumerable <T> GetSubPatch <T>(this IEnumerable <T> self, V2i origin, V2i size, V2i resolution) { //Exception for now - think of good handling of the different cases //return empty grid if (origin.X >= resolution.X || origin.Y >= resolution.Y) { throw new NotImplementedException("requested origin outside of source grid"); } //return full grid if (size.X >= resolution.X || size.Y >= resolution.Y) { throw new NotImplementedException("requested size bigger than source grid"); } //return grid as big as possible if (origin.X + size.X >= resolution.X || origin.Y + size.Y >= resolution.Y) { throw new NotImplementedException("requested tile exceeds source grid boundaries"); } int i = -1; int firstIndex = origin.Y * resolution.X + origin.X; var last = origin + size; int lastIndex = (last.Y - 1) * resolution.X + last.X; int startRow = firstIndex; int endRow = firstIndex + size.X; Report.Line(1, "Skipping {0} entries", firstIndex); foreach (var x in self) { i++; if (i < firstIndex) { continue; } if (i >= startRow && i < endRow) { if (i == endRow - 1) { //Console.WriteLine(); //Console.WriteLine("old start: {0},end: {1}", startRow, endRow); startRow += resolution.X; endRow += resolution.X; // Console.WriteLine("new start: {0},end: {1}", startRow, endRow); } yield return(x); } if (i == lastIndex) { yield break; } } }
public static int[] GetRowAsIndices(V2i size, int rowNumber) { var colInds = new List <int>(); for (int i = 0; i < size.X; i++) { colInds.Add(size.X * rowNumber + i); } return(colInds.ToArray()); }
public static int[] GetColumnAsIndices(V2i size, int colNumber) { var colInds = new List <int>(); for (int i = 0; i < size.Y; i++) { colInds.Add(size.X * i + colNumber); } return(colInds.ToArray()); }
public static int[] ComputeLineStripIndexArray(V2i size) { var indexArray = new int[(size.X * size.Y)]; for (int j = 0; j < size.Y; j++) { for (int i = 0; i < size.X; i++) { int index = j * size.X + i; indexArray[index] = index; } } return(indexArray); }
/// <summary> /// Creates normals for the OPC in opcBasePath and saves them as Normals.aara. /// </summary> public static void BuildNormals(OpcPaths opcPaths, bool overrideExisting = false, IObserver <Tup <float, string> > progress = null, CancellationToken cancelToken = default(CancellationToken)) { var normalFileName = "Normals.aara"; var posFiles = StorageConfig.GetDirectories(opcPaths.PatchesSubDir) .SelectMany(x => StorageConfig.GetFiles(x)) .Where(fileWpath => fileWpath.EndsWith("Positions.aara", StringComparison.OrdinalIgnoreCase)); foreach (var file in posFiles) { if (cancelToken.IsCancellationRequested) { if (progress != null) { progress.OnNext(Tup.Create(0f, "Building normals cancelled.")); progress.OnCompleted(); } cancelToken.ThrowIfCancellationRequested(); } var normalsFilePath = Path.Combine(Path.GetDirectoryName(file), normalFileName); if (overrideExisting || !StorageConfig.FileExists(normalsFilePath)) { var posAara = AaraData.FromFile(file); var tileSize = new V2i(posAara.Size[0], posAara.Size[1]); var posArray = AaraData.ConvertArrayToV3ds[posAara.DataTypeAsSymbol](posAara.LoadElements()); var invalidPoints = OpcIndices.GetInvalidPositions(posArray); var indices = OpcIndices.ComputeIndexArray(tileSize, invalidPoints); var normals = OpcIndices.GenerateVertexNormals(indices, posArray) .Select(p => p.ToV3f()).ToArray(); WriteV3fArrayAsAara(normalsFilePath, normals, tileSize); } if (progress != null) { progress.OnNext(Tup.Create(1f / posFiles.Count(), "")); } } if (progress != null) { progress.OnCompleted(); } }
public static IPointSampleGrid2d GetSubPatch(this IPointSampleGrid2d self, V2i origin, V2i size) { var result = self.Positions.GetSubPatch(origin, size, self.Resolution); return(new PointSampleGrid2d(new PointSampleSet(result), size)); //var posList = new List<V3d>(); //var xOffset = origin.X; //var yOffset = origin.Y; //var stream = self.Positions; //var rowOrigin = yOffset * self.Resolution.X + xOffset; //var enumerator = stream.GetEnumerator(); //Report.BeginTimed("construction subset of size {0}", size.ToString()); //Report.BeginTimed("skipping {0} objects", rowOrigin); //for (int i = 0; i < rowOrigin; i++) //{ // enumerator.MoveNext(); //} //Report.End(); //for (int j = 0; j < size.Y; j++) //{ // //take a row and add it to poslist // //move iterator to end of row // for (int i = 0; i < size.X; i++) // { // posList.Add(enumerator.Current); // enumerator.MoveNext(); // } // //move iterator to begin of next row // for (int i = 0; i < size.X; i++) enumerator.MoveNext(); // Report.Progress(posList.Count / (double)(size.X * size.Y)); // Report.Line(); //} //Report.End("done"); }
/// <summary> /// Computes the neighbour indices in grid for a given position. /// </summary> private static List <int> GetGridNeighbourIndices(int x, int y, V2i tileSize) { var resultList = new List <int>(); //North if (y > 0) { resultList.Add((y - 1) * tileSize.X + x); } //East if (x < tileSize.X - 1) { resultList.Add(y * tileSize.X + x + 1); } //South if (y < tileSize.Y - 1) { resultList.Add((y + 1) * tileSize.X + x); } //West if (x > 0) { resultList.Add(y * tileSize.X + x - 1); } if (x == tileSize.X - 1) { resultList.Add(y * tileSize.X + x - 1); } //if (resultList.Count == 0) //{ // resultList.Add((y - 1) * tileSize.X + x); // resultList.Add(y * tileSize.X + x - 1); //} return(resultList); }
public static int[] ComputeTriangleStripIndexArray(V2i size) { var numOfStrips = size.Y - 1; var numOfSwapIndices = (numOfStrips) * 2; var numOfStripIndices = numOfStrips * size.X * 2; var numOfIndices = numOfSwapIndices + numOfStripIndices; var indexArray = new int[numOfIndices]; int linItr = 0; for (int y = 0; y < size.Y - 1; y++) { for (int x = 0; x < size.X; x++) { var indexUp = size.X * y + x; var indexDown = indexUp + size.X; //(size.X * (y + 1)) + x; if (x == 0) { indexArray[linItr] = indexUp; linItr++; } indexArray[linItr] = indexUp; linItr++; indexArray[linItr] = indexDown; linItr++; if (x == size.X - 1) { indexArray[linItr] = indexDown; linItr++; } } } return(indexArray); }
public static int[] GetTriangleStripIndexArray(V2i size) { if (s_triangleStripIndexArrayTable == null) { s_triangleStripIndexArrayTable = new ConcurrentDictionary <V2i, int[]>(); } int[] indices; s_triangleStripIndexArrayTable.TryGetValue(size, out indices); try { if (indices != null) { return(indices); } else { indices = OpcIndices.ComputeTriangleStripIndexArray(size); s_triangleStripIndexArrayTable.TryAdd(size, indices); return(indices); } } catch (ArgumentException) { return(s_triangleStripIndexArrayTable[size]); } //if (s_triangleStripIndexArrayTable.ContainsKey(size)) // return s_triangleStripIndexArrayTable[size]; //else //{ // s_triangleStripIndexArrayTable.Add(size, OpcTile.ComputeTriangleStripIndexArray(size)); // return s_triangleStripIndexArrayTable[size]; //} }
public static int[] ComputeIndices(V2i size, IEnumerable <int> invalidPoints, V3f[] points, float maxTriangleSize) { var indexArray = new int[(size.X - 1) * (size.Y - 1) * 6]; int k = 0; var invalidDict = invalidPoints.ToDictionary(n => n); int a1, b1, c1; int a2, b2, c2; var indices = new List <int>(); bool invalidFace = false; int counter = 0; int oversized_counter = 0; for (int y = 0; y < size.Y - 1; y++) { for (int x = 0; x < size.X - 1; x++) { a1 = y * size.X + x; b1 = (y + 1) * size.X + x; c1 = y * size.X + x + 1; a2 = y * size.X + x + 1; b2 = (y + 1) * size.X + x; c2 = (y + 1) * size.X + x + 1; indices.Clear(); indices.Add(a1); indices.Add(b1); indices.Add(c1); indices.Add(a2); indices.Add(b2); indices.Add(c2); invalidFace = indices.Select(n => n).Where(m => invalidDict.ContainsKey(m)).ToList().Count() > 0; if (invalidFace) { //Console.WriteLine("Invalid Face Found"); counter++; k += 6; continue; } if (!IsOversizedTriangle(points, a1, b1, c1, maxTriangleSize)) //if (!IsOversizedTriangleSideRatio(points, a1, b1, c1, maxTriangleSize)) { indexArray[k] = a1; indexArray[k + 1] = b1; indexArray[k + 2] = c1; } else { oversized_counter++; } if (!IsOversizedTriangle(points, a2, b2, c2, maxTriangleSize)) //if (!IsOversizedTriangleSideRatio(points, a2, b2, c2, maxTriangleSize)) { indexArray[k + 3] = a2; indexArray[k + 4] = b2; indexArray[k + 5] = c2; } else { oversized_counter++; } k += 6; } } if (counter > 0) { Report.Line(5, "Invalid faces found: " + counter); } return(indexArray.ToArray()); }
public static int[] ComputeIndexArray(V2i size, IEnumerable <int> invalidPoints) { var indexArray = new int[(size.X - 1) * (size.Y - 1) * 6]; int k = 0; bool hasInvalids = invalidPoints != null; #region no invalids if (!hasInvalids) { for (int y = 0; y < size.Y - 1; y++) { for (int x = 0; x < size.X - 1; x++) { indexArray[k] = y * size.X + x; indexArray[k + 1] = (y + 1) * size.X + x; indexArray[k + 2] = y * size.X + x + 1; indexArray[k + 3] = y * size.X + x + 1; indexArray[k + 4] = (y + 1) * size.X + x; indexArray[k + 5] = (y + 1) * size.X + x + 1; k += 6; } } return(indexArray.ToArray()); } #endregion #region has invalids else { var invalidDict = invalidPoints.ToDictionary(n => n); int a1, b1, c1; int a2, b2, c2; var indices = new List <int>(); bool invalidFace = false; int counter = 0; for (int y = 0; y < size.Y - 1; y++) { for (int x = 0; x < size.X - 1; x++) { a1 = y * size.X + x; b1 = (y + 1) * size.X + x; c1 = y * size.X + x + 1; a2 = y * size.X + x + 1; b2 = (y + 1) * size.X + x; c2 = (y + 1) * size.X + x + 1; indices.Clear(); indices.Add(a1); indices.Add(b1); indices.Add(c1); indices.Add(a2); indices.Add(b2); indices.Add(c2); invalidFace = indices.Select(n => n).Where(m => invalidDict.ContainsKey(m)).ToList().Count() > 0; if (invalidFace) { //Console.WriteLine("Invalid Face Found"); counter++; k += 6; continue; } indexArray[k] = a1; indexArray[k + 1] = b1; indexArray[k + 2] = c1; indexArray[k + 3] = a2; indexArray[k + 4] = b2; indexArray[k + 5] = c2; k += 6; } } if (counter > 0) { Report.Line(5, "Invalid faces found: " + counter); } return(indexArray.ToArray()); } #endregion }
public static int[] ComputeTriangleStripIndexArray(V2i size, List <int> invalidPoints) { return(null); }
public void Write(V2i x) { Write(x.X); Write(x.Y); }
//First public static int[] GetFirstColumnAsIndices(V2i size) { return(GetColumnAsIndices(size, 0)); }
public static int[] GetLastRowAsIndices(V2i size) { return(GetRowAsIndices(size, size.Y - 1)); }
/// <summary> /// Loads VertexGeometry from aara files. Beware: add Local2Global node for global space. /// </summary> /// <param name="positions">Raw positions, read from aara files for possible further processing.</param> /// <param name="dataType">DataType of positions.</param> /// <returns>Vertex Geometry in local OPC space.</returns> public static VertexGeometry LoadPatch(PatchFileInfo info, string basePath, PositionsType posType, out Array positions, out Symbol dataType, bool loadNormals = true, bool loadTexCoords = true, bool loadDiffTex = true, bool loadHueTex = true, float maxTriangleSize = float.PositiveInfinity, bool loadAsDoubles = false) { var vg = new VertexGeometry(GeometryMode.TriangleList); positions = null; // load metadata var aara3dPos = AaraData.FromFile( Path.Combine(basePath, posType == PositionsType.V3dPositions ? info.Positions : info.Positions2d)); dataType = aara3dPos.DataTypeAsSymbol; var resolution = new V2i(aara3dPos.Size); if (resolution.AnySmaller(2)) { Report.Warn("ignoring patch {0} due to invalid gridresolution {1}", basePath, resolution); return(null); } // load positions positions = aara3dPos.LoadElements(); var positions3d = loadAsDoubles ? positions : AaraData.ConvertArrayToV3fs[aara3dPos.DataTypeAsSymbol](positions); //var positionsV3 = loadAsDoubles ? // (Array)AaraData.ConvertArrayToV3ds[aara3dPos.DataTypeAsSymbol](positions) : // (Array); vg.Positions = positions3d; var p = AaraData.ConvertArrayToV3fs[aara3dPos.DataTypeAsSymbol](positions); // calculate indices var invalidPoints = OpcIndices.GetInvalidPositions(p); // limit triangle size if ((maxTriangleSize < float.PositiveInfinity) && (maxTriangleSize > 0.000001f)) { vg.Indices = OpcIndices.ComputeIndexArray(resolution, invalidPoints.ToList(), p, maxTriangleSize); } else { vg.Indices = OpcIndices.ComputeIndexArray(resolution, invalidPoints.ToList()); } // load normals if (loadNormals) { var normalPath = Path.Combine(basePath, "Normals.aara"); if (StorageConfig.FileExists(normalPath)) { var normals = AaraData.FromFile(normalPath); var normals3d = AaraData.ConvertArrayToV3fs[normals.DataTypeAsSymbol](normals.LoadElements()); vg.Normals = normals3d; } } // load coordinates vg.Coordinates = new CoordinatesMap(); if (loadTexCoords) { var coordPath = Path.Combine(basePath, info.Coordinates.First()); var coordinates = AaraData.FromFile(coordPath).LoadElements() as V2f[]; vg.Coordinates[VertexGeometry.Property.DiffuseColorCoordinates] = coordinates; } // load textures vg.Textures = new TexturesMap(); if (loadDiffTex) { var texFile = Path.ChangeExtension(info.Textures.First(), ".dds"); var texPath = Path.GetFullPath(Path.Combine(basePath, @"..\..\images", texFile)); if (StorageConfig.FileExists(texPath)) { var img = Convertible.FromFile(texPath); vg.Textures[VertexGeometry.Property.DiffuseColorTexture] = new Aardvark.Rendering.Texture(img) { ForceImmediateUpload = false }; } } if (loadHueTex) { vg.Textures[VertexGeometry.Property.LightMapTexture] = new Aardvark.Rendering.Texture(Resources.HueColorMap.Convertible()); } return(vg); }
/// <summary> /// Computes the number of levels of a bottom-up hierarchy built on a grid of tiled elements. It is assumed /// that the root (top) of the hierarchy finally consists of one single tile. /// </summary> public static int ComputeHierarchyDepth(V2i gridSize) { var depth = System.Math.Log(System.Math.Max(gridSize.X, gridSize.Y), 2); return(System.Math.Ceiling(depth).ToInt()); }
static void Main(string[] args) { Aardvark.Base.Aardvark.Init(); // PixImage DevIL init var device = new Device(); Report.Line("Version={0}", device.Version); Report.Line("RayMaskSupported={0}", device.RayMaskSupported); Report.Line("FilterFunctionSupported={0}", device.FilterFunctionSupported); var geos = new[] { new EmbreeIndexedGeometry(device, IndexedGeometryPrimitives.Sphere.solidPhiThetaSphere(new Sphere3d(V3d.OOO, 0.5), 1200, new C4b(160, 120, 190))), //new EmbreeIndexedGeometry(device, // IndexedGeometryPrimitives.Quad.solidQuadrangle(V3d.OOO, V3d.IOO, V3d.IOI, V3d.OOI, new C4b(255, 255, 255), V3d.OIO)), //new EmbreeIndexedGeometry(device, // IndexedGeometryPrimitives.Box.solidBox(new Box3d(V3d.OOO, V3d.III), new C4b(240, 150, 220))), //new EmbreeIndexedGeometry(device, // IndexedGeometryPrimitives.Cone.solidCone(V3d.OOO, V3d.OOI, 1.0, 0.25, 12, new C4b(120, 130, 170))), //new EmbreeIndexedGeometry(device, // IndexedGeometryPrimitives.Cylinder.solidCylinder(V3d.OOO, V3d.OOI, 1.0, 0.25, 0.15, 16, new C4b(250, 100, 140))), //new EmbreeIndexedGeometry(device, // IndexedGeometryPrimitives.Torus.solidTorus(new Torus3d(V3d.OOO, V3d.OOI, 0.8, 0.2), new C4b(200, 180, 255), 12, 8)), }; Report.Line("TriangleCount: {0}", geos.Sum(x => x.IndexedGeometry.FaceCount)); var scene = new Scene(device, RTCBuildQuality.High, false); Report.BeginTimed("Create Scene"); var geoMap = new Dictionary <uint, EmbreeIndexedGeometry>(); // geometries with absolute transformation foreach (var g in geos) { geoMap.Add(scene.Attach(g.EmbreeGeometry), g); } //// instanced geometries with transformation matrix //foreach (var g in geos) //{ // var gi = new GeometryInstance(device, g.EmbreeGeometry, Affine3f.Identity); // geoMap.Add(scene.Attach(gi), g); //} scene.Commit(); Report.End(); var cam = new CameraViewWithSky(); cam.Location = V3d.III * 0.8; cam.LookAt(V3d.OOO); var vpSize = new V2i(3840, 2160); var proj = new CameraProjectionPerspective(60, 0.1, 10, vpSize.X / (double)vpSize.Y); var pix = RenderSimple(scene, vpSize.X, vpSize.Y, cam.ViewTrafo, proj.ProjectionTrafo, geoMap); device.Dispose(); var file = "C:\\Debug\\Embree.png"; pix.SaveAsImage(file); //Process.Start(file); }
/// <summary>Computes MD5 hash of given data.</summary> public static Guid ComputeMd5Hash(this V2i x) => ComputeMd5Hash(bw => { bw.Write(x.X); bw.Write(x.Y); });
/// <summary> /// Compute index array to triangulate an ordered point set with /// a resolution of size.x X size.y /// </summary> /// <param name="size">V2i specifying number of points /// in x and y direction respectively</param> /// <returns>index array</returns> public static int[] ComputeIndexArray(V2i size) { return(ComputeIndexArray(size, null)); }
public static int[] GetIndexArray(V2i size) { return(GetIndexArray(size, null)); }
public static System.Drawing.Point ToPoint(this V2i p) { return(new System.Drawing.Point(p.X, p.Y)); }
public static int[] GetFirstRowAsIndices(V2i size) { return(GetRowAsIndices(size, 0)); }
public static System.Drawing.Size ToSize(this V2i v) { return(new System.Drawing.Size(v.X, v.Y)); }
//Last public static int[] GetLastColumnAsIndices(V2i size) { return(GetColumnAsIndices(size, size.X - 1)); }