0

hierarchical 3D model via Visual3D and AddVisual3DChild -> only root is rendered...

LuNo 8 months ago in Question • updated 8 months ago 1

Hi,


I am relatively new to the HelixToolkit and I have a (probably simple) question: I want to build a scene out of several .stl files and I aim to employ parent/children relations in order to apply transforms to the whole hierarchy "automatically".
I created the following class to represent a mechanical axis (imagine a robot arm with a few scene graph nodes), but when I build up the data structure, only the root is rendered. The strange thing is: The Visual3D objects cannot be added to the Viewport3D once they have been set as a child somewhere else (e.g. after I added the Visual3D children to the parents, this is expected behaviour afaik). But these children are not rendered (except the root). I do assume I am missing some event or notification I should trigger? I browsed through most of the examples, usually a Model3D is built on the fly if an aggragation of meshes is needed. I would be grateful for any hints in this matter.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows;
using System.Windows.Media.Media3D;
using PropertyTools.DataAnnotations;
using BrowsableAttribute = System.ComponentModel.BrowsableAttribute;

using HelixToolkit.Wpf;

namespace Vizualizer_WPF
{
    //class MachineAxis3D : UIElement3D
    class MachineAxis3D: ModelVisual3D
    {
        public static DependencyProperty RotationAngleProperty = DependencyPropertyEx.Register<double, MachineAxis3D>("RotationAngle", 0, (s, e) => s.AppearanceChanged());
        public static readonly DependencyProperty PrincipalDirectionProperty = DependencyPropertyEx.Register<Vector3D, MachineAxis3D>("PrincipalDirection", new Vector3D(1, 0, 0), (s, e) => s.AppearanceChanged());

        public MachineAxis3D()
        {

        }

        [Category("AxisProperties")]
        [Slidable(0, 360)]
        [Browsable(true)]
        public double RotationAngle
        {
            get
            {
                return (double)this.GetValue(RotationAngleProperty);
            }

            set
            {
                this.SetValue(RotationAngleProperty, value);
            }
        }

        public Vector3D PrincipalDirection
        {
            get
            {
                return (Vector3D)this.GetValue(PrincipalDirectionProperty);
            }

            set
            {
                this.SetValue(PrincipalDirectionProperty, value);
            }
        }

        public int ChildrenCount()
        {
            return this.Visual3DChildrenCount;
        }

        public void AddChild(Visual3D visual3D, Model3D model3D)
        {
            Model3DGroup newGroup = new Model3DGroup();
            newGroup.Children.Add(this.Content);
            newGroup.Children.Add(model3D);
            Content = newGroup;
            AddVisual3DChild(visual3D);
        }        

        // handles the rotation of the axis
        private void AppearanceChanged()
        {
            var tg = new Transform3DGroup();
            tg.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(PrincipalDirection, RotationAngle)));
            Transform = tg;
        }
    }
}



Media3D WPF

Solved in the meantime: First of all I realized that the issue is actually connected to WPF and not the HelixToolkit, sorry for that. Then I used the inherited members from the base class ModelVisual3D (e.g. myAxisInstance.Children.Add). My initial class to represent an axis now looks as follows:


using System.Windows;
using System.Windows.Media.Media3D;
using PropertyTools.DataAnnotations;
using BrowsableAttribute = System.ComponentModel.BrowsableAttribute;
using HelixToolkit.Wpf;
namespace Vizualizer_WPF
{
    class MachineAxis3D: ModelVisual3D
    {
        public static DependencyProperty RotationAngleProperty = DependencyPropertyEx.Register<double, machineaxis3d="">("RotationAngle", 0, (s, e) => s.AppearanceChanged());
        public static readonly DependencyProperty PrincipalDirectionProperty = DependencyPropertyEx.Register<vector3d, machineaxis3d="">("PrincipalDirection", new Vector3D(1, 0, 0), (s, e) => s.AppearanceChanged());
        public MachineAxis3D()
        {
        }
        [Category("AxisProperties")]
        [Slidable(0, 360)]
        [Browsable(true)]
        public double RotationAngle
        {
            get
            {
                return (double)this.GetValue(RotationAngleProperty);
            }
            set
            {
                this.SetValue(RotationAngleProperty, value);
            }
        }
        public Vector3D PrincipalDirection
        {
            get
            {
                return (Vector3D)this.GetValue(PrincipalDirectionProperty);
            }
            set
            {
                this.SetValue(PrincipalDirectionProperty, value);
            }
        }
        // handles the rotation of the axis
        private void AppearanceChanged()
        {
            var tg = new Transform3DGroup();
            tg.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(PrincipalDirection, RotationAngle)));
            Transform = tg;
        }
    }
}