This is the discussion forum for Helix Toolkit.
For bugs and new features, use the issue tracker located at GitHub.
Also try the chat room!
0

using Caliburn MVVM

Anonymous 10 years ago 0
This discussion was imported from CodePlex

AQSRanck wrote at 2014-03-17 15:09:

Hi, I am just getting started with Helix - it looks great! I already use Caliburn Micro.

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:

OK I found the answer myself to the easy part - All I need now is to understand how to add the triangular object on top of the box, The code to add the box itself is, shown below.
(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:

I was able to add a triangular roof module to the top of my housebox with the ExtrudedVisual3D.
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
0

SharpDX - high GPU usage

Anonymous 10 years ago 0
This discussion was imported from CodePlex

glgweeke wrote at 2014-06-11 12:41:

Hi,

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?
0

HelixToolkit.Wpf.SharpDX - alpha backfaces

Anonymous 10 years ago 0
This discussion was imported from CodePlex

eonxxx wrote at 2014-08-14 12:13:

Diffuse objects with alpha value lower than 1.0 seems to show their backfaces, so p.e. a pipe-object does it.

is there a way to avoid/ switch off the backfaces?
0

No opacity after importing 3ds file

Anonymous 10 years ago 0
This discussion was imported from CodePlex

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:

Is this problem solved in the newest version?

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:

Still not solved completely. The file I had changed: StudioReader.cs in folder Importers.
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.
0

How to bind How to bind that Visual3DCollection to an ObservableCollection?

Anonymous 10 years ago 0
This discussion was imported from CodePlex

BogusException wrote at 2014-08-25 04:37:

HelixToolkit.wpf.SphereVisual3D ->has a-> System.Windows.Media.Media3D.Visual3DCollection
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:

This is interesting, and I would like to know it too.

But I think that binding collections is not allowed at this moment in Helix...

objo wrote at 2014-08-25 22:04:

The 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:

@objo

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:

The property is read-only, so you cannot bind 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:

@objo,
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:

Also, does anyone know how I can use the Content attribute in this scenario?

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?

:)
0

Helixtoolkit BoxVisual3D

Anonymous 10 years ago updated by anonymous 5 years ago 0
This discussion was imported from CodePlex

Irfan_Maulana wrote at 2014-01-07 14:37:

hi everyone i want to create cubes that represented as point3D(x,y,z) and the value is represented as color..
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:

You can improve performance by grouping all cubes that share the same material in a 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:

Something just came to my mind.
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:

Yes, this works and I think performance should be much better. I have not tested if there is a performance hit related to assigning texture coordinates or not and gradient brush vs. solid color brush - that would be interesting to know!

AnotherBor wrote at 2014-01-10 09:15:

If it really works nice, maybe adding single texture coordinate to all convenience calls as optional parameter would be a nice way to assign different colors to elements belonging to the same mesh?

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:

Yes, I think this is a good idea. Can you add an issue on this?

AnotherBor wrote at 2014-01-10 09:54:

Sure, will do.
0

SharpDX fork no BackMaterial property in MeshGeometryModel3D

Anonymous 10 years ago 0
This discussion was imported from CodePlex

Lolipedobear wrote at 2014-03-05 14:27:

Didn't find BackMaterial property in MeshGeometryModel3D. Back side of the polygon is black - is there any solution to apply texture to it? Tried to add additional points with inversed normals, but polygons overlap when displayed, so that color from the back side of polygon is also visible.

geoarsal wrote at 2014-03-12 18:49:

Today I face the same issue with meshbuilder and following is the code I used to create duplicate triangles. Here mb is the meshbuilder class.
            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:

Thanks for your reply. I tried to do the same thing manually. Sometimes polygons overlaps and scene glitches when i try to scale or rotate. In WPF branch i had the same problem and it was resolved by setting NearPlaneDistance in camera. Possible, I made a mistake. Did you try your solution for large scenes (1000 or more units)?

geoarsal wrote at 2014-03-14 08:07:

I had used that approach to render mesh surface consisiting of more than 200,000 triangles, and I haven't faced the overplap issue. However for some cases, i have to reverse the original normals prior to creating their copy, may be thats the issue your facing. Also, i had set NearPlaneDistance to 0.5 and FarPlaneDistance to 10000.
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)
0

Demo Of a 3D Editor Using Helix Tookit + Augmented Reality

Anonymous 10 years ago 0
This discussion was imported from CodePlex

Raathigesh wrote at 2013-04-18 14:41:

Hi Everyone,
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:

Great demo! It's exciting to see that you based it on the helix toolkit. Nice user interface!
Is the application also available for testing?
ps. The earth texture seems to be flipped!

Raathigesh wrote at 2013-04-18 20:39:

Thank You for your feedback and the wonderful helix toolkit. Unfortunately the application is still not available for testing. I'll update you once the application is available for testing. Thank you for pointing out the texture issue. I will correct it.

Best Regards,
Raathigeshan.

detp wrote at 2013-12-12 19:56:

Hi Raathigeshan

How is the project going? Nice user interface, did you base it on something currently in the market?
Is it ready for testing?

Regards
0

Import Model From FileStream or Stream... [Solved]

Anonymous 10 years ago 0
This discussion was imported from CodePlex

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>

In code-behind is this...

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.

 

0

Importing Mesh & Calculating Normals

Anonymous 10 years ago 0
This discussion was imported from CodePlex

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|         |  / /
              |         |." "
              |         |- '
              .=========.