/// /// This file is part of ILNumerics Community Edition. /// /// ILNumerics Community Edition - high performance computing for applications. /// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net /// /// ILNumerics Community Edition is free software: you can redistribute it and/or modify /// it under the terms of the GNU General Public License version 3 as published by /// the Free Software Foundation. /// /// ILNumerics Community Edition is distributed in the hope that it will be useful, /// but WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /// GNU General Public License for more details. /// /// You should have received a copy of the GNU General Public License /// along with ILNumerics Community Edition. See the file License.txt in the root /// of your distribution package. If not, see . /// /// In addition this software uses the following components and/or licenses: /// /// ================================================================================= /// The Open Toolkit Library License /// /// Copyright (c) 2006 - 2009 the Open Toolkit library. /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal /// in the Software without restriction, including without limitation the rights to /// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of /// the Software, and to permit persons to whom the Software is furnished to do /// so, subject to the following conditions: /// /// The above copyright notice and this permission notice shall be included in all /// copies or substantial portions of the Software. /// /// ================================================================================= /// using System; using System.Collections.Generic; using System.Text; namespace ILNumerics.Algorithms { public partial class Graphic { /// /// Increase the number of triangles by doubling existing triangles /// /// Vertices /// Triangle index definitions /// Number of iterations, each iteration will make 4 triangles out of each triangle /// [Output] Vertices. /// [Output] Triangles /// Incoming triangles are expected not to be degenerated. This means: /// Every edge is used only twice at most. No triangle shares more than 2 /// corners with some other triangle. /// None of the incoming arrays will get altered public static void Triangularize(ILInArray vertices, ILInArray triangles, int iterations, ILOutArray outVertices, ILOutArray outTriangles) { using (ILScope.Enter(vertices, triangles)) { int numVertices = vertices.Size[1]; int numTriangles = triangles.Size[1]; outVertices.a = vertices.C; outTriangles.a = triangles.C; // being pessimistic: expect to create a larger number of vertices than probable outVertices[0, numVertices * 2] = 0; outTriangles[0, numTriangles * 2] = 0; int triIndLast = numTriangles; int vertIndLast = numVertices; for (int it = 0; it < iterations; it++) { int triIndItEnd = triIndLast; for (int triInd = 0; triInd < triIndItEnd; triInd++) { int vertInd0 = outTriangles.GetValue(0, triInd); int vertInd1 = outTriangles.GetValue(1, triInd); int vertInd2 = outTriangles.GetValue(2, triInd); // create new vertices float v0x = (outVertices.GetValue(0, vertInd0) + outVertices.GetValue(0, vertInd1)) / 2f; float v0y = (outVertices.GetValue(1, vertInd0) + outVertices.GetValue(1, vertInd1)) / 2f; float v0z = (outVertices.GetValue(2, vertInd0) + outVertices.GetValue(2, vertInd1)) / 2f; float v1x = (outVertices.GetValue(0, vertInd1) + outVertices.GetValue(0, vertInd2)) / 2f; float v1y = (outVertices.GetValue(1, vertInd1) + outVertices.GetValue(1, vertInd2)) / 2f; float v1z = (outVertices.GetValue(2, vertInd1) + outVertices.GetValue(2, vertInd2)) / 2f; float v2x = (outVertices.GetValue(0, vertInd2) + outVertices.GetValue(0, vertInd0)) / 2f; float v2y = (outVertices.GetValue(1, vertInd2) + outVertices.GetValue(1, vertInd0)) / 2f; float v2z = (outVertices.GetValue(2, vertInd2) + outVertices.GetValue(2, vertInd0)) / 2f; #region new vertex exists already? TODO: This needs to be replaced with a b-tree implementation!! int newVertID0 = -1; int newVertID1 = -1; int newVertID2 = -1; for (int vi = 0; vi < vertIndLast; vi++) { float tmpX = outVertices.GetValue(0, vi); float tmpY = outVertices.GetValue(1, vi); float tmpZ = outVertices.GetValue(2, vi); if (tmpX == v0x && tmpY == v0y && tmpZ == v0z) { newVertID0 = vi; } if (tmpX == v1x && tmpY == v1y && tmpZ == v1z) { newVertID1 = vi; } if (tmpX == v2x && tmpY == v2y && tmpZ == v2z) { newVertID2 = vi; } if (newVertID0 >= 0 && newVertID1 >= 0 && newVertID2 >= 0) break; } #endregion if (newVertID0 < 0) { newVertID0 = vertIndLast++; outVertices[0, newVertID0] = v0x; outVertices[1, newVertID0] = v0y; outVertices[2, newVertID0] = v0z; } if (newVertID1 < 0) { newVertID1 = vertIndLast++; outVertices[0, newVertID1] = v1x; outVertices[1, newVertID1] = v1y; outVertices[2, newVertID1] = v1z; } if (newVertID2 < 0) { newVertID2 = vertIndLast++; outVertices[0, newVertID2] = v2x; outVertices[1, newVertID2] = v2y; outVertices[2, newVertID2] = v2z; } // create new triangles outTriangles.SetValue(newVertID0, 1, triInd); outTriangles.SetValue(newVertID2, 2, triInd); outTriangles.SetValue(newVertID2, 0, triIndLast); outTriangles.SetValue(newVertID1, 1, triIndLast); outTriangles.SetValue(vertInd2, 2, triIndLast++); outTriangles.SetValue(newVertID2, 0, triIndLast); outTriangles.SetValue(newVertID0, 1, triIndLast); outTriangles.SetValue(newVertID1, 2, triIndLast++); outTriangles.SetValue(newVertID0, 0, triIndLast); outTriangles.SetValue(vertInd1, 1, triIndLast); outTriangles.SetValue(newVertID1, 2, triIndLast++); } } outVertices.a = outVertices[":;0:" + (vertIndLast - 1)]; outTriangles.a = outTriangles[":;0:" + (triIndLast - 1)]; } } } }