title: Update color of single point of GeometryModel3D Material rather than whole system of points
body: <p>I'm having trouble getting my head around the colour/material system of C# WPF projects, currently I am updating the colour of an entire system of points on each update of the model when I would instead like to just update the colour of a single point (as it is added).</p>
  <h1>AggregateSystem Class</h1>
  <pre><code>public class AggregateSystem {
      // stack to store each particle in aggregate
      private readonly Stack&lt;AggregateParticle&gt; particle_stack;
      private readonly GeometryModel3D particle_model;
      // positions, indices and texture co-ordinates for particles
      private readonly Point3DCollection particle_positions;
      private readonly Int32Collection triangle_indices;
      private readonly PointCollection text_coords;
      // brush to apply to particle_model.Material
      private RadialGradientBrush rad_brush;
      // ellipse for rendering
      private Ellipse ellipse;
      private RenderTargetBitmap render_bitmap;
  
      public AggregateSystem() {
          particle_stack = new Stack&lt;AggregateParticle&gt;();
          particle_model = new GeometryModel3D { Geometry = new MeshGeometry3D() };
          ellipse = new Ellipse {
              Width = 32.0,
              Height = 32.0
          };
          rad_brush = new RadialGradientBrush();
          // fill ellipse interior using rad_brush
          ellipse.Fill = rad_brush;
          ellipse.Measure(new Size(32,32));
          ellipse.Arrange(new Rect(0,0,32,32));
          render_bitmap = new RenderTargetBitmap(32,32,96,96,PixelFormats.Pbgra32));
          ImageBrush img_brush = new ImageBrush(render_bitmap);
          DiffuseMaterial diff_mat = new DiffuseMaterial(img_brush);
          particle_model.Material = diff_mat;
          particle_positions = new Point3DCollection();
          triangle_indices = new Int32Collection();
          tex_coords = new PointCollection();
      }
  
      public Model3D AggregateModel =&gt; particle_model;
  
      public void Update() {
          // get the most recently added particle
          AggregateParticle p = particle_stack.Peek();
          // compute position index for triangle index generation
          int position_index = particle_stack.Count * 4;
          // create points associated with particle for circle generation
          Point3D p1 = new Point3D(p.position.X, p.position.Y, p.position.Z);
          Point3D p2 = new Point3D(p.position.X, p.position.Y + p.size, p.position.Z);
          Point3D p3 = new Point3D(p.position.X + p.size, p.position.Y + p.size, p.position.Z);
          Point3D p4 = new Point3D(p.position.X + p.size, p.position.Y, p.position.Z);
          // add points to particle positions collection
          particle_positions.Add(p1);
          particle_positions.Add(p2);
          particle_positions.Add(p3);
          particle_positions.Add(p4);
          // create points for texture co-ords
          Point t1 = new Point(0.0, 0.0);
          Point t2 = new Point(0.0, 1.0);
          Point t3 = new Point(1.0, 1.0);
          Point t4 = new Point(1.0, 0.0);
          // add texture co-ords points to texcoords collection
          tex_coords.Add(t1);
          tex_coords.Add(t2);
          tex_coords.Add(t3);
          tex_coords.Add(t4);
          // add position indices to indices collection
          triangle_indices.Add(position_index);
          triangle_indices.Add(position_index + 2);
          triangle_indices.Add(position_index + 1);
          triangle_indices.Add(position_index);
          triangle_indices.Add(position_index + 3);
          triangle_indices.Add(position_index + 2);
          // update colour of points - **NOTE: UPDATES ENTIRE POINT SYSTEM** 
          // -&gt; want to just apply colour to single particles added
          rad_brush.GradientStops.Add(new GradientStop(p.colour, 0.0));
          render_bitmap.Render(ellipse);
          // set particle_model Geometry model properties
          ((MeshGeometry3D)particle_model.Geometry).Positions = particle_positions;
          ((MeshGeometry3D)particle_model.Geometry).TriangleIndices = triangle_indices;
          ((MeshGeometry3D)particle_model.Geometry).TextureCoordinates = tex_coords;
      }
  
      public void SpawnParticle(Point3D _pos, Color _col, double _size) {
          AggregateParticle agg_particle = new AggregateParticle {
              position = _pos, colour = _col, size = _size;
          }
          // push most-recently-added particle to stack
          particle_stack.Push(agg_particle);
      }
  
  }
  </code></pre>
  <p>where <code>AggregateParticle</code> is a POD class consisting of <code>Point3D position</code>, <code>Color color</code> and <code>double size</code> fields which are self-explanatory.</p>
  <p>Is there any simple and efficient method to update the colour of the single particle as it is added in the <code>Update</code> method rather than the entire system of particles? Or will I need to create a <code>List</code> (or similar data structure) of <code>DiffuseMaterial</code> instances for each and every particle in the system and apply brushes for the necessary colour to each?</p>
  <p>[The latter is something I want to avoid at all costs, partly due to the fact it would require large structural changes to my code, and I am certain that there is a better way to approach this than that - i.e. <em>there <strong>MUST</strong> be some simple way to apply colour to a set of texture co-ordinates, surely?!</em>.]</p>
  <p><strong>Further Details</strong></p>
  <ul>
  <li><p><code>AggregateModel</code> is a single <code>Model3D</code> instance corresponding to the field <code>particle_model</code> which is added to a <code>Model3DGroup</code> of the <code>MainWindow</code>.</p>
  </li>
  <li><p>I should note that what I am trying to achieve, specifically, here is a &quot;gradient&quot; of colours for each particle in an aggregate structure where a particle has a <code>Color</code> in a &quot;temperature-gradient&quot; (computed elsewhere in the program) which is dependent upon order in which it was generated - i.e. particles have a colder colour if generated earlier and a warmer colour if generated later. This colour list is pre-computed and passed to each particle in the <code>Update</code> method as can be seen above.</p>
  </li>
  <li><p>One solution I attempted involved creating a separate <code>AggregateComponent</code> instance for each particle where each of these objects has an associated <code>Model3D</code> and thus a corresponding brush. Then an <code>AggregateComponentManager</code> class was created which contained the <code>List</code> of each <code>AggregateComponent</code>. This solution works, however it is horrendously slow as each component has to be updated every time a particle is added so memory usage explodes - is there a way to adapt this where I can cache already rendered <code>AggregateComponent</code>s without having to call their <code>Update</code> method each time a particle is added?</p>
  </li>
  </ul>
  <p>Full source code (C# code in the <code>DLAProject</code> directory) can be found on GitHub: <a href="https://github.com/SJR276/DLAProject" rel="nofollow noreferrer">https://github.com/SJR276/DLAProject</a></p>