For bugs and new features, use the issue tracker located at GitHub.
Also try the chat room!
using Caliburn MVVM
AQSRanck wrote at 2014-03-17 15:09:
In one of the older sample projects, there is a little Red house with a gable roof. I'd like to do this in the Mvvm Project.
All I really need is an example of the code for the view model to add the rectangular box representing the house and then the code to add the triangular roof. It would help if the two objects had different colors. Add more detail if you wish, but this will be a great help in getting me started.
Thanks
AQSRanck wrote at 2014-03-18 14:31:
(Objects is an Observable Collection which is bound to the ItemsSource of the HelixViewport3D) and this works just fine.
public void AddFigure()
{
Objects.Clear();
if (Objects.Count == 0) {
Objects.Add(new SunLight());
}
BoxVisual3D housebox1 = new BoxVisual3D();
housebox1.Width = 35;
housebox1.Length = 25;
housebox1.Height = 8;
housebox1.Fill = Brushes.DarkGray;
housebox1.Center = new Point3D(0, 0, -8);
Objects.Add(housebox1);
}
Obviously, Helix does not have a "RoofVisual3D" so the question is how do you build this triangular solid element to add to the Objects collection? All I am trying to understand is how to construct the code to build a custom triangular solid element
element to add to the collection.AQSRanck wrote at 2014-03-21 03:28:
ExtrudedVisual3D Gable = new ExtrudedVisual3D();
PointCollection sect = new PointCollection();
sect.Add(new Point(0, 15));
sect.Add(new Point(17.5, 4));
sect.Add(new Point(-17.5, 4));
Gable.Section = sect;
Gable.Path.Add(new Point3D(-12.5, 0, 0));
Gable.Path.Add(new Point3D(12.5, 0, 0));
Gable.SectionXAxis = new Point3D(0, 1, 0);
Gable.Fill = Brushes.SaddleBrown;
Gable.IsPathClosed = true;
Gable.IsSectionClosed = true;
Objects.Add(Gable);
However, this is obviously not the right solution. The triangle is open on both ends and you can see right through it. At first, I thought of adding end caps to the extrusion but my sense is that I really need a geometry mesh. Also, as I move from a simple
Gable to a more complex Hip Roof, the ExtrudedVisual is clearly wrong. So if someone could help with a geometry mesh, I would be grateful. Here are the points for a simple Hip roof. An earlier post in this forum shows how to add a 2D mesh, but I still don't
have a clue for the syntax for a 3D mesh in Helix. A Hip Roof has four slopes, If I don't use Helix toolkit, I can divide the roof up into 6 Triangles and determine indices, and calculate normal. What I need help with is: How do I use Helix tools to achieve
the same results? All I need is the code that would precede the line below.Objects.Add(Roof1);
The first four points are the perimeter - - - and the final two points represent the two points in the middle of a hip roof.
Pt0=(0,0,0)
Pt1=(0,35,0)
Pt2=(35,25,0)
Pt3=(0,25,0)
Pt4=(5,12.5,5)
Pt5=(5,22.5,5)
Thank you
SharpDX - high GPU usage
glgweeke wrote at 2014-06-11 12:41:
why is the GPU usage so high, when I start the ImageViewDemo or other examples with SharpDX.
I use the processexplorer detect this.
(IDLE > 20%, Rotating > 50 %)
A "normal" DirectX-Application (no SharpDx) uses on my System < 5% GPU.
Is this usual for applications using SharpDX?
No opacity after importing 3ds file
mmmmmm wrote at 2012-11-04 17:24:
Hi,
have some problems after importing transparent 3ds files, transparent objects didn't show transparency. Didn't found an entry for opacity within the studio importer. Are there some sub defines for edit_material something like MAT_OPACITY missing?
Would be thankful for response
mm
mmmmmm wrote at 2012-11-06 08:37:
Hi,
solve it as a first step, but there is still a problem with the correct opacity value (double), hope I can solve it later:
// add to enum ChunkID // below sub defines of EDIT_MATERIAL MAT_TRANSPARENCY = 0xA050, //add to function ReadMaterial case ChunkID.MAT_TRANSPARENCY: bytes = this.ReadData(reader, size - 6); if (BitConverter.IsLittleEndian) bytes = ReverseBytes(bytes); opacity = BitConverter.ToDouble(bytes, 0); break; //change in function ReadMaterial (add opacity to brushes) if (texture != null) { string ext = Path.GetExtension(texture); if (ext != null) { ext = ext.ToLower(); } // TGA not supported - convert textures to .png! if (ext == ".tga") { texture = Path.ChangeExtension(texture, ".png"); } var actualTexturePath = this.TexturePath ?? string.Empty; string path = Path.Combine(actualTexturePath, texture); if (File.Exists(path)) { var img = new BitmapImage(new Uri(path, UriKind.Relative)); var textureBrush = new ImageBrush(img) { Opacity = opacity, ViewportUnits = BrushMappingMode.Absolute, TileMode = TileMode.Tile }; mg.Children.Add(new DiffuseMaterial(textureBrush)); } else { Debug.WriteLine(string.Format("Texture not found: {0}", Path.GetFullPath(path))); mg.Children.Add(new DiffuseMaterial(new SolidColorBrush(diffuse) { Opacity = opacity })); } } else { mg.Children.Add(new DiffuseMaterial(new SolidColorBrush(diffuse) { Opacity = opacity })); } mg.Children.Add(new SpecularMaterial(new SolidColorBrush(specular) { Opacity = opacity }, specularPower) ); // add function private static byte[] ReverseBytes(byte[] inArray) { int highCtr = inArray.Length - 1; for (int ctr = 0; ctr < inArray.Length / 2; ctr++) { byte temp = inArray[ctr]; inArray[ctr] = inArray[highCtr]; inArray[highCtr] = temp; highCtr -= 1; } return inArray; }
objo wrote at 2012-11-06 19:28:
thanks for sharing the code! Do you have a small example file we can use to test? Can you create a fork with your changes?
mmmmmm wrote at 2012-11-07 07:48:
Hi objo,
thanks for responding. Yes, we (Gregor (glgweeke) and me) want to make a branch end of month with some addings: we want to check in the last release of the VRML reader, the visibility problem and a box extension to multi material box. I will add a transparency sample for 3ds.
Best regards
Manfred
Von: objo [email removed]
Gesendet: Dienstag, 6. November 2012 20:29
An: mm@mm-ing.de
Betreff: Re: No opacity after importing 3ds file [helixToolkit:401840]
From: objo
thanks for sharing the code! Do you have a small example file we can use to test? Can you create a fork with your changes?
musicxpg wrote at 2013-02-25 14:33:
I tried the newest version, the same problem occurs.
Can anybody tell me which file should be modified to introduce mmmmmm's contribution? Thank you!
mmmmmm wrote at 2013-02-25 15:48:
Values were taken from Blender, but Meshlap seems to have better values. If you have some time, please search in Meshlap for opacity part and copy it into the StudioReader.
How to bind How to bind that Visual3DCollection to an ObservableCollection?
BogusException wrote at 2014-08-25 04:37:
Q: How to bind that Visual3DCollection to an ObservableCollection?
How can I use an ObservableCollection as my collection of <Object>.Children ?
I mean, instead of always using someCube.Children.Add(<someObject>), why can't I, or how can I, simply bind (like everything else in WPF) a collection to the Visual3DCollection (or whatever other mechanism exists), and manipulate the ObservableCollection?
We do this with other WPF objects, and since I'm having a hell of a time with my app crashing constantly, I'm hoping there is a way to simplify all of this...
Your thoughts?
(the issue worsded a different way below)
Using Helix toolkit, but might apply to generic WPF. How can I use an observablecollection to manage objects as children of a WPF object?An object like Helixtoolkit.wpf.cubevisual3d can have:
theCube.children.add()
The visual3d object, and it's children, do not have an ItemsSource() property to bind to like datagrids do. Even if the updating of the visual3d object (the one with the children) has to be done manually (not via ObsColl itemchanged, etc. events), managing all the children in a collection seems easiest.
Since i only know how to use ObsColl's like this, is there an equivelent, or viable workaround, for a Visual3d/model3d object (whether or not Helix, but helix is very convenient)?
everytimer wrote at 2014-08-25 20:58:
But I think that binding collections is not allowed at this moment in Helix...
objo wrote at 2014-08-25 22:04:
Children
property is readonly: http://msdn.microsoft.com/en-us/library/system.windows.media.media3d.modelvisual3d.children(v=vs.110).aspx
But you can probably do this with an attached dependency property or derive a class and create an
ItemsSource
property where you synchronize the changes to the collection with the
Children
collection... See also the
Source\Examples\WPF\ExampleBrowser\Examples\DataTemplate
for some ideas on templating 3D content!BogusException wrote at 2014-08-25 22:35:
If the Children property is read-only, then why can I do:
SomeObject.Children.Add(someOtherObject) ?
Isn't Children a collection?
objo wrote at 2014-08-25 23:20:
Children
to your observable collection as we do with
ItemsSource
on other WPF elements (based on ItemsControl). ps. Posting the question on stack overflow may be worth a try for general questions like this! :-)
BogusException wrote at 2014-08-26 02:19:
Got no takers (none) on SO. What is acceptable, though, is to maintain a collection, then completely replace the existing one via code (versus elaborate events, as is typical in OCs..
What I mean is, I can easily create & maintain my collection of objects in code (I am stuck for 2 weeks now at this stage, so this is not pointless theory discussion), and then as my code sees fit (after a significant change, timer, etc. the code would REPLACE the existing Children() collection.
It isn't binding, I don't think (since binding isn't apparently possible-which is an even stranger situation/restriction), but more like in one frame it displays CollectionA, and the next frame it shows CollectionB. Right now, even writing on the UI thread, I am crashing my app after about 4 seconds of running. And by crashing, I mean the app leaves no log trace of what it does, and goes back to app.run with that idiotic "incorrect number of parameters', which nobody knows anything about or understands.
I need to add a few to hundreds of children to an object, and manage them (they fade over time, then go away after they are transparent. I know WPF doesn't like collections being changed by non-UI threads, but I can't see any of that happening. I'm desperate at this point, which is why I am at the point we're at now.
I will be testing how this works out, but until then if anyone has any input, it would be great.
I can't continue (been stuck ~17 days now) until I get past this, and I don't want to get rid of Helix and do it 'bare bones'. My app is a simple WPF project, I should be able to do this with high level tools.
BogusException wrote at 2014-08-26 02:31:
SomeSphere as SphereVisual3D has children:
SomeSphere.Children.Add()
SomeSphere.Content being System.Windows.Media.Media3D.Model3D:
SomeSphere.Content.*, which includes .Traverse() and .Transform()...
Any of this give anyone any ideas?
:)
Helixtoolkit BoxVisual3D
Irfan_Maulana wrote at 2014-01-07 14:37:
I have tried to create some cubes with height=21cube width = 21 cube and length 21 cube, but the result is not quite good
because when I navigate the cubes, the motion of the cubes is so lag, (the code is shown below).
public MainWindow()
{
InitializeComponent();
// Upper
for (double i = -10; i <= 12; i = i + 1.1)
{
for (double j = -10; j <= 12; j = j + 1.1)
{
BoxVisual3D box = new BoxVisual3D() { Center = new Point3D() { X = i, Y = j, Z = 12 }, Fill = Brushes.DarkKhaki };
view3DHelix.Children.Add(box);
}
}
//Bottom
for (double i = -10; i <= 12; i = i + 1.1)
{
for (double j = -10; j <= 12; j = j + 1.1)
{
BoxVisual3D box = new BoxVisual3D() { Center = new Point3D() { X = i, Y = j, Z = -10 }, Fill = Brushes.DarkKhaki };
view3DHelix.Children.Add(box);
}
}
//Right
for (double i = -10; i <= 12; i = i + 1.1)
{
for (double k = -8.9; k <= 12; k = k + 1.1)
{
BoxVisual3D box = new BoxVisual3D() { Center = new Point3D() { X = i, Y = 12, Z = k }, Fill = Brushes.DarkKhaki };
view3DHelix.Children.Add(box);
}
}
//Left
for (double i = -10; i <= 12; i = i + 1.1)
{
for (double k = -8.9; k <= 10.9; k = k + 1.1)
{
BoxVisual3D box = new BoxVisual3D() { Center = new Point3D() { X = i, Y = -10, Z = k }, Fill = Brushes.DarkKhaki };
view3DHelix.Children.Add(box);
}
}
//Front
for (double j = -8.9; j <= 10.9; j = j + 1.1)
{
for (double k = -8.9; k <= 12; k = k + 1.1)
{
BoxVisual3D box = new BoxVisual3D() { Center = new Point3D() { X = 12, Y = j, Z = k }, Fill = Brushes.DarkKhaki };
view3DHelix.Children.Add(box);
}
}
//Behind
for (double j = -8.9; j <= 10.9; j = j + 1.1)
{
for (double k = -8.9; k <= 12; k = k + 1.1)
{
BoxVisual3D box = new BoxVisual3D() { Center = new Point3D() { X = -10, Y = j, Z = k }, Fill = Brushes.DarkKhaki };
view3DHelix.Children.Add(box);
}
}
}
anyone have any idea for a better result?objo wrote at 2014-01-07 22:51:
GeometryModel3D
. Use the HelixToolkit.Wpf.MeshBuilder
to create a
MeshGeometry3D
of the cubes. You can then group all the models in a
Model3DGroup
and add it to a ModelVisual3D
. I also recommend reading
http://msdn.microsoft.com/en-us/library/bb613553(v=vs.110).aspx
http://blogs.msdn.com/b/johngossman/archive/2005/10/13/480748.aspx
AnotherBor wrote at 2014-01-10 07:51:
What if I add cubes (by add rectangular mesh or other method) to one MeshBuilder, add a linear gradient brush based material to the model and assign texture coordinates to every single cube in a way to apply the color I need?
It all would then count as one mesh, but "separate" cubes could have different colors.
I wonder if that would work?
objo wrote at 2014-01-10 09:03:
AnotherBor wrote at 2014-01-10 09:15:
Then we would have calls like
MeshBuilder.AddTube( {point1, point2}, width, segments, cap, uniformTextureCoordForTheWholeTubeMesh)
, what do you think?objo wrote at 2014-01-10 09:38:
AnotherBor wrote at 2014-01-10 09:54:
SharpDX fork no BackMaterial property in MeshGeometryModel3D
Lolipedobear wrote at 2014-03-05 14:27:
geoarsal wrote at 2014-03-12 18:49:
var copytri = new int[mb.TriangleIndices.Count];
mb.TriangleIndices.CopyTo(copytri);
Array.Reverse(copytri);
var copynorm = new Vector3[mb.Normals.Count];
for (int i = 0; i < copynorm.Length; i++)
copynorm[i] = -1 * mb.Normals[i];
mb.Append(mb.Positions.ToArray(), copytri, copynorm, mb.TextureCoordinates.ToArray());
Lolipedobear wrote at 2014-03-14 06:23:
geoarsal wrote at 2014-03-14 08:07:
var copynorm = new Vector3[mb.Normals.Count];
for (int i = 0; i < copynorm.Length; i++)
{
mb.Normals[i] *= -1;
copynorm[i] = -1 * mb.Normals[i];
}
Hope that will help you with your issue. P.S. Reversing the original normal was required when your building triangles using Right Hand Rule (WPF approach) instead of using Left Hand Rule (DirectX/SharpDX approach)
Demo Of a 3D Editor Using Helix Tookit + Augmented Reality
Raathigesh wrote at 2013-04-18 14:41:
I'm Raathigeshan Kugarajan following a Software Engineering (BEng) degree program conducted by Informatics Institute of Technology affiliated with University of Westminster, UK.
I am currently in the progress of evaluating a tool targeting desktop devices which helps novice users to create 3D visuals and present them using marker-less augmented reality.
Your feedback and comments on this research will help to improve it further.
Video Demonstration Of the Prototype - http://www.youtube.com/watch?v=TH5LD4FMK68
Feedback Form - http://edu.surveygizmo.com/s3/1220975/User-Evaluation
objo wrote at 2013-04-18 15:01:
Is the application also available for testing?
ps. The earth texture seems to be flipped!
Raathigesh wrote at 2013-04-18 20:39:
Best Regards,
Raathigeshan.
detp wrote at 2013-12-12 19:56:
How is the project going? Nice user interface, did you base it on something currently in the market?
Is it ready for testing?
Regards
Import Model From FileStream or Stream... [Solved]
ysinotelodigo wrote at 2012-05-01 03:11:
Hey,
I want to load or import model from stream in C#... I have played with this library and I did it.
<helix:HelixViewport3D Background="AliceBlue" ShowViewCube="False" Name="Pantallazo"> <helix:DefaultLights/> <helix:FileModelVisual3D Source="Ferarri40.3ds" > <helix:FileModelVisual3D.Transform> <ScaleTransform3D ScaleY="0.01" ScaleX="0.01" ScaleZ="0.01"/> </helix:FileModelVisual3D.Transform> </helix:FileModelVisual3D> </helix:HelixViewport3D>
FileModelVisual3D a = new FileModelVisual3D(); a.Source = "Ferarri40.3ds"; ScaleTransform3D b = new ScaleTransform3D(0.05, 0.05, 0.05); a.Transform = b; Pantallazo.Children.Add(a); //Pantallazo is the name of HelixViewPort3D
But I need read the 3ds from stream because the model will come from DataBase I did it...
But I don't know how I go on...
FileStream c = new FileStream("Ferarri40.3ds", FileMode.Open, FileAccess.Read, FileShare.Read); FileModelVisual3D d = new FileModelVisual3D(); d.Source = ¿¿?? //HELP!! Pantallazo.Children.Add(d);
This library is nice!
objo wrote at 2012-05-02 21:08:
The FileModelVisual3D cannot be bound to a stream.
Create a "StudioReader" instance, and use the Read(Stream) method. The result is a Model3D you can bind to the Content of a ModelVisual3D!
http://msdn.microsoft.com/en-us/library/system.windows.media.media3d.modelvisual3d.content.aspx
ysinotelodigo wrote at 2012-05-06 19:01:
Hello,
Thank you, very much for your answer. But I have several questions, I'm sorry for I am new and I don't speak english well.
My final objective is that my application can put and remove 3d model. This model will be in 3ds or obj format. (Perphaps en 3ds because it has a texture). So that I decided add and remove children...
I understand that I have create a "StudioReader" class with a method called Read(stream) for example. And the result will be a System.Windows.Media.Media3D.Model3D But, How could I transform this stream (in 3ds) to Model3D?
Thank you!
objo wrote at 2012-05-07 17:57:
Yes, you have to create an instance of the StudioReader class, and use the read method.
If your 3d viewport contains the following element (defined in xaml)
<ModelVisual3D Content="{Binding MyModel}"/>
you can import your stream by
var reader = new StudioReader(); this.MyModel = reader.Read(myStream);
this requires the MyModel property to be defined in your data context (ViewModel)
public Model3D MyModel { get; set; }
Your data context (ViewModel) should also implement INotifyPropertyChanged, then you can simply write
this.MyModel = null;
to remove the model again.
http://msdn.microsoft.com/en-us/library/system.windows.media.media3d.modelvisual3d.aspx
http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx
objo wrote at 2012-05-07 17:58:
Note that if you want to use textures, the StudioReader only supports reading these from files at the moment - not from streams...
ysinotelodigo wrote at 2012-05-16 00:36:
Sorry to disturb again.
I tried to follow your instrutions but I don't know how i go on...
I created this .xaml
<Window x:Class="WpfApplication7.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication7" Title="MainWindow" Height="350" Width="525"> <Window.DataContext> <local:MainWindowViewModel/> </Window.DataContext> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Label Content="{Binding Texto}"/> <Viewport3D Name="myViewport" Grid.Row="1"> <Viewport3D.Camera> <PerspectiveCamera Position="0,0,500" /> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFffFFF" Direction="-3,-4,-5" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D Content="{Binding MyModel}"/> </Viewport3D> </Grid> </Window>
And this ViewModel:
using System.Text; using System.Windows.Media.Media3D; using HelixToolkit; using System.IO; namespace WpfApplication7 { class MainWindowViewModel { public MainWindowViewModel() { Texto = "Prueba"; var reader = new StudioReader(); // This works well. //MyModel = reader.Read("Ferarri40.3ds"); // But, I need that (Stream come from DataBase) // Why does it work? Stream myStream = new FileStream("Ferarri40.3ds", FileMode.Open, FileAccess.Read, FileShare.Read); MyModel = reader.Read(myStream); } public String Texto { set; get; } public Model3D MyModel { get; set; } } }
I don´t know why it doesn't work?
I want to add that my application has to add and remove several model... I''ve been learned MVVM... if you could say the steps, I would appreciate it.
Thank you very much
objo wrote at 2012-05-31 22:35:
I see, the reader didn't know where to look for the textures and was throwing an exception since TexturePath was null. Add the following line
reader.TexturePath = @"directoryofyour3dsmodel";
I am checking in a fix!
ysinotelodigo wrote at 2012-06-01 11:07:
Thank you, very much!
Your indications have been userful.
Here, I have copied my code for other persons....
MainWindows.xaml
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:helix="clr-namespace:HelixToolkit;assembly=HelixToolkit" xmlns:local="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"> <Window.DataContext> <local:MainWindowViewModel/> </Window.DataContext> <Grid> <helix:HelixViewport3D Background="AliceBlue" ShowViewCube="False" Name="Pantallazo"> <helix:DefaultLights/> <ModelVisual3D Content="{Binding MyModel}"> <ModelVisual3D.Transform> <ScaleTransform3D ScaleY="0.05" ScaleX="0.05" ScaleZ="0.05"/> </ModelVisual3D.Transform> </ModelVisual3D> </helix:HelixViewport3D> </Grid> </Window>
MainWindowViewModel.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using PFG; using System.Windows.Media.Media3D; using System.IO; using HelixToolkit; namespace WpfApplication1 { public class MainWindowViewModel : BaseINPC { public MainWindowViewModel() { FileStream c = new FileStream("Ferarri40.3ds", FileMode.Open, FileAccess.Read, FileShare.Read); var reader = new StudioReader(); reader.TexturePath = "."; MyModel = reader.Read(c); } private Model3D mymodel; public Model3D MyModel { get { return mymodel; } set { mymodel = value; OnPropertyChanged("MyModel"); } } } }
Sorry to be disturb.
Importing Mesh & Calculating Normals
alexalthauser wrote at 2012-04-07 02:36:
I am loading a model with borrowed code from the Helix Modelviewer example. The imported 3D model is called _currentModel. How would I go about getting the normals from the vertices in this new model?
Thanks,
-Alex
objo wrote at 2012-04-08 01:13:
you have to traverse the Model3D hierarchy and find all GeometryModel3D objects. Then read the Normals property from the MeshGeometry3D objects referenced in the Geometry properties. See the HelixToolkit.Wpf.Visual3DHelper.Traverse methods, this should make it very easy to traverse the model.
alexalthauser wrote at 2012-04-12 01:57:
I'm trying to use the traverse method, but I'm not sure how it works. I tried:
Visual3DHelper.Traverse<T>(model3d);
with no success. is there a tutorial somewhere?
So far I have the importer working like a charm, but I need to get to the vertex, triangle indexes, and normal information. It's strange that such useful data wouldn't be readily accessible from an imported model. I suppose there's a good reason for it?
alexalthauser wrote at 2012-04-12 21:12:
I came across this code while searching the web, it seems to do the trick.
GeometryModel3D gm3d = ModelVisualObjects.Content as GeometryModel3D;
MeshGeometry3D mesh = gm3d.Geometry as MeshGeometry3D;
objo wrote at 2012-04-14 00:05:
Right, you'll get the mesh as you show in the last posting.
You need to pass an Action<GeometryModel3D,Transform3D> to the Traverse methods, the following example should show how you could access the Positions collection of all meshes in the model:
int countVertices = 0; Visual3DHelper.TraverseModel<GeometryModel3D>(yourModel, (geometryModel,transform) => { var mesh = (MeshGeometry3D)geometryModel.Geometry; countVertices += mesh.Positions.Count; });
alexalthauser wrote at 2012-04-14 00:31:
I spoke too soon. Actually,
GeometryModel3D gm3d = ModelVisualObjects.Content as GeometryModel3D;
MeshGeometry3D mesh = gm3d.Geometry as MeshGeometry3D;
returns null.
// Open document string filename = dlg.FileName; // Load 3DModel CurrentModel = ModelImporter.Load(filename); //loads as a modelgroupobject modelgroupobjects.Children.Add(CurrentModel); ModelVisualObjects.Content = modelgroupobjects; GeometryModel3D gm3d = ModelVisualObjects.Content as GeometryModel3D; MeshGeometry3D mesh = gm3d.Geometry as MeshGeometry3D;
and I tried the code you posted
int countVertices = 0; Visual3DHelper.TraverseModel(CurrentModel, (geometryModel, transform) => { var mesh = geometryModel.Content as GeometryModel3D; countVertices += mesh.Positions.Count; });
and I get an error underlying Visual3DHelper.TraverseModel that states: Error 2 The type arguments for method 'HelixToolkit.Visual3DHelper.TraverseModel (System.Windows.Media.Media3D.Model3D, System.Action)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
I appreciate your help.
objo wrote at 2012-04-14 00:49:
Sorry for the bugs in the example (I corrected the code).
Here is a unit test that works:
[Test] public void Load_Test_ValidNumberOfVertices() { var model = ModelImporter.Load(@"Models\obj\test.obj"); int countVertices = 0; Visual3DHelper.TraverseModel<GeometryModel3D>( model, (geometryModel, transform) => { var mesh = (MeshGeometry3D)geometryModel.Geometry; countVertices += mesh.Positions.Count; }); Assert.AreEqual(8, countVertices); }
alexalthauser wrote at 2012-04-14 01:13:
Works Great, Thanks!
( o )o) ( o )o )o) (o( ~~~~~~~~~o ( )' ~~~~~~~~' ( )|) |-. o| |-. \ o| | \ \ | | o| | / / | |." " | |- ' .=========.
Customer support service by UserEcho