New major version of 3ds file reader brings a major price reduction for the library

by abenedik 22. April 2015 09:37

This time I have one great and one even greater news for you.

The first great news is that a new major release of the best 3ds file reader (Ab3d.Reader3ds) brings some great new features to the library.

And an even greater news is that all this come with greatly reduced price. For example, the price for Ab3d.Reader3ds single developer library has been lower from $489 to only $199! Prices for Viewer3ds and for team and site developer license have been also reduced accordingly. To see the new prices, please visit our Purchase page.


And now to new features of the 9th major version of the library.

The library is mostly used for reading 3D models into WPF applications where the models are shown. But because of the great accuracy of importing 3ds file (in some cases the library imports 3D models even when 3D Studio Max does not import the models) the library is sometimes used as a converter to some other data format – for example to read 3D models from 3ds file and create an objective C code that defines 3D objects for iOS application. 

Such custom converter applications read 3D models from 3ds file into WPF 3D models and then convert that models into some other data format. But the problem with such approach is that some of the data is lost when converting to WPF objects. For example if 3ds file defines materials with bump and reflection map, those two textures are not available in WPF. Also when 3ds file contains animations, the animation can be played in WPF application, but you were not able to access the raw animation data.

With the new version of Ab3d.Reader3ds you are now able to get all the materials and animation key frames data that are stored in 3ds file.


The materials data can be get with the new Materials3ds dictionary on Reader3ds object. The key in the dictionary represents the model name. The model name is the same as in the NamedObjects dictionary (note that you can get all the names of the objects with running the DumpNamedObjects method in Visual Studio immediate window after the 3ds file has been read). The value in the Materials3ds dictionary represents a new Material3ds type. This type contains all the material data that are defined in 3ds file specification. The Material3ds type also contains a Maps list that contain all the maps (textures) used by the material. 3ds file support the following map type: DiffuseColor (the only one supported in WPF), SpecularLevel, Opacity, Bump and Reflection.

The following Class diagram shows all the fields of Material3ds and MaterialMap3ds:

Material3ds Class diagram

It may appear that there are many fields defined for materials. But compared to animation data, materials are really elementary. The Class diagram for animation data is as follows:

Reader3ds key frames data Class diagram

And that are only the classes. Each class also defines their own fields.

The key frame data can be get with calling the new GetKeyFramesData method. The method takes the model name as parameter and returns a list of BaseKeyframesTrack objects (for example PositionTracks and RotationTracks).

Each Tracks object defines their own array of Keys that define data about the object at specific time. For example PositionTracks use PositionKeys to define different positions of object at various time stamps.

To demonstrate the ability to get raw 3ds file data I have added a new sample to Reader3dsSamples project. With the sample users can drag and drop 3ds files to the sample Window and see the materials and key frames data for the 3ds file.


The next very interesting new feature of the new version of Reader3ds is that now it is possible to get the OptimizedMeshGeometry3D object for any 3D model read from 3ds file. The OptimizedMeshGeometry3D is a simple struct that is defined with the following code:

public struct OptimizedMeshGeometry3D
    public List<Point3D> Positions;
    public List<Vector3D> Normals;
    public List<Point> TextureCoordinates;
    public List<Int32> TriangleIndices;

As you see this is very similar to WPF’s MeshGeometry3D. The field names are the same, but the types of collections are fundamentally different. The OptimizedMeshGeometry3D uses simple Lists but MeshGeometry3D uses Point3DCollection, Vector3DCollection, PointCollection and Int32Collection.

The difference between those two types of collections is that the simple Lists are very fast when accessing individual items in the list. On the other hand the collection used in MeshGeometry3D are much more complex – on each get or set the code checks if the call is done on the correct thread, then after a few other ifs the data is get to the underlying FrugalStructList that is also not well optimized for performance.

When the Positions[i] is converted into assembly language the getter from List is converted in only a few lines of code, but in the MeshGeometry3D many lines of assembly code is executed.

This means that if you want to manipulate the 3D models with changing the individual positions, texture coordinates or other low lever data, it is much faster to change the data in a List and then regenerate the Point3DCollection from the changed list then to modify the data inside the Point3DCollection. Also if you are just reading the positions (for example to calculate the bounds), it is much faster when reading data from List then from Point3DCollection.

So, to allow using the faster lists, it is now possible to get the OptimizedMeshGeometry3D for any model read from 3ds file with the new GetOptimizedMeshGeometry3D method.

To demonstrate the performance gains, there is also a new sample in the Reader3dsSamples project.

The following are some of the results get from this sample:

Start performance tests on models with 34.403 positions and with executing each test 10 times
  Calculate bounds with MeshGeometry3D: 20,464ms
  Calculate bounds with OptimizedMeshGeometry3D: 13,779ms
  Change positions with MeshGeometry3D: 84,531ms
  Change positions with MeshGeometry without disconnecting MeshGeometry3D: 363,597ms
  Change positions with OptimizedMeshGeometry3D: 7,788ms

Start performance tests on models with 1.644.282 positions and with executing each test 10 times
  Calculate bounds with MeshGeometry3D: 1001,744ms
  Calculate bounds with OptimizedMeshGeometry3D: 669,594ms
  Change positions with MeshGeometry3D: 4191,129ms
  Change positions with MeshGeometry without disconnecting MeshGeometry3D: 11469,894ms
  Change positions with OptimizedMeshGeometry3D: 493,173ms

As you can see, calculating bounds is almost 40% faster. Changing positions (y += 10) is almost 10 times faster! And this with already optimizing the code with disconnecting MeshGeometry3D object from its parent GeometryModel3D. Without disconnecting the MeshGeometry3D object, using OptimizedMeshGeometry3D is more than 20 times faster.

To see the full test code please check the source of the sample.


And this is not the end of improvements.

The new version also prevents a "cross thread access" exception that could be thrown when the Reader3ds instance is created on another thread then the Read method is called.

And lastly, the new version improves animating objects when the animation does not start at first frame. In some cases the previous version wrongly positioned the objects on frames before first frame.

I hope that you like the new improvements to the Reader3ds library.

To check the new features, please download the latest trial version from the Downloads page or use your User Account page to download the latest commercial version.

Let me finish with a great news for everyone that already own a Reader3ds license, but have expired updates period: because the license renewal price is calculated based on the current price, you can now renew the Redader3ds license with greatly reduced renewal price.



New version of ReaderSvg improved support for Inkscape and adds many other new features

by abenedik 25. March 2015 20:39

I am happy to announce that the ViewerSvg (svg to xaml converter) and the ReaderSvg library have been greatly improved.

After some great customer feedback I spent some time in Inkscape. It is really a great vector drawing application with very good svg files support. The reason for checking Inkscape was that I wanted to check how custom rotate point in Inkscape is saved into svg file. The trick is that standard svg file does not support saving custom rotate point. To preserve data about custom rotate point Inkscape saves that into its custom attribute: inkscape:transform-center-x and inkscape:transform-center-y.

When drawings from svg files are shown, the custom rotate points is not important. But when the parts of the drawing are animated, the custom rotate point is very important.

Therefore I am happy to inform you that ReaderSvg has been improved so that the custom rotate center is read into the RenderTransformOrigin WPF property. This way quite tricky to implement because Inkscape saves the custom rotate center in absolute coordinates, but RenderTransformOrigin requires values to be in relative coordinates. Anyway, this works very well now.

After that improvement I have invested some additional time and added the following improvements and fixes to ReaderSvg:

  • Added possibility to set the WPF name of the objects from the Inkscape's Label (inkscape:label attribute).
  • Changed reading transformations from svg files so that the type of transformation is preserved (rotate transform is read as RotateTransform and not as MatrixTransform as before). Added new property to ReaderSvg to control this behavior: ConvertTransformationsToMatrixTransform. You can set it to true for backward compatibility.
  • Fixed reading text that is rendered with outlines.
  • Improved using viewBox attribute.
  • Improved using svg and use elements when they use clipPath, transform and viewBox.
  • Improved TrueTransform when transforming LinearGradient and RadialGradient brushes.
  • Improved support for clipping when converting shapes to geometry.
  • Added "preview Images" option to ViewerSvg. Fixing some bugs in ViewerSvg application.
  • Improved transforming object's position and size to simplify creating XAML from parts of svg file.
  • Removed setting some default values on TextBlock element: FontStyle="Normal" FontWeight="Normal" HorizontalAlignment="Center" VerticalAlignment="Bottom" (this creates cleaner XAML).
  • Improved clipping behavior with adding support for UserSpaceOnUse value in svg clipPathUnits attribute.
  • Changing the way names are set to objects when a new Canvas is created to host the object's transformation. Now the object gets the original svg name. The created transformation Canvas gets the name that has "_transform" suffix. This behavior can be controlled by SetSvgNameToParentTransformCanvas and TransformCanvasNameFormatString properties.


For example for the following svg file:

<rect id="rect1" x="20" y="10" transform="matrix(-1 0 0 1 0 0)" />

ReaderSvg creates the following XAML:

<Canvas Name="rect1_transform" RenderTransform="-1 0 0 1 0 0" >
    <Rectangle Name="rect1" Canvas.Left="20" Canvas.Top="10" />

This way all the data from the svg file are preserved – x and y are converted into Canvas.Left and Canvas.Top, matrix transform is converted into RenderTransform.

To preserve the values we also need to create a new Canvas that contains the RenderTransform. If RenderTransform would be added to the Rectangle, than the Rectangle would be rendered at the wrong location because the Canvas.Left and Canvas.Top would not be transformed with RenderTransform matrix (Canvas position is applied after the transformation).


Already the most accurate svg reader has been improved. And I have also shown that the product is still actively developed. So if you find a svg file that is not imported correctly, just upload it with using the Feedback panel. 



Improved ResourceDictionaryWriter for ReaderWmf library

by abenedik 3. February 2015 21:10

I the previous post I have described how easily is to create ResourceDictionaries from svg fils.

Today I would like to inform you that the ResourceDictionaries improvements from ReaderSvg have also come to ReaderWmf library. This means that creating ResourceDictionaries from metafiles (emf, emf) files have been greatly improved too.

What is more, the ResourceDictionaryWriter from the previous week has been further improved – now it is possible to control the number of decimals that are used in XAML. The following screenshot shows the new application:

This improvement has been also added to ResourceDictionaryWriter that comes with ReaderSvg.

After a series of improvements of 2D products I will now devote more time to 3D products again.

Tags: , , ,


Improved creating ResourceDictionaries from svg files in new version of Ab2d.ReaderSvg

by abenedik 28. January 2015 20:31

I am happy to announce that the best svg reader for .Net has been improved.

I am also happy that I have not received any svg file that would not be read correctly for very long time. This means that the reader very accurately converts the files to WPF object. So this part of the ReaderSvg did not get any upgrade.

The improvements in this update are focused on what you can do when you have the svg file in WPF objects tree. 

The main new improvement is better support for creating ResourceDictionaries from multiple svg files. ResourceDictionaries can be created with using ResourceDictionaryWriter application. The application is available with full source code and therefore it can be fully customized. The following is a screenshot of the new version of the application:

That screenshot was created after we have added two svg files for ResourceDictionary – one was home6.svg and the second was birthday_cake.svg. This can be seen from the left panel where images of both read files are seen. On the right side you can see the ResourceDictionary XAML.

As you see the SolidColorBrushes and Pens have been also specified as resources. This means that you can simple change the brush or pen with changing the resource value.

With the new version of ResourceDictionaryWriter application it is possible to specify when the SolidColorBrushe or Pen are written to resources and when they are defined as attributed for the elements. The screenshot shows an option that specifies that SolidColorBrushes and Pens are written to resources when they are used 2 times or more. So for example in the pre-last line of the XAML you can see that the GeometryDrawing is using a White brush. Because this brush is still defined as attribute, this means that this brush is used only once. If it would be used 2 times, it would be specified as resource. The application allows you to specify to always use resource, to never use resources and also allows you to specify a few options in between (with changing the source code you can use any possible option).

An improvement of the new version is that when importing objects as Shapes it is also possible to write Brushes are resources (before this was possible only for Geometries).

It is also possible to specify whether the objects will be written as Shapes (Canvas, Path, Rectangle, Ellipse, etc.) or as Geometry objects (as shown in the screenshot). Advantage of Shapes is that they are simpler to use and manipulate. The Geometry objects on the other hand are much lower lever objects and are harder to manipulate but have better performance and use less memory.

ResourceDictionaries are a very useful concept in WPF and I hope that with the improvements in this version it will be easier to create them.


Another improvement of the new version is with using RenderToBitmap method. Now it is possible to also specify custom dpi settings for the created bitmap. I have also fixed an issue where all objects were scaled to the border of the image the svg file was read with AutoSize set to false and we specified a custom sized bitmap.

After adding dpi support to RenderToBitmap method I have also improved SvgToPngConverter (sample console application) and added dpi and some other settings to it.

Also the main ReaderSvg samples have been improved. They now use custom control (TextBlockEx) to show information about each section of samples. The TextBlockEx allows you to very quickly define the text with new lines, bold regions, bullets and some other special formatting (for example hyperlinks). It replaced the clumsy DocumentViewer that require a lot of XAML for simple text and also produces annoying handled exceptions. Also the Frame element was replaced by custom DynamicContentControl that can be bind to UserControl type name to show the correct UserControl. Both new classes are part of the sample and can be freely used for your projects also.


In the following days I will also update the ResourceDictionaryWriter that comes with ReaderWmf library. It will provide similar improvements as the one that comes with ReaderSvg.


I hope you are satisfied with improvements. As always, if you find a svg file that is not correctly read, please send it to me. Also if you are missing a special functionality and think that it could be also beneficial to others, please let know and maybe I will implement it for you – usually after a day or two you can already get a pre-released version with new functionality.

Tags: ,


Improved multi-touch support in new version of ZoomPanel

by abenedik 13. January 2015 15:44

I am happy to announce that a new version of ZoomPanel has been just released.

The new version brings improved support for touch and multi-touch.

The previous version of ZoomPanel already has touch support. But for that you need to use a custom MultiTouchZoomPanel control that was available in a separate project.

The reason for that separation was that the ZoomPanel library was built with .Net 3.5 framework that do not have support for touch. The MultiTouchZoomPanel was built on .Net 4 framework and was able to use touch events.

In the new version the code from MultiTouchZoomPanel is integrated into the core ZoomPanel control. The trick is that ZoomPanel comes with two builds: one .Net 3.5 and one .Net 4.0. This allows us to implement all the touch manipulation in the .Net build. The .Net 3.5 build preserves all the new properties that control the touch behaviour but an error is thrown if user wants to enable touch support.

So if you want to use touch controls all you need to do is to use the .Net 4 build of ZoomPanel. Touch controls are already enabled by default.


What is more, this version improves the pinch to zoom behavior with improving the position where the zoom occurs - now the center of zoom is between the fingers that do the pinch.



Import 3D models from almost any 3D file with new major update of Ab3d.PowerToys library

by abenedik 27. November 2014 23:43

I am really happy that after a long development all great new features of Ab3d.PowerToys library are now available.

The biggest new feature is that now it is possible to import 3D models into WPF or WinForms application from almost any 3D file – including Collada, fbx, blend, dxf, ase, lwg and many more (see

This is possible with help of Open Source Assimp importer library and a new Ab3d.PowerToys.Assimp helper library that converts Assimp’s Scene object into WPF 3D objects.

For example the following XAML imports a Collada duck.dae file:

<assimpVisuals:AssimpModelVisual3D Source="/Resources/duck.dae" 
                            Position="0 0 0" PositionType="Center"

And the result is of course the standard Collada duck 3D model:

Collada duck model opened with Ab3d.PowerToys.Assimp

And what is more, just as Assimp importer is free to use, the new Ab3d.PowerToys.Assimp library is also free to use without need to purchase a commercial version of Ab3d.PowerToys (when not used with commercial version of Ab3d.PowerToys, Ab3d.PowerToys.Assimp is distributed under MIT license).


And today I have many other very good news for you.


Let’s continue with presenting you a whole new sample project – Ab3d.PowerToys.AssimpViewer.

This project uses Assimp library to import 3D models from file and show 3D model in the application. What makes it very interesting is that it has some advanced features like:

  • Shows objects names and hierarchies 
  • Shows detailed information about 3D objects
  • Allows object selection with mouse
  • Showing bounding box, normals and triangles for selected object.

For example the following image shows selected duck model with bounding box, triangles and normals:

AssimpViewer with shown bounding box, normals and triangles

This makes it similar to what is possible with Viewer3ds application. The main difference is that for AssimpViewer you can see the whole source code.

This application also demonstrates a new ModelDecoratorVisual3D class that makes showing selected object incredibly simple – for example:

<visuals1:ModelDecoratorVisual3D x:Name="SelectedModelDecorator" 
                                     ShowBoundingBox="False" BoundingBoxLineColor="Red" BoundingBoxLineThickness="2"
                                     ShowNormals="True" NormalsLineColor="Blue" NormalsLineThickness="1"
                                     ShowTriangles="True" TrianglesLineColor="Green" TrianglesLineThickness="1"
                                     TargetModel3D="{Binding ElementName=MyModel3D}"
                                     RootModelVisual3D="{Binding ElementName=ContentRootVisual3D}"/>

As you can see, we just set the target model (selected model), parent Visual and then decide how we want to decorate the selected model – with bounding box, with normal or with triangles. Super simple.

Another improvement from the new version of Ab3d.PowerToys library is a better and nicer CameraAxisPanel – as seen in the lower right corner the new version now shows real 3D arrows instead of 3D lines with arrows. This looks much nicer.

This sample is still under construction (version 0.8). I have big plans with it. I want to turn it into a simple 3D editor where you will be able to add multiple 3D objects from multiple files, move the models around, scale and rotate them. I know that many customers are working on some similar applications. Creating such sample application could mean a huge development time saving for many of them.


And now to some other new features.

Many customers are concerned about WPF 3D performance when they need to show very complex 3D models with a lot of 3D parts. One reason for performance problem can be that WPF is using DirectX 9 rendering and that it does not have an optimal rendering pipeline. But many times the reason for slow rendering is that simply too many GeometryModel3D objects are rendered.

This can cause problems because each GeometryModel3D is rendered with using its own DirectX draw call. Draw call is a low level command, that instructs graphics driver and graphics card how to draw one object. Because graphics drivers need to prepare many things before the data from draw call can be send to graphics card, draw calls are very expensive operations. This is also true for DirectX and high end 3D games – usually games tend to keep number of draw calls per frame under 3000. Higher numbers can slow down rendering regardless of the hardware.

With Ab3d.PowerToys we cannot improve the WPF 3D rendering pipeline, but with a new ModelOptimizer it is possible to significantly reduce the number of required draw calls and therefore improve rendering performance. This is done with analyzing the model and combing all models that have the same material into one model – so that only one draw call is needed instead of many.

The following image shows the ModelOptimizer sample that shows (marked with red arrow) that ModelOptimizer has reduces number of objects from 3381 to only 30. 

ModelOptimized sample

This had significant impact on performance. With optimized model the frame rate was easily at 60 FPS (on i7 3770 CPU and GeForce 560 Ti). But when the original model was shown, the FPS dropped to 14.

A drawback of using ModelOptimizer is that you loose the original object structure (but this can be solved with saving the hierarchy and individual objects data into some custom data structure before optimizing the model).


There have been some other improvements. 

For example showing 3D models from obj files has been simplified with adding ObjModelVisual3D that can be used in XAML. MaterialTypeConverter has also been improved so that it now Visual Studio 2013 designer can show textures on 3D models. Updating 3D lines has also been improved to allow more flexibility when the lines are updates and when not.

To simplify debugging there are now many extension methods that can be called from Visual Studio Immediate Window to show you many details of the 3D object (see “Dump and Name sample” for more info).

Now it is also very easy to set name to any Model3D object, Visual3D, MeshGeometry or Material – this can be simply done with new extension method: SetName. To get the name, you just call GetName method.

The whole list of improvements and fixes is really long. You can see it on the PowerToys web page (scroll down to versions history).


Finally I would like describe my future plans. I have already mentioned that I want to improve AssimpViewer sample. To do that I will add new helper objects that will make moving, rotating and scaling selected object very easy. I am also planning to add support for reading compiled 3D model files (Visual Studio 2013 can compile 3D models from fbx, dae and obj files into its own file format). This would remove the need to use Assimp importer in your projects.

And I am also working hard on a new DirectX 11 rendering engine that should eradicate rendering performance problems and will also bring improved rendering quality to WPF 3D world. I hope that I will be able to release a first open beta version in the beginning of the next year.


As always, the existing customers can get the latest version of Ab3d.PowerToys (and Ab3d.PowerToys.Assimp library) from their User Account pages. Others please install the new evaluation version form our Downloads page.


And the final great news is a reward to all of you that have read this blog post to the end – to get the reward check out our web site today!



WPF trends in Windows UI technologies

by abenedik 1. October 2014 11:16

I have just stumbled upon Google trends web site that can show how the search terms change over time.

I thought it would be very useful to check how WPF is working (is it really dead?).

The results were very interesting. Therefore I have decided to share them with:

Google trends for WPF, XAML, WinRT and WinForms


As you can see the worldwide search amount for WPF has decreased a little bit in the last 2 years, but it is still very high. Also its comparison with WinForms and WinRT shows that is used very much. Especially WinRT search volume shows that this was a big fail for Microsoft.

The differences between the countries are also interesting - the decrease of WPF usage was quite high in US, but in Germany WPF search indicates that is still used as much as in its best times.

In the previous image I have excluded Silverlight from the graph. The reason for that is that Silverlight is still getting much more search terms that WPF and would therefore worsen the clarity of the results. Let's see:

Google trends for WPF, XAML, WinRT, WinForms and Silverlight

For me this is very surprising. I was not expecting so much search volume for Silverlight. Maybe the reason for that is that users how build WPF or WinForms applications are many times searching for with .Net or c# search term, but when they search for Silverlight, they use this keyword more times because of the differences between standard .Net and Silverlight's version of .Net.


The Google trends web site is very interesting and can show many insights into what is in. Check it by yourself - the following link shows the last graph with Silverlight included: