TubeVisual3D and Material

Jan 12, 2012 at 10:19 PM


Let me first start off by saying thank you very much for your efforts and for sharing this code, it is a tremendous piece of software and exceptionally well written.  I'm wondering if you can give me your advice on how to accomplish the following: 

I'm using the TubeVisual3D class to represent a pipe and what I'd like to do is draw a colored circle at a specific location on the surface of the pipe.  Any suggestions on how this could be done, is there something in the existing library that would allow me to do this?  I'm currently looking at using the Material attribute of the TubeVisual3D to accomplish this, but I'm not sure if this is the best approach.

Again, thanks very much, great work.


Jan 13, 2012 at 6:47 PM

You could do this by a rendering the circle to a bitmap and use that as a texture. But the edge of the circle will not look very sharp when zooming close, and it could be challenging to calculate the right texture coordinates.

I think it would be better to render the circle(s) as a separate mesh slightly outside the tube, but then the challenge is to calculate the 3D coordinates... Look at how the tangents and normals are calculated in the tube implementation, I hope this can help!

Jan 13, 2012 at 7:56 PM

Hi objo,

Thanks for the advice, I will look at rendering the circle as a separate mesh slightly outside the tube.  I seem to be having difficulty applying a Material to the TubeVisual3D class.  Am I doing something wrong here?  In this case the tube shows up completely green:

<Window x:Class="PipeDemo.Window1"
     Title="Pipe Demo" Height="480" Width="640">
		<MaterialGroup x:Key="dm1">
					<LinearGradientBrush StartPoint="0, 0.5" EndPoint="1, 0.5">
							<GradientStop Color="Yellow" Offset="0" />
							<GradientStop Color="Red" Offset=".25" />
							<GradientStop Color="Blue" Offset=".50" />
							<GradientStop Color="LimeGreen" Offset=".75" />

		<ht:HelixViewport3D ZoomExtentsWhenLoaded="True" PanGesture="LeftClick"  >
			<ht:SunLight  />
			<ht:TubeVisual3D Path="{Binding Pipe}" Diameter="5" IsPathClosed="False" Material="{StaticResource dm1}" BackMaterial="{StaticResource dm1}" />

 and my code:

public IList<Point3D> Pipe { get; set; }
public Window1()
	Pipe = this.CreatePath();
	DataContext = this;

private IList<Point3D> CreatePath()
	List<Point3D> list = new List<Point3D>();
	for (int i = -5; i < 5; i++)
		list.Add(new Point3D(i * 10, 0, 5));
	return list;


Jan 13, 2012 at 8:10 PM

I see the TubeVisual3D is not currently supporting texture coordinates. 

I will add a Values property where you can set the texture X (u) coordinates. The Y value (around the tube) is difficult to define and will simply be linear from 0 to 1.

You can also create the tube geometry by MeshBuilder.AddTube (where you also can specify the diameters along the tube).

Jan 19, 2012 at 2:53 AM

Hi objo,

Thanks for adding the TextureCoordinates property to the TubeVisual3D class, I also see that you added a Diameters property as well.  I'm still not sure how to apply a texture to a TubeVisual3D though, would it be possible for you to give me a very simple example?  I basically want to apply a RadialGradientBrush to a TubeVisual3D, any advice you can provide is greatly appreciated.


Jan 19, 2012 at 9:53 AM

see the "StreamLinesDemo" example. It is currently using MeshBuilder.AddTube, but could now be rewritten to use the TubeVisual3D. The example uses a linear gradient brush (hue colours) in the material, and uses the streamline velocities (scaled to [0,1]) as "values" (first texture coordinate). It is difficult to control the position of the texture around the tube (second texture coordinate) (unless we specify a normal direction for each point of the path), so I am currently only using "1-dimensional" textures.