+3

FEX: An example of some capabilities of Helix!

everytimer 4 years ago in Information • updated by Wim Huyghe 3 years ago 8
Hello dear Helix mates!
I always loved Helix examples library: many examples and every one with something particularly interesting.
Last few months I've been developing a small but fairly complex application that is based on Helix Toolkit (WPF). If you are developing using this library you might be interested in seeing some of its features!





I have written a small article covering some highlights for Helix Toolkit users:

  • Custom design Orientation Cube
  • More ScreenSpaceVisual3D
  • Rotation around screen perpendicular axis
  • Improving performance by hiding mesh visuals
  • Several layers to enable hover visuals, selection and more
  • Transparency and sorting
  • Hit detection even not directly over the Visual

you can read it here:

www.f-e-x.com/helix.html

PD. FEX is mainly for engineers who work with Finite Element Method models (in this case Nastran). I've attached an example for all of you in order to be able to experiment and play a little bit.

It would be awesome to hear back from you of what do you think of this!

Cheers

WPF
This is really good looking stuff. I might have an interest in this. How can I learn more about it? Will it take on STL graphic files? How about applications for Finite Difference problems alongside the FEM stuff?
+1
Hello Rob,
You can find the download link and some features & tutorials on the main page (www.f-e-x.com).

At this moment FEX is fully capable of reading all Nastran Input Files (.dat, .bdf) and I am planning to expand it to Abaqus (.inp). It is pretty easy to read a .stl file as Helix is capable of reading it by default. Are you trying to compare geometry with your model? Or your mesh is directly in .stl format? As far as I know stl can store only triangular elements.

I would love to talk about this with you. As this issue is not directly related to Helix Toolkit I think it's best that we continue by PM.

Cheers,
Tim

Very nice, really impressed. Any change parts of this will ever be released open source? I just started playing around with the Helix toolkit, and your library would be wonderfull to improve the looks and features...

+1

No plans so far in releasing the source code since it is not as clean as I would like it to be. In addition, FEX is a separate application which uses Helix Toolkit and the capabilities of the latter are much wider. All visual features included in FEX are in someway already in Helix. The 'looks' are custom made using the bricks and tools provided by Helix.


Said this, if you are interested in a particular feature or behavior just post it here and I'll do my best to help you in order to achieve it in your application.


Tim.

Hi,


Many thanx for the quick reply. There are actually 2 features I would like some hints on:

- how to make distance measurements between two points in a model

- showing the wire mesh on top of the coloured surfaces


For this last one I read I should use the LinesVisual3D and populate that using the Tesselate function, but this function seems not available on my imported STL-file (a ModelVisual3D object).

To perform a measurement between two points you first have to get the position of those points and obtain the module of vector going from one to another. To get the position of a point at your mouse, you can use FindHIts method in Viewport3DHelper:


private Point3D p1 {get; set;}

private Point3D p2 {get; set;}

private void Helix_MouseUp_Measure(object sender, MouseButtonEventArgs e)

{

Point p = e.GetPosition(Helix);

var hits = Viewport3DHelper.FindHits(Helix.Viewport, p);

if (hits.Any())

{

p1 = hits[0].Position;

//Store first point and repeat

}

}


For the lines on top of the mesh you can indeed use LinesVisual3D as you have said. I'm not familiar with STL file format and I'm not aware of methods and helpers in Helix for that. For a general case you want to populate Points property of LinesVisual3D with pairs of points that represents each edge of your mesh.


Good luck!

Hi, many thanks for the tips, these allowed to already find a solution for the "mesh on top". The trick was NOT to use the modelimporter class, but to use the STLReader class directly, as this exposes the read-in meshes. The modelimporter only gives a Model3DGroup back, and from this you cannot recreate the points collection (or at least I did not find out how...)


My code now looks like this:


StLReader reader = new StLReader();

reader.Read(fileName);
LinesVisual3D lines = new LinesVisual3D();
lines.Thickness = 1;
lines.Points = reader.Meshes[0].Positions;

viewPort3d.Children.Add(lines);


Now to solve the measurement function...

Got the measurement working also. Here my (dirty) code, but should give others some idea how to add the measurement line and label with distance:


private void viewPort3d_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{
// Remove previour measurement line
if (viewPort3d.Children.Contains(mMeasurementline)) viewPort3d.Children.Remove(mMeasurementline);
if (viewPort3d.Children.Contains(mMeasurementText)) viewPort3d.Children.Remove(mMeasurementText);

// Define first point
System.Windows.Point p = e.GetPosition(viewPort3d);
var hits = Viewport3DHelper.FindHits(viewPort3d.Viewport, p);
if (hits.Any()) mPoint1 = hits[0].Position;
}

private void viewPort3d_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
System.Windows.Point p = e.GetPosition(viewPort3d);
var hits = Viewport3DHelper.FindHits(viewPort3d.Viewport, p);

if (hits.Any())
{
// Define second point
mPoint2 = hits[0].Position;
if (mPoint1 != null && mPoint2 != null)
{
double distance = Math.Sqrt(Math.Pow(mPoint1.X - mPoint2.X, 2) + Math.Pow(mPoint1.Y - mPoint2.Y, 2) + Math.Pow(mPoint1.Z - mPoint2.Z, 2));
mMeasurementText = new TextVisual3D();
mMeasurementText.Text = Math.Round(distance, 3).ToString() + " mm";
mMeasurementText.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
mMeasurementText.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
mMeasurementText.Height = distance / 10;
mMeasurementText.Position = new Point3D((mPoint1.X + mPoint2.X) / 2, (mPoint1.Y + mPoint2.Y) / 2, (mPoint1.Z + mPoint2.Z) / 2);
mMeasurementText.TextDirection = new Vector3D((mPoint1.X - mPoint2.X) / distance, (mPoint1.Y - mPoint2.Y) / distance, (mPoint1.Z - mPoint2.Z) / distance);
mMeasurementText.UpDirection = viewPort3d.Camera.UpDirection;
mMeasurementText.UpDirection.Normalize();
mMeasurementText.Foreground = new SolidColorBrush(Colors.Black);
viewPort3d.Children.Add(mMeasurementText);

mMeasurementline = new LinesVisual3D();
mMeasurementline.Points.Add(mPoint1);
mMeasurementline.Points.Add(mPoint2);
viewPort3d.Children.Add(mMeasurementline);
}
}

}