The best platform for business applications that require 3D graphics

by abenedik 11. September 2012 23:18

In the blog posts that were posted so far I was mostly describing new versions of the products. During recent vacation at seaside I have decided to change that and prepare blog posts that would present some of the features of Ab3d.PowerToys and Ab3d.Reader3ds libraries.

I would also like to persuade you that WPF 3D with Ab3d.PowerToys and Ab3d.Reader3ds libraries is the best platform for building business applications that require 3D graphics.

Ab3d.PowerToys library greatly simplifies work with WPF 3D and make WPF 3D the easiest platform for business applications that require 3D graphics.

In this blog post I will try to write about some of the basic new concepts that are introduced with the library.

Plot 3D sample

This post is divided into the following sections:

  1. Basic 3D scene setup
  2. Cameras
  3. 3D Objects
  4. Showing objects from 3ds files
  5. Conclusion


1) Basic 3D scene setup

This section shows how to prepare an XAML file to show 3D content.
First we need to add a reference to the Ab3d.PowerToys library. Then the following namespace declarations are usually added to the XAML file:


cameras namespace defines the possible cameras (SceneCamera, FirstPersonCamera, ThirdPersonCamera, etc.)

controls namespace defines controls that will be used to control the camera (MouseCameraController, CameraControlPanel).

visuals namespace defines 3D objects that can be added to Viewport3D (BoxVisual3D, SphereVisual3D, ConeVisual3D, LineVisual3D, WireBoxVisual3D, HeightMapVisual3D and many more).

Now we can define our 3D scene with the following XAML:

<Border Name="ViewportBorder" Background="Transparent">
    <Viewport3D Name="MainViewport">

<cameras:SceneCamera Name="Camera1" Heading="40" Attitude="-20" Bank="0" 
                     Distance="250" ShowCameraLight="Always"
                     TargetViewport3D="{Binding ElementName=MainViewport}"/>

<controls:CameraControlPanel VerticalAlignment="Bottom" HorizontalAlignment="Left" 
                             Margin="5" Width="225" Height="75" 
                             TargetCamera="{Binding ElementName=Camera1}"/>

<controls:MouseCameraController UsedMouseButton="Left" 
                                TargetCamera="{Binding ElementName=Camera1}"
                                EventsSourceElement="{Binding ElementName=ViewportBorder}"/>

<controls:CameraAxisPanel HorizontalAlignment="Right" VerticalAlignment="Bottom" />

First we defined a Border that contains an empty Viewport3D control. Then we added SceneCamera, CameraControlPanel (shows buttons to control the camera), MouseCameraController (use mouse to control the camera) and CameraAxisPanel (shows the orientation of the coordinate axes).

An interesting difference from standard WPF’s way is that the camera is not defined inside Viewport3D but outside it as a standard control. The reason for that is that all WPF’s cameras are sealed or contain internal virtual methods that cannot be defined in derived class. Therefore it is not possible to derive custom cameras from any WPF’s camera.

Before describing the cameras let me first describe how the added controls are connected to each other.

First we need to connect our SceneCamera to the Viewport3D. The connected Viewport3D will be controlled by our SceneCamera. This can be done with setting the TargetViewport3D property on SceneCamera. Using that property and simple binding is the most efficient way to connect the camera to the Viewport3D. But it is not the only possible way to do it. Instead it would be also possible to set TargetViewport3DName property to “Camera1”. It would be even possible to skip both that properties. In that case the camera would check the WPF controls tree and connect to the first found Viewport3D. Because the code where the TargetViewport3D property is set with binding is executed slightly faster that other methods, it is recommended to use it. But when there are only a few controls defined in the parent Window or UserControl, it is also ok to skip the TargetViewport3D definition and let the camera to connect automatically. In case when you want to connect the camera to the Viewport3D later in code and do not define TargetViewport3D and TargetViewport3DName in XAML, you can set the IsAutoViewport3DFindingEnabled to false to prevent the automatic camera connection.

In a similar way the CameraControlPanel and the MouseCameraController are connected to the SceneCamera. As with the camera we could use TargetCameraName property or skip the TragetCamera property and leave the control to find the Camera automatically by searching the objects tree.

The MouseCameraController is also connected to the ViewportBorder element. The connection is created with the EventsSourceElement property. This property defines which element is used as the source of mouse events that are used to control the camera. Because this element has a transparent background, the mouse events are triggered on the whole area of the border element (if the background property would not be defined, than the mouse events would be triggered only on areas where some content is shown). This means that when a user would be over the ViewportBorder element the mouse event would be used to control the camera. It is very easy to define what keyboard and mouse button combinations rotate and which move the camera – by default right mouse button is used to rotate the camera and ALT + right mouse button is used to move the camera – see the help file or samples that come with Ab3d.PowerToys for more info. If EventsSourceElement property would not be defined, the source of mouse events would be the Viewport3D that is connected to the camera. But because Viewport3D does not have the Background property, it would be only possible to rotate the camera when the mouse would be over shown 3D objects – clicking on the area around the objects would not trigger any mouse events.

The MouseCameraController also shows a special cursor icon when the camera is rotating or when the user can rotate the camera with left mouse button. If you would like to use different cursor, you can set the RotationCursor property to some other value.

With the CameraControlPanel it is possible to control the camera with clicking on the shown buttons. By default the CameraControlPanel shows buttons to rotate the camera and to change the distance of the camera. With adding ShowMoveButtons property and setting it to true, additional buttons to move the camera would be also shown.


2) Cameras

Now let me describe the cameras in Ab3d.PowerToys in more details.

In the XAML above we are using SceneCamera. This is just one of the cameras that come with Ab3d.PowerToys library. It is the most advanced and the most easy to use. The camera automatically measures the 3D scene (3D objects inside Viewport3D) and shows them from the specified angle (Heading="40" Attitude="-20" Bank="0") and distance (Distance="250"). Those four properties are common to all the cameras in Ab3d.PowerToys. They represent the main advantage over the WPF’s cameras because it is much easier to define the camera with angles than with 3D directional vectors. The following image (taken from Ab3d.PowerToys Samples) is showing how different angles are rotating the camera:

Camera Heading, Attitude, Bank

As sad before SceneCamera measures the objects in 3D scene and calculates the center position of the scene’s bounding box. The value that is specified with the Distance property is the distance of the camera from the center position of the scene.

Because measuring the scene also gives us the size of the shown 3D objects, it is also possible to use the IsDistancePercent property. If that property would be set to true then the Distance value would mean the percentage of the size of shown objects. For example if Distance would be set to 2, this would mean that the camera’s actual distance from the center of the scene would be 2 times the size of the object’s bounding box (length of diagonal). This makes the camera usage really simple because you do not need to worry about the size of the shown 3D objects. But note that if you change the content of the Viewport3D you need to call Refresh method on the SceneCamera so the scene is measured again. You can also set the IsDynamicTarget property to true and the camera will check the size and center position of the scene on every rendering event (on more complex scenes this can take some time, so it is recommended to manually call Refresh method).

If you check the above XAML more carefully you will see that the camera also sets the ShowCameraLight property to Always. This is another great feature of the cameras and simplifies defining the lights. It adds a DirectionalLight to Viewport3D that is illuminating the scene in the same direction as the camera is facing. This is almost the same as a light would be mounted to a real camera because when the camera rotates the light direction will be also changed accordingly. The value “Always” means that the DirectionalLight is always added. We could also set the value of ShowCameraLight to “Auto” – this would mean that the camera would check the scene and if it would not find any light, it would add the DirectionalLight. This is also the default value of the ShowCameraLight property. But if you know that you will define your own lights and want to skip the check for the lights, you can set the ShowCameraLight to “Never”.

SceneCamera is just one of many cameras in Ab3d.PowerToys library. The following is a list of the most useful camera types:

  • SceneCamera
  • ThirdPersonCamera
  • TargetPositionCamera
  • FirstPersonCamea

ThirdPersonCamera is very similar to SceneCamera. But instead of looking at the whole scene it only looks at a specified object (set to CenterObject property). The angles define from which direction the camera looks at the object. The distance in that case defines the distance from the object’s center position. With ThirdPersonCamera it is also possible to use IsDistancePercent property.

TargetPositionCamera is similar to SceneCamera and ThirdPersonCamera but does not have any automatic measurement. Instead there you have full control of the position where the camera is looking at (set with TargetPosition property). If you know the position and size of your 3D objects you can use that camera instead of SceneCamera. TragetPositionCamera is also used when you want full control of the position where the camera is looking at. This camera does not have IsDistancePercent property.

FirstPersonCamera is a camera that does not look at the scene, target position or specified object as previous cameras. Instead it looks at the world from the specified position (set with Position property) – the position of the camera. The angles define the orientation of the camera. This camera does not have the Distance property.

The following pdf file shows samples of using the described cameras:
Cameras cheat sheet

The following image shows the class diagram of the cameras (click on the image to see it in full resolution):


Cameras class diagram

This was just a really brief description of the cameras. To learn more about them please see the help file and check the samples that come with the library.


3) 3D Objects

After so many words we still do not have anything to show. So it is really time to add some 3D objects.

Ab3d.PowerToys library comes with many 3D objects. The following are available in version 3.4:

  • Axis
  • Box
  • CenteredLineText
  • Circle
  • ColoredAxis
  • Cone
  • Cylinder
  • HeightMap
  • HorizontalPlane
  • LineArc
  • Line
  • LineWithText
  • MultiLine
  • MultiMaterialBox
  • Plane
  • PolyLine
  • Pyramid
  • Rectangle
  • Sphere
  • Text
  • Tube
  • VerticalPlane
  • WireBox
  • WireCross
  • WireGrid

If you define 3D objects in XAML you have two possible choices: you can create 3D object that are derived from Visual3D or from UIElement3D. For example to define a 3D box you can create a BoxVisual3D or BoxUIElement3D. The later add some additional features like focus, mouse events, tool tip, etc. But if you do not need that features you can use Visual3D objects.

When defining 3D objects in code, you can still create instances of Visual3D or UIElement3D objects. But you can also get a more low level objects (GeometryModel3D) with Model3DFactory, Line3DFactory, WireframeFactory or Text3DFactory classes.

As seen from the list above, the library also supports 3D lines. Here and additional note is needed. Because 3D lines are not supported in WPF 3D, they are not rendered in hardware. Therefore 3D lines are created with triangles that are than send to WPF 3D to render them in hardware.

For example if we need to create a 10 pixels wide 3D line, we are need to calculate the positions that will form two triangles that are oriented in such a way that they are facing the camera. This means that when the camera is changed, we need to recalculate the positions of the triangles so they are still facing the new camera. When we are showing only a few lines this is not a problem. But if we are showing many lines, for example a wireframe from a model with 20.000 vertices, then line recalculation can bring the CPU down and make the application response very bad. There are some tricks that can be used to improve the performance of 3D lines. They are described in the “Lines Stress Test” sample that came with the library (see the comments in the source code of that sample). Here I would just like to notify you that 3D lines in WPF 3D are much slower than solid models and should be used in greater quantities with care. However smaller number of lines are surely not a problem.

Now let’s add some 3D objects.

Insert the following into the Viewport3D:

<visuals:BoxVisual3D CenterPosition="0 5 0" Size="20 10 40" Material="Blue"/>

This will add a blue box to the 3D scene. The box is added to the specified location, with specified size and material. But wait! The Material definition looks very simple. If you are familiar with standard WPF 3D programming than you are more familiar with the following Material definition:

<visuals:BoxVisual3D CenterPosition="0 5 0" Size="20 10 40">
                <SolidColorBrush Color="Blue"/>

This is the standard WPF’s way to assign a Blue material. Luckily all the 3D objects in Ab3d.PowerToys library have custom MaterialTypeConverter that enables you to use only one simple word to define the material. The used MaterialTypeConverter is very powerful – with simple strings you can define many possible materials.

For example the same blue material could be specified with Material="#0000FF".

In similar fashion it is also possible to set an image file as a texture. To do that just set the Material to the image file name – for example Material="Images/MyTexture.png".

It is also possible to define a SpecularMaterial. Let’s add a 3D sphere to show you how:

<visuals:SphereVisual3D CenterPosition="30 10 0" Radius="10" Material="S:64;Silver"/>

This creates a MaterialGroup with two children: SpecularMaterial (SpeculaPower = 64, Brush = White) and DiffuseMaterial (Brush = Silver). The SpeculaPower is defined by “S:64;” text. This short material definition always set the SpecularMaterial’s Brush to White (the most common setting). The following string sets a texture image instead of Silver brush: Material="S:64;Images/MyTexture.png".

It is also possible to use EmissiveMaterial. The following will create a sphere that is always Yellow regarding of the lights:

<visuals:SphereVisual3D CenterPosition="30 10 0" Radius="10" Material="E:Yellow"/>

Emissive material is created with a MaterialGroup with black DiffuseMaterial and EmissiveMaterial with brush defined with used string.


The following XAML defines some other 3D objects:

<visuals:BoxVisual3D CenterPosition="0 5 0" Size="20 10 40" Material="Blue"/>

<visuals:SphereVisual3D CenterPosition="30 10 0" Radius="10" Material="s:64;Silver"/>

<visuals:SphereVisual3D CenterPosition="-40 20 40" Radius="3" Material="e:Yellow"/>

<visuals:WireCrossVisual3D Position="-40 20 10" LinesLength="15" 
                            LineColor="Red" LineThickness="3"/>

<visuals:LineVisual3D StartPosition="10 10 -20" EndPosition="20 20 -20"
                        LineColor="Blue" LineThickness="2" StartLineCap="ArrowAnchor" />
<visuals:LineWithTextVisual3D StartPosition="20 20 -20" EndPosition="60 20 -20" 
                                LineColor="Blue" LineThickness="2"
                                Text="3D TEXT"/>

<visuals:WireGridVisual3D x:Name="BottomWireGrid" LineColor="#777" LineThickness="1" 
                        WidthCellsCount="10" HeightCellsCount="10" Size="100 100" />

And here is a screenshot from Visual Studio with the 3D scene defined above:

3D Objects in Visual Studio 2010

All the defined 3D objects are seen in the preview window.

In the lower left corner are buttons for the CameraControlPanel. In the lower right corner there is an icon which represents the SceneCamera. This icon is visible only in design time and is there so you can easily select the camera in XAML with simply clicking on the icon (note: if you do not want to see the icon in design time you can set the IsDesignTimeInfoIconShown property to false).

Now you can try out one of the nicest features of the library – the preview of the changes. Everything you change in the XAML, the change will be immediately shown in the preview. This means that you can simple change the heading or attitude of the camera and you will see your objects from another direction. You can also change the position or size of the objects. This way it is very easy to compose your 3D scene. Note: sometimes it can happen that the scene and XAML are not in sync any more – in that case the best solution is to rebuild your project and the preview should be showing the correct image again.

If you run that sample now you will see the 3D objects and will be able to rotate the camera around the objects with left mouse button and move the camera with holding ALT key and left mouse button. You could also rotate the camera with CameraControlPanel buttons. Not bad for just a few lines of XAML.
As shows in the list before the Ab3d.PowerToys define many other 3D objects. The following pdf file shows many of them:
Objects cheat sheet


4) Showing objects from 3ds files

Usually you will want to show more complex 3D models that are defined in some 3D modeling application. This can be done with Ab3d.Reader3ds library.

The Ab3d.Reader3ds library contains classes that can read 3D objects with all of their properties, lights, cameras and animations from 3ds files. The 3ds file format is one of the most commonly used file format for storing 3D models. Therefore almost all 3D modeling applications support exporting into it.

The following schema shows the process of showing 3D objects in WPF application:

Reader3ds Schema

Here let me present just the simplest usage of the Ab3d.Reader3ds.

I will show you how to add 3D objects from 3ds file to your scene defined in XAML file. First you need to add reference to the Ab3d.Reader3ds library and add the following namespace declaration:


Than you can use the following XAML to read 3D objects:

<visual3ds:Model3ds Source="Resources/MyObject.3ds" 
                    Position="0 0 0" PositionType="BottomCenter" />

<visual3ds:Model3ds Source="Resources/OtherObjects.3ds" ObjectName="Car01" 
    Position="100 0 0" PositionType="BottomCenter" SizeX="100"/>

The first line reads 3D models from MyObject.3ds file. The model is positioned so that its bottom center position is at (0, 0, 0) coordinates.

The second line reads the OtherObjects.3ds file. It does not show all the objects from that file (as in the first line) but only the object with the “Car01” name. The Car01 object is scaled so its x size is 100 and positioned so that its bottom center is at (100, 0, 0).

Note that when using more than one Model3D with the same 3ds file, the 3ds file is read only once.
Ab3d.Reader3ds also provides many other ways to read 3ds file. To see more please check the samples and help file that come with the library.


5) Conclusion

There are still many features that were not described in this blog post. For example in Ab3d.PowerToys library there is an EventManager3D class that simplifies using mouse events on 3D objects – you can use MouseClick, MouseOver, MouseDrag and other mouse events on specific 3D objects. The library also solves problem with semi-transparent 3D objects with TransparencySorter.

I hope I have persuaded you that the Ab3d.PowerToys and Ab3d.Reader3ds libraries are really easy to use and provide many features to create great WPF 3D applications.

To read more about other advantaged of using WPF 3D and our libraries you are also invited to read the 3D Overview page.

Tags: , ,

Ab3d.PowerToys | Reader3ds

Solution for problematic 3ds files exported from 3ds Max 2013

by abenedik 24. August 2012 09:17

Recently some customers reported that they have problems with reading some 3ds files with Ab3d.Reader3ds and Viewer3ds.

After investigating the files I have found out that the material names were not correctly written - only the first character of the material name was written to the 3ds file. For example instead of "Wood" only "W" was written as material name. In 3ds file, materials are defined first. After materials 3d objects are defined. Each object defines the used material by its name. In the broken files the full name was used - for example "Wood". But because the materials were defined by wrong names, the objects did not get the materials assigned. This problem was common in all the broken files I got recently. In some of the files there were also some other problems that broke the structure of 3ds file so much that only a first few objects could be read.

Soon we have found out that all the files with the above symptoms were exported from 3ds Max 2013. Previous versions of 3ds Max created valid 3ds files, but some changes in the new version broke the exported 3ds files.

After some search on the internet, a fix for that problem was found. It can be downloaded from:


Until an official fix from Autodesk, I recommend applying this fix. It was tested from some of our customers and they confirmed that the problems were gone after installing it.

The new version of Viewer3ds (published yesterday) can also detect the problematic files and based on the above symptoms can alert the user that the file was probably exported from 3ds Max and that a fix should be applied.



This problem has been fixed by an official 2013 PU6 update.

See more:



New release brings improved products, added .Net 4 assemblies and better installer

by abenedik 23. August 2012 22:23

This release brings the following:

-    improved installation on 64 bit Windows
-    added .Net 4 assemblies
-    improved Ab3d.PowerToys, Ab3d.Reader3ds and ZoomPanel libraries

The new installer has been improved to work better on 64 bit windows. Now the products are no longer installed under “Program Files (x86)” folder, but under “Program Files”. All the products are built with “Any CPU” setting and therefore do not need to be in the folder where all the “old stuff” is. Note that if you were referencing our products from the x86 folder, you will need to update the path to our products.

All the products now also contain assemblies that are built on .Net 4.0 Client Profile framework. When building .Net 4.0 applications, you can now reference native .Net 4 assemblies. Before you had to reference original .Net 3.0 (Ab3d.Reader3ds, Ab2d.ReaderSvg, Ab2d.ReaderWmf or ZoomPanel) or .Net 3.5 SP1 (Ab3d.PowerToys) assemblies. This was not a problem because the 4.0 CLR runs the assemblies on previous target frameworks natively inside 4.0 CLR (without running them in some kind of virtual machine). So it was already possible to use our libraries on machines where only .Net 4.0 is installed. Anyway time goes on and now almost all new applications are built on 4.0 so I decided to prepare native builds for that framework. Of course the original 3.0 and 3.5 assemblies are still available. Original assemblies are inside bin folder as before. The new assemblies can be found inside bin\.Net 4 folder.

Because all our products except Ab2d.ReaderWmf are using AllowPartiallyTrustedCallers assembly attribute, I had to take a closer look at the security critical sections of the code and add some security related attributes on some methods. This made the code .Net 4.0 compliant.

Note that the Viewer3ds, ViewerSvg and Paste2Xaml applications were not ported to .Net 4.0 and still requires older framework to run (older applications cannot run inside 4.0 CLR - only assemblies can be used inside 4.0 applications).


As mentioned before some of the products were also improved.

ZoomPanel library got improved ZoomPanelMiniMap control. Here controlling ZoomPanel with moving rectangle around was improved (before movements were slow). In the previous version it could happen that when a content of ZoomPanel was changed from a big to a much smaller content, than the new image in ZoomPanelMiniMap was too small. This is fixed now.

Ab3d.Reader3ds library also got a few improvements. Most of the work there was done to improve reading of broken 3ds files. Because 3ds file is very old and very commonly used, there are many applications out there that can export to that file format. Unfortunately not all of them create valid 3ds files. I got some of such files. Most of them were so screwed that it was not possible to import them into 3D Studio Max (invalid file format error was shown). Despite that there were still some valid data inside those files. And the new version tries to read as much from them as possible.

In case when a broken 3ds file is read with Reader3ds, you will still get FileFormatException (when reading with default settings). But now you can catch the exception. Than you can warn the user about problematic file and if the user wants to read the file anyway, you can set the new TryToReadBrokenFiles property on Reader3ds to true and read the file again. You can also have that property always true and just check the IsBroken property after reading 3ds file. Both those options are also used in the new version of Viewer3ds.

One nice new feature of Viewer3ds is showing object’s bounding box, triangles and normal. This is very useful in finding the cause of the problems in some 3D objects that do not look correct. Because Viewer3ds uses powerful 3D lines capabilities of Ab3d.PowerToys library this was an easy task to do. The following screenshot shows that new feature:

Viewer3ds: Showing details of selected object - bounding box in red, triangles in green and normals in blue.

The longest list of new features for this release belongs to Ab3d.PowerToys library. Today I will just write short descriptions of new features. In one of the following posts I will discuss some of them in more details. So the improvements are:
-    Improved LinesUpdater performance and removed possible memory leaks.
-    Added Reset method to LinesUpdater that takes Viewport3D as parameter to reset (remove all lines) only from specific Viewport3D.
-    Added HeightMapVisual3D and HeightMapMesh3D (with two very nice samples)
-    Added TubeMesh3D, TubeVisual3D and TubeUIElement3D.
-    Added support to very easily create 3D curves: added Ab3d.Utilities.BezierCurve and Ab3d.Utilities.BSpline classes; also added CreateBSpline3D and CreateNURBSCurve3D to Line3DFactory.
-    Added MouseWheel event to EventManager3D – now you can subscribe to MouseWheel event on any Model3D object.

Ab3d.ReaderSvg and Ab2d.ReaderWmf libraries did not get any new features of fixes. But they also got new versions (with same major and minor version but increased build version) because of new .Net 4.0 assemblies and small changes that were needed in the code to make the code 4.0 compliant.

Tags: , , , ,

Ab3d.PowerToys | Reader3ds | ReaderSvg | ReaderWmf | ZoomPanel

Maintenance releases for Ab2d.ReaderSvg and Ab2d.ReaderWmf published

by abenedik 28. May 2012 08:00

I am happy to announce that maintenance releases are now available for Ab2d.ReaderWmf and Ab2d.ReaderSvg.

The improvements and fixes in Ab2d.ReaderWmf are:

  • Improved scaling of text. Before sometimes the text was not correctly scaled - for example when pasting cells from excel the text can go out of bounds. The text is scaled with RenderTransform on TextBlocks. Note that scaling can be turned off with setting ProcessCharacterSpacing property to false.
  • Added support for text that is defined by glyphs indexes instead of unicode characters (usually when the metafile was created from the data that was sent to printer).
  • Fixed processing character spacing for special charter marks that are shown over another character like carets, etc.
  • Fixed exporting to XAML when the content of the Text property contains curly brackets. Before parser wanted to use them for binding expression.
  • Added ResolveRasterOperation delegate that enables using custom brush when an unsupported raster operation is used in metafile.


The following are the changes in Ab2d.ReaderSvg:

  • Fixed exporting to XAML when the content of Text property contains curly brackets. Before parser wanted to use them for binding expression.
  • Prevented throwing ArgumentException when right or bottom value in object's bounds was negative.


As usual the new version can be downloaded from User Account page (for commercial users) or from my Downloads page (for evaluation version).

Tags: , ,

ReaderSvg | ReaderWmf

FINALLY! So long the stone-aged web site and welcome the new web site

by abenedik 21. May 2012 09:43

I knew it from the beginning - the previous web site design was surely not looking like we are developing software for high end applications. It was more appropriate for some stone-age museum. No more - the new greatly looking web site is live!

The preparations for the new site were quite long.

First the new domain had to be acquired. Because the domain was already taken this was not an easy and cheap task. I think that I should clarify that going away from does not mean that we will abandon the WPF. No worries, we are not affected by MS marketing departments and still believe that WPF is by far the best technology to build advanced desktop applications. Anyway the previous domain was related only to WPF. This was not very convenient for our tools that can be used for Silverlight as well. The new domain is technology independent and is therefore opened for any possible future. Of course we will still support and improve the current products. What is more we are preparing a new very excited product that will be still based on WPF.

Let's continue our new web site story. After the new domain was acquired we needed a new logo. I think that logo is important - it is shown in many placed and somehow subconsciously represents the idea of the company. Having high requirements for the logo, there was no way I could create it by myself. Therefore the was used to gather many developers that created hundreds of ideas. This process was really amazing and I think that the winning logo design is also amazing.

After that we started discussing and preparing drafts for the new web site. I see now that it is surely not easy to be a designer - creating something that customer wants when the customer is not really sure what he wants. After some going back and forth I thing we created a great web site that looks nice and is functional. Some parts are still not finished - for example the Purchase page still needs some polishing.

Enjoy the new site...


Web Page

Fixed ReaderWmf publised

by abenedik 3. March 2012 22:40

The new version of ReaderWmf 5.5.4436 greatly improved reading metafiles from stream because it read the stream directly and did not create a temporary file from it as previous versions did.

But unfortunately the code change had a bug that could produce NullReferenceException.

This exception can also happen when using WmfViewbox or WmfDrawing.

A new version 5.5.4445 that fixes that issue has been just published.



Maintenance releases for all products are now available

by abenedik 24. February 2012 22:13

I am happy to announce that maintenance releases are now available for the following products:

  • Ab3d.Reader3ds and Viewer3ds
  • Ab3d.PowerToys
  • Ab2d.ReaderSvg and ViewerSvg
  • Ab2d.ReaderWmf and Paste2Xaml
  • ZoomPanel (evaluation version only)


Everybody that are using evaluation version will be happy to know that new evaluation versions of all the products now show the evaluation information dialog only once per day. Previous versions show evaluation information dialogs on each start of your application. If two or more controls were used (for example ReaderSvg and ZooomPanel) than each time you started your application two dialogs were shown. This was too annoying and is now lessened so the dialogs are shown only once per day.

Another important change in evaluation version allows you to reinstall evaluation version (the same version or newer) after 90 days from the date of installing previous evaluation version. The 60-day evaluation time limit is still the same. But with previous versions you need to contact support to extend the evaluation version after 60 days. This was not very practical when you tried an older version before some time and at that time you did not need the library or it did not have all the features you wanted. But after some time you decided to try with the new version and you were not able to install the evaluation because it has already expired. Now this is not the case any more because after 90 days you can reinstall the evaluation version again. Note that when reinstalling the same version it is recommended to uninstall it before installing it again. There is still 30 days between evaluation expiration and possibility to reinstall after 90 days - this is left to prevent continuous use of only evaluation version. But if you need to extend the 60-day period you can still contact support to extend your evaluation.


Of course there are also some other improvements and new features that apply for both evaluation and commercial version.

Let me start with Ab2d.ReaderSvg (and ViewerSvg). The changes in new version are:

  • Improved reading size of root svg object (improved support for viewBox and added support for preserveAspectRatio).
  • The GetXaml method now preserves the width and height in specified units (cm or inch).
  • Removed memory leak that occurred sometimes when reading embedded images.
  • Improved reading embedded images - they are now read faster and with lower memory usage.
  • Fixed problems when Path bounds were negative and IsSizeSetToPathElement in SilverlightXamlWriterSettings was set to true.
  • Prevented adding PresentationOptions:Freeze="True" text to XAML for Silverlight.
  • Added option to export for Silverlight 5.
  • Fixed reading svg file that contain links to images and were read without specifying the whole path (Read method was called only with svg file name without the full path).


Ab2d.ReaderWmf got the following changes:

  • Fixed leaking GDI+ handles under some circumstances. This could lead to "Cannot open wmf file!" exception after opening a few thousands metafiles.
  • The Read and ReadGeometry methods that take stream as parameter now read the metafiles directly from the stream and do not create a temp file from stream as before.


Changes for Ab3d.Reader3ds:

  • Improved reading textures in Model3ds and Viewport3ds. Added TexturesPath property to both controls - it can be used to specify custom textures path. If TexturesPath is not specified, the path of the 3ds file is used.
  • Added support for cameras that are children of helper objects (for example when camera is linked to a helper object so the camera is transformed as the helper object).
  • Fixed setting IsCameraAnimated property - Reader3ds sets this property to true if the 3ds file contains camera animations. Before the property could be set to true in cases when the camera was not animated.
  • Added ReadLightRange property to Reader3ds. Before the Range of PointLights and SpotLights was not read. Now it is possible to read the Range with setting ReadLightRange to true. Note that attenuation data are not present in the 3ds file - if they are used they need to be manually set to lights after the 3ds file is read.

It is also worth noting that with new version of Viewer3ds all the cameras defined in 3ds file are exported as comments in xaml. The xaml also get a description of the exported cameras. This makes switching between cameras defined in 3ds file very easy.


There are also a few improvements for Ab3d.PowerToys:

  • Fixed rotating with MouseCameraController and CameaControlPanel when the scene in vertically inverted when Attitude is between 90 and 270 degrees.
  • Fixed EventManager3D where under some circumstances a new object drag can be automatically stared just after end drag event.
  • Improved MaterialTypeConverter: Added support for simply defining SpecularMaterial and EmissiveMaterials. For example the "s:32;Blue" text can be used to define MaterialGroup with DiffuseMaterial and SpecularMaterial (SpecularPower = 32; SpecularBrush = White; DiffuseMaterial = Blue). The "e:Yellow" can be used to show yellow emissive material. Also improved support for defining textures path (now files from local disk and from http can be used).
  • Fixed occasional NullReferenceException in SphericalCamera when layout is updated in Visual Studio designer.


The commercial version of ZoomPanel was not updated.


I would like to conclude the blog post with something completley different - a new logo for the company AB4D d.o.o.

ab4d logo

I got the new logo from a design contest that run on I was really satisfied with the contest and would really recommend that page to everyone. We are also making a redesign of the web page that will be available soon.

We are also preparing a very interesting new product (but more on that later).

I surely believe that the future is very bright for the company. I hope that our products will also make it brighter for you.