PageRenderTime 80ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/WpfCSharp/AutodeskWpfReCap/MainWindow.xaml.cs

https://github.com/PandazZ/Autodesk-ReCap-Samples
C# | 639 lines | 489 code | 74 blank | 76 comment | 100 complexity | 3efe323083a73fa5449d344b1d84a2b7 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
  1. // (C) Copyright 2014 by Autodesk, Inc.
  2. //
  3. // Permission to use, copy, modify, and distribute this software in
  4. // object code form for any purpose and without fee is hereby granted,
  5. // provided that the above copyright notice appears in all copies and
  6. // that both that copyright notice and the limited warranty and
  7. // restricted rights notice below appear in all supporting
  8. // documentation.
  9. //
  10. // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
  11. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
  12. // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
  13. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
  14. // UNINTERRUPTED OR ERROR FREE.
  15. //- Written by Cyrille Fauvel, Autodesk Developer Network (ADN)
  16. //- http://www.autodesk.com/joinadn
  17. //- January 20th, 2014
  18. //
  19. using System;
  20. using System.Collections;
  21. using System.Collections.Generic;
  22. using System.Collections.ObjectModel;
  23. using System.Reflection;
  24. using System.IO;
  25. using System.IO.Compression;
  26. using System.Net;
  27. using System.Xml;
  28. using System.Xml.Linq;
  29. using System.ComponentModel;
  30. using System.Web;
  31. using System.Windows;
  32. using System.Windows.Controls;
  33. using System.Windows.Input;
  34. using System.Windows.Media;
  35. using System.Windows.Media.Imaging;
  36. using System.Windows.Shapes;
  37. using System.Windows.Media.Media3D;
  38. using System.Windows.Resources;
  39. using System.Windows.Automation.Peers;
  40. using System.Windows.Automation.Provider;
  41. using System.Resources;
  42. using System.Linq;
  43. using System.Threading.Tasks;
  44. using System.Diagnostics;
  45. using RestSharp;
  46. using RestSharp.Authenticators;
  47. using RestSharp.Contrib;
  48. using Newtonsoft.Json;
  49. using Newtonsoft.Json.Linq;
  50. using Autodesk.ADN.Toolkit.Wpf.RestLogger;
  51. using Autodesk.ADN.Toolkit.Wpf.Viewer;
  52. using Autodesk.ADN.Toolkit.ReCap;
  53. /*
  54. http://codereview.stackexchange.com/questions/20820/use-and-understanding-of-async-await-in-net-4-5
  55. */
  56. namespace Autodesk.ADN.WpfReCap {
  57. public class ReCapPhotosceneProject {
  58. public string Name { get; set; }
  59. public string Type { get; set; }
  60. public string Image { get; set; }
  61. }
  62. public partial class MainWindow : Window {
  63. protected AdskReCap _recap =null ;
  64. protected RestLoggerWnd _logger =null ;
  65. protected List<string> _forPreview =new List<string> () ;
  66. protected Dictionary<string, AdskReCap.Format> _requestedFormat =new Dictionary<string, AdskReCap.Format> () ;
  67. public MainWindow () {
  68. InitializeComponent () ;
  69. PhotoScenes.View =PhotoScenes.FindResource ("recapView") as ViewBase ;
  70. serverLabel.Inlines.Clear () ;
  71. serverLabel.Inlines.Add (UserSettings.ReCapAPIURL) ;
  72. serverLabel.NavigateUri =new Uri (UserSettings.ReCapAPIURL.Replace ("/API/", "/api-docs/")) ;
  73. var values =Enum.GetValues (typeof (AdskReCap.MeshQuality)) ;
  74. foreach ( var value in values )
  75. outputQuality.Items.Add (value.ToString ()) ;
  76. outputQuality.SelectedItem =AdskReCap.MeshQuality.DRAFT.ToString () ;
  77. values =Enum.GetValues (typeof (AdskReCap.Format)) ;
  78. foreach ( var value in values )
  79. outputFormat.Items.Add (((AdskReCap.Format)value).ToFriendlyString ()) ;
  80. outputFormat.SelectedItem =AdskReCap.Format.OBJ.ToFriendlyString () ;
  81. }
  82. private void Window_Loaded (object sender, RoutedEventArgs e) {
  83. LoggerInit () ;
  84. Login () ;
  85. }
  86. public async void Login () {
  87. bool isNetworkAvailable =System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable () ;
  88. if ( !isNetworkAvailable ) {
  89. LogError ("Network Error: Check your network connection and try again...") ;
  90. MessageBox.Show ("GetPointCloudArchive failed", "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  91. return ;
  92. }
  93. // This isn't really secure as the tokens will be stored in the application settings
  94. // but not protected - This code is there to help testing the sample, but you should consider
  95. // securing the Access Tokens in a better way, or force login each time the application starts.
  96. LogInfo ("Authentification", LogIndent.PostIndent) ;
  97. if ( Properties.Settings.Default.oauth_token.Length == 0
  98. || Properties.Settings.Default.oauth_token_secret.Length == 0
  99. || Properties.Settings.Default.oauth_session_handle.Length == 0
  100. || !await oAuth.AccessToken (true, null)
  101. ) {
  102. oAuth wnd =new oAuth () ;
  103. wnd.ShowDialog () ;
  104. }
  105. ReCapLoginIcon.Source =(Properties.Settings.Default.oauth_token_secret.Length == 0 ?
  106. new BitmapImage (new Uri (@"Images\Login.png", UriKind.Relative))
  107. : new BitmapImage (new Uri (@"Images\Logout.png", UriKind.Relative))
  108. ) ;
  109. LogInfo ("", LogIndent.PostUnindent) ;
  110. await ConnectWithReCapServer () ;
  111. Properties.Settings.Default.recap_UserID =await GetUserID () ;
  112. await ListPhotoScenes () ;
  113. }
  114. public async void Logout () {
  115. bool bRet =await oAuth.InvalidateToken () ;
  116. _recap =null ;
  117. ReCapLoginIcon.Source =(Properties.Settings.Default.oauth_token_secret.Length == 0 ?
  118. new BitmapImage (new Uri (@"Images\Login.png", UriKind.Relative))
  119. : new BitmapImage (new Uri (@"Images\Logout.png", UriKind.Relative))
  120. ) ;
  121. }
  122. #region Window events
  123. // UI - Menu Commands
  124. private void LoginMenu_Click (object sender, RoutedEventArgs e) {
  125. if ( Properties.Settings.Default.oauth_token.Length == 0
  126. || Properties.Settings.Default.oauth_token_secret.Length == 0
  127. || Properties.Settings.Default.oauth_session_handle.Length == 0
  128. )
  129. Login () ;
  130. else
  131. Logout () ;
  132. }
  133. private void LoggerMenu_Click (object sender, RoutedEventArgs e) {
  134. e.Handled =true ;
  135. LoggerInit () ;
  136. }
  137. private async void CreatePhotoscene_Click (object sender, RoutedEventArgs e) {
  138. e.Handled =true ;
  139. string photosceneid =await CreateReCapPhotoscene (
  140. (AdskReCap.Format)((string)outputFormat.SelectedItem).ToReCapFormatEnum (),
  141. (AdskReCap.MeshQuality)Enum.Parse (typeof (AdskReCap.MeshQuality), (string)outputQuality.SelectedItem, true)
  142. ) ;
  143. if ( photosceneid == "" )
  144. return ;
  145. if ( PhotoScenes.ItemsSource != null ) {
  146. ObservableCollection<ReCapPhotosceneProject> items =new ObservableCollection<ReCapPhotosceneProject> ((IEnumerable<ReCapPhotosceneProject>)PhotoScenes.ItemsSource) ;
  147. items.Add (new ReCapPhotosceneProject () {
  148. Name =photosceneid,
  149. Type ="CREATED",
  150. Image =@"Images\ReCap.jpg"
  151. }) ;
  152. PhotoScenes.ItemsSource =items ;
  153. PhotoScenes.Items.Refresh () ;
  154. }
  155. }
  156. private void PhotoScenesRefresh_Click (object sender, RoutedEventArgs e) {
  157. PhotoScenes_Refresh (sender, e) ;
  158. }
  159. // UI - Commands
  160. private void recapAPI_RequestNavigate (object sender, System.Windows.Navigation.RequestNavigateEventArgs e) {
  161. e.Handled =true ;
  162. System.Diagnostics.Process.Start (new System.Diagnostics.ProcessStartInfo (e.Uri.AbsoluteUri)) ;
  163. }
  164. private void recap360_RequestNavigate (object sender, System.Windows.Navigation.RequestNavigateEventArgs e) {
  165. e.Handled =true ;
  166. System.Diagnostics.Process.Start (new System.Diagnostics.ProcessStartInfo (e.Uri.AbsoluteUri)) ;
  167. }
  168. private async void PhotoScenes_SelectionChanged (object sender, SelectionChangedEventArgs e) {
  169. e.Handled =true ;
  170. propertyGrid.SelectedObject =null ;
  171. if ( PhotoScenes.SelectedItems.Count != 1 )
  172. return ;
  173. ReCapPhotosceneProject item =PhotoScenes.SelectedItem as ReCapPhotosceneProject ;
  174. if ( await PhotosceneProperties (item.Name) )
  175. propertyGrid.SelectedObject =new AdskReCapPhotoscene (_recap.xmlLinq ()) ;
  176. }
  177. private async void showDeleted_Checked (object sender, RoutedEventArgs e) {
  178. //showDeleted
  179. e.Handled =true ;
  180. await ListPhotoScenes () ;
  181. }
  182. #endregion
  183. #region PhotoScenes Context Menu events
  184. private async void PhotoScenes_TestConnection (object sender, RoutedEventArgs e) {
  185. e.Handled =true ;
  186. await TestConnection () ;
  187. }
  188. private async void PhotoScenes_Refresh (object sender, RoutedEventArgs e) {
  189. e.Handled =true ;
  190. await ListPhotoScenes () ;
  191. }
  192. private async void PhotoScenes_Properties (object sender, RoutedEventArgs e) {
  193. e.Handled =true ;
  194. if ( PhotoScenes.SelectedItems.Count != 1 )
  195. return ;
  196. ReCapPhotosceneProject item =PhotoScenes.SelectedItem as ReCapPhotosceneProject ;
  197. if ( await PhotosceneProperties (item.Name) ) {
  198. PropertiesWnd wnd =new PropertiesWnd (new AdskReCapPhotoscene (_recap.xmlLinq ())) ;
  199. wnd.Owner =this ;
  200. wnd.Show () ;
  201. }
  202. }
  203. private void PhotoScenes_UploadPhotos (object sender, RoutedEventArgs e) {
  204. e.Handled =true ;
  205. if ( PhotoScenes.SelectedItems.Count != 1 )
  206. return ;
  207. ReCapPhotosceneProject item =PhotoScenes.SelectedItem as ReCapPhotosceneProject ;
  208. ShotsWindow wnd =new ShotsWindow (item.Name) ;
  209. wnd.Owner =this ;
  210. wnd.Show () ;
  211. }
  212. private async void PhotoScenes_ProcessPhotoscene (object sender, RoutedEventArgs e) {
  213. e.Handled = true;
  214. if ( PhotoScenes.SelectedItems.Count != 1 )
  215. return ;
  216. ReCapPhotosceneProject item =PhotoScenes.SelectedItem as ReCapPhotosceneProject ;
  217. if ( await ProcessPhotoscene (item.Name) ) {
  218. JobProgress jobWnd =new JobProgress (item.Name) ;
  219. jobWnd._callback =new ProcessPhotosceneCompletedDelegate (this.ProcessPhotosceneCompleted) ;
  220. jobWnd.Owner =this ;
  221. jobWnd.Show () ;
  222. }
  223. }
  224. public void ProcessPhotosceneCompleted (string photosceneid, string status) {
  225. foreach ( ReCapPhotosceneProject item in PhotoScenes.Items ) {
  226. if ( item.Name == photosceneid ) {
  227. item.Type =status ;
  228. PhotoScenes.Items.Refresh () ;
  229. break ;
  230. }
  231. }
  232. }
  233. private async void PhotoScenes_DownloadResult (object sender, RoutedEventArgs e) {
  234. if ( e != null )
  235. e.Handled =true ;
  236. if ( PhotoScenes.SelectedItems.Count != 1 )
  237. return ;
  238. ReCapPhotosceneProject item =PhotoScenes.SelectedItem as ReCapPhotosceneProject ;
  239. AdskReCap.Format format =(AdskReCap.Format)((string)outputFormat.SelectedItem).ToReCapFormatEnum () ;
  240. string link =await GetPhotosceneResult (item.Name, format, e == null) ;
  241. if ( link != "" )
  242. DownloadReCapResult (item.Name, link, e == null) ;
  243. }
  244. private void DownloadReCapResult (string photosceneid, string link, bool forPreview =false) {
  245. DownloadFileWnd wnd =new DownloadFileWnd (
  246. link,
  247. System.IO.Path.GetFullPath (AppDomain.CurrentDomain.BaseDirectory)
  248. + photosceneid + System.IO.Path.GetExtension (link)
  249. ) ;
  250. if ( forPreview ) // Preview
  251. wnd._callback =new DownloadFileCompletedDelegate (this.DownloadResultForPreviewCompleted) ;
  252. else
  253. wnd._callback =new DownloadFileCompletedDelegate (this.DownloadResultCompleted) ;
  254. wnd.Owner =this ;
  255. wnd.Show () ;
  256. }
  257. public void DownloadResultCompleted (string photosceneid, string filename) {
  258. string location =System.IO.Path.GetFullPath (AppDomain.CurrentDomain.BaseDirectory) + photosceneid + ".zip" ;
  259. if ( !File.Exists (location) )
  260. return ;
  261. foreach ( ReCapPhotosceneProject item in PhotoScenes.Items ) {
  262. if ( item.Name == photosceneid ) {
  263. item.Image =photosceneid + ".zip:icon.png" ;
  264. PhotoScenes.Items.Refresh () ;
  265. break ;
  266. }
  267. }
  268. }
  269. public void DownloadResultForPreviewCompleted (string photosceneid, string filename) {
  270. DownloadResultCompleted (photosceneid, filename) ;
  271. PhotoScenes_Preview (null, null) ;
  272. }
  273. // If not using .NET 4.5, http://dotnetzip.codeplex.com/
  274. private void PhotoScenes_Preview (object sender, RoutedEventArgs e) {
  275. if ( e != null )
  276. e.Handled =true ;
  277. if ( PhotoScenes.SelectedItems.Count != 1 )
  278. return ;
  279. ReCapPhotosceneProject item =PhotoScenes.SelectedItem as ReCapPhotosceneProject ;
  280. string location =System.IO.Path.GetFullPath (AppDomain.CurrentDomain.BaseDirectory) + item.Name + ".zip" ;
  281. if ( !File.Exists (location) ) {
  282. if ( e != null ) { // Do not enter into an infinite loop
  283. outputFormat.SelectedItem =AdskReCap.Format.OBJ.ToString () ; // Our viewer support OBJ only
  284. PhotoScenes_DownloadResult (null, null) ;
  285. }
  286. return ;
  287. }
  288. ViewerWindow wnd =new ViewerWindow () ;
  289. wnd.Owner =this ;
  290. wnd.Show () ;
  291. wnd.LoadModel (location) ;
  292. }
  293. private async void PhotoScenes_DeletePhotoscene (object sender, RoutedEventArgs e) {
  294. e.Handled =true ;
  295. ObservableCollection<ReCapPhotosceneProject> items =new ObservableCollection<ReCapPhotosceneProject> ((IEnumerable<ReCapPhotosceneProject>)PhotoScenes.ItemsSource) ;
  296. foreach ( ReCapPhotosceneProject item in PhotoScenes.SelectedItems ) {
  297. if ( await DeletePhotoscene (item.Name) )
  298. items.Remove (item) ;
  299. }
  300. PhotoScenes.ItemsSource =items ;
  301. PhotoScenes.Items.Refresh () ;
  302. }
  303. #endregion
  304. #region ReCap Calls
  305. protected async Task<bool> ConnectWithReCapServer () {
  306. if ( _recap != null )
  307. return (true) ;
  308. _recap =new AdskReCap (
  309. UserSettings.ReCapClientID,
  310. UserSettings.CONSUMER_KEY, UserSettings.CONSUMER_SECRET,
  311. Properties.Settings.Default.oauth_token, Properties.Settings.Default.oauth_token_secret
  312. ) ;
  313. System.Diagnostics.Debug.WriteLine ("tokens: " + Properties.Settings.Default.oauth_token + " - " + Properties.Settings.Default.oauth_token_secret, "Debug") ;
  314. if ( !await TestConnection () )
  315. _recap =null ;
  316. return (_recap != null) ;
  317. }
  318. protected async Task<bool> TestConnection () {
  319. // Test connection
  320. LogInfo ("Test Connection", LogIndent.PostIndent) ;
  321. if ( !await _recap.ServerTime () ) {
  322. connectedLabel.Content ="Connection to ReCap Server failed!" ;
  323. connectedTimeLabel.Content ="" ;
  324. LogError ("ReCap Error: Connection to ReCap Server failed!", LogIndent.PostUnindent) ;
  325. MessageBox.Show ("ReCap Error: Connection to ReCap Server failed!", "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  326. return (false) ;
  327. }
  328. // XML sample
  329. //XmlDocument doc =_recap.xml () ;
  330. //XmlNode node =doc.SelectSingleNode ("/Response/date") ; // doc.DocumentElement.SelectSingleNode ("/Response/date/text()").Value
  331. //DateTime dt =DateTime.Parse (node.InnerText) ;
  332. // XML LINQ sample
  333. //XDocument doc =_recap.xmlLinq () ;
  334. //XElement node =doc.Element ("Response").Element ("date") ;
  335. //DateTime dt =(DateTime)node ;
  336. // JSON sample (would require to use true in the call of _recap.ServerTime (true))
  337. //JObject doc =_recap.json () ;
  338. //JToken node =doc2 ["Response"] ["date"] ;
  339. //DateTime dt =(DateTime)node2 ;
  340. // ReCap Reponse dynamic object sample
  341. dynamic response =_recap.response () ;
  342. DateTime dt =DateTime.Parse (response.date) ;
  343. connectedLabel.Content =dt.ToLongDateString () ;
  344. connectedTimeLabel.Content =dt.ToLongTimeString () ;
  345. LogInfo ("ReCap Server date: " + dt.ToLongDateString () + " " + dt.ToLongTimeString (), LogIndent.PostUnindent) ;
  346. return (true) ;
  347. }
  348. protected async Task<string> GetUserID () {
  349. if ( !await ConnectWithReCapServer () )
  350. return ("") ;
  351. // Deleting the given Photoscene
  352. LogInfo ("Request current UserID", LogIndent.PostIndent) ;
  353. //bool ret =await _recap.DeleteScene (photosceneid) ;
  354. if ( !await _recap.User (Properties.Settings.Default.x_oauth_user_name, Properties.Settings.Default.x_oauth_user_guid) ) {
  355. LogError ("Getting UserID failed", LogIndent.PostUnindent) ;
  356. MessageBox.Show ("Getting UserID failed", "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  357. return ("") ;
  358. }
  359. dynamic response =_recap.response () ;
  360. LogInfo (string.Format ("UserID - {0}", response.User.userID), LogIndent.PostUnindent) ;
  361. return (response.User.userID) ;
  362. }
  363. private async Task ListPhotoScenes () {
  364. if ( !await ConnectWithReCapServer () )
  365. return ;
  366. // List Photoscene on the server
  367. LogInfo ("List Photoscenes", LogIndent.PostIndent) ;
  368. PhotoScenes.ItemsSource =null ;
  369. PhotoScenes.Items.Refresh () ;
  370. if ( !await _recap.SceneList ("userID", Properties.Settings.Default.recap_UserID) ) {
  371. LogError ("ListPhotoScenes failed", LogIndent.PostUnindent) ;
  372. MessageBox.Show ("ListPhotoScenes failed", "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  373. return ;
  374. }
  375. // XML sample
  376. //ObservableCollection<ReCapPhotosceneProject> items =new ObservableCollection<ReCapPhotosceneProject> () ;
  377. //XmlDocument doc =_recap.xml () ;
  378. //XmlNodeList nodes =doc.SelectNodes ("/Response/Photoscenes/Photoscene") ;
  379. //string logText ="Photoscenes List:" ;
  380. //foreach ( XmlNode fnode in nodes ) {
  381. // XmlNode p0 =fnode.SelectSingleNode ("deleted") ;
  382. // if ( p0 != null && p0.InnerText == "true" )
  383. // continue ;
  384. // XmlNode p1 =fnode.SelectSingleNode ("photosceneid") ;
  385. // string photosceneid =p1.InnerText ;
  386. // XmlNode p2 =fnode.SelectSingleNode ("status") ;
  387. // logText +=string.Format ("\n\t{0} [{1}]", p1.InnerText, p2.InnerText) ;
  388. // // If we have the result downloaded, displays the resulting icon instead of the generic image
  389. // items.Add (new ReCapPhotosceneProject () {
  390. // Name =photosceneid,
  391. // Type =(p0 != null && p0.InnerText == "true" ? "Deleted (" + p2.InnerText + ")" : p2.InnerText),
  392. // Image =(File.Exists (photosceneid + ".zip") ? photosceneid + ".zip:icon.png" : @"Images\ReCap.jpg")
  393. // }) ;
  394. //}
  395. // ReCap Response dynamic object sample (the beauty here is that this is the same code if you're using json vs xml)
  396. ObservableCollection<ReCapPhotosceneProject> items =new ObservableCollection<ReCapPhotosceneProject> () ;
  397. dynamic response =_recap.response () ;
  398. dynamic nodes =response.Photoscenes ; // if json, do doc.Photoscenes.Photoscene
  399. if ( nodes.GetType () != typeof (AdskDynamicDictionary) ) { // no scenes for this user
  400. LogInfo ("No scene for that user on the server.", LogIndent.PostUnindent) ;
  401. return ;
  402. }
  403. string logText ="Photoscenes List:" ;
  404. foreach ( KeyValuePair<string, object> pair in nodes.Dictionary ) {
  405. dynamic fnode =pair.Value ;
  406. bool bDeleted =false ;
  407. try {
  408. bDeleted =(fnode.deleted == "true") ;
  409. if ( showDeleted.IsChecked == false && bDeleted ) // deleted might not be present in the response unless it is true
  410. continue ;
  411. } catch { }
  412. logText +=string.Format ("\n\t{0} [{1}]", fnode.photosceneid, fnode.status) ;
  413. // If we have the result downloaded, displays the resulting icon instead of the generic image
  414. items.Add (new ReCapPhotosceneProject () {
  415. Name =fnode.photosceneid,
  416. Type =(bDeleted ? "Deleted (" + fnode.status + ")" : fnode.status),
  417. Image =(File.Exists (fnode.photosceneid + ".zip") ? fnode.photosceneid + ".zip:icon.png" : @"Images\ReCap.jpg")
  418. }) ;
  419. }
  420. PhotoScenes.ItemsSource =items ;
  421. PhotoScenes.Items.Refresh () ;
  422. LogInfo (logText, LogIndent.PostUnindent) ;
  423. }
  424. protected async Task<string> CreateReCapPhotoscene (AdskReCap.Format format, AdskReCap.MeshQuality quality) {
  425. if ( !await ConnectWithReCapServer () )
  426. return ("") ;
  427. //- Create Photoscene
  428. LogInfo (string.Format ("Create Photoscene {0} / {1}", format.ToFriendlyString (), quality.ToString ()), LogIndent.PostIndent) ;
  429. Dictionary<string, string> options =new Dictionary<string, string> () {
  430. { "callback", "email://" + Properties.Settings.Default.x_oauth_user_name }
  431. } ;
  432. if ( !await _recap.CreatePhotoscene (/*AdskReCap.Format.OBJ*/format, /*AdskReCap.MeshQuality.DRAFT*/quality, options) ) {
  433. LogError ("CreatePhotoscene failed - Failed to create a new Photoscene", LogIndent.PostUnindent) ;
  434. MessageBox.Show ("CreatePhotoscene failed - Failed to create a new Photoscene", "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  435. return ("") ;
  436. }
  437. dynamic response =_recap.response () ;
  438. LogInfo (string.Format ("CreatePhotoscene succeeded - PhotoSceneID = {0}", response.Photoscene.photosceneid), LogIndent.PostUnindent) ;
  439. return (response.Photoscene.photosceneid) ;
  440. }
  441. protected async Task<bool> PhotosceneProperties (string photosceneid) {
  442. if ( photosceneid == "" || !await ConnectWithReCapServer () )
  443. return (false) ;
  444. // Photoscene Properties
  445. LogInfo ("Photoscene Properties", LogIndent.PostIndent) ;
  446. bool bRet =await _recap.SceneProperties (photosceneid) ;
  447. Log (bRet ? "Photoscene Properties returned" : "PhotosceneProperties failed", LogIndent.PostUnindent, bRet ? "Info" : "Error") ;
  448. return (bRet) ;
  449. }
  450. protected async Task<bool> ProcessPhotoscene (string photosceneid) {
  451. if ( photosceneid == "" || !await ConnectWithReCapServer () )
  452. return (false) ;
  453. // Launch Photoscene
  454. LogInfo ("Launch Photoscene", LogIndent.PostIndent) ;
  455. bool bRet =await _recap.ProcessScene (photosceneid) ;
  456. Log (bRet ? "Photoscene processing request sent" : "ProcessPhotoscene failed", LogIndent.PostUnindent, bRet ? "Info" : "Error") ;
  457. return (bRet) ;
  458. }
  459. protected async Task<string> GetPhotosceneResult (string photosceneid, AdskReCap.Format format =AdskReCap.Format.OBJ, bool bForPreview =false) {
  460. if ( photosceneid == "" || !await ConnectWithReCapServer () )
  461. return ("") ;
  462. // Get Photoscene result (mesh)
  463. LogInfo ("Getting the Photoscene result (mesh)", LogIndent.PostIndent) ;
  464. if ( !await _recap.GetPointCloudArchive (photosceneid, format) ) {
  465. LogError ("GetPointCloudArchive failed", LogIndent.PostUnindent) ;
  466. MessageBox.Show ("GetPointCloudArchive failed", "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  467. return ("") ;
  468. }
  469. dynamic response =_recap.response () ;
  470. LogInfo (string.Format ("GetPhotosceneResult succeeded - {0}", response.Photoscene.scenelink), LogIndent.PostUnindent) ;
  471. if ( response.Photoscene.scenelink == "" ) {
  472. // That means there is a conversion happening and we need to wait
  473. if ( bForPreview )
  474. _forPreview.Add (photosceneid) ;
  475. _requestedFormat.Add (photosceneid, format) ;
  476. JobProgress jobWnd =new JobProgress (photosceneid) ;
  477. jobWnd.Owner =this ;
  478. jobWnd._callback =new ProcessPhotosceneCompletedDelegate (this.ConvertPhotosceneCompleted) ;
  479. jobWnd.Show () ;
  480. return ("") ; // Return "" to not continue processing the command
  481. }
  482. return (response.Photoscene.scenelink) ;
  483. }
  484. public void ConvertPhotosceneCompleted (string photosceneid, string status) {
  485. if ( status == "DONE" ) {
  486. LogInfo (string.Format ("Photoscene {0} conversion completed successfully", photosceneid)) ;
  487. // Was it for d/l or Preview?
  488. bool bRet =_forPreview.Remove (photosceneid) ;
  489. AdskReCap.Format format =_requestedFormat [photosceneid] ;
  490. outputFormat.SelectedItem =format.ToString () ;
  491. MenuItemAutomationPeer menuPeer =new MenuItemAutomationPeer (bRet ? menuPreview : menuDownloadResult) ;
  492. IInvokeProvider invokeProv =menuPeer.GetPattern (PatternInterface.Invoke) as IInvokeProvider ;
  493. invokeProv.Invoke () ;
  494. } else {
  495. LogError (string.Format ("Photoscene {0} conversion failed", photosceneid)) ;
  496. MessageBox.Show (string.Format ("Photoscene {0} conversion failed", photosceneid), "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  497. }
  498. }
  499. protected async Task<bool> DeletePhotoscene (string photosceneid) {
  500. if ( photosceneid == "" || !await ConnectWithReCapServer () )
  501. return (false) ;
  502. // Deleting the given Photoscene
  503. LogInfo ("Deleting a Photoscene", LogIndent.PostIndent) ;
  504. //bool ret =await _recap.DeleteScene (photosceneid) ;
  505. bool ret =_recap.DeleteSceneTempFix (photosceneid) ;
  506. if ( !ret ) {
  507. LogError ("DeletePhotoscene failed", LogIndent.PostUnindent) ;
  508. MessageBox.Show ("DeletePhotoscene failed", "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  509. return (false) ;
  510. }
  511. LogInfo ("DeletePhotoscene call succeeded") ;
  512. dynamic response =_recap.response () ;
  513. try {
  514. string nb =response.Photoscene.deleted ;
  515. LogInfo (string.Format ("Photoscene {0} deleted - {1} resources deleted", photosceneid, nb), LogIndent.PostUnindent) ;
  516. } catch {
  517. Log ("Failed deleting the Photoscene and resources", LogIndent.PostUnindent, "Exception") ;
  518. MessageBox.Show ("Exception: Failed deleting the Photoscene and resources", "WpfReCap", MessageBoxButton.OK, MessageBoxImage.Error) ;
  519. return (false) ;
  520. }
  521. return (true) ;
  522. }
  523. #endregion
  524. #region Logger Window
  525. private void LoggerInit () {
  526. if ( _logger != null ) {
  527. _logger.Visibility =Visibility.Visible ;
  528. RestLoggerIcon.Source =new BitmapImage (new Uri (@"Images\RestLogger.png", UriKind.Relative)) ;
  529. return ;
  530. }
  531. _logger =new RestLoggerWnd () ;
  532. _logger.Owner =this ;
  533. _logger.Top =this.Top ;
  534. _logger.Left =this.Left + this.Width ;
  535. _logger.Closing +=_logger_Closing ;
  536. _logger.Updated +=_logger_Updated ;
  537. _logger.Show () ;
  538. }
  539. private void _logger_Closing (object sender, CancelEventArgs e) {
  540. e.Cancel =true ;
  541. _logger.Visibility =Visibility.Hidden ;
  542. }
  543. private void _logger_Updated () {
  544. if ( _logger.Visibility == Visibility.Hidden )
  545. RestLoggerIcon.Source =new BitmapImage (new Uri (@"Images\RestLoggerUpd.png", UriKind.Relative)) ;
  546. }
  547. protected enum LogIndent { None =0, PreIndent =1, PreUnindent =-1, PostIndent =2, PostUnindent =-2 } ;
  548. private static void LogInfo (string msg, LogIndent indent =LogIndent.None) {
  549. Log (msg, indent, "Info") ;
  550. }
  551. private static void LogError (string msg, LogIndent indent =LogIndent.None) {
  552. Log (msg, indent, "Error") ;
  553. }
  554. private static void Log (string msg, LogIndent indent =LogIndent.None, string category ="Info") {
  555. if ( Math.Abs ((int)indent) == 1 )
  556. Trace.IndentLevel +=(int)indent ;
  557. if ( msg != "" )
  558. Trace.WriteLine ("WpfRecap: " + msg, category) ;
  559. if ( Math.Abs ((int)indent) == 2 )
  560. Trace.IndentLevel +=((int)indent) / 2 ;
  561. }
  562. #endregion
  563. }
  564. }