2

I'm need to show a circular torus in a helix-toolkit viewport. The closest option I found was the HelixVisual3D, but it has open ends. So I tried to create my own class to draw it, with a HelixVisual3D and two thin cones to close the ends. I used the classes from their Building Demo as reference, so I came up with this:

public class TorusVisual3D : UIElement3D
{ 
    public static readonly DependencyProperty AngleProperty = DependencyPropertyEx.Register("Angle", 90, (s, e) => s.AppearanceChanged());
    public static readonly DependencyProperty RadiusProperty = DependencyPropertyEx.Register("Radius", 0.35, (s, e) => s.AppearanceChanged());
    public static readonly DependencyProperty DiameterProperty = DependencyPropertyEx.Register("Diameter", 0.1, (s, e) => s.AppearanceChanged());

    private GeometryModel3D torus = new GeometryModel3D();
    private GeometryModel3D cap1 = new GeometryModel3D();
    private GeometryModel3D cap2 = new GeometryModel3D();

    public TorusVisual3D()
    {
        AppearanceChanged();

        Model3DGroup model = new Model3DGroup();

        model.Children.Add(this.torus);
        model.Children.Add(this.cap1);
        model.Children.Add(this.cap2);

        this.Visual3DModel = model;
    }


    public double Angle
    {
        get
        { 
            return (double)this.GetValue(AngleProperty); 
        }
        set 
        { 
           this.SetValue(AngleProperty, value); 
        }
    }

    public double Radius
    {
        get
        {
            return (double)this.GetValue(RadiusProperty);
        }
        set
        {
            this.SetValue(RadiusProperty, value);
        }
   }

    public double Diameter
    {
        get
        {
            return (double)this.GetValue(DiameterProperty);
        }
        set
        {
            this.SetValue(DiameterProperty, value);
        }
    }

    private void AppearanceChanged()
    {
        Material mat = MaterialHelper.CreateMaterial(Utils.GetRandomColor());

        HelixVisual3D h = new HelixVisual3D();
        h.Origin = new Point3D(0, 0, 0);
        h.Diameter = Diameter;
        h.Turns = Angle / 360.0;
        h.Radius = Radius;
        h.Length = 0;
        h.BackMaterial = mat;
        h.Material = mat;
        h.UpdateModel();
        this.torus = h.Model;

        MeshBuilder cap1Builder = new MeshBuilder(false, false);
        Point3D p1 = new Point3D(0, Radius, 0);
        cap1Builder.AddCone(p1, new Vector3D(0, 1, 0), h.Diameter / 2, h.Diameter / 2, 0.0001, true, true, 40);
        this.cap1.Material = MaterialHelper.CreateMaterial(Colors.Yellow); 
        this.cap1.Geometry = cap1Builder.ToMesh();


        MeshBuilder cap2Builder = new MeshBuilder(false, false);
        Point3D p2 = new Point3D(-1, 0, 0);
        cap2Builder.AddCone(p2, new Vector3D(1, 0, 0), h.Diameter / 2, h.Diameter / 2, 0.0001, true, true, 40);
        this.cap2.Material = MaterialHelper.CreateMaterial(Colors.Red);
        this.cap2.Geometry = cap2Builder.ToMesh();
    }
}

To draw it I'm using the following code:

TorusVisual3D t = new TorusVisual3D();
t.Angle = m_angle;
t.Radius = m_radius1;
t.Diameter = m_radius2 * 2.0;
t.Transform = new TranslateTransform3D(0, 0, 0);
ModelVisual3D model = new ModelVisual3D();
model.Children.Add(t);
var container = new ContainerUIElement3D();
container.Children.Add(model);
viewport.Children.Add(container);

The problem is that the Helix is drawn with the default values (Radius=0.35, Diameter=0.1 and Angle=90) and is never updated again. No matter what values I set on the Properties, it stays the same. The both cylinder are updated correctly, just the Helix isn't.

What am I'm doing wrong?

rbasniak
  • 4,484
  • 11
  • 51
  • 100

0 Answers0