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

CameraController not defined

Anonymous 10 years ago 0
This discussion was imported from CodePlex

ppcomma wrote at 2011-12-21 21:07:

Hi!

Hi! I need to add HelixView3D on my form in the code. so, run-time error:: "cameracontroller not defined". What should I do?


objo wrote at 2011-12-21 21:44:

Are you using an old version? The control has been renamed to HelixViewport3D.

Are you calling any methods on the control before the control template has been applied? (the camera controller is undefined until the template is applied).

In what part of the code are you adding the control?

Is it possible to create the control in the view XAML? See the examples.


ppcomma wrote at 2011-12-21 22:13:

this is my code.. i have to add HVP3D dynamically..

string
[] AllFiles = Directory.GetFiles(@"C:\Users\..", "*.3ds"); HelixViewport3D[] hel_ar = new HelixViewport3D[AllFiles.Count()]; for (int i = 0; i < AllFiles.Count(); i++) { hel_ar[i] = new HelixViewport3D(); PerspectiveCamera myPCamera = new PerspectiveCamera(); myPCamera.Position = new Point3D(10000, 0, 0); myPCamera.LookDirection = new Vector3D(-1, 0, 0); myPCamera.FieldOfView = 60; hel_ar[i].Viewport.Camera = myPCamera; DirectionalLight myDirectionalLight = new DirectionalLight(); myDirectionalLight.Color = Colors.White; myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61); hel_ar[i].Viewport.Height = 115; hel_ar[i].Viewport.Width = 115; Model3DGroup m3d = new Model3DGroup(); m3d = ModelImporter.Load(AllFiles[i]); m3d.Children.Add(myDirectionalLight); ModelVisual3D m = new ModelVisual3D(); m.Content = m3d; hel_ar[i].Viewport.Children.Add(m); stackPanel1.Children.Add(hel_ar[i]); }


ppcomma wrote at 2011-12-21 22:22:

Thanks, i did it


ppcomma wrote at 2012-01-28 15:52:

One more question..

I create HelixViewport3D in C# code and import 3ds model. When i run project, HelixViewport does not show anything until doubleMMB.

What should i do to fix it? i want helixviewport to show my model at once.


objo wrote at 2012-01-29 09:20:

It seems like your camera position/look direction is wrong. Try to use the ZoomExtents or ResetCamera method in HelixViewport3D after importing the 3ds model.

There is currently not a "ModelLoaded" event on the FileModelVisual3D, I think that is something that should be added.

0

Multiline Closed Path Polygons

Michael Powell 10 years ago updated by ไอยดา สุรีวงค์ 4 years ago 1
Hello,

Please pardon my clumsy use of verbiage here...

I will probably default to the RectangleVisual3D, initially, but I'd like to know whether there is something like a closed-path LinesVisual3D. Could work its way out in 3D, in my case it would be along a 2D plane.

Basically I'd like to render things like triangles, trapezoids, etc. Then be able to potentially specify things like line issues (i.e. brush), and fill.

Thank you...
0

Help needed rendering Kinect data with HelixToolkit.Wpf.SharpDX

Anonymous 10 years ago 0
This discussion was imported from CodePlex

Ehee wrote at 2014-05-27 18:09:

I am trying to build a working example program to render Kinect data using the Helix SharpDX API and I need the correct steps for continually rendering a changing model. I have the old Kinect example from the WPF API working and I can generate a 3D model from the Kinect however all of the SharpDX examples use static models that are created in the MainViewModel constructors prior to rendering. Could someone provide the most efficient steps to continually rendering a changing model using the Helix SharpDX API?
0

When does Viewport3D.CameraController gets initialized?

Anonymous 10 years ago 0
This discussion was imported from CodePlex

mplisov wrote at 2013-03-11 22:04:

Greetings,

Thanks for your great toolkit.

Please explain a little bit when does CameraController get initialized? It seems to be null on Viewport3D creation and I need to set some properties to it when programmatically creating Viewport3d.

Best regards,
Mikhail

objo wrote at 2013-04-15 13:01:

For HelixViewport3D the CameraController is defined in the control template. You can get the reference after the OnApplyTemplate method has been called.
Can the DefaultCamera property help in your case?
0

How to set camera in helixviewport3d

Anonymous 10 years ago 0
This discussion was imported from CodePlex

charismatubagus wrote at 2013-01-25 08:19:

I am newbie in helixtoolkit,

I wanna know how I can control Camera to view only R/L/U/D at the beginning. How can I do it in XAML?

 

Thanks


objo wrote at 2013-02-07 21:08:

The HelixViewport3D control has "Camera" and "DefaultCamera" properties.

See examples in
Source\Examples\ExampleBrowser\Examples\SurfacePlot\MainWindow.xaml
and
Source\Examples\ExampleBrowser\Examples\CameraControl\MainWindow.xaml

The DefaultCamera property sets the camera properties used when resetting the view.
0

strange behavior when i put two RectangleVisual3D nearly

Anonymous 10 years ago 0
This discussion was imported from CodePlex

qjt wrote at 2014-03-05 03:14:

Hi,when i am using your toolkit.A strange thing occurred. i put two RectangleVisual3D of different color (one of them is RED ,the other is BLUE) closely, one RectangleVisual3d looked like dissolve into another RectangleVisual3d just like the picture below:

the code:
 <t:RectangleVisual3D Length="100" Width="100" Origin="0,0,1" Fill="#FFF50404" >
            </t:RectangleVisual3D>
            <t:RectangleVisual3D Length="100" Width="100" Origin="0,0,1.0001" Fill="#FF0611FB">
            </t:RectangleVisual3D>

qjt wrote at 2014-03-05 03:17:

another picture:


Lolipedobear wrote at 2014-03-05 11:53:

Did you set NearPlaneDistance in Camera? Had the same problem when NearPlaneDistance was 0.

qjt wrote at 2014-03-06 03:40:

Thank you for your help,but it can't solve the problem.The code:
 this.Position = camera.Position;
            this.LookDirection = camera.LookDirection;
            this.UpDirection = camera.UpDirection;
            //this.NearPlaneDistance = camera.NearPlaneDistance;
            this.NearPlaneDistance = 0;
            this.FarPlaneDistance = camera.FarPlaneDistance;

Lolipedobear wrote at 2014-03-06 06:05:

Set value different from 0. Chosen value is depends on situation - if scene is large value can be 10 or more, if it is a small scene then value can be 0.1. I set 15 to NearPlaneDistance and it resolved problem on 1500x1500 units scene. Parts of the scene closer to camera than value in NearPlaneDistance property won't be displayed. As far as i know this problem is connected with floating point rounding when renderer is trying to determine which object is closer to camera.
<PerspectiveCamera Position="0, 600, 525" LookDirection="0, -600, -525" UpDirection="0,1,0" NearPlaneDistance="15"/>
0

Getting all vertices from MeshBuilder?

Ardahan 9 years ago updated by ไอยดา สุรีวงค์ 4 years ago 3

I want to get all vertices from my MeshBuilder sample. In meshbuilder there is list of normals and positions. Are these positions defining triangle vertices . I am confused because in my cube model there is 36 triangleindices and positions and normals. Each one is 36. So are these positions represent each vertices or what? Should normal count equal triangle count because each triangle have one normal and three vertices.

0

ObjReader/MeshBuilder Issues

Anonymous 10 years ago 0
This discussion was imported from CodePlex

przem321 wrote at 2012-01-12 17:24:

Hi Mr. Objo,

well, first of all - congratulations, this lib a is very good effort. Eventually this makes WPF3D usable for more advanced projects. 

I am working on meshes and I have just switched to your lib for my new project. Thus, I play around with the ObjReader and MeshBuilder a little. Yesterday I provided you the minor fixes to the Opacity value to the ObjReader. Today I encountered further problems with importing general polygonal objects. After an investigation, I finally conclude that a couple of problems is caused by the null-default values of the MeshBuilder properties (MeshBuilder.cs, line: 198):

        public Vector3DCollection Normals
        {
            get
            {
                return this.normals ?? (this.normals = new Vector3DCollection());
            }
        }

This causes that your sanity checks in the Append(...) method may fail. In particular you check (MeshBuilder.cs, line 1818):

            if (this.normals != null && normalsToAppend == null)
            {
                throw new InvalidOperationException(SourceMeshNormalsShouldNotBeNull);
            }

 

The problem is, that if one has called the Normals property prior to this check (for what ever reason, maybe just to check if it is null) the filed normal is not null and the sanity check throws an exception here. This is not what we want I guess. Of course this also applies to other fields like positions and texcoords, though there will be hardly a mesh with a null-valued position array.

My suggested solution is to remove the null-default values from the properties - in fact I don't see a purpose for that here? I mean like that (MeshBuilder.cs, line: 198):

        public Vector3DCollection Normals
        {
            get
            {
                return this.normals;// ?? (this.normals = new Vector3DCollection());
            }
        }

This works fine with all types of meshes I have tested. But I might have caused some side-effects I am not aware of. Thus you should check it - if there is a specific reason why you set the default-values with the ?? operator than my solution might be wrong. Otherwise, I suggest to throw away the ??-defaults and to check normals, and texcoords for null in order to determine if the mesh uses them or not. This makes it all more controllable I guess, but its up to you. I will send you the MeshBuilder.cs as well as some further minor fixes in the ObjReader.cs per bug-report. 

Cheers

Przem

 

PS. I have also created half-edge based mesh data structures, so once my stuff is running properly, maybe you will be interested in replacing the (very) limited Mesh3D class. 


objo wrote at 2012-01-12 21:02:

hi Przem, you are right - the getter should simply return the this.normals field. Thank you for reviewing the code! I'll apply the patch tomorrow.

A half-edge or winged-edge mesh representation would be very interesting!! Great if you could submit an implementation and a tiny example how to use it! 


przem321 wrote at 2012-01-13 17:47:

Thanks for reply.

I have some further questions/suggestions. My first is the reason you are using the Collection<T> class for collection the Groups in the ObjReader (line 53). Wouldn't it be better to expose a IList<T> interface and allocate a List<T> internally, since the latter one is better optimized for speed than Collection<T>? Well, this is a minor issue, since ObjReader is not real-time critical.

The second issue is that members exposed by IModelReader are not very useful. While, true, it is fine to read a file and obtain a ready Model3DGroup, this does nos cover all the cases where you would like to edit the model. Furthermore, the rule of thumb is to expose as general as possible types, which than can still be typed more strongly. In the case of your lib the MeshBuilder class seems to me to be the most general one. Thus I would suggest the IModelReader  to deliver MeshBuilder or IList<MeshBuilder> results, which than can be very easily converted to whatever the user wishes. 

Third, I have a remark regarding the MeshBuilder: while this class is very good, I am afraid that it gets a little bit overcrowded. For example, I don't think that it is a proper place to implement SDS - this is a case for Mesh3D or some own class. I also think that all the factoring methods should be implemented as static methods such that they deliver distinct MeshBuilder which than can be appended to each other. Static methods make it easier to keep independence and also maintenance. Maybe it makes sense to extract some interface of the MeshBuilder? To sum up: I really like this class and I think this is the best for geometry exchange. 

Finally, I would suggest to use as general types as possible. For example the ScreenSpaceVisual3D class expects its points as a Points3DCollection, but internally it uses the collection just as a container. Therefore there is no need to use a Points3DCollection (which is only good for renderable MeshGeomerty3D objects), I would suggest to use IList<Point3D>, such that one can provide any IList of 3d points, in cases one holds the points in other containers. Otherwise one has to copy the points to a Point3DCollection which is not used anyway.

Well, these I just some thoughts. I must say that I am not a code-guru, I am more into maths and geometry, and I only code in order to get my geometry projects running (unfortunately, MATLAB is too limited for interactive 3d modeling). And I have to say again that this framework is a great effort and it is fun using it!

Cheers

Przem


objo wrote at 2012-01-13 20:17:

#1: Agree on this. I also changed in other classes that used Collection<T>. I remember having read this reply: http://stackoverflow.com/questions/271710/collectiont-versus-listt-what-should-you-use-on-your-interfaces, but I need to understand when to use Collections and Lists better..

#2: What if the imported model contains a hierarchy of meshes and transforms? And materials. Then I think the hierarchic Model3D structure is needed. The import classes could be more general (even platform independent), but it has not been the goal for the library (so far..) (I have simply used the WPF 3D classes where possible)

#3: Agree on this, the builder should only contain the simple mesh operations (no questionable/experimental algorithms...) I like to use the MeshBuilder to combine several objects using the same material into the same geometry (for performance), then I guess allocating a mesh for each object and finally appending all these meshes will cost more (should profile this). I think the MeshBuilder should work like the System.Text.StringBuilder, i.e. not as static factory methods. Good performance for large/composite meshes is the goal here.

#4: Agree, I am changing this!

Thanks for great comments! 


przem321 wrote at 2012-01-13 20:42:

Thant for reply.

#1: According to http://blogs.msdn.com/b/codeanalysis/archive/2006/04/27/585476.aspx one should use the Collection<T> if one wants to override some methods. This is usually not the case when one just wants to store the elements. 

#2: Well, on a one hand you are right. I thought a IList<MeshBuilder> might be an option. But this does not contain materials, etc. Maybe this is fine like it is. Or maybe one should use the Wavefront structure (Group,Material, etc.) in order to keep the object (for all types of inputs) after loading and than, on demand one might create the Model3DGroup. The problem I have with the current solution is that sometimes one does not want to obtain a Model3DGroup after loading. With the current solution in such a case one needs to convert the Model3DGroup back to whatever one needs. Or just to use the ObjReader directly without the IModelReader interface in order to get access to the Groups and Materials. Since the OBJ format is a well established exchange-format, why not to keep its structure internally as a "raw" model representation? Well, this is just a suggestion. But let me think a little on it, maybe I will come up with a better one is few days.

#3: I just thought each Primitive would be appended like the current Append(...) function. But you are right this would cause unnecessary overhead. Its fine like it is.

 


objo wrote at 2012-01-13 21:03:

#2: Yes, implementing the domain model of the Wavefront structure would be a good idea. Then create the WPF3D model on request.

Another issue with the obj reader is the handling of smoothing groups. It is currently flat shading everything.


przem321 wrote at 2012-01-26 19:15:

Hi,

just wanted to report a bug: in the current version of the ObjReader.cs, line 378, Polygone3D will not accept a List<Point3D> in the constructor. The project will not compile. I fixed it locally, but just wanted to let you know. 


objo wrote at 2012-01-26 19:41:

are you sure your Polygon3D.cs file is updated? There should be a constructor Polygon3D(IList<Point3D> pts) there.


bcblanka wrote at 2012-02-01 12:30:

Hi,

 

First of all great work on the Helix toolkit; we are using it in a 3D modelling application and we would have been far behind on development without this toolkit. I was recently working with importing 3D models from OBJ files (ObjReader) and I saw that the material applied on a 3D surface isn't always visible. These are my findings:

In the ObjReader.cs, GetMaterial() method where you are creating the brush for the 3D object, the opacity is set to: "Opacity = 1.0 - this.Dissolved" for both color or image brushes. This is what I read about OBJ materias:

"d factor 
Specifies the dissolve for the current material. 
factor - is the amount this material dissolves into the background. A factor of 1.0 is fully opaque. This is the default when a new material is created. A factor of 0.0 is fully dissolved (completely transparent). http://www.fileformat.info/format/material/

So when an object has a dissolve factor of 1 (fully opaque) the GetMaterial() method will create a completely transparent material for it.

My fix for this issue was setting a default value of 1 for the Dissolved property, and setting the" Opacity = this.Dissolved" for the brush. It seems to be working, but I am not too familiar with obj files so this might be wrong or breaking other functionalities of obj reader.

 

Thanks for the great toolkit!

Blanka


objo wrote at 2012-02-01 18:53:

thanks for the bug report - this was the original implementation, but it was changed in #74137. I am reverting back to the original implementation now: Opacity = dissolve value. Also setting default value to 1.0. przem321, do you agree?


przem321 wrote at 2012-02-02 19:06:

Well, in my case this is exactly the opposite. I have used models converted in Deep Exploration and all models where invisible with Opacity = Dissolved. By inverting it as mentioned above, the models were fine. But according to the specification referenced above Dissolved should refer to Opacity, thus is seems that bcblanka is right. 

I will try to figure out what is the actual problem with my models and post it here than. 


bcblanka wrote at 2012-02-03 07:26:

Hi,

The code: "Opacity = 1.0 - this.Dissolved" worked fine when the dissolve factor was not specified in the *.mtl file. Maybe that is the case for your models, przem321. However, if a dissolve value is specified in the *.mtl file, for example 1 for opaque, the opacity will be 0 (Opacity = 1.0 - this.Dissolved; Opacity = 1-1).


objo wrote at 2012-02-03 08:41:

I changed the default value for Dissolved to 1.0


przem321 wrote at 2012-02-03 15:46:

bcblanka wrote:

The code: "Opacity = 1.0 - this.Dissolved" worked fine when the dissolve factor was not specified in the *.mtl file. Maybe that is the case for your models,

This is clear. The problem was that the code: "Opacity = Dissolved" didn't worked, but it did other way, this is the reason I've changed it. It appeared that Dissolved applies to the model's transparency, but I haven't checked the spec though. 

Now, I guess there must be some other reason, like that the models are skewed up. I'll try to check this in a free moment. Thanks for clarification. 

0

Touch events

Anonymous 10 years ago 0
This discussion was imported from CodePlex

JohnSourcer wrote at 2012-12-06 14:25:

Thanks for a fantastic framework. It's changed my approach to 3D on WPF. I'm not clear on how to handled touch events. Do we need to wire them up ourselves? I see manipulation events firing if I add them to the user control containing a HelixViewport3D. Mouse manipulations work 100%.

Currently, I'm doing: 

 
 <h:HelixViewport3D RotationSensitivity="0.3" InfiniteSpin="True" x:Name="HelixViewport3D" Height="1100" IsManipulationEnabled="True" ManipulationStarted="GlobeManipulationStarted"...


protected void GlobeManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            base.OnManipulationStarted(e);
//handle manipulations
            e.Handled = true;
        }...

Is this the correct approach?


balameeta wrote at 2013-03-27 17:42:

Hi there.

Use this code for multi-touch manipulation of the scene to work:
viewPortName.CameraController.TouchMode = TouchMode.Rotating;
Amun
0

Pick a PipeVisual3D object

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

rinaldin wrote at 2013-09-27 11:05:

Hi all,
I need to delect a PipeVisual3D object in the viewport, and I followed the example "UIelement", adding a sphere and a PipeVisual3D object. Unfortunately I cannot pick the PipeVisual3D object. Why it doesn't work?
The code I used is below:
        ' selezione
        Dim container = New ContainerUIElement3D()
        Dim element = New ModelUIElement3D()
        Dim geometry = New GeometryModel3D()
        Dim meshBuilder = New MeshBuilder()
        meshBuilder.AddSphere(New Point3D(0, 0, 0), 2, 100, 50)
        'meshBuilder.AddQuad(pt, pt1, pt1, pt)
        geometry.Geometry = meshBuilder.ToMesh()
        geometry.Material = Materials.Green
        element.Model = geometry
        element.Transform = New TranslateTransform3D(5, 0, 0)

        ' genera linee in modelspace
        Dim ts2 As New PipeVisual3D
        Dim pt1 As New Point3D(10, 10, 10)
        Dim pt2 As New Point3D(20, 10, 10)
        ts2.Point1 = pt1
        ts2.Point2 = pt2
        ts2.Material = Materials.Green
        ts2.Diameter = 0.1

        AddHandler element.MouseDown, AddressOf Me.ContainerElementMouseDown
        container.Children.Add(element)
        ' add lines and points to the container
        container.Children.Add(lines)
        container.Children.Add(pts)

        container.Children.Add(ts2)

        'container.Children.Add(New AmbientLight(Colors.White))
        HelixViewport3D1.Children.Add(container)
I used the ContainerElementMouseDown sub that I found in the example, but as I said it works only for the sphere:
    Private Sub ContainerElementMouseDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        If e.LeftButton = MouseButtonState.Pressed Then
            Dim element = TryCast(sender, ModelUIElement3D)
            Dim model = TryCast(element.Model, GeometryModel3D)
            If model.Material Is Materials.Green Then
                model.Material = Materials.Yellow
            ElseIf model.Material Is Materials.Yellow Then
                model.Material = Materials.Green
            End If
            'model.Material = If(model.Material Is Materials.Green, Materials.Gray, Materials.Green)
            e.Handled = True
        End If
    End Sub
I supposed that I cannot use the LinesVisual3D because they are in the in the screen space; I though I have to use something that is in the model space. Is it right?

Thanks,
Giovanni

objo wrote at 2013-09-29 09:27:

Right, the LinesVisual3D is not derived from UIElement3D and will not receive mouse events. But the lines are rendered as MeshGeometry3D in the model space and it should be possible to implement the same functionality in a 3D UI element!

rinaldin wrote at 2013-09-29 12:32:

Thank you for your answer. I can always use PipeVisual3D instead of LinesVisual3D.
As far I've understood, PipeVisual3D has the capability for receiving mouse events. I found how to add a Pipe in ModelUIElement3D.
But how can I use the mouse events to pick (e.g. select) a Pipe instead of another? Is there a property ti do so?

Giovanni

rinaldin wrote at 2013-09-29 17:05:

I used as many container as element, so any object ban be selected alone. Is it the best way?

Furthermore, is it another command that allows picking objects by drawing an imaginary box that intersecates one or more elements? Such as Autocad...

Thanks,
Giovanni

rinaldin wrote at 2013-10-01 15:02:

Anyone has the same problem?

a5r wrote at 2013-10-01 17:35:

The pipevisual is never connected to the 'element' object. The 'element' object triggers the ContainerElementMouseDown event in this case.
If you change it like this it will trigger the event:
        PipeVisual3D pipe = new PipeVisual3D();
        pipe.Point1 = new Point3D(10, 10, 10);
        pipe.Point2 = new Point3D(20, 10, 10);
        pipe.Material = Materials.Green;
        pipe.Diameter = 0.1;
        var element2 = new ModelUIElement3D();
        element2.Model = pipe.Model;
        element2.MouseDown += this.ContainerElementMouseDown;
        container.Children.Add(element2);

rinaldin wrote at 2013-10-03 21:50:

Thanks for your reply, I've solved in VB.net as follow:
Dim pipe As New PipeVisual3D()
pipe.Point1 = New Point3D(10, 10, 10)
pipe.Point2 = New Point3D(20, 10, 10)
pipe.Material = Materials.Green
pipe.Diameter = 0.1
Dim element2 = New ModelUIElement3D()
element2.Model = pipe.Model
AddHandler element2.MouseDown, AddressOf Me.ContainerElementMouseDown
container.Children.Add(element2)
anyway, now I just need to have the box selection instead of single click-on-object selection. Any idea?

AQSRanck wrote at 2014-06-28 17:18:

Hi rinaldin,
I also work in VB and while this response is for an old post I have a few ideas that may be applicable to your needs.

objo sent the following reply to my post "How to draw a funnel"

See the usage of MeshBuilder.AddSurfaceOfRevolution in the example Source\Examples\WPF\ExampleBrowser\Examples\BuildingDemo\SiloVisual3D.cs, I think a similar approach can be used to model a funnel.

After a lot of experimenting I was finally able to open the BuildingDemo project albeit in C#. I noticed (for the first time) that when you click on a silo/tank in the viewport, a property page appeared on the right side of the screen, and, more interestingly, if you clicked on a chimney a different property page appeared. But the cool thing is that a change in the property actually changes the visual! There are two chimneys in the illustration, but only one visual redraws with the new parameters! So there is a lot in this demo that may be useful to you.

I have converted the parts I needed to VB and have more complex visual mouse click selections already working in my own project.

In fact, I have a property page live modification of an object working in a VB project with exactly two lines of code and no code behind in the view. To accomplish this you need 3 things:
  1. You need to be using Caliburn Micro (It is absolutely the best for MVVM applications) If you don't have it you can get it here.
  2. You need to grab the PropertyGrid at this web site
  3. Selecting an item and dispaying its propertys in an interactive propertygrid has a lot to do with your projects organization. I was successful because I used the same design concepts that are illustrated in the SiloVisual3D.vb class
While this is a late response, I hope it may help in your work,

Bob Ranck