question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

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>`



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 !

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:19 (8 by maintainers)

github_iconTop GitHub Comments

5reactions
holancecommented, Jan 26, 2022

Change MeshGeometryVisual3D to ContainerUIElement3D for grouping fixed the issue.

            <ContainerUIElement3D x:Name="_cubeObjects">
            </ContainerUIElement3D>
            <ContainerUIElement3D x:Name="_ballClickPoints">
            </ContainerUIElement3D>
            <ContainerUIElement3D x:Name="_tubeObjects">
            </ContainerUIElement3D>
1reaction
ehtickcommented, Jan 24, 2022

The demo draws a cylinder with caps, when clicking on the screen the cylinder is always clicked on first. The tube are inside the cylinder so if you want to do something like this you should use an other method.

When you want to click through the objects on the screen use the ResultCallback function you already created. In this all the objects that are in the ray are hit. if you click on the tube then you will hit cylinder, tube,… cylinder.

in this function you can pass this when other functions are active, such as adding the points to draw a new tube.

so what i did is

        _viewport.MouseLeftButtonDown += _viewport_MouseLeftButtonDown;


    private void _viewport_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        MouseHitTest(sender, e);
    }


    public void MouseHitTest(object sender, MouseButtonEventArgs args)
    {
        Point mousePos = args.GetPosition(_viewport);
        PointHitTestParameters hitParams = new PointHitTestParameters(mousePos);
        VisualTreeHelper.HitTest(_viewport, null, ResultCallback, hitParams);
    }

in tube

    public void ShowTooltip()
    {
        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() + " tube";
        }

        _timer.Interval = 1000; // 50 is very short is in millisecs !
        _timer.Start();

    }

// should be false because it closes it. private void ShowToolTip(object sender, ElapsedEventArgs e) { _timer.Stop(); if (_toolTip != null) _toolTip.Dispatcher.Invoke(new Action(() => { _toolTip.IsOpen = false; })); }

Maybe this helps a bit, i am sure that the problem is not in Helix 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Helix Toolkit recently added tube objects in WPF ...
The Visuals of the objects are added successfully, but some of the recently added objects (in this case tube objects) are not firing...
Read more >
[Solved]-Touch events not firing C# WPF-wpf
Helix Toolkit recently added tube objects in WPF application, are not firing events or reacts on mouse interaction? My little test program that...
Read more >
helix-toolkit
Helix Toolkit recently added tube objects in WPF application, are not firing events or reacts on mouse interaction? $ 0.
Read more >
PointsVisual3D | Paynter's Palace
In my last episode of the Magnetometer Calibration Tool soap opera, I had a 'working' WPF application that could be used to generate...
Read more >
wpf 3d performance : r/csharp
I am making a unity game right now and I would love it if I could use xaml for my UI. Highly recommend...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found