public Bar3DProps(Axis3DProps axis, AllBar3D parent, int index, int x, int y)
            {
                _axis = axis;
                _parent = parent;

                this.Index = index;
                this.X = x;
                this.Y = y;
            }
        private void RebuildBars()
        {
            if (_axis == null)
            {
                return;
            }

            if (_bars != null)
            {
                _viewport.Children.Remove(_bars.Visual);

                if (_bars.HoverVisual != null)
                {
                    _viewport.Children.Remove(_bars.HoverVisual);
                }

                ClearSelected();

                _bars = null;
            }

            AllBar3D bars = new AllBar3D();

            bars.Models = new Model3DGroup();

            List<Bar3DProps> individualBars = new List<Bar3DProps>();

            for (int y = 0; y < _height; y++)
            {
                int indexOffset = y * _width;

                for (int x = 0; x < _width; x++)
                {
                    int index = indexOffset + x;

                    Bar3DProps bar = RebuildBars_Bar(_axis, bars, index, x, y, _values[index]);

                    bars.Models.Children.Add(bar.Model);
                    individualBars.Add(bar);
                }
            }

            bars.Bars = individualBars.ToArray();

            bars.UpdateColors(radRangeZeroPos.IsChecked.Value, chkIsRedBlue.IsChecked.Value);

            ModelVisual3D visual = new ModelVisual3D();
            visual.Content = bars.Models;
            bars.Visual = visual;

            _bars = bars;
            _viewport.Children.Add(_bars.Visual);
        }
        private static Bar3DProps RebuildBars_Bar(Axis3DProps axis, AllBar3D bars, int index, int x, int y, double value)
        {
            Bar3DProps retVal = new Bar3DProps(axis, bars, index, x, y);

            retVal.Model = new GeometryModel3D();

            //NOTE: Material is updated by bars.UpdateColors

            double xPos = -axis.HalfX + (x * axis.BarSize);
            double yPos = axis.HalfY - (y * axis.BarSize);

            retVal.Model.Geometry = UtilityWPF.GetCube(new Point3D(xPos, yPos, 0), new Point3D(xPos + axis.BarSize, yPos - axis.BarSize, 1));

            Transform3DGroup transform = new Transform3DGroup();
            retVal.HeightTransform = new ScaleTransform3D(1, 1, 1);
            transform.Children.Add(retVal.HeightTransform);
            transform.Children.Add(new TranslateTransform3D(0, 0, axis.AxisOffset));
            retVal.Model.Transform = transform;

            retVal.Height = value;

            return retVal;
        }
        private void RebuildBars_WRONGY()
        {
            if (_axis == null)
            {
                return;
            }

            if (_bars != null)
            {
                _viewport.Children.Remove(_bars.Visual);
                _bars = null;
            }

            AllBar3D bars = new AllBar3D();

            bars.Models = new Model3DGroup();

            List<Bar3DProps> individualBars = new List<Bar3DProps>();

            for (int y = 0; y < _height; y++)
            {
                int indexOffset = y * _width;

                for (int x = 0; x < _width; x++)
                {
                    Bar3DProps bar = new Bar3DProps(_axis, bars, indexOffset + x, x, y);

                    bar.Model = new GeometryModel3D();

                    //NOTE: Material is updated by bar.Height set

                    double xPos = -_axis.HalfX + (x * _axis.BarSize);
                    double yPos = -_axis.HalfY + (y * _axis.BarSize);

                    bar.Model.Geometry = UtilityWPF.GetCube(new Point3D(xPos, yPos, 0), new Point3D(xPos + _axis.BarSize, yPos + _axis.BarSize, 1));

                    Transform3DGroup transform = new Transform3DGroup();
                    bar.HeightTransform = new ScaleTransform3D(1, 1, 1);
                    transform.Children.Add(bar.HeightTransform);
                    transform.Children.Add(new TranslateTransform3D(0, 0, _axis.AxisOffset));
                    bar.Model.Transform = transform;

                    bar.Height = _values[indexOffset + x];

                    bars.Models.Children.Add(bar.Model);
                    individualBars.Add(bar);
                }
            }

            bars.Bars = individualBars.ToArray();



            ModelVisual3D visual = new ModelVisual3D();
            visual.Content = bars.Models;
            bars.Visual = visual;

            _bars = bars;
            _viewport.Children.Add(_bars.Visual);
        }