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!

CompositionTarget.Rendering memory leak

Anonymous 4 years ago 0
This discussion was imported from CodePlex

ddklo wrote at 2012-01-12 18:56:


I notice that this event is subscribed to in multiple places in the Helix 3D Toolkit creating a memory leak if it is not unsubscribed. In some of the places there is a method or property to unsubscribed from this event which is nice, but it can be hard to know when these objects should be disposed. In our app we leak HelixViewport3D's because there is no way to unsubscribed from this event which is attached in the constructor for the fps. Perhaps weak event subscription as discussed in this blog post: could be used to allow for garbage collection. Or an public Unsubscribe/Dispose method on the HelixViewport3D.




objo wrote at 2012-01-12 21:09:

thanks for the link, that's an interesting implementation!

Another approach: Can overriding OnVisualParentChanged be used to unsubcribe the Rendering events? Like I did in the ScreenSpaceVisual3D class, it seems to work there. Subscribe if the parent is not null, and unsubscribe if the parent is null.

ddklo wrote at 2012-01-13 00:03:

I think the OnVisualParentChanged method only works when the parent becomes "null" which might not always be the case unless it is explicit set to be null be implementing some dispose logic. We have some scenarios where we generate at lot of screenshots of the HelixViewport3D (hv) off screen where the hv is assigned a temporary RootVisual and in another circumstances the hv is contained within a another control so even though the container control parent might become "null" I don't think the hv parent will be null.

Since knowing exactly when to unsubscribe from the CompositionTarget.Rendering can be hard I think the weak event solution looks good. Also it might make sense to only subscribe to the event if needed (ShowTriangleCountInfo or ShowFrameRate is enabled) since it is fired a lot.

ddklo wrote at 2012-01-15 00:10:


I profiled the source code with the ANTS MemoryProfiler by having a window open another window containing the HelixVewport3D and other visuals. By subscribing to the CompositionTarget.Rendering event a strong reference is created from the object subscribing to System.Windows.Media.MediaContext which prevents the object from being garbage collected.  Even worse if the scene contains one of the visuals subscribing to this event the entire scene and viewport is kept in memory. Closing the window did not trigger the OnVisualParentChanged event so it was never removed for the visuals where this method is overrided.

By copying over the WeakEventListner for the blog post and replacing all the events subscriptions to CompositionTarget.Rendering with

var weakEvent = WeakEventListener.SubscribeToWeakEvent(this, null, "Rendering", CompositionTargetRendering);

 all the memory leaks went away. And it did not seem to have any impact on the performance for the samples.

Currently this is quite a big issue for us, especially the event on the HelixViewport3D where there is no way to unsubscribe.

Do you think it makes sense changing the event subscription? If so can you provide a timeframe? We can work around it by compiling the source code ourself, but it would be nice to still get updates through nuget.

Regards Dagfinn


objo wrote at 2012-01-15 12:35:

hi Dagfinn, I am looking into this now! Thanks for good change suggestions!

I prefer to explicitly unsubscribe the events, but if there is not a reliable way to do this, I'll go for the weak event listener.

Can subscribing/unsubscribing to the Rendering event be done in the Loaded/Unloaded events? This seems to work in my test cases.

Using WeakEventListener I see the HelixViewport3Ds are freed, but it is leaking instances of WeakEventListener. Do you know what I am doing wrong? I used:

WeakEventListener<HelixViewport3D,CompositionTarget,EventArgs>.SubscribeToWeakEvent(this, null, "Rendering", this.CompositionTargetRendering); 
Please upload a patch if you have all this working properly! :)

ddklo wrote at 2012-01-15 13:07:

I agree that explictly unsubscribing usually is the prefered approch. But I think its quiet common to use weak events when designing WPF controls (see the Weak Event Pattern - I'm not sure why the framework designeres didn't make the CompositionTarget.Rendering a weak event (probably some performance reason I think thats why the signature is using EventArgs instead of RenderingEventArgs).

I think what you are seeing is the expected behaviour it can take a little while before the  WeakEventListener is GC. Try waiting a while and then calling:


The unloaded worked for my simple example for the HelixViewport3D, but then you have to be careful and reconnected when its loaded again. But since the Unloaded event is only for framework elements it can't be used for the Visual3D's. Not sure what would be the best approch overall, but I think since managing lifetime can be hard the weak event options is the safest. Otherwise it can be hard to know when the HelixToolkit could cause memory leaks without looking at the source code.

objo wrote at 2012-01-16 05:47:

Thanks! I was using dotTrace Memory, and it didn't do the garbage collection before taking the snapshot.

I have the Catel solution working, but I would like to see if it can be done with a standard WeakEventManager. I posted a question on stack overflow why a static event does not seem to work. Do you know?

ddklo wrote at 2012-01-16 11:08:

No, I'm not sure . Remember trying it myself without luck. It will be interesting to see if anyone knows.

There is an interesting article discribing different approches on codeproject:

I think the Catel solution is an improvment on Solution 4: Reusable Wrapper.

objo wrote at 2012-01-18 12:14:

Found the error (should set sender=null when calling DeliverEvent), will submit the solution using WeakEventManager soon.

Grunwald's article is great. I will also keep the Catel solution in mind!

objo wrote at 2012-01-18 21:02:

See change set 74235. I hope I got it right now!

ddklo wrote at 2012-01-19 10:21:


I profiled some more and can't see any memory leaks now. Thank you for your efforts. I also think its worth removing the destructors/finalizers since they are not needed or only include them in the debug build because they are expensive for the gc and causes the objects to live longer.

objo wrote at 2012-01-19 11:07:

good, I'll remove the finalizers (in the latest changeset they are wrapped in #if DEBUGs) and Debug.WriteLine completely if the problem is solved! Using the HelixViewport3D in TabControls seems to hold the instances a little longer than other containers, but from what I can see, these HelixViewport3D instances are also freed later...


Unexpected skin behaviour

Anonymous 4 years ago 0
This discussion was imported from CodePlex

saphua wrote at 2011-02-24 18:55:


Disclaimer: First time user of Helix and complete 3D nubcake.

I am trying to load and display 3d models from a game called League of Legends. The models are stored as .skn files and the materials as .dds files. I found two tools that help me conver these to a .obj and a .jpg file.

After converting I can add them to a Expression Bled project and drop the .obj file in my workspace. I can then alter the create DiffuseMaterial to use a ImageBrush and get this result:

Now I am trying to do the same using Helix using this simple method which loads and parses the .obj file and changes the Diffusematerial to use an ImageBrush with the .jpg file:

        private Model3D LoadFile(string objPath, string jpgPath)
            BitmapImage bmp = new BitmapImage();
            bmp.UriSource = new Uri(jpgPath, UriKind.Relative);

            Model3DGroup group = ModelImporter.Load(objPath);
            GeometryModel3D model = group.Children[0] as GeometryModel3D;
            MaterialGroup materialGroup = model.Material as MaterialGroup;
            DiffuseMaterial material = materialGroup.Children[0] as DiffuseMaterial;
            material.Brush = new ImageBrush(bmp);
            return group;

However, this produces this result (face-sword?):

What do I need to do to fix this?

Here are my source files (copyright League of Legends blah blah!)


saphua wrote at 2011-02-25 09:52:

Ok, I am one step further:

Apperantly when I flip the image vertically it works perfectly.

Now I need to figure out how to do this in Helix.

Edit: Applying a ScaleTransform to the Brush doesn't seem to change a thing.

Edit: Oh wait, it does work! Woohoo!

objo wrote at 2011-02-25 11:23:

there might be a bug in the obj importer - not sure if I tested it with texture coordinates - try to change the ObjReader.AddTexCoord method to

        private void AddTexCoord(string values)
            double[] fields = Split(values);
            TexCoords.Add(new Point(fields[0], 1-fields[1]));

let us know if this solves the problem!

saphua wrote at 2011-03-01 12:06:

Yes that fixed it, although I'm not sure if my textures are upside down or if the code was 'upside down'.

objo wrote at 2011-03-02 19:50:

If it was correct in Blend I guess this was wrong in Helix toolkit. I will check with other obj files with texture coordinates.


Loading a texture onto a model.

Anonymous 4 years ago 0
This discussion was imported from CodePlex

Rogad wrote at 2013-12-05 17:04:

I understand the way to apply basic colours, but what about when we have a model with a texture. How can we load the texture at runtime please ?

Eventually I will be moving vertices around, so I need to know how to load the textures dynamically.

I can understand this code taken from the SimpleDemo :
            // Create some materials
            var greenMaterial = MaterialHelper.CreateMaterial(Colors.Green);
            var redMaterial = MaterialHelper.CreateMaterial(Colors.Red);
            var blueMaterial = MaterialHelper.CreateMaterial(Colors.Blue);
            var insideMaterial = MaterialHelper.CreateMaterial(Colors.Yellow);

            // Add 3 models to the group (using the same mesh, that's why we had to freeze it)
            modelGroup.Children.Add(new GeometryModel3D { Geometry = mesh, Material = greenMaterial, BackMaterial = insideMaterial });
            modelGroup.Children.Add(new GeometryModel3D { Geometry = mesh, Transform = new TranslateTransform3D(-2, 0, 0), Material = redMaterial, BackMaterial = insideMaterial });
            modelGroup.Children.Add(new GeometryModel3D { Geometry = mesh, Transform = new TranslateTransform3D(2, 0, 0), Material = blueMaterial, BackMaterial = insideMaterial });
How do I do this same thing but with an image, for example I am trying to load a .PNG image....

Many thanks !

Rogad wrote at 2013-12-05 18:20:

Here's where I am at now with this.

I load a .OBJ model that has 7 children, the first child 0 is the mesh of the hair.

I'm loading my 'start' model like this :
ObjReader CurrentHelixObjReader = new ObjReader();
start = CurrentHelixObjReader.Read("C:/Users/Roger/Desktop/head/base_med_.obj");
So I load the OBJ fine but when I try to grab the material of the original model child 0 (ie the hair) like this :
Material matty = (MaterialGroup)((GeometryModel3D)start.Children[0]).Material;
It gives me an error :
An unhandled exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll

Additional information: 'The invocation of the constructor on type 'HelixTrial.MainWindow' that matches the specified binding constraints threw an exception.' Line number '4' and line position '9'.
I can remove the line and get the model to load, but I need to get hold of the start up material for the hair so that I can apply it later when I alter the mesh via morph targets and rebuild it.

So I would be trying to apply 'matty' like so (partial code) when I rebuild the model :
final.Children.Add(new GeometryModel3D { Geometry = mes, Material = matty });
That last line is part of a loop that rebuilds the Model3DGroup for display in the viewport.

I hope I made sense ! Anyone care to tell me what I am doing wrong ? Here's a picture if it helps visualise... it's just a starting point, I haven;t looked at transparency for the hair at all yet.


Rogad wrote at 2013-12-05 21:04:

I must stop asking questions so quickly, I managed to piece it together ! But for anyone else this is what you can do :

To load a material image you can simple do this :
Material myMaterial = MaterialHelper.CreateImageMaterial("path/to/image/image.jpg", 1);
The '1' is opacity.

And in my particular problem of getting an existing model's texture you can do this :

Instead of my using :
Material matty = (MaterialGroup)((GeometryModel3D)start.Children[0]).Material;
I did this :
Material anotherMaterial = ((GeometryModel3D)start.Children[0]).Material;
Now I have grabbed the hair texture from the original model and can use it later to reapply it when needed.

I do still have an icky problem with the hair and it's transparency. The original model used TGA images. I am not sure exactly how these compare to PNG, but I used an online converter and converted it to PNG. The texture loads but it's not rendering quite right.


As can be seen it doesn't appear to be rendering the transparent areas as see-through.

Any ideas on fixing that please ?

Performance of camera rotation with big STL file

Anonymous 4 years ago 0
This discussion was imported from CodePlex

gmgunderground wrote at 2014-05-07 18:44:

Hi to everyone, I'm making some tests with this fantastic library. I have a simple 3D view, inside this I load a STL file with 800.000 triangles, all is working fine but camera rotation, and zoom are very very slow. Is normal? Is there a solution to speed up the process? Does WPF use DirectX for rendering or is all software?

Best regards

Importing DAZ3D model, textures messed up.

Anonymous 4 years ago 0
This discussion was imported from CodePlex

Rogad wrote at 2013-12-10 17:43:

Aloha !

So I am trying to load a Daz3D figure. Only problem is the textures are all messed up. Most of the textures don't show up at all. The face is about the only one that loads up correctly, despite one eye texture going AWOL too. Confused :/


I looked at the UV maps in UVMapper and they seem okay, so I don't think it's an export problem in DazStudio.

I'm exporting from DazStudio in .OBJ file format.

Do you think there could be a problem with your .OBJ importer ?

I can send you the model I guess, I won't post a link here as it's probably copyright, even though it's a freebie and freely obtainable.

Thanks for looking :)

Rogad wrote at 2013-12-13 11:25:

Objo,, any thoughts ?

objo wrote at 2013-12-16 18:45:

Yes, this is probably bug or limitation in the obj importer. Did you try importing into other software, e.g. MeshLab?
Can you export a small model that can be used for debugging? I would prefer a model that can be posted here and included in the unit tests!

Rogad wrote at 2013-12-16 21:19:

Hi :)

Yes I imported the model into Blender and the textures all load correctly. The only thing that was not quite right was the eyelashes, but I think that is some transparency thing that I have yet to figure out.

I don't have any other models from Daz3D I just have a few morphs which are commercial so I cannot pass on. It's free to download DazStudio though if you want to have a look. It should come with a basic figure and texture.

David_NET wrote at 2013-12-18 23:32:

I wonder if it is worth using Assimp.NET as model importer. Not sure this is possible as preliminary Google search has not shown anyone attempted for WPF3D. It is used in SharpDX.

Rogad wrote at 2013-12-21 17:36:

I've not heard of that David.

Objo, would you like me to email you the model so you can experiment ?

objo wrote at 2014-01-07 22:38:

Rogad: Yes, please send the model.
David: It should be possible, and it would be interesting to see a WPF demo using Assimp.NET!

Rogad wrote at 2014-01-09 01:42:

Thanks, I have sent you a message about where to send the model too :)

objo wrote at 2014-01-24 21:32:

I think the problem is the material is not set for groups. I have submitted a fix that seems to help.

Rogad wrote at 2014-01-25 20:23:

Thanks very much, this is just to confirm the textures are working as expected. There are a couple of artefacts that show through but they are not anywhere I need to worry about as for now it's just the face and head I need. Look on the top of the head if you want an example of what I mean, also in a couple of other places, that may be more to do with the model though.

I just realised the eyebrows are not transparent, but it's using a JPG file for that, so no wonder. I will try to locate a PNG and see if that works.

Great work objo !

Coordinate system

Anonymous 4 years ago 0
This discussion was imported from CodePlex

lhs wrote at 2012-01-20 11:34:


Though this is a great piece of work, I just can't figure out why is z axis pointing up. That just looks so wrong to me, am I missing something?

objo wrote at 2012-01-20 19:03:

Yes, Z is the default up direction in this library, but both HelixViewport3D and CameraController also supports Y as up direction.

I have mostly used this library for engneering/math projects, that's why I chose this convention. (I know it is common in computer graphcis to use Y up, and the default UpDirection of Media3D.ProjectionCamera is 0,1,0)

lhs wrote at 2012-01-20 19:20:

Thanks for reply.

I just thought that it was WPF related, so Y should be up...

What is the easiest way to switch the logic, without rotating models or going through every line of code?

objo wrote at 2012-01-20 19:23:

sorry, I forgot:

set ModelUpDirection="0,1,0" on your HelixViewport3D.

See the UpdirectionDemo example.

lhs wrote at 2012-01-20 19:46:

Tried that, but I get right view instead of front view. Still need to rotate models, which will mess up my transforms (long story...).

Never mind, I thought that you could save me some time, but I guess that I will have to do it myself.

Thanks anyway. Keep up the good work.

objo wrote at 2012-01-26 19:50:

sorry, I don't see the problem here. Do you need a left handed system? Let us know if there is a bug in the handling of the up direction!

przem321 wrote at 2012-01-28 00:42:

I guess the problem is that the view-cube is a little bit messed up. Usually, in graphics libraries like OpenGL and WPF, which both use a RHS (right-handed coordinate system) the Z-axis points towards the camera, the Y-axis to the sky and the X-axis to the right.  In a LHS system (like Direct3D) the Z-axis points away from the camera. In the Helix-Viewport generally everything works well except the view-cube which shows an R instead of F, B instead R, and so on, and the default camera. But one can customize the cube and the camera anyway. ...

Well, this is not a bug and also a minor issue. Personally, I would also prefer the have the front direction looking along the negative Z-axis as the very default setting, just because this is standard, not only in WPF, but also OpenGL... well I know, there is no real standard, Maya handles it differently, Blender and 3D Studio too, in truth this topic is a mess... just for this reason I stick to the coordinate-system of the libraries, and for WPF it is like explained. 

Anyway, lhs, you don't have to play around with your model transforms (if the model is in RHS), you just have to get used to the view-cube and, I recommend it, change the default camera position to something like 


            view.Camera.Position = new Point3D(4, 2, 16);
            view.Camera.LookDirection = new Vector3D(-4, -2, -16);
            view.Camera.UpDirection = new Vector3D(0, 1, 0);


Btw, we have already elaborated about the default camera here:


PS: Maybe one could add a property to set the 'front-direction' just analogous to the 'up-direction' property? This shouldn't cause problems since the third axis would be derived automatically according to the CS?

objo wrote at 2012-01-29 09:15:

Great post! How would you implement support for a front-direction property? Apply a ScaleTransform3D(1,1,-1) to the model? Also note that there is a ViewCubeFrontText property in HelixViewport3D that can be used if you need to change the text on the faces of the view cube. 

przem321 wrote at 2012-01-31 04:23:

Yes, I think changing the text of the view-cube is the simplest way to achieve the goal. I wouldn't work with any additional transforms, the front-direction property should just imply how to set up the view-cube, i.e. setting the model-up and front-direction should imply how to setup the view cube naming, etc. This is basically not a really important issue, just cosmetics. 

RobPerkins wrote at 2012-07-05 09:22:

I've been reading and using Helix for awhile now and I'm very pleased so far. 

One thing I do need is a way to transform the coordinate system to an RHS. The display requirements I have are for X increasing to the right, Y increasing "into" the screen, and Z increasing up. It's said to be the coordinate system used by draftsmen. The one I see "by default" is a left-hand system with Y increasing towards the user. 

Is it possible to set properties for world coordinates in a Z-up RHS?  Possible to subclass HelixViewport3D for that? What approach would you suggest? Unless I'm seeing this wrong? 

objo wrote at 2012-07-07 00:48:

Isn't the ProjectionCamera only supporting LHS? I have not studied the code yet, may be wrong...

If a MatrixCamera is needed to support RHS the camera controller may need some changes.. 

I found simple explanations to LHS and RHS projection matrices in this presentation:

Direct3D has LH and RH versions of all the projection functions, e.g.

RobPerkins wrote at 2012-07-07 01:02:

Let's see..

Helix appears to rotate the WPF default 90 degrees CCW about X, so that Z is up. I need that much, plus a -Y transformation. I can compute that at load and apply a reverse transformation during hit testing, that part is no problem.

I just need the coordinate system axes graphic to also invert the Y arrow, and I'm good to go.

przem321 wrote at 2012-07-26 15:41:

The link you have posted is somewhat misleading. WPF and OpenGL both use the RHS!!! This applies to the HelixToolkit too.

objo wrote at 2012-08-09 01:02:

Was getting confused here. Agree that WPF use RHS coordinate system for the cameras!

I see there is a need to create an example showing the different configurations...


RobPerkins wrote at 2012-08-09 02:42:

I agree! I'm confused myself and was about to ask, with the "default" axis arrows, which color is x, which is y, which z...

I'm not the one to write that demo, though, in the confused state I'm in...

RobPerkins wrote at 2012-10-02 04:52:

RobPerkins wrote:

I agree! I'm confused myself and was about to ask, with the "default" axis arrows, which color is x, which is y, which z...

I'm not the one to write that demo, though, in the confused state I'm in...

Not confused any longer. I'd modified the axis arrows and caused my own pain. It's RHS with no problems at all once I cleared that up. 


how to create elliptic cylinder?

Anonymous 4 years ago 0
This discussion was imported from CodePlex

seiya wrote at 2013-08-17 22:14:

is these simple way to create elliptic cylinder?

objo wrote at 2013-08-17 22:43:

use a ScaleTransform3D on a cylinder!

seiya wrote at 2013-08-18 06:22:

that's great!
thank you very much!

Problem importing Materials

Anonymous 4 years ago 0
This discussion was imported from CodePlex

Nneme wrote at 2012-01-09 14:12:

Hi, how can I import accompany obj materials (.mtl)?

The documentation for "Importing" is currently empty.

The source file too does not provide any sample code only executable.



objo wrote at 2012-01-09 19:35:

Download the latest version of the source code from the "Source Code" tab. The "" download only contains the binaries.

Placing the material files (.mtl) and textures in the same folder as the .obj file should work. Tga textures must be converted to jpeg or png.


future plans with WPF and sharpdx

Anonymous 4 years ago 0
This discussion was imported from CodePlex

glgweeke wrote at 2012-11-02 09:27:


what are your plans with the sharpdx based engine.

Will it be possible to see all your current examples based on sharpdx in the future?

Have you made some performance test?



Best regards,


objo wrote at 2012-11-02 22:29:

yes, I created an experimental fork to test SharpDX! A new world is opening up when getting access to more advanced DirectX features :)

Sorry, I have no plans to convert all examples of this library - they are made for WPF 3D!

RobPerkins wrote at 2012-11-03 18:10:

+1 for this! (I think any demos or examples would have to be significantly rewritten)

glgweeke wrote at 2012-11-03 19:53:


examples are not so importend.

The use of DirectX for beginners is to hard.

So your work can help many developers to get quick started with DirectX and C#.

Great work!



Disable resize of TextBillboardVisual3D

Anonymous 4 years ago 0
This discussion was imported from CodePlex

mplisov wrote at 2013-02-23 22:03:


Is it possible to disable resize of TextBillboardVisual3D on camera zoom or make TextVisual3D always face the camera like TextBillboardVisual3d do?

objo wrote at 2013-03-12 12:09:

I think this should be implemented as a new class, I don't want to add more features into BillboardTextVisual3D. The code you need to change is in the BillboardGeometryBuilder.GetPositions method.