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!

Color Interpolation for object surface

Ehsan M A. 7 years ago updated by Fdjjj Duuree 2 years ago 205

I have a mesh, say for example a triangle with three corners p1, p2 and p3.

i want to create a gradient that cause for example color C1 in P1 corner of triangle, C2 in P2 corner and C3 in P3 corner. Please note that C1 and C2 and C3 are different.

Any idea on how to do it?


Reference bugs in examples/source?

zangatsu 8 years ago updated by Kong Lee 2 years ago 243

Hi I just downloaded the newest source of the helix-toolkit. I wanted to get through all the examples to learn about the application, but unfortunately I get a lot of reference errors and I do not know why. I could solve most of them by reinstalling NuGetPackages and adjusting the fakes assemblies, however there are still a lot left. For example in MainViewModel:BaseViewModel class I get the reference error:

Error CS0246 The type or namespace name 'Camera' could not be found (are you missing a using directive or an assembly reference?) DemoCore _NET40 C:\..\helix-toolkit-master\Source\Examples\WPF.SharpDX\DemoCore\BaseViewModel.cs 29 Active.

This goes on with RenderTechnique, IEffectsManager and so on.

Do you have any solution? My references in DemoCore_NET40 all seem to work fine, at least I am getting no yellow symbol in the solution explorer...


Is there a way to create extruded 3d solid from planar polygon?

Anonymous 9 years ago 0
This discussion was imported from CodePlex

luanshixia wrote at 2013-03-02 03:35:

I am using HelixToolkit to create a simple city data visualization app. I need to extrude building plans from AutoCAD dwg file. ExtrudedVisual3D only result the side surface, without caps.

Rossie wrote at 2013-03-04 01:06:

Hi I had a similar requirement - but i had caps. The way I achieved it was to find the border edges of the polygon(s) and extrude them along the Z axis. But I implemented my own FindBorderEdges() method - because Helix3D's version did not entirely suit. Mainly because I wanted a contiguous list of edges - (Helix3D will put the output edges in the same sequence as the input edges - meaning that they may/may not be a contiguous list) I also wanted them in a particular winding order. I'll post my implementation - that might help you. (and perhaps the guys developing the Helix3D devs might want to use this code as well) I'll just paste in the main methods to do the work - i made a class called MeshGeometryHelper2. Let me know if i have missed anything - you might have to fiddle the source to fit your purpose.
        public static List<int> FindBorderEdges(MeshGeometry3D mesh)
            var dict = new Dictionary<ulong, int>();

            for (int i = 0; i < mesh.TriangleIndices.Count / 3; i++)
                int i0 = i * 3;
                for (int j = 0; j < 3; j++)
                    int index0 = mesh.TriangleIndices[i0 + j];
                    int index1 = mesh.TriangleIndices[i0 + (j + 1) % 3];
                    int minIndex = Math.Min(index0, index1);
                    int maxIndex = Math.Max(index1, index0);
                    ulong key = CreateKey((UInt32)minIndex, (UInt32)maxIndex);
                    if (dict.ContainsKey(key))
                        dict[key] = dict[key] + 1;
                        dict.Add(key, 1);

            var edges = new List<int>();
            foreach (var kvp in dict)
                // find edges only used by 1 triangle
                if (kvp.Value == 1)
                    uint i0, i1;
                    ReverseKey(kvp.Key, out i0, out i1);

            var borderPoints = new List<Point>();
            mesh.Positions.ToList().ForEach(p => borderPoints.Add(new Point(p.X, p.Y)));

            var result = OrganizeEdges(edges, borderPoints);
            return result;

        private static List<int> OrganizeEdges(List<int> edges, List<Point> positions)
            var visited = new Dictionary<int, bool>();
            var edgeList = new List<int>();
            var resultList = new List<int>();
            var nextIndex = -1;
            while (resultList.Count < edges.Count)
                if (nextIndex < 0)
                    for (int i = 0; i < edges.Count; i += 2)
                        if (!visited.ContainsKey(i))
                            nextIndex = edges[i];

                for (int i = 0; i < edges.Count; i += 2)
                    if (visited.ContainsKey(i))

                    int j = i + 1;
                    int k = -1;
                    if (edges[i] == nextIndex)
                        k = j;
                    else if (edges[j] == nextIndex)
                        k = i;

                    if (k >= 0)
                        var edge = edges[k];
                        visited[i] = true;
                        nextIndex = edge;
                        i = 0;

                // calculate winding order - then add to final result.
                var borderPoints = new List<Point>();
                edgeList.ForEach(ei => borderPoints.Add(positions[ei]));
                var winding = CalculateWindingOrder(borderPoints);
                if (winding > 0)

                edgeList = new List<int>();
                nextIndex = -1;

            return resultList;

        public static MeshGeometry3D Extrude(MeshGeometry3D surface, double z)
            var borderIndexes = MeshGeometryHelper2.FindBorderEdges(surface);
            var borderPoints = new List<Point3D>();
            borderIndexes.ToList().ForEach(bi => borderPoints.Add(surface.Positions[bi]));

            var topPoints = borderPoints.ToList();
            var botPoints = borderPoints.Select(p => new Point3D(p.X, p.Y, p.Z + z)).ToList();
            var allPoints = new List<Point3D>();
            var allIndexes = new List<int>();
            var allNormals = new List<Vector3D>();

            // sides.

            for (int i = 0; i < topPoints.Count; i +=2)
                int j = (i + 1) % topPoints.Count;

                allIndexes.Add(topPoints.Count + j);
                allIndexes.Add(topPoints.Count + j);
                allIndexes.Add(topPoints.Count + i);

                var a = allPoints[i].ToVector3D();
                var b = allPoints[j].ToVector3D();
                var c = allPoints[topPoints.Count + j].ToVector3D();

                var n0 = b.Subtract(a).Cross(c.Subtract(a)).Unit();

            var surfaceNormals = new List<Vector3D>();
            if (surface.Normals == null)
                surface.TriangleIndices.ToList().ForEach(i => surfaceNormals.Add(new Vector3D(0, 0, 1)));

            // top
            var count = allPoints.Count;
            var topSurfacePoints = surface.Positions.Select(p => new Point3D(p.X, p.Y, p.Z + z)).ToList();
            var topNormals = surfaceNormals.ToList();
            var topSurfaceIndexes = surface.TriangleIndices.Select(i => count + i).ToList();
            AddTriangleIndexes(topSurfaceIndexes, allIndexes, false);

            // bottom
            count = allPoints.Count;
            var botSurfacePoints = surface.Positions.ToList();
            var botNormals = surfaceNormals.Select(n => n.Flip()).ToList();
            var botSurfaceIndexes = surface.TriangleIndices.Select(i => count + i).ToList();
            AddTriangleIndexes(botSurfaceIndexes, allIndexes, true);

            var mesh = new Mesh3D(allPoints, allIndexes);
            var meshGeom = mesh.ToMeshGeometry3D();
            meshGeom.Normals = new Vector3DCollection(allNormals);

            if (z < 0) 

            var simple = Simplify(meshGeom);
            return simple;

        private static void AddTriangleIndexes(List<int> triangleIndices, List<int> allIndexes, bool reverseWindingOrder)
            for (int i = 0; i < triangleIndices.Count; i += 3)
                var i0 = triangleIndices[i + 0];
                var i1 = triangleIndices[i + 1];
                var i2 = triangleIndices[i + 2];
                if (reverseWindingOrder)
                    allIndexes.AddRange(new[] { i2, i1, i0 });
                    allIndexes.AddRange(new[] { i0, i1, i2 });

        public static void ReverseWinding(MeshGeometry3D mesh)
            var indices = mesh.TriangleIndices.ToList();
            var flippedIndices = new List<int>();
            AddTriangleIndexes(indices, flippedIndices, true);
            mesh.TriangleIndices = new System.Windows.Media.Int32Collection(flippedIndices);

       /// <summary>
        /// returns 1 for CW, -1 for CCW, 0 for unknown.
        /// </summary>
        public static int CalculateWindingOrder(IList<Point> points)
            // the sign of the 'area' of the polygon is all we are interested in.
            var area = CalculateSignedArea(points);
            if (area < 0.0)
                return 1;
            else if (area > 0.0)
                return -1;        
            return 0; // error condition - not even verts to calculate, non-simple poly, etc.

        public static double CalculateSignedArea(IList<Point> points)
            double area = 0.0;
            for (int i = 0; i < points.Count; i++)
                int j = (i + 1) % points.Count;
                area += points[i].X * points[j].Y;
                area -= points[i].Y * points[j].X;
            area /= 2.0;

            return area;


Viewcube image

Denwood 8 years ago updated by anonymous 4 years ago 4
I want to add an image to my Helix viewcube( all 6 directions). How to do it?

Show wireframe as quads with Helix and SharpDX

Raul Burgos 8 years ago updated by nxymin10 4 days ago 704
Is it possible to get this effect ( Connected Mesh to QuadFaces ) in the viewportDX when a .OBJ model is readed on it?.
I'm using HelixToolkit.Wpf.SharpDX.
Somebody can post a example?
Thanks in advance.


Bug \ display artifact 3d model

ilya 11 months ago updated 11 months ago 1


The display of elements is incorrect, as if it is multiplying (no overlays).

What can be wrong?

Image 188


ATS selidbe

ATS 3 years ago updated by ไอยดา สุรีวงค์ 2 years ago 2

ATS agencija za selidbe Beograd posluje više od 24 godine.Tokom vremena stekli smo znanje,mudrost i iskustvo u našoj branši.Kao najstarija transportna i selidbena agencija u regionu, svesni smo koliko je za naše klijente važno da se presele kvalitetno, efikasno i sigurno uz poštovanje vremenskih rokova i dogovorenih usluga.Stoga poslujemo u tom smeru,kako bismo uslugu selidbe održali na visokom nivou i na zadovoljstvo naših klijenata.ATS agencija za transport i selidbe pruža niz objedinjenih usluga u domenu selidbe i skladištenja.


Touch operation issues

greentea175 4 years ago updated by Fdjjj Duuree 2 years ago 210


The sample ModelViewer is operated by touch.

Open \Models\obj\wall12.obj.

After expanding wall12.obj,

Even if you move your finger over this model, you cannot rotate or zoom in smoothly.

With mouse operation, you can rotate and zoom smoothly.

It seems that OnManipulationDelta() of CameraController.cs is hard to occur. . .

\Models\obj\leone.3DBuilder.obj can be rotated and enlarged smoothly by touch operation.

I want to rotate and zoom in smoothly even with touch operation.

Please tell me how.

Thank you.


How to Download

Haydee Herron 5 years ago updated by sneha rani 3 years ago 2

Quick Trick: Download YouTube Videos in a split second via changing to

VidPaw Online YouTube Video Downloader is a site to download high-quality YouTube videos without downloading any desktop program. As an all-rounded online YouTube video downloader, it offers totally free-to-download service for users, supporting almost all devices connected to the network such as Windows, MacBook, iPhone, iPad, Android and so forth. What’s more, it also allows users to download the subtitle, muted video, or audio of the YouTube video.

Moreover, it also serves as an online video converter. With VidPaw Online YouTube Downloader, downloaded YouTube videos will be save in MP4/3GP/WEBM format. Moreover, the audio file will be saved in M4A/WEBM. All output settings are up to you.

  • Supported video quality - 144p, 240p, 360p, 720p, 1080p, 1440p, 2K, 4K,8k.
  • Supported audio quality - 64kbps, 96kbps, 128kbps, 256kbps, 320kbps.

Next, we will show you how to download Download YouTube Videos Online on both PCs and mobile devices like iPhone/iPad and Android.

TIPS: VidPaw also provides downloader extensions in Chrome, Safari, and Firefox on Windows or MacBook for users to have a better overall experience.

Part 1: How to Download Online Videos from YouTube to PC?

VidPaw Online YouTube Downloader is accessible to all browsers on Windows 10/8/7/Vista/XP. To download online videos from YouTube to your PC, just a few steps are needed.

STEP 1. Open on Chrome/Foxfire/Safari.
STEP 2. Paste the YouTube video link on the blank field, then, click on "Start" button.

STEP 3. Choose an output format and quality > Click on "Download" button.

TIPS. It’s available to download video-only or audio of the YouTube video. 

STEP 4. Waiting for a while, you can successfully save high-quality YouTube videos offline on your PC.

Tips. Quick Way to Download YouTube Videos with VidPaw Extension

To skip the step to paste the video URL, VidPaw considerately provides a YouTube Video Downloader extension. If you are looking for a more convenient way to save YouTube video offline to PC, you can try it.

Read More: How to Download and Install VidPaw Video Downloader Extension.


Part 2: How to Download YouTube Videos on iPhone/iPad?

Some of you might want to download YouTube videos to the camera roll to iPhone/iPad. To successfully save YouTube videos offline on your iPhone/iPad, you will need a third-party app called Documents to help you. Before downloading YouTube video, you should download Documents on iPhone/iPad first. After that, you can start downloading YouTube videos on iPhone/iPad. 

STEP 1. Launch Documents app. 

STEP 2. Tap the icon on the bottom right corner of the screen. 

STEP 3. Navigate to 

STEP 4. Select a desired format and quality, and then, click the "Download" button to start downloading. 

STEP 5. Download videos will be saved in Documents. If you want to save YouTube video to camera roll on iPhone, you can open the "Downloads" folder, and then click "Edit" to select the video. Next, move the YouTube Video to Camera Roll on iPhone/iPad.

Part 3: How to Download YouTube Videos on Android?

Likewise, you can also download YouTube Videos on Android with VidPaw Online YouTube Downloader. What’s more, compared with the operations on iPhone/iPad, downloading YouTube Videos on Android is much easier. You just need few simple steps to download your favorite videos online. 

STEP 1. Open a browser app on your Android device. 

STEP 2. Go to  

STEP 3. Stick the video link from YouTube on the blank.  

STEP 4. Download YouTube video with a suitable format and quality.

After that, you might be also curious about how to save a youtube video to camera roll on Android. Don’t worry. All of your wanted YouTube videos will be downloaded to the camera roll automatically when the downloading process is finished.

Youtube video