For bugs and new features, use the issue tracker located at GitHub.
Also try the chat room!
Adding Tubes to the Flights Demo programmatically (4 days on this is too long...)
BogusException wrote at 2014-07-18 04:06:
This is just getting to the point where it is dragging me down mentally. I hate being stuck on something long after I've 'paid my dues' (searched & tried way more than I should have to on a single issue)...
It is actually simple:
-Do what the OnMouseDown() does i the Flights Demo, but programmatically.
Private Overloads Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
Dim ftv = New ConnectionVisual3D(Me, ConnectionPoints(0), ConnectionPoints(1))
ftv.MyOpacity = 1.0
view1.Children.Add(ftv)
2014-07-18 EDIT:
I neglected to show how I am calling my child WPF window (the Flight Demo). This is probably important:Private Sub mnuDisplay_DisplayEarth_click(sender As Object, e As RoutedEventArgs)
Dim wpfEarth As New TheEarthWindow(Me)
wpfEarth.Show()
Dim newWindowThread As New Thread(New ThreadStart(Sub()
Dim tempWindow As New TheEarthWindow(Me)
AddHandler tempWindow.Closed, Sub(s2, e2) Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background)
tempWindow.Show()
System.Windows.Threading.Dispatcher.Run()
End Sub))
' required for WPF:
newWindowThread.SetApartmentState(ApartmentState.STA)
' Make the thread a background thread
newWindowThread.IsBackground = True
' Start the thread
newWindowThread.Start()
Q: I tried DOZENS of ways to open up a child WPF window, and this was the best I could do. How does spawning a child WPF Window like this impact addressing and adding children in the child window (I called the Flight Demo window "TheEarthWindow" here)?TIA!
ORIGINAL POST FOLLOWS
I have the main thread watching a MSMQ, which feeds it 'connections'. Al lthis is fine. The problem comes when I go to add the 'connecction' to the 'earth', and I get either:- The dread "The calling thread cannot access this object because a different thread owns it."
- Or the less frequent "This API was accessed with arguments from the wrong context."
I have even tried creating my own ItemsControl in XAML, but I can't figure out how to code it for the tubes (no intellisense accepts it), or where in the 'tree' to place the following:
<ItemsControl ItemsSource="{Binding Flights}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Viewport3D /> <---???
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Here is how I last was configured to Private Sub AddTheConnection(sender As Object, e As EventArgs)
Try
Me.childConn.MyOpacity = 1.0
TheEarthSphere.Children.Add(childConn)
Me.Connections.Add(childConn) ' for reference so they can be removed later...
Catch ex As Exception
Dim m As String = "AddTheConnection"
log.Fatal(m & "() Exception.Message(): " & ex.Message)
log.Fatal(m & "() Exception.ToString(): " & ex.ToString)
log.Fatal(m & "() Exception.StackTrace(): " & ex.StackTrace)
End Try
End Sub
This was called any number of ways, and some attempts were without an event signature on the methods. Here is a commented summary of failures: ' this crashed App.run:
'If Not Application.Current.Dispatcher.CheckAccess() Then
' Application.Current.Dispatcher.Invoke(New MyFunctionDelegate(AddressOf AddChildToScene))
' Return ' Important to leave the culprit thread
'End If
'=========================================================================
' this:
'Me.TheEarthSphere.Children.Add(childObject)
'TheEarthSphere.Children.Add(childObject)
' yields: The calling thread cannot access this object because a different thread owns it.
'=========================================================================
' this:
'Me.Dispatcher.Invoke(Sub()
' TheEarthSphere.Children.Add(childObject)
' End Sub)
'' yields: This API was accessed with arguments from the wrong context.
'=========================================================================
' this:
' MyBase.AddChild(childObject)
' yields: The calling thread cannot access this object because a different thread owns it.
'=========================================================================
' this:
' Me.AddChild(childObject)
' yields: The calling thread cannot access this object because a different thread owns it.
'=========================================================================
' this:
'stackPanel.Dispatcher.BeginInvoke(DispatcherPriority.Normal, Sub() stackPanel.Children.Add(New TextBlock With {.Text = text})))
'TheEarthSphere.Dispatcher.BeginInvoke(Sub()
' TheEarthSphere.Children.Add(childObject)
' End Sub)
' yields: Exception has been thrown by the target of an invocation.
' from this line in Firsty: System.Windows.Threading.Dispatcher.Run()
'=========================================================================
' this:
'Me.view1.Children.Add(childObject)
' yields: The calling thread cannot access this object because a different thread owns it.
'=========================================================================
' this:
'Me.view1.Dispatcher.Invoke(Sub()
' view1.Children.Add(childObject)
' End Sub)
' yields: This API was accessed with arguments from the wrong context.
'=========================================================================
' this:
' Application.Current.Dispatcher.Invoke(New Action(Sub()
'Me.Dispatcher.Invoke(New Action(Sub()
' TheEarthSphere.Children.Add(childObject)
' End Sub))
' yields: The calling thread cannot access this object because a different thread owns it.
'=========================================================================
'Me.view1.Dispatcher.Invoke(New Action(Sub()
' 'TheEarthSphere.Children.Add(childConn)
' Me.Conns.Add(childConn)
' End Sub))
' yields: The calling thread cannot access this object because a different thread owns it.
'=========================================================================
' this:
'Me.Dispatcher.Invoke(New Action(Sub()
' Me.Conns.Add(childConn)
' End Sub))
' yields:
'=========================================================================
' an event to allow thread communication?
'RaiseEvent ConnectionAdded(Me, EventArgs.Empty)
'=========================================================================
tried view1.Children.Add(childConn) and got: The calling thread cannot access this object because a different thread owns it.Seriously, what am I going to have to do to get past this and move on?
Yours in desperation...
pat
:(
Super simple C# example
Bamboozled wrote at 2012-06-03 18:19:
Hi all,
I am trying to learn the very basics of using Helix to build an application using C#. There are some wonderful and sometimes quite spectacular examples of using XAML and C#, but I'm finding them a bit too complicated as a first example.
Frustratingly I haven't found any super simple example online. Has anyone got an example of how to build, e.g., a cube using C# and the Helix toolkit?
Many thanks,
B.
objo wrote at 2012-06-04 22:30:
yes, I agree, the "SimpleDemo" example should contain some very simple C# code too (a ViewModel), not only XAML. Will fix this soon!
objo wrote at 2012-06-04 22:48:
the "SimpleDemo" example has been changed, I hope this helps.
Bamboozled wrote at 2012-06-05 22:01:
I apologise if I'm missing something obvious, but after updating the package ..\Helix\Source\Examples\SimpleDemo\MainWindow.xaml.cs looks like this:
using System.Windows;
namespace ExampleBrowser
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
There's no C# code. Where should I be looking?
objo wrote at 2012-06-05 22:09:
It seems like you are not looking at the latest version. There should be a line
this.DataContext = new MainViewModel();
in there. Then see MainViewModel.cs for the code.
Any easy one this time! Unresponsive WPF Window (as child)
BogusException wrote at 2014-07-10 03:26:
Maybe I can get some help with this problem.
I have the Flights Demo code running fine in a WPF window-as long as that window is the "Startup URI" in my project's Properties -> Application -> Statup URI. It responds to mouse & keyboard as expected.
BUT, when I call that same class from code as a child of a parent WPF window, the child displays fine-and even animates-but is completely unresponsive to mouse & keyboard (except to close the window itself.
Now here is the weird part/hint that might tell the right person what the issue is:
When I close the child WPF window by clicking the close("x") widget, the window goes away, but I can see it still generating log entries!
Figuring on a thread-centric need, I have tried the following with no change in symptoms:
A. Just call it:
Dim wpfEarth As New vASA.TheEarthWindow
wpfEarth.Show()
B. Dispatchers:(calling function/sub):
Dim thread = New Thread(New ThreadStart(AddressOf Me.DisplayEarthOnThread))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()
[...]
Private Sub DisplayEarthOnThread()
Try
Dim wpfEarth As New vASA.TheEarthWindow
wpfEarth.Show()
AddHandler wpfEarth.Closed, Sub(s, e) wpfEarth.Dispatcher.InvokeShutdown()
System.Windows.Threading.Dispatcher.Run()
Catch ex As Exception
[...]
End Try
End Sub
C. A ton of random variations on:Dispatcher.Invoke(Sub()
Dim wpfEarth As New vASA.TheEarthWindow
wpfEarth.Show()
AddHandler wpfEarth.Closed, Sub(sender2, e2) wpfEarth.Dispatcher.InvokeShutdown()
System.Windows.Threading.Dispatcher.Run()
End Sub)
D. This is SUPPOSED to kill the child window when it closes, but doesn't (still unresponsive like the above ones):Dim newWindowThread As New Thread(New ThreadStart(Sub()
' When the window closes, shut down the dispatcher
' Start the Dispatcher Processing
Dim tempWindow As New TheEarthWindow()
AddHandler tempWindow.Closed, Sub(s2, e2) Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background)
tempWindow.Show()
System.Windows.Threading.Dispatcher.Run()
End Sub))
newWindowThread.SetApartmentState(ApartmentState.STA)
' Make the thread a background thread
newWindowThread.IsBackground = True
' Start the thread
newWindowThread.Start()
...I could really use some insight... The parent is a stock WPF Window Project, and the Child is a HelixViewport3D window...
TIA!
pat
:)
BogusException wrote at 2014-07-11 17:40:
I always tell people, and it may well be a part of Murphy's or Man Law, but if you are really stuck, just ask someone for help. The fact that you posted a request for help almost guarantees it is a stupid, silly oversight on your part.
Now, with the answer at hand, it WAS a stupid, silly thing, and one which had (relatively) little to do with Helix.
Suitably embarrassed, let's just leave it at "RTFM", shall we? :)
Thanks!
pat
:)
objo wrote at 2014-07-11 21:42:
Maybe there should be a special forum for rubber duck problem solving? :-)
Bug or feature - BillboardTextGroupVisual3D doesn't accept ObservableCollection<BillboardTextItem>
mesta wrote at 2013-11-19 12:54:
I had a project that with the latest version stopped working because of this modification, so i had to take the source and recompile them with IList.
Maybe you should consider to return to IList as Items property for the next versions ?
/// <summary>
/// Identifies the <see cref="Items"/> dependency property.
/// </summary>
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
"Items",
typeof(List<BillboardTextItem>),
typeof(BillboardTextGroupVisual3D),
new UIPropertyMetadata(null, VisualChanged));
/// <summary>
/// Gets or sets the items.
/// </summary>
/// <value>The items.</value>
public List<BillboardTextItem> Items
{
get
{
return (List<BillboardTextItem>)this.GetValue(ItemsProperty);
}
set
{
this.SetValue(ItemsProperty, value);
}
}
objo wrote at 2013-11-19 13:31:
mesta wrote at 2013-11-19 13:45:
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(IList<BillboardTextItem>), typeof(BillboardTextGroupVisual3D), new UIPropertyMetadata(null, new PropertyChangedCallback(BillboardTextGroupVisual3D.VisualChanged)));
Thank you, your library is awesome !objo wrote at 2013-11-19 18:45:
new PropertyChangedCallback(
? I think this is a redundant delegate constructor. Tested with NET 4.0 and 4.5.chadsixt wrote at 2014-04-17 18:24:
I am using the BillboardTextGroupVisual3D, defined in xaml. I have the Items bound to an ObservableCollection<BillboardTextItem>, so when I add a BillboardTextItem to the Group all is well. When I attempt to detect the user clicking on one of the BillboardTextItems, I only see the BillboardTextGroupVisual3D, and I am unable to detect which actual item it is, so I can remove it from the group. I could come up with a algorithm to find the closest Item in the group based on the HitPoint? Is there something that can help already there somewhere...?? I,d rather not have to add BillboardTextVisuals for ever Item I want to display in the viewport...
Thanks again, Love the project
Chad
objo wrote at 2014-04-29 10:20:
I added https://helixtoolkit.codeplex.com/workitem/10038
Some Suggestions/Wish List
przem321 wrote at 2012-01-26 19:32:
Hi Objo,
here are some issues I would like to mention:
- PointsVisual3D will not work if Points is set to null. While this is not a bug, I like to disable the visual without removing it from the Viewport.Childern by setting Poins=null. I know, there is the IsRendering prop, but it serves a different purpose. Would it not make sense to add a line like
if (Points == null) return;
to the
protected override void UpdateGeometry() function?
The same applies to all ScreenSpaceVisual3D classes?
- Shouldn't the MeshNormals3D class be called MeshNormalsVisual3D for sake of consistency?
- The BoundingBoxVisual3D has a hard-coded color to Yellow - well, not the perfect solution. I added a Property "Fill" to it, there one can set the color. I submit the file as a patch.
objo wrote at 2012-01-26 20:09:
thanks for reporting bugs/inconsistencies! I'm correcting all three now.
objo wrote at 2012-01-26 20:13:
I used the property name "Color" instead of "Fill" (which should be of type Brush).
objo wrote at 2012-01-26 21:13:
After one more thought I changed again to "Fill" as you suggested, to be consistent with the other objects in the library.
Controlling Camera Position
jacobya wrote at 2012-01-23 06:00:
Hi objo,
I have a question regarding controlling the camera position and the direction the camera is looking. What I'm essentially trying to do is to move the camera to a specific position (i.e. new Point3D(0, 100, 100)) and have the camera look at position 0, 0, 0. The code I am using is this:
Viewport.CameraController.CameraPosition = new Point3D
(0, 100, 100);Viewport.LookAt(new Point3D
(0, 0, 0), 1500);This doesn't seem to have the expected behavior. After I move the camera around in the Viewport and change the Rotation etc..., executing the following code seems to move the camera and then puts it back where it was before the code was executed. Any idea what I'm doing wrong? I noticed there is a LookAt overload that takes a Vector3D as the second argument, but I'm not sure what should be passed here.
Thanks,
Jason
objo wrote at 2012-01-26 20:02:
hi Jason, the LookAt method you are using should keep the LookDirection unchanged and is changing the Position of the camera. There is an overload that also takes a LookDirection as an argument:
public static void LookAt(ProjectionCamera camera, Point3D target, Vector3D newLookDirection, double animationTime)
Also note that it should be possible to write
Viewport.Camera.Position = new Point3D(0,100,100);
(not using CameraController).
Pivot Point for RotationManipulator
przem321 wrote at 2012-01-14 07:12:
Hi,
I just needed the RotatonManipulator and figured out that there is no property to provide a pivot (= center of the rotation). It might appear as it is not necessary, but the current manipulator only rotates an object around its center if the geometry is centered around the origin. If the objects geometry is shifted (i.e. the actual vertex positions are such that the object does not center around the origin) than the object does not rotate around its center, but around its actual local origin. This point can now be set with the Pivot property. Note in most cases the geometry is centered properly such that it can be left at (0,0,0). A good test case is a box with its min corner at (0,0,0) and max at (1,1,1).
I added the prop to the abstract Manipulator class and changed the rotation call (OnMouseMove in the RotationManipulator class). I also provided these props to the CombinedManipulater class. Further I added a Bind and UnBind method for easy in-code-binding, since someone was asking how does it work:
/// <summary> /// Binds this manipulator to a given Visual3D. /// </summary> /// <param name="source">Source Visual3D which receives the manipulator transforms.</param> public virtual void Bind(ModelVisual3D source) { BindingOperations.SetBinding(this, CombinedManipulator.TargetTransformProperty, new Binding("Transform") { Source = source }); BindingOperations.SetBinding(this, CombinedManipulator.TransformProperty, new Binding("Transform") { Source = source }); } /// <summary> /// Releases the binding of this manipulator. /// </summary> public virtual void UnBind() { BindingOperations.ClearBinding(this, CombinedManipulator.TargetTransformProperty); BindingOperations.ClearBinding(this, CombinedManipulator.TransformProperty); }
I will sent you the patch, maybe you want to integrate it. Cheers. P.
objo wrote at 2012-01-16 07:16:
Great! I submitted these changes. Should also add an example in the ManipulatorDemo...
Updating FOV from bound code
cobra18t wrote at 2011-12-20 17:02:
I have the field of view of a perspective camera bound to a int variable in the code behind. Right now, it will not update the field of view until I "flick" the mouse with the right mouse button. Just rotating around will not cause the update. Is there something, perhaps a function that I can call, to force the camera FOV to update automatically?
objo wrote at 2011-12-21 21:36:
Sorry, I don't understand the problem here.
Here is an example binding the FieldOfView property of a PerspectiveCamera to a Slider
<Grid> <helix:HelixViewport3D> <helix:DefaultLights/> <helix:CubeVisual3D SideLength="4" Fill="Blue"/> <helix:HelixViewport3D.Camera> <PerspectiveCamera FieldOfView="{Binding Value, ElementName=FieldOfViewSlider}"/> </helix:HelixViewport3D.Camera> </helix:HelixViewport3D> <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="8"> <Slider Name="FieldOfViewSlider" Value="45" Minimum="10" Maximum="160" Width="200"/> </StackPanel> </Grid>
cobra18t wrote at 2011-12-21 21:45:
Let me see if I can clarify...I am an idiot and forgot to raise a propertychanged event. It works just fine now.
Orthographic Camera - Undesired Clipping on Zoom In (Near Plane Issues?)
ezolotko wrote at 2013-08-02 04:28:
Thank you for the great library.
I have successfully used the orthographic camera to display my scene, but with one problem:
when I zoom in my scene by moving the mouse wheel forward, I encounter the polygons clipping like it is shown in the picture:
I tried to reduce the camera near plane distance, but with no noticeable effect. Here is my camera definition:
Camera = new OrthographicCamera
{
LookDirection = new Vector3D(-398.987, -42.626, -19.482),
UpDirection = new Vector3D(-0.049, -0.001, 0.999),
Position = new Point3D(398.987, 42.626, 19.482),
Width = 235,
};
Am I doing anything wrong?ezolotko wrote at 2013-08-05 03:03:
ezolotko wrote at 2013-08-06 04:03:
Mrme wrote at 2013-08-06 10:09:
ezolotko wrote at 2013-08-06 10:17:
ShadesJeff wrote at 2013-09-24 23:02:
To reproduce, open the Camera demo, then switch to the Orthographic mode. Do some random zooming and rotating and you should be able to get it into a mode where the clipping is incorrect. In my trials, it seems that the incorrect clipping only affects the top and bottom regions, it does not appear to clip incorrectly on the left or right.
Sometimes the incorrect clipping is dynamic, e.g. the clipping line will move as you rotate the model whereas other times it is fixed.
objo wrote at 2013-09-25 08:59:
The near plane distance should not be changed when zooming or rotating.
Currently the near plane distance is copied when the user change from perspective to orthographic, maybe this code should be removed.
objo wrote at 2013-09-26 22:40:
Set
ShowCameraInfo = true
on the HelixViewport3D to review the settings of the camera.ShadesJeff wrote at 2013-09-26 22:47:
That's essentially was the problem - I had universally specified my look directions as unit vectors, when in fact they need to be scaled to world units in order for the view to function correctly. I still think there is an issue when changing between orthographic and perspective projections (field of view explodes), but I cannot reliably recreate it.
objo wrote at 2013-09-27 11:12:
Maybe zooming in orthographic mode should change the CameraPosition and LookDirection in the same way as for perspective camera.
rinaldin wrote at 2013-10-03 22:14:
so what's the solution? Pressing "S" in my case solved the problem, but I just want to prevent the clipping happening.
From this:
Finally, I ended up using CameraHelper.LookAt to position the camera and OrthographicCamera.Width to zoom - manually, it doesn't produce the effects the CameraController does.How can I leave the default mouse control and ovverride the Zoom function? Sorry, but it is not clear to me.
Giovanni
rinaldin wrote at 2013-10-25 22:27:
var newRelativePosition = relativePosition * (1 + delta);
changing it to:var newRelativePosition = relativePosition * (1.1 + delta);
No more clipping and no need to use LookAt.wangzh wrote at 2014-07-24 04:56:
I finally solved changing the Helix source code in the file ZoomHandles.cs at line:rinaldin,
changing it to:var newRelativePosition = relativePosition * (1 + delta);
No more clipping and no need to use LookAt.var newRelativePosition = relativePosition * (1.1 + delta);
I have the same issue when I use the latest Helix version. I checked the source codes and didn't find the ZoomHandles.cs file. Only ZoomHandler.cs found. Is it same file? Also, I didn't find the code
var newRelativePosition = relativePosition * (1 + delta);
in the file ZoomHandler.cs.Any comment and suggestion to resolve the problem?
Thanks in advance!
rinaldin wrote at 2014-07-24 19:46:
wangzh wrote at 2014-07-25 02:42:
Yes, the file is ZoomHandler.cs, it was a typing mistake. Anyway, I noticed that in the later version of Helix Toolkit that code changes and it is written in a different way. I used the version helixtoolkit_f5a96293a071.rinaldin,
Thanks for your reply. I found the latest revision changed from:
var newRelativePosition = relativePosition * (1 + delta);
var newRelativeTarget = relativeTarget * (1 + delta);
to var f = Math.Pow(2.5, delta);
var newRelativePosition = relativePosition * f;
var newRelativeTarget = relativeTarget * f;
The latest version still has the same issue. It is a great library. However, I am stuck in this step. Since I am new in WPF, I am wondering if you could send me correct HelixToolkit.Wpf.dll to me it will be greatly appreciated.
my email: wangzh2000@yahoo.com
wangzh wrote at 2014-07-25 15:49:
public MainWindow()
{
InitializeComponent();
resetZoom();
}
Then write resetZoom()private void resetZoom()
{
OrthographicCamera myOCamera = new OrthographicCamera(new Point3D(0, 0, 0), new Vector3D(100000, 100000, -100000), new Vector3D(0, 0, 1), 5000);
ViewPort.Camera = myOCamera;
}
Each time, when creating a model, using ZoomExtents() at the end of method, for instance:double z1 = 0;
double h = 500;
private void cylinder_Click(object sender, RoutedEventArgs e)
{
PipeVisual3D pipe = new PipeVisual3D();
pipe.Point1 = new Point3D(0, 0, z1);
pipe.Point2 = new Point3D(0, 0, z1+h);
pipe.Material = Materials.LightGray;
pipe.Diameter = 1200;
pipe.InnerDiameter = 1180;
z1 += h;
SolidModels.Children.Add(pipe);
ViewPort.ZoomExtents();
}
I am a green bee in WPF and C#, any education and new simple way in the issue sharing will be greatly appreciated.This WPF library package is great. Thanks objo for this work!!!
Cheers,
CREATE CURVED PANELS
esi wrote at 2013-10-18 15:30:
I would like to create a curved surface to join two Cube faces together.
is this possible with helix3dToolKit?
I tried with AddExtrudedGeometry and AddLoftedGeometry but I didn't understand the right way to use them.
Did someone used those methods?
Thank You in advance for help
Regards
Customer support service by UserEcho