This is the discussion forum for Helix Toolkit.
For bugs and new features, use the issue tracker located at GitHub.
Also try the chat room!
+1
Under review

HelixVisual3d not updating after created

Rodrigo Basniak 5 years ago in Question • updated by Franz Spitaler 3 years ago 5
Hi,

I'm need to show a circular torus on the viewport. The closest option I found was the HelixVisual3D, but it has open ends. So I tried to create my own class to draw this, with a HelixVisual3D and two thin cones to close the ends. I used the classes from the 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?

Thanks in advance,
Rodrigo
WPF Media3D
+1

Storyboard animation

Anonymous 5 years ago 0
This discussion was imported from CodePlex

xyxa wrote at 2012-07-14 15:56:

Thanks so much for very useful toolkit.

But unfortunately I could not create a storyboard animation via Blend for any MeshElement3D. It's strange, because I can create such animation for ModelVisual3D. What is the reason for this behavior and Is there any ways to solve it?

+1

MeshGeometryHelper Cut Method

Anonymous 5 years ago 0
This discussion was imported from CodePlex

badgerbadger wrote at 2012-07-26 16:50:

I would like to modify the MeshGeometryHelper.Cut method so that it (also) meshes the opening created by the planar cut (i.e. currently the mesh is open at the location of the plane, I need a closed surface)

Can anyone figure out a neat way of achieving this in the Cut method? (Objo? :) )  (maybe uncommenting some of the commented-code in the Cut method achieves this..?)

Otherwise I guess I will have to get a contour of the planar mesh, attempt to mesh that surface and add to the Cut mesh - but a bit messy.


objo wrote at 2012-08-09 00:59:

Yes, you could change the cut method to also provide the contour(s). See the GetContourSegments...

When you have the contour(s), you can use the MeshBuilder.AddPolygonByCuttingEars to triangulate by the cutting/ears method (easy algorithm, but not very efficient).


badgerbadger wrote at 2012-08-09 10:41:

Many thanks Objo, yes I ended up doing something similar but used the AddPolygon instead of CuttingEars version (which I'll now investigate). I meant to post my hack but moved on to the next problem. Here is the mk1 code ( meshOrig is the original mesh while cutMesh is after the plane cut has been applied; plane is the cut plane).

I should add my code was not required to produce a nice mesh, it is only an intermediate step towards a bigger problem involving segmenting a mesh, so if others use it, it is worth investigating replacing AddPolygon (which applies a fan mesh)..

        private static MeshGeometry3D MeshPlaneCut(MeshGeometry3D meshCut, MeshGeometry3D meshOrig, Plane3D plane)
        {
            //Store the positions on the cut plane
            var segments = MeshGeometryHelper.GetContourSegments(meshOrig, plane.Position, plane.Normal).ToList();

            //assumes largest contour is the outer contour!
            IList<Point3D> vertexPoints = MeshGeometryHelper.CombineSegments(segments, 1e-6).ToList().OrderByDescending(x=>x.Count).First();

            //meshCut the polygon opening and add to existing cut mesh
            var builder = new MeshBuilder(false,false);
            builder.Append(meshCut.Positions, meshCut.TriangleIndices);
            builder.AddPolygon(vertexPoints);
           
            MeshGeometry3D mg3D = builder.ToMesh();

            return mg3D;
        }


ulissespi wrote at 2012-12-24 08:06:

I'm also interested in having a MeshGeometryHelper.Cut that as result creates a solid (non hollow) mesh.

I changed the ApplyCuttingPlanesToModel method in the CuttingPlaneGroup.cs file, replacing the call   

g = MeshGeometryHelper.Cut(g, p, n);

by    

g = MeshGeometryHelper.MeshPlaneCut(g, p, n);   

to use the method described in the previous post, but obviously it didn't work as the parameters are not the same.

Could you please give a bit more detail on how do you call your new method?

(maybe have a piece of the calling code) 

 

Or if someone else found another way of resolving this issue, other code examplesare wellcome.


badgerbadger wrote at 2012-12-24 11:39:

Hi Ulissepi - I should point out that my problem wasn't concerned with drawing a cut (and closed) mesh, only in calculating the mesh so that I could apply a contour algorithm to it. If you need to display the visual then something more sophisticated will be required.

I've tried to pick out the relevant bits from my code. It's been a while so hopefully I have included everything relevant. Hope it helps!

Geometry3D originalGeometry = model.Geometry;
//create a copy of the mesh
var g = originalGeometry as MeshGeometry3D;
MeshGeometry3D gOrig = g.Clone();

//Cut the Mesh and then apply the cutplane

//cp, p & n are the cut plane (Plane3D) and the position (Point3D) and the normal (Vector3D) of the plane

g = MeshGeometryHelper.Cut(g, p, n);

g = MeshPlaneCut(g, gOrig, cp);

GeometryModel3D gm3d = model.Clone();
 gm3d.Geometry = g;

+1

Collision Detection

Anonymous 5 years ago • updated by anonymous 2 years ago 3
This discussion was imported from CodePlex

BCBlanka wrote at 2012-11-10 08:47:

Hello,

 

Is there a way to detect collision between 3D models?

 

Thanks

Blanka


objo wrote at 2012-11-11 22:14:

sorry, no collision detection is implemented in this library. But it would be interesting to see integration of the models defined here with bullet or some other physics library! 

http://bulletphysics.org/
http://code.google.com/p/bulletsharp/
http://www.ode.org/
http://newtondynamics.com 


bcblanka wrote at 2012-11-12 06:40:

Thanks for the prompt response.

 

Blanka


davidop wrote at 2013-05-28 16:53:

Did you find the solution? What library do you recommend? Do you have any example?

BCBlanka wrote at 2013-05-29 10:10:

I ended up comparing the bounds of the models (Rect3D) and checking their intersection. This was enough for what I needed.

davidop wrote at 2013-05-30 11:00:

Do not you will have a small example? I need it for when moving objects (ModelVisual3D) with the mouse

objo wrote at 2013-06-07 12:01:

A small collision detection demo is on the wish list! Simple geometries (boxes) would be sufficient. Also a larger demo combining WPF3D and one of the well-known physics engines would be very interesting to see. Sorry, I don't have time to do this myself at the moment :)
+1

Migrate to HelixToolKit WPF to HelixToolKit SharpDX

Anonymous 5 years ago • updated by anonymous 2 years ago 5
This discussion was imported from CodePlex

cedrelo wrote at 2014-02-07 08:50:

Hi,

First really thanks for your work!!!!


I use HelixToolKit WPF to develop an WPF application of robot trajectory, i use import of .stl, camera, viewport3D, LineVisual3Ds.

It's works really great, but when we load large data and a lots of stl, the perfomance fall on
some computer.

Do you think it's possible to migrate the projet to the fork HelixToolKit SharpDX to improve perfomance ?
Does the fork has all the functionnality of the orginal project ?
It is possible to use HelixToolKit SharpDX inside a WPF application ?


Thanks

Cedre
+1

Control Zoom in/out

Anonymous 5 years ago 0
This discussion was imported from CodePlex

veerammalkumaran wrote at 2014-08-07 12:11:

I can zoom in/out using mouse wheel. But it goes infinity. How to prevent the zoom in/out at a particular position?
IsZoomEnabled option is disabled the zoom in/out, but I want prevent the user from zoom in/out infinitely.
Is there any way to do this...?

everytimer wrote at 2014-08-08 01:31:

You can try to disabling the zoom (IsZoomEnabled) when the camera is further than a specific value, there is a property that indicates you the Camera Distance. Create an event for the wheel and play with the delta. I'm not sure about this as I've never tried it. Good luck!

veerammalkumaran wrote at 2014-08-08 08:31:

Thanks for the answer, the problem is IsZoomEnabled stops the camera distance then when should we enable the zoom.
we can disable based on the camera movements, once disabled the camera won't move then when that should be enabled.

veerammalkumaran wrote at 2014-08-08 09:47:

I done that using PreviewMouseWheel event of view port 3d (MouseWheel event doesn't trigger on helix view port 3d)
        private void viewPort3D_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (viewPort3D.Camera.LookDirection.Length >= 800 && e.Delta<0)
            {
                e.Handled = true;
            }

            if (viewPort3D.Camera.LookDirection.Length <= 15 && e.Delta > 0)
            {
                e.Handled = true;
            }
        }
+1

Zoom out

Anonymous 5 years ago 0
This discussion was imported from CodePlex

Cygor6 wrote at 2012-11-23 22:40:

I'm beginners and would need your help! I made a console application 
to save down a rendered image. BUT the camera is too close and
I can not somehow zoom out.






How do I solve this?
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Shapes;
using HelixToolkit.Wpf;

namespace ConsoleApplication1
{
    internal class Program
    {             
        public static IHelixViewport3D HelixView { get; set; }
        public static Model3D MyModel { get; set; }

        private static void Main(string[] args)
        {
            var thread = new Thread(Test);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join();
        }

        private static void Test()
        {
            var c = new FileStream("Ferarri40.3ds", FileMode.Open, FileAccess.Read, FileShare.Read);
            var reader = new StudioReader {TexturePath = "."};
            MyModel = reader.Read(c);

            var m = new ModelVisual3D {Content = MyModel};

            const string Path = @"H:\test.png";
            const int Height = 480;
            const int Width = 640;

            var vp = new HelixViewport3D {Width = Width, Height = Height};

            vp.Viewport.Children.Add(m);

            vp.Children.Add(new DefaultLights());

            var zoom = new ScaleTransform3D(1.5, 1.5, 1.5);
            var t = new Transform3DGroup();
            t.Children.Add(zoom);
            vp.Camera.Transform = t;

            vp.Camera = CameraHelper.CreateDefaultCamera();
            vp.Camera.Position = new Point3D(5.300, -12.300, 3.300);
            vp.Camera.LookDirection = new Vector3D(-6.300, 11.000, -6.600);
            vp.Camera.UpDirection = new Vector3D(0.000, 0.000, 1.000);
            vp.Camera.NearPlaneDistance = 0.123;         

            var r = new Rectangle {Width = vp.ActualWidth, Height = vp.ActualHeight};
            var cb = new BitmapCacheBrush(vp) {BitmapCache = new BitmapCache(0)};
            r.Fill = cb;
            r.Arrange(new Rect(0, 0, r.Width, r.Height));
            r.UpdateLayout();            

            vp.Export(Path);
        }       
    }
}
+1

Solved - render a scene with screen space geometry to bitmap

Anonymous 5 years ago 0
This discussion was imported from CodePlex

ezolotko wrote at 2013-08-20 06:21:

In case if anybody will struggle with this - if you are trying to render a viewport to a bitmap without displaying it on screen, and the scene contains some screen space geometry (like LinesVisual3D) - this geometry is absent in the resulting bitmap. This is because CompositionTarget.Rendering event gets never fired in drawing-to-bitmap mode.

This is my dirty as hell solution to this - call this function before your render-to-bitmap code:
        void InvokeRenderingEvent()
        {
            // For those about to hack

            var mediaContextType = typeof(MatrixTransform).Assembly.GetType("System.Windows.Media.MediaContext");

            var fromMethod = mediaContextType.GetMethod("From", BindingFlags.Static | BindingFlags.NonPublic);
            var renderingField = mediaContextType.GetField("Rendering", BindingFlags.Instance | BindingFlags.NonPublic);

            var mediaContext = fromMethod.Invoke(null, new object[] { Dispatcher.CurrentDispatcher });

            var eventDelegate = (MulticastDelegate)renderingField.GetValue(mediaContext);

            if (eventDelegate != null)
            {
                foreach (var handler in eventDelegate.GetInvocationList())
                {
                    handler.Method.Invoke(handler.Target, new object[] { null, EventArgs.Empty });
                }
            }
        }
Hope this will help someone,
Yevgeni.
+1

Is there any thing for moving objects?

Anonymous 5 years ago 0
This discussion was imported from CodePlex

behnam263 wrote at 2014-04-13 09:10:

Hi
I'm looking for a method or a way to move or scale or rotate objects like sphere or cube in 3d view
(not moving or rotating camera or viewport movement). Could you help me to do that?
tnx.

behnam263 wrote at 2014-04-16 23:39:

I found my answer in project examples in source code and manipulation(mainwindow.xaml) which user can move or rotate object and etc by myself :)