Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Drawing/Shapes/ILCompositeShape.cs @ 11194

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

#1967: ILNumerics source for experimentation

File size: 21.5 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
40
41
42using System;
43using System.Drawing;
44using System.Collections.Generic;
45using System.Text;
46using ILNumerics.Drawing.Graphs;
47using ILNumerics;
48using ILNumerics.Exceptions;
49using ILNumerics.Drawing.Interfaces;
50using ILNumerics.Drawing;
51using ILNumerics.Misc;
52
53namespace ILNumerics.Drawing.Shapes {
54    public abstract class ILCompositeShape<VertexType> : ILShape<VertexType>
55        where VertexType : struct, IILVertexDefinition {
56
57        #region eventing
58        #endregion
59
60        #region attributes
61        /// <summary>
62        /// actual indices used for rendering (sorted for translucent shapes)
63        /// </summary>
64        protected int[] m_renderIndices;
65        /// <summary>
66        /// cache indices defining each shapes corners
67        /// </summary>
68        protected ILArray<int> m_shapeIndices = ILMath.returnType<int>();
69        /// <summary>
70        /// cache camera position of last sorting
71        /// </summary>
72        protected ILPoint3Df m_oldCameraPosition;
73
74        //private float[] m_vertexPositions;
75        #endregion
76
77        #region properties
78        /// <summary>
79        /// Indices used to render primitives from vertices
80        /// </summary>
81        public ILRetArray<int> Indices {
82            get {
83                return m_shapeIndices.C;
84            }
85            set {
86                m_shapeIndices.a = value;
87            }
88        }
89        #endregion
90
91        #region constructors
92        /// <summary>
93        /// create composite shape
94        /// </summary>
95        /// <param name="panel">scene hosting the scene</param>
96        /// <param name="numVertices">number of overall vertices for the shape</param>
97        /// <param name="verticesPerShape">Number of vertices per shape</param>
98        public ILCompositeShape (ILPanel panel, int numVertices, int verticesPerShape)
99            : base(panel,numVertices,verticesPerShape) {
100            Opacity = 255;
101            m_shapeIndices.a = ILMath.toint32(
102                ILMath.counter(0.0,1.0,VerticesPerShape,numVertices / VerticesPerShape));
103        }
104
105        ///// <summary>
106        ///// create composite shape
107        ///// </summary>
108        ///// <param name="panel">hosting panel</param>
109        ///// <param name="verticesPerShape">number of vertices per shape</param>
110        ///// <param name="X">x coordinates vector </param>
111        ///// <param name="Y">y coordinates vector </param>
112        ///// <param name="Z">z coordinates vector </param>
113        ///// <remarks>The constructor creates a new composite shape out of all vertices specified in X,Y and Z.
114        ///// Every vertex is only used once. Every shape uses
115        ///// <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> vertices one after another.</remarks>
116        //public ILCompositeShape(ILPanel panel, int verticesPerShape, ILBaseArray X, ILBaseArray Y, ILBaseArray Z)
117        //    : base(panel, X.Length, verticesPerShape) {
118        //    Update(X, Y, Z);
119        //    m_shapeIndices.a = ILMath.toint32(
120        //        ILMath.counter(0.0, 1.0, VerticesPerShape, m_vertCount / VerticesPerShape));
121        //    Opacity = 255;
122        //    m_shading = ShadingStyles.Flat;
123        //}
124
125        ///// <summary>
126        ///// create composite shape
127        ///// </summary>
128        ///// <param name="panel">hosting panel</param>
129        ///// <param name="verticesPerShape">number of vertices per shape</param>
130        ///// <param name="X">x coordinates vector </param>
131        ///// <param name="Y">y coordinates vector </param>
132        ///// <param name="Z">z coordinates vector </param>
133        ///// <param name="mapping">Mapping of shapes, composes shapes out of vertices. Matrix having 
134        ///// <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> rows.
135        ///// Every element in a column specifies the index of a vertex according to its position in X,Y,Z.
136        ///// The <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> elements in a column therefore
137        ///// compose a single shape. Vertices may get used arbitrary times (or not at all). All elements must be
138        ///// positive integer values in range 0...[<see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/>-1].</param>
139        //public ILCompositeShape (ILPanel panel, int verticesPerShape, ILBaseArray X, ILBaseArray Y, ILBaseArray Z, ILBaseArray mapping)
140        //    : base (panel,X.Length,verticesPerShape) {
141        //    Update(X, Y, Z, mapping);
142        //    Opacity = 255;
143        //    m_shading = ShadingStyles.Interpolate;
144        //}
145
146        ///// <summary>
147        ///// create composite shape
148        ///// </summary>
149        ///// <param name="panel">hosting panel</param>
150        ///// <param name="verticesPerShape">number of vertices per shape</param>
151        ///// <param name="X">x coordinates vector </param>
152        ///// <param name="Y">y coordinates vector </param>
153        ///// <param name="Z">z coordinates vector </param>
154        ///// <param name="colors">matrix with <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/>
155        ///// rows, 3 columns for (R,G,B) or 4 columns for
156        ///// (A,R,G,B) for every vertex specified by X,Y,Z. Elements must range from 0..255. If colors
157        ///// has 3 columns only, alpha values of 255 are used as default.</param>
158        ///// <param name="mapping">Mapping of shapes, composes shapes out of vertices. Matrix having 
159        ///// <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> rows.
160        ///// Every element in a column specifies the index of a vertex according to its position in X,Y,Z.
161        ///// The <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> elements in a column therefore
162        ///// compose a single shape. Vertices may get used arbitrary times (or not at all). All elements must be
163        ///// positive integer values in range 0...[<see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/>-1].</param>
164        //public ILCompositeShape (ILPanel panel, int verticesPerShape, ILBaseArray X, ILBaseArray Y, ILBaseArray Z, ILBaseArray colors, ILBaseArray mapping)
165        //    : base (panel,X.Length,verticesPerShape) {
166        //    Update(X, Y, Z, mapping, colors);
167        //    System.Diagnostics.Debug.Assert(ILMath.toint32(mapping).MaxValue < Vertices.Length);
168        //    Opacity = 255;
169        //    m_shading = ShadingStyles.Interpolate;
170        //}
171
172        #endregion
173
174        #region public interface
175        /// <summary>
176        /// update vertices of this shape
177        /// </summary>
178        /// <param name="inX">x coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
179        /// <param name="inY">y coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
180        /// <param name="inZ">z coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
181        /// <param name="mapping">Mapping of shapes, composes shapes out of vertices. Matrix having
182        /// <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> rows.
183        /// Every element in a column specifies the index of a vertex according to its position in X,Y,Z.
184        /// The <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> elements in a column therefore
185        /// compose a single shape. Vertices may get used arbitrary times (or not at all). All elements must be
186        /// positive integer values in range 0...[<see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/>-1].</param>
187        /// <param name="colors">matrix with <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/>
188        /// rows, 3 columns for (R,G,B) or 4 columns for
189        /// (A,R,G,B) for every vertex specified by X,Y,Z. Elements must range from 0..255. If colors
190        /// has 3 columns only, alpha values of 255 are used as default.</param>
191        /// <remarks>All vertices of the shape are updated with the data specified in X,Y and Z. Neither the colors or any
192        /// other data of vertices are changed, if they are not provided. The shape is invalidated for reconfiguration at next redraw. </remarks>
193        public void Update(ILInArray<float> inX, ILInArray<float> inY, ILInArray<float> inZ, ILInArray<int> inMapping = null, ILInArray<int> inColors = null) {
194            using (ILScope.Enter(inX, inY, inZ, inMapping, inColors)) {
195                if (!VertexDefinition.StoresColor)
196                    throw new NotSupportedException("The underlying vertex type cannot store individual color values! Use another shape type, flat shading or ommit color values!");
197                ILArray<float> X = ILMath.check(inX, (a) => { return (a.IsVector) ? a : null; }, true, "numeric vectors of same length expected for: X, Y and Z");
198                ILArray<float> Y = ILMath.check(inY, (a) => { return (a.IsVector && a.Length == X.Length) ? a : null; }, true, "numeric vectors of same length expected for: X, Y and Z");
199                ILArray<float> Z = ILMath.check(inZ, (a) => { return (a.IsVector && a.Length == X.Length) ? a : null; }, true, "numeric vectors of same length expected for: X, Y and Z");
200                ILArray<int> mapping = ILMath.check(inMapping, (a) => { return (inMapping.IsMatrix && inMapping.S[0] == VerticesPerShape) ? a : null; }, true
201                                                    , "mapping must be a numeric matrix, " + VerticesPerShape.ToString() + " rows, each column specifies indices for the vertices of a single shape.");
202                ILArray<int> colors = ILMath.check(inColors, (a) => { return ((a.S[1] == 3 || a.S[1] == 4) && a.S[0] == X.Length) ? a : null; }, true
203                                                    , "invalid size of colors data! Colors must have 3 or 4 columns with color components (RGB) or alpha value + color components (ARGB) respectively. Number of rows must match number of vertices.");
204
205                if (!ILMath.isnull(mapping)) {
206                    int minInd, maxInd;
207                    if (mapping.GetLimits(out minInd, out maxInd) && (minInd < 0 || maxInd >= X.Length))
208                        throw new ILArgumentException("invalid mapping: indices out of range of vertices");
209                    m_shapeIndices.a = mapping.C;
210                }
211                if (ILMath.isnull(colors)) {
212                    for (int i = 0; i < m_vertices.Length && i < X.Length && i < Y.Length && i < Z.Length; i++) {
213                        m_vertices[i].XPosition = X.GetValue(i);
214                        m_vertices[i].YPosition = Y.GetValue(i);
215                        m_vertices[i].ZPosition = Z.GetValue(i);
216                    }
217                } else if (colors.Size[1] == 3) {
218                    for (int i = 0; i < m_vertices.Length; i++) {
219                        m_vertices[i].XPosition = X.GetValue(i);
220                        m_vertices[i].YPosition = Y.GetValue(i);
221                        m_vertices[i].ZPosition = Z.GetValue(i);
222                        m_vertices[i].Color = Color.FromArgb(
223                                colors.GetValue(i, 0),
224                                colors.GetValue(i, 1),
225                                colors.GetValue(i, 2));
226                    }
227                } else if (colors.Size[1] == 4) {
228                    for (int i = 0; i < m_vertices.Length; i++) {
229                        m_vertices[i].XPosition = X.GetValue(i);
230                        m_vertices[i].YPosition = Y.GetValue(i);
231                        m_vertices[i].ZPosition = Z.GetValue(i);
232                        m_vertices[i].Color = Color.FromArgb(
233                                colors.GetValue(i, 1),
234                                colors.GetValue(i, 2),
235                                colors.GetValue(i, 3));
236                        m_vertices[i].Alpha = (byte)colors.GetValue(i);
237                    }
238                }
239                Invalidate();
240            }
241        }
242        protected override void IntDrawShape(ILRenderProperties props) {
243            if (m_vertCount >= VerticesPerShape) {
244                // draw from back to front
245                if (m_oldCameraPosition != m_panel.Camera.Position
246                    || m_renderIndices == null) {
247                    if (m_shading == ShadingStyles.Flat && m_fillColor.A == byte.MaxValue) {
248                        m_shapeIndices.ExportValues(ref m_renderIndices);
249                    } else {
250                        sortPrimitives();
251                    }
252                }
253                m_renderer.Draw(props,this,m_renderIndices);
254            }
255        }
256        protected override void IntDrawLabel(ILRenderProperties props) {
257            if (m_vertCount >= VerticesPerShape) {
258                ILPoint3Df cent = m_vertices[m_shapeIndices.GetValue(0)].Position;
259                // draw label at center of first shape
260                if (!String.IsNullOrEmpty(m_label.Text)) {
261                    for (int i = 1; i < VerticesPerShape; i++) {
262                        cent += m_vertices[m_shapeIndices.GetValue(i)].Position;
263                    }
264                    m_label.Draw(props, cent / VerticesPerShape);
265                }
266            }
267        }
268        protected override void  ComputeLimits() {
269            // only consider used(!) vertices (having indices in mapping)         
270          ILPoint3Df cent = new ILPoint3Df();
271            if (m_shapeIndices.IsEmpty) {
272                // fast exit
273                m_positionCenter = cent;
274                m_positionMin = cent;
275                m_positionMax = cent;
276                return;
277            }
278            ILPoint3Df max = ILPoint3Df.MinValue, min = ILPoint3Df.MaxValue, cur;
279            foreach (int vertexID in m_shapeIndices) {
280                cur = m_vertices[vertexID].Position;
281                cent = cent + cur;
282                max = ILPoint3Df.Max(max, cur);
283                min = ILPoint3Df.Min(min, cur);
284            }
285            m_positionCenter = cent / m_vertices.Length;
286            m_positionMax = max;
287            m_positionMin = min;
288            //updateVertexPositions(Vertices, ref m_vertexPositions);
289        }
290        #endregion
291
292        #region private helper
293
294        //protected void sortPrimitives() {
295        //    m_oldCameraPosition = m_panel.Camera.Position;
296        //    Computation.SortIndices(
297        //                m_vertices, m_shapeIndices, m_vertCount, m_panel.Camera.Position,
298        //                VerticesPerShape).ExportValues(ref m_renderIndices);
299        //}
300
301        private void sortPrimitives() {
302            m_oldCameraPosition = m_panel.Camera.Position;
303            if (m_renderIndices == null || m_renderIndices.Length < m_shapeIndices.Size.NumberOfElements)
304                m_renderIndices = new int[m_shapeIndices.Size.NumberOfElements];
305            float camScale = (ILPoint3Df.Max(m_positionMax, m_positionMin) - m_positionCenter).GetLength();
306            Computation.SortIndices(
307                        Vertices
308                        , m_shapeIndices
309                        , m_vertCount
310                        , m_panel.Camera.LookAt + ((m_panel.Camera.LookAt - m_panel.Camera.Position) * camScale)
311                        , VerticesPerShape
312                        , m_renderIndices);
313        }
314       
315        private void updateVertexPositions(VertexType[] vertices, ref float[] vertexPositions) {
316            if (vertexPositions == null || vertexPositions.Length < 3 * vertices.Length) {
317                vertexPositions = new float[3 * vertices.Length];
318            }
319            int p = 0;
320            if (vertices is C4bV3f[]) {
321                C4bV3f[] verticesC4bV3f = (C4bV3f[])(object)vertices;
322                foreach (C4bV3f vertex in verticesC4bV3f) {
323                    vertexPositions[p++] = vertex.XPosition;
324                    vertexPositions[p++] = vertex.YPosition;
325                    vertexPositions[p++] = vertex.ZPosition;
326                }
327            } else if (vertices is C4fN3fV3f[]) {
328                C4fN3fV3f[] verticesC4fN3fV3f = (C4fN3fV3f[])(object)vertices;
329                foreach (C4fN3fV3f vertex in verticesC4fN3fV3f) {
330                    vertexPositions[p++] = vertex.XPosition;
331                    vertexPositions[p++] = vertex.YPosition;
332                    vertexPositions[p++] = vertex.ZPosition;
333                }
334            }
335            // ... more vertex types here?
336        }
337
338        private class Computation : ILMath {
339           
340            public static void SortIndices(VertexType[] vertices,
341                                            ILInArray<int> shapeIndices, int vertCount,
342                                            ILPoint3Df camera, int vertPerPrimitive, int[] renderIndices) {
343                using (ILScope.Enter(shapeIndices)) {
344                    bool dummy;
345                    ILArray<float> dist = array<float>(ILMemoryPool.Pool.New<float>(vertCount, false, out dummy) ,1,vertCount);
346                    float[] distArr = dist.GetArrayForWrite();
347                    for (int vPos = 0; vPos < vertCount; ) {
348                        distArr[vPos] = (vertices[vPos++].Position - camera).GetLength();
349                    }
350#if DEBUG
351                    //ILArray<double> indDeb;
352                    //ILArray<float> minID = sort(new ILArray<float>(dist, 1, dist.Length), out indDeb,1,false);
353                    //System.Diagnostics.Debug.Write("ind: " + shapeIndices.ValuesToString(0));
354                    //System.Diagnostics.Debug.Write("dist: " + new ILArray<float>(dist, 1, dist.Length).ValuesToString(0));
355                    //System.Diagnostics.Debug.Write("dist[ind]: " + (new ILArray<float>(dist, 1, dist.Length)[shapeIndices]).ValuesToString(0));
356                    //System.Diagnostics.Debug.Write("sum(dist[ind]): " + sum(new ILArray<float>(dist, 1, dist.Length)[shapeIndices]).ValuesToString(0));
357#endif
358                    ILArray<double> idx = empty();
359                    sort(sum(dist[shapeIndices], 0), idx, 1, false).Dispose();
360                    // ind: indices into shapeIndices' columns
361                    shapeIndices[full, idx].ExportValues(ref renderIndices);
362                }
363            }
364
365            //public static ILArray<int> SortIndices(VertexType[] vertices,
366            //                                ILArray<int> shapeIndices, int vertCount,
367            //                                ILPoint3Df camera, int vertPerPrimitive) {
368            //    //System.Diagnostics.Debug.Assert(Math.IEEERemainder(vertCount,vertPerPrimitive) == 0);
369            //    float[] posArr = new float[3 * vertCount];
370            //    int p = 0;
371            //    foreach (VertexType vertex in vertices) {
372            //        posArr[p++] = vertex.XPosition;
373            //        posArr[p++] = vertex.YPosition;
374            //        posArr[p++] = vertex.ZPosition;
375            //    }
376            //    ILArray<float> pos = new ILArray<float>(posArr, 3, vertCount);
377            //    ILArray<float> cam = new ILArray<float>(
378            //                         new float[] { camera.X, camera.Y, camera.Z }, 3, 1);
379            //    // flip the camera around and move it outside the scene
380            //    ILArray<double> ind = null;
381            //    cam = -cam * maxall(pos);
382            //    cam = repmat(cam, 1, vertCount);
383            //    pos = pos - cam;
384            //    pos = sum(pos * pos, 0);   // pos holds distances for eaech vertex now
385            //    // sort per primitive
386            //    pos = sum(reshape(pos[shapeIndices[":"]], vertPerPrimitive, shapeIndices.Dimensions[1]), 0);
387            //    ind = ILArray<double>.empty();
388            //    sort(pos, out ind, 1, false);
389            //    // ind: indices into shapeIndices' columns
390            //    return shapeIndices[null, ind][":"];
391            //}
392
393        }
394
395        #endregion
396    }
397}
Note: See TracBrowser for help on using the repository browser.