/// <summary>
        /// update composite shape
        /// </summary>
        /// <param name="X">x coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
        /// <param name="Y">y coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
        /// <param name="Z">z coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
        /// <param name="mapping">Mapping of shapes, composes shapes out of vertices. Matrix having
        /// <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> rows.
        /// Every element in a column specifies the index of a vertex according to its position in X,Y,Z.
        /// The <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> elements in a column therefore
        /// compose a single shape. Vertices may get used arbitrary times (or not at all). All elements must be
        /// positive integer values in range 0...[<see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/>-1].</param>
        /// <remarks>All vertices of the shape are updated with the data specified in X,Y and Z. Neither the colors or any
        /// other data of vertices are changed. The shape is invalidated for reconfiguration at next redraw. </remarks>
        public void Update(ILBaseArray X, ILBaseArray Y, ILBaseArray Z, ILBaseArray mapping)
        {
            if (!X.IsVector || !Y.IsVector || !Z.IsVector || X.Length != Y.Length || Y.Length != Z.Length)
            {
                throw new ILArgumentException("numeric vectors of same length expected for: X, Y and Z");
            }
            if (mapping == null || mapping.IsEmpty || !mapping.IsMatrix || !mapping.IsNumeric || mapping.Dimensions[0] != VerticesPerShape)
            {
                throw new ILArgumentException("mapping must be a numeric matrix, " + VerticesPerShape.ToString() + " rows, each column specifies indices for the vertices of a single shape.");
            }
            if (mapping is ILArray <int> )
            {
                m_shapeIndices = (mapping as ILArray <int>).C;
            }
            else
            {
                m_shapeIndices = ILMath.toint32(mapping);
            }
            ILArray <float> fX = ILMath.tosingle(X);
            ILArray <float> fY = ILMath.tosingle(Y);
            ILArray <float> fZ = ILMath.tosingle(Z);

            for (int i = 0; i < m_vertices.Length; i++)
            {
                m_vertices[i].XPosition = fX.GetValue(i);
                m_vertices[i].YPosition = fY.GetValue(i);
                m_vertices[i].ZPosition = fZ.GetValue(i);
            }
            Invalidate();
        }
        /// <summary>
        /// update composite shape
        /// </summary>
        /// <param name="X">x coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
        /// <param name="Y">y coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
        /// <param name="Z">z coordinates, vector of length <see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/></param>
        /// <param name="mapping">Mapping of shapes, composes shapes out of vertices. Matrix having
        /// <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> rows.
        /// Every element in a column specifies the index of a vertex according to its position in X,Y,Z.
        /// The <see cref="ILNumerics.Drawing.Shapes.ILShape&lt;T>.VerticesPerShape"/> elements in a column therefore
        /// compose a single shape. Vertices may get used arbitrary times (or not at all). All elements must be
        /// positive integer values in range 0...[<see cref="ILNumerics.Drawing.Shapes.ILShape.VertexCount"/>-1].</param>
        /// <param name="colors">The colors.</param>
        /// <remarks>All vertices of the shape are updated with the data specified in X,Y and Z. Neither the colors or any
        /// other data of vertices are changed. The shape is invalidated for reconfiguration at next redraw. </remarks>
        public void Update(ILBaseArray X, ILBaseArray Y, ILBaseArray Z, ILBaseArray mapping, ILBaseArray colors)
        {
            if (!VertexDefinition.StoresColor)
            {
                throw new NotSupportedException("The underlying vertex type cannot store individual color values! Use another shape or flat shading!");
            }
            if (!X.IsVector || !Y.IsVector || !Z.IsVector || X.Length != Y.Length || Y.Length != Z.Length)
            {
                throw new ILArgumentException("numeric vectors of same length expected for: X, Y and Z");
            }
            if ((colors.Dimensions[1] != 3 && colors.Dimensions[1] != 4) || colors.Length != X.Length)
            {
                throw new ILArgumentException("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.");
            }
            if (mapping == null || mapping.IsEmpty || !mapping.IsMatrix || !mapping.IsNumeric || mapping.Dimensions[0] != VerticesPerShape)
            {
                throw new ILArgumentException("mapping must be a numeric matrix, " + VerticesPerShape.ToString() + " rows, each column specifies indices for the vertices of a single shape.");
            }
            if (mapping is ILArray <int> )
            {
                m_shapeIndices = (mapping as ILArray <int>).C;
            }
            else
            {
                m_shapeIndices = ILMath.toint32(mapping);
            }
            if (m_shapeIndices.MinValue < 0 || m_shapeIndices.MaxValue >= X.Dimensions[1])
            {
                throw new ILArgumentException("invalid mapping: indices must point to existing vertex indices");
            }
            ILArray <float> fX   = ILMath.tosingle(X);
            ILArray <float> fY   = ILMath.tosingle(Y);
            ILArray <float> fZ   = ILMath.tosingle(Z);
            ILArray <byte>  fcol = ILMath.tobyte(colors);

            if (fcol.Dimensions[1] == 3)
            {
                for (int i = 0; i < m_vertices.Length; i++)
                {
                    m_vertices[i].XPosition = fX.GetValue(i);
                    m_vertices[i].YPosition = fY.GetValue(i);
                    m_vertices[i].ZPosition = fZ.GetValue(i);
                    m_vertices[i].Color     = Color.FromArgb(
                        fcol.GetValue(i, 0),
                        fcol.GetValue(i, 1),
                        fcol.GetValue(i, 2));
                }
            }
            else if (fcol.Dimensions[1] == 4)
            {
                for (int i = 0; i < m_vertices.Length; i++)
                {
                    m_vertices[i].XPosition = fX.GetValue(i);
                    m_vertices[i].YPosition = fY.GetValue(i);
                    m_vertices[i].ZPosition = fZ.GetValue(i);
                    m_vertices[i].Color     = Color.FromArgb(
                        fcol.GetValue(i, 1),
                        fcol.GetValue(i, 2),
                        fcol.GetValue(i, 3));
                    m_vertices[i].Alpha = fcol.GetValue(i);
                }
            }
            Invalidate();
        }