Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Drawing/Shapes/ILLitSphere.cs @ 10903

Last change on this file since 10903 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 17.4 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Collections.Generic;
42using System.Runtime.InteropServices;
43using System.Text;
44using System.Drawing;
45using ILNumerics.Drawing;
46using ILNumerics;
47using ILNumerics.Drawing.Graphs;
48using ILNumerics.Exceptions;
49
50namespace ILNumerics.Drawing.Shapes {
51   
52    public class ILLitSphere
53        : ILLitCompositeShape<C4fN3fV3f>
54    {
55
56        #region attributes
57        ILPoint3Df m_center;
58        float m_radius;
59        int m_detail = 1;
60        #endregion
61
62        #region properties
63        #endregion
64
65        #region constructors
66        /// <summary>
67        /// create new lit sphere, resolution of 3
68        /// </summary>
69        /// <param name="panel">panel hosting the scene</param>
70        /// <param name="center">center position</param>
71        /// <param name="radius">radius of the sphere</param>
72        /// <param name="color">color of the sphere</param>
73        public ILLitSphere (ILPanel panel, ILPoint3Df center, float radius, Color color)
74            : this (panel, center, radius, color, 3) {
75        }
76        /// <summary>
77        /// create new lit sphere for a scene graph
78        /// </summary>
79        /// <param name="panel">panel hosting the scene</param>
80        /// <param name="center">center position</param>
81        /// <param name="radius">radius of the sphere</param>
82        /// <param name="color">color of the sphere</param>
83        /// <param name="detail">number of triangularization iterations, typical: 0..4</param>
84        public ILLitSphere (ILPanel panel, ILPoint3Df center, float radius, Color color, int detail)
85            : base (panel,3,3) {
86            m_fillColor = color;
87            m_center = center;
88            m_radius = radius;
89            m_detail = detail;
90            Material.Shininess = 60;
91            AutoNormals = true;
92            m_shading = ShadingStyles.Interpolate;
93            createVertices(detail);
94        }
95        #endregion
96
97        #region public interface
98        #endregion
99       
100        private void createVertices(int detail) {
101            using (ILScope.Enter()) {
102                //ILArray<float> vertData = Computation.CreateVertices(
103                //            m_center,m_radius,horRes,vertRes, out m_shapeIndices);
104                ILArray<float> vertData = Computation.CreateVerticesTri(
105                            detail, m_shapeIndices);
106                Resize(vertData.Size[1]);
107                vertData = vertData * m_radius;
108                for (int r = 0, pos = 0; r < VertexCount; r++) {
109                    m_vertices[pos].XPosition = vertData.GetValue(0, r) + m_center.X;
110                    m_vertices[pos].YPosition = vertData.GetValue(1, r) + m_center.Y;
111                    m_vertices[pos].ZPosition = vertData.GetValue(2, r) + m_center.Z;
112                    m_vertices[pos].Color = m_fillColor;
113                    m_vertices[pos++].Alpha = m_fillColor.A;
114                }
115            }
116        }
117
118        private new class Computation : ILMath {
119
120            private static Dictionary<int, ILCell> s_vertexCache = new Dictionary<int, ILCell>();
121            /// <summary>
122            /// increase the number of triangles by doubling existing triangles
123            /// </summary>
124            /// <param name="vertices">vertices</param>
125            /// <param name="triangles">triangle index definitions</param>
126            /// <param name="iterations">number of iterations. On each iteration, 4 triangles will replace every single triangle!</param>
127            /// <param name="outVertices">The out vertices.</param>
128            /// <param name="outTriangles">The out triangles.</param>
129            /// <remarks><para>Incoming triangles are expected not to be degenerated. This means:
130            /// Every edge is used only twice at most. No triangle shares more than 2
131            /// corners with some other triangle. </para>
132            /// </remarks>
133            public static void Triangularize(ILInArray<float> vertices, ILInArray<int> triangles,
134                                            int iterations,
135                                            ILOutArray<float> outVertices,
136                                            ILOutArray<int> outTriangles) {
137                using (ILScope.Enter(vertices, triangles)) {
138                    int numVertices = vertices.Size[1];
139                    int numTriangles = triangles.Size[1];
140                    outVertices.a = vertices.C;
141                    outTriangles.a = triangles.C;
142                    // beeing pessimistic: expect to create a larger number of vertices than probable
143                    outVertices[0, numVertices * 2] = 0;
144                    outTriangles[0, numTriangles * 2] = 0;
145
146                    int triIndLast = numTriangles - 1;
147                    int vertIndLast = numVertices - 1;
148                    for (int it = 0; it < iterations; it++) {
149                        int triIndItEnd = triIndLast;
150
151                        for (int triInd = 0; triInd <= triIndItEnd; triInd++) {
152                            int vertInd0 = outTriangles.GetValue(0, triInd);
153                            int vertInd1 = outTriangles.GetValue(1, triInd);
154                            int vertInd2 = outTriangles.GetValue(2, triInd);
155                            // create new vertices
156                            float v0x = (outVertices.GetValue(0, vertInd0) + outVertices.GetValue(0, vertInd1)) / 2f;
157                            float v0y = (outVertices.GetValue(1, vertInd0) + outVertices.GetValue(1, vertInd1)) / 2f;
158                            float v0z = (outVertices.GetValue(2, vertInd0) + outVertices.GetValue(2, vertInd1)) / 2f;
159                            float v1x = (outVertices.GetValue(0, vertInd1) + outVertices.GetValue(0, vertInd2)) / 2f;
160                            float v1y = (outVertices.GetValue(1, vertInd1) + outVertices.GetValue(1, vertInd2)) / 2f;
161                            float v1z = (outVertices.GetValue(2, vertInd1) + outVertices.GetValue(2, vertInd2)) / 2f;
162                            float v2x = (outVertices.GetValue(0, vertInd2) + outVertices.GetValue(0, vertInd0)) / 2f;
163                            float v2y = (outVertices.GetValue(1, vertInd2) + outVertices.GetValue(1, vertInd0)) / 2f;
164                            float v2z = (outVertices.GetValue(2, vertInd2) + outVertices.GetValue(2, vertInd0)) / 2f;
165                            #region new vertex exists already? TODO: This needs to be replaced (with a b-tree implementation?)!!
166                            int newVertID0 = -1;
167                            int newVertID1 = -1;
168                            int newVertID2 = -1;
169                            for (int vi = 0; vi <= vertIndLast; vi++) {
170                                float tmpX = outVertices.GetValue(0, vi);
171                                float tmpY = outVertices.GetValue(1, vi);
172                                float tmpZ = outVertices.GetValue(2, vi);
173                                if (tmpX == v0x && tmpY == v0y && tmpZ == v0z) {
174                                    newVertID0 = vi;
175                                }
176                                if (tmpX == v1x && tmpY == v1y && tmpZ == v1z) {
177                                    newVertID1 = vi;
178                                }
179                                if (tmpX == v2x && tmpY == v2y && tmpZ == v2z) {
180                                    newVertID2 = vi;
181                                }
182                                if (newVertID0 >= 0 && newVertID1 >= 0 && newVertID2 >= 0)
183                                    break;
184                            }
185                            #endregion
186
187                            if (newVertID0 < 0) {
188                                newVertID0 = ++vertIndLast;
189                                outVertices[0, newVertID0] = v0x;
190                                outVertices[1, newVertID0] = v0y;
191                                outVertices[2, newVertID0] = v0z;
192                            }
193                            if (newVertID1 < 0) {
194                                newVertID1 = ++vertIndLast;
195                                outVertices[0, newVertID1] = v1x;
196                                outVertices[1, newVertID1] = v1y;
197                                outVertices[2, newVertID1] = v1z;
198                            }
199                            if (newVertID2 < 0) {
200                                newVertID2 = ++vertIndLast;
201                                outVertices[0, newVertID2] = v2x;
202                                outVertices[1, newVertID2] = v2y;
203                                outVertices[2, newVertID2] = v2z;
204                            }
205
206                            if (outTriangles.S[1] <= triIndLast + 3)
207                                outTriangles[0, triIndLast * 2] = 0;
208
209                            // create new triangles
210                            outTriangles.SetValue(newVertID0, 1, triInd);
211                            outTriangles.SetValue(newVertID2, 2, triInd);
212
213                            outTriangles.SetValue(newVertID2, 0, ++triIndLast);
214                            outTriangles.SetValue(newVertID1, 1, triIndLast);
215                            outTriangles.SetValue(vertInd2, 2, triIndLast);
216
217                            outTriangles.SetValue(newVertID2, 0, ++triIndLast);
218                            outTriangles.SetValue(newVertID0, 1, triIndLast);
219                            outTriangles.SetValue(newVertID1, 2, triIndLast);
220
221                            outTriangles.SetValue(newVertID0, 0, ++triIndLast);
222                            outTriangles.SetValue(vertInd1, 1, triIndLast);
223                            outTriangles.SetValue(newVertID1, 2, triIndLast);
224                        }
225
226                    }
227                    outVertices.a = outVertices[":;0:" + vertIndLast];
228                    outTriangles.a = outTriangles[":;0:" + triIndLast];
229                }
230            }
231
232            /// <summary>
233            /// create vertex data [unevenly distributed, depricated]
234            /// </summary>
235            /// <param name="center"></param>
236            /// <param name="radius"></param>
237            /// <param name="horRes"></param>
238            /// <param name="vertRes"></param>
239            /// <param name="indices"></param>
240            /// <returns></returns>
241            public static ILRetArray<float> CreateVertices(ILPoint3Df center, float radius, int horRes, int vertRes, ILOutArray<int> indices) {
242                using (ILScope.Enter()) {
243                    ILArray<float> phi = repmat(tosingle(linspace(-pi, pi, horRes + 1)), vertRes + 1, 1);
244                    ILArray<float> rho = repmat(tosingle(linspace(0, pi, vertRes + 1)).T, 1, horRes + 1);
245                    bool dummy;
246                    float[] retArr = ILNumerics.ILMemoryPool.Pool.New<float>((horRes + 1) * (vertRes + 1), false, out dummy);
247                    ILArray<float> ret = new ILArray<float>(retArr, vertRes + 1, horRes + 1);
248                    // create normals
249                    ret[":;:;3"] = sin(phi) * sin(rho);
250                    ret[":;:;4"] = cos(phi) * sin(rho);
251                    ret[":;:;5"] = cos(rho);
252                    // translate + scale vertices
253                    ret[":;:;0"] = (ILArray<float>)radius * ret[":;:;3"] + center.X;
254                    ret[":;:;1"] = (ILArray<float>)radius * ret[":;:;4"] + center.Y;
255                    ret[":;:;2"] = (ILArray<float>)radius * ret[":;:;5"] + center.Z;
256                    // create index mappings
257                    //horRes--; vertRes--;
258                    indices.a = zeros<int>(4, (horRes) * (vertRes));
259                    for (int r = 0, pos = 0; r < vertRes; r++) {
260                        for (int c = 0; c < horRes; c++) {
261                            indices.SetValue(c + r * (horRes + 1), pos++);
262                            indices.SetValue(c + (r + 1) * (horRes + 1), pos++);
263                            indices.SetValue((c + 1) + (r + 1) * (horRes + 1), pos++);
264                            indices.SetValue((c + 1) + r * (horRes + 1), pos++);
265                        }
266                    }
267                    System.Diagnostics.Debug.Assert(maxall(indices) <= ret[":;:;0"].Size.NumberOfElements);
268                    System.Diagnostics.Debug.Assert(minall(indices) >= 0);
269                    return ret;
270                }
271            }
272            /// <summary>
273            /// create vertices by triangularization, starting from icosahedron and subseq. creating finer grained details
274            /// </summary>
275            /// <param name="detail">number of iterations for triangularization</param>
276            /// <param name="indices">out param: return triangles</param>
277            /// <returns>vertex data</returns>
278            public static ILRetArray<float> CreateVerticesTri(int detail, ILOutArray<int> indices) {
279                using (ILScope.Enter()) {
280                    if (s_vertexCache.ContainsKey(detail) && s_vertexCache[detail] != null) {
281                        ILCell data = s_vertexCache[detail];
282                        indices.a = data.GetArray<int>(1);
283                        return data.GetArray<float>(0);
284                    } else {
285
286
287                        // regular octahedron
288                        //float[,] pos = new float[,] {
289                        //    {1, 0, 0}, {-1, 0, 0},
290                        //    {0, 1, 0}, {0, -1, 0},
291                        //    {0, 0, 1}, {0, 0, -1}
292                        //};
293                        //int[,] ind = new int[,] {
294                        //   {4, 0, 3}, {4, 3, 1}, {4 ,1 ,2}, {4, 2 ,0},
295                        //   {0, 2, 5}, {3, 0, 5}, {1, 3, 5}, {1, 5, 2}
296                        //};
297                        //// regular icosahedron
298                        float X = 0.525731112119133606f;
299                        float Z = 0.850650808352039932f;
300
301                        float[,] pos = new float[,] {
302                   {-X, 0, Z}, {X, 0, Z}, {-X, 0, -Z}, {X, 0, -Z},
303                   {0, Z, X}, {0, Z, -X}, {0, -Z, X}, {0, -Z, -X},
304                   {Z, X, 0}, {-Z, X, 0}, {Z, -X, 0}, {-Z, -X, 0}
305                };
306                        int[,] ind = new int[,] {
307                   {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
308                   {8,10,1}, {8,3,10},{5,3,8}, {5,2,3}, {2,7,3},
309                   {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
310                   {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11}
311                };
312                        ILArray<float> vertices = pos;
313                        indices.a = ind;
314                        //vertices = vertices[":;0:2"];
315                        //indices = new int[] { 0, 1, 2 };
316                        //indices = indices.T;
317                        ILArray<float> outVertices = empty<float>();
318                        Triangularize(vertices, indices, detail, outVertices, indices);
319                        // normalize vertices
320                        outVertices.a = Normalize(outVertices);
321                        // store in cache
322                        s_vertexCache.Add(detail, cell(new ILSize(2, 1), outVertices, indices));
323                        return outVertices;
324                    }
325                }
326            }
327
328            private static ILRetArray<float> Normalize(ILDenseArray<float> vertices)
329            {
330                using (ILScope.Enter(vertices)) {
331                    return vertices / repmat(sqrt(sum(vertices * vertices, 0)), 3, 1);
332                }
333            }
334        }
335    }
336}
Note: See TracBrowser for help on using the repository browser.