Charles Petzold



The Petzold.Media3D Library: Uniting the Two Triangulation Strategies

August 24, 2007
Roscoe, N.Y.

In the section "Using Type Visibility and Member Accessibility Intelligently" of the modern classic CLR via C# (pages 169-172), Jeffrey Richter discusses why he believes that most classes should be defined as sealed. The Microsoft developers behind the System.Windows.Media.Media3D namespace seem to agree: In this namespace, every class is either abstract or sealed with just one exception: ModelVisual3D.

This architecture creates challenges for the programmer wishing to write classes that generate triangle meshes algorithmically. The most straightforward approach would be deriving from MeshGeometry3D but you just can't do it. As I discuss in Chapter 6 of my new book 3D Programming for Windows, you have two good alternatives that let you reference your mesh-generation classes in XAML:

  1. Write a class that has a public property of type MeshGeometry3D. Instantiate this class as a resource in a XAML file. Define a binding between the property of this resource and the Geometry property of a GeometryModel3D element.
  2. Derive from ModelVisual3D, and reference the class directly in markup.

In the Petzold.Media3D library (available here) I have used both strategies, with base classes named MeshGeneratorBase and ModelVisualBase, respectively. Because classes that derive from MeshGeneratorBase are usually defined as resources and can be shared, these classes are often simpler and have fewer properties than the classes that derive from ModelVisualBase. For example, the CylinderMesh class that derives from MeshGeneratorBase lets you specify Radius and Length properties but always positions the cylinder sitting at the XZ plane centered around the positive Y axis. You'll use transforms to position the cylinder elsewhere. But the Cylinder class that derives from ModelVisualBase has Point1 and Point2 properties that let you specify the beginning and end positions of the cylinder, and also Radius1 and Radius2 properties to give the cylinder a non-uniform radius.

There may perhaps come a time when you wish that a class that derived from MeshGeneratorBase actually derived from ModelVisualBase so you can do something implemented only in ModelVisualBase, for example, the algorithmic transforms that I discussed a few days ago.

The solution is a class named ModelVisual. This class derives from ModelVisualBase but has a property named MeshGenerator that you can set to a object of type MeshGeneratorBase. Here's how it might look in XAML:

TeapotMesh is a class that derives from MeshGeneratorBase and generates the MeshGeometry3D for the famous Utah teapot.

That markup is part of the following XAML file that applies an animated algorithmic transform known as Twister to the teapot. You can run the following XAML file in XamlCruncher 2.0 with the Petzold.Media3D library loaded:

AnotherTeapotTwister.xaml

Or, you can run an XBAP based on this same XAML file:

AnotherTeapotTwister.xbap

I'm calling this AnotherTeapotTwister because I showed a different approach to animating triangle meshes in the July 2007 issue of MSDN Magazine referenced in this blog entry.

Buy my book and we'll both be happy!
Amazon.com BookSense.com quantumbooks
Barnes & Noble Amazon Canada Amazon UK
Amazon Français Amazon Deutsch Amazon Japan