Search code examples
c#wpfeventshelix-3d-toolkithelix

Helix Toolkit recently added tube objects in WPF application, are not firing events or reacts on mouse interaction?


I am using WPF application with Helix Toolkit, where I dynamically add multiple 3D objects into the Viewport. The Visuals of the objects are added successfully, but some of the recently added objects (in this case tube objects) are not firing events, neither show their appropriate tooltip message. After some interaction with the GUI of the app and adding new additional 3D objects to the Viewport, the old already added objects are firing events and show their tooltip message... Also I have noticed that if I add some other new 3D objects and if I rotate the camera with right button pressed of the mouse, they are coming responsive!

So what Is causing this problem? Is it there some rendering or camera problem or something else?

I am using this code about the Viewport with SortingVisual3D where all of the objects are added behind the transparent surface:


<helix:HelixViewport3D Grid.Column="0" Grid.Row="1" Grid.RowSpan="10" Background="GhostWhite"  Name="_viewport"  ShowFrameRate="True"  ShowTriangleCountInfo="True" ShowViewCube="True"  IsHitTestVisible="True" CalculateCursorPosition="True" ShowCoordinateSystem="True" >

<helix:DefaultLights/>

<helix:SortingVisual3D x:Name="sortingVisual1"  Method="BoundingBoxCorners" IsSorting="True"  SortingFrequency="4"  >
                <helix:MeshGeometryVisual3D x:Name="_cubeObjects">
                </helix:MeshGeometryVisual3D>                

                <helix:MeshGeometryVisual3D x:Name="_tubeObjects">

                </helix:MeshGeometryVisual3D>             

               //Transparent surface

                <helix:MeshGeometryVisual3D x:Name="_transparentSurface"  >

                </helix:MeshGeometryVisual3D>            

            </helix:SortingVisual3D>
        </helix:HelixViewport3D>
      </strike>

This is how I dynamically add the objects:

AddObject tubeObject = new AddObject(points3dCollection, "Tube Object", tubeDiameter, 36, objectMaterial);
                                     
                   tubeObject.MouseLeftButtonDown += new MouseButtonEventHandler(tubeObjectClick);
                    tubeObject.IsHitTestVisible = true;              
                    tubeObject.SetName("Tube Object");

 ContainerUIElement3D cui = new ContainerUIElement3D();               
                cui.Children.Add(tubeObject);
                _tubeObjects.Children.Add(cui);


'-------------------This is the class AddObject definition:-------------------------------'


class AddObject : UIElement3D,INotifyCollectionChanged
    {       

        private readonly Timer _timer;
        private readonly ToolTip _toolTip;

        public AddObject DataContext { get; }
            
      
        public AddObject(Point3DCollection path, string objectName, double diametar_1, int thetaDiv, Material material)
        {
            MeshBuilder builder = new MeshBuilder();       
                           
               
                List<Point3D> list = new List<Point3D>();

                for (int i = 0; i < path.Count; i++)
                {

                    list.Add(path[i]);

                }               

                list = CanonicalSplineHelper.CreateSpline(list, 0.5, null, false, 0.9);
            
                builder.AddTube(list, diametar_1, thetaDiv, false, true, true);          
           
                GeometryModel3D model = new GeometryModel3D(builder.ToMesh(), material);             
                model.SetName(objectName);
                Visual3DModel = model;            
             
                _toolTip = new ToolTip();
              
                _timer = new Timer { AutoReset = false };
                _timer.Elapsed += ShowToolTip;

                DataContext = this;        
          


        }

 public event NotifyCollectionChangedEventHandler CollectionChanged
        {
            add
            {
                ((INotifyCollectionChanged)DataContext).CollectionChanged += value;
            }

            remove
            {
                ((INotifyCollectionChanged)DataContext).CollectionChanged -= value;
            }
        }

        public object ToolTipContent { get { return _toolTip.Content; } set { _toolTip.Content = value; } }    

        private void ShowToolTip(object sender, ElapsedEventArgs e)
        {
            _timer.Stop();
            if (_toolTip != null)
                _toolTip.Dispatcher.Invoke(new Action(() => { _toolTip.IsOpen = true; }));
        }

       protected override void OnMouseEnter(MouseEventArgs e)
        {
            base.OnMouseEnter(e);

            var gm = Visual3DModel as GeometryModel3D;        

            gm.Material = gm.Material == materialtype ? Materials.Yellow : materialtype;

            if (_toolTip != null)
            {
                _toolTip.IsOpen = true;
                _toolTip.Content = gm.GetName().ToString().Trim() + " vein "; }
            //  _timer.Interval = ToolTipService.GetInitialShowDelay(Application.Current.MainWindow);
            _timer.Interval = 50;
            _timer.Start();          

            e.Handled = true;
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            base.OnMouseLeave(e);

            var gm = Visual3DModel as GeometryModel3D;
            gm.Material = gm.Material == materialtype ? Materials.Yellow : materialtype;

            _timer.Stop();
            if (_toolTip != null)
            { _toolTip.IsOpen = false;
                _toolTip.Content = "";            
            }           

            e.Handled = true;

        }

}


What should I check at first? Any idea is welcomed ! Please help !

Solution

  • The immediate response problem of the recently inserted objects is solved with this code:

    <helix:MeshGeometryVisual3D >
                    <ContainerUIElement3D x:Name="_cubeObjects">
                </ContainerUIElement3D>
                    </helix:MeshGeometryVisual3D>
                <helix:MeshGeometryVisual3D >
                    <ContainerUIElement3D x:Name="_ballClickPoints">
                    </ContainerUIElement3D>
    
                </helix:MeshGeometryVisual3D>
                    <helix:MeshGeometryVisual3D >
                    <ContainerUIElement3D x:Name="_tubeObjects">
                    </ContainerUIElement3D>
    
                </helix:MeshGeometryVisual3D>
               
                            <helix:MeshGeometryVisual3D x:Name="_transparentSurface">
    
                </helix:MeshGeometryVisual3D>
    

    So the change is in using ContainerUIElement3D into MeshGeometryVisual3D.. The objects are responding immediately on mouse events .