private void OnDataGridSelectionChanged(object sender, SelectionChangedEventArgs e) { var viewModel = MainGrid.DataContext as CapturefineryWindowViewModel; if (e.AddedItems.Count > 0) { _study = e.AddedItems[0] as StudyInfo; // Display the options pane with automatic height TaskOptions.Visibility = Visibility.Visible; TaskOptions.Height = double.NaN; TaskOptions.Margin = new Thickness(10); if (_study != null && viewModel != null) { _hof = viewModel.GetHallOfFame(_study); _complete = viewModel.GetHallOfFame(_study); // Get it twice to avoid cloning _complete = viewModel.GetComplete(_study, _complete); viewModel.InitProperties(_hof.solutions.Length, _complete.solutions.Length, viewModel.UseComplete); DisplayOrHideControls(true, true); } } }
public int[] GetSolutionOrder(HallOfFame hof, string[] parameters) { // Populate default array with sequential order var maxItems = hof.solutions.Length; var res = new int[maxItems]; for (int i = 0; i < maxItems; i++) { res[i] = i; } if (parameters.Length > 0 && !(parameters.Length == 1 && parameters[0] == null)) { var idx = GetParameterIndex(hof, parameters[0]); var selected = hof.solutions.Select((item, index) => new { item, index }); var ordered = selected.OrderBy(a => Extract(a.item[idx])); for (int i = 1; i < parameters.Length; i++) { var parameter = parameters[i]; if (parameter == null) { break; } var idx2 = GetParameterIndex(hof, parameter); ordered = ordered.ThenBy(a => Extract(a.item[idx2])); } return(ordered.Select(a => a.index).ToArray <int>()); } return(res); }
public HallOfFame GetComplete(StudyInfo study, HallOfFame hof) { var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); var localFile = string.Format(@"GenerativeDesign\hof_hist-results-{0}.csv", study.Name); var fileName = Path.Combine(appData, localFile); if (!File.Exists(fileName)) { localFile = string.Format(@"Refinery\hof_hist-results-{0}.csv", study.Name); // Support old location fileName = Path.Combine(appData, localFile); } if (File.Exists(fileName)) { var expected = hof.variables.Length + hof.goals.Length; using (var reader = new StreamReader(fileName)) { var lines = new List <string>(); var curGen = 0; var curGenSize = 0; var firstLine = reader.ReadLine(); var firstValues = firstLine.Split(','); var genCount = Int32.Parse(firstValues[1]); var genSizes = new int[genCount]; while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); if (values.Length < expected) { if (curGenSize > 0) { genSizes[curGen] = curGenSize; curGenSize = 0; curGen++; } } else { float empty; if (values.All(s => (float.TryParse(s, out empty)) || s == "True" || s == "False") && !lines.Contains(line)) { lines.Add(line); curGenSize++; } } } var solutions = new string[lines.Count][]; for (int i = 0; i < lines.Count; i++) { solutions[i] = lines[i].Split(','); } hof.solutions = solutions; } } return(hof); }
public CapturefineryWindow() { InitializeComponent(); // Hide the options pane until something is selected TaskOptions.Visibility = Visibility.Hidden; TaskOptions.Height = 0; _study = null; _hof = null; }
private int GetParameterIndex(HallOfFame hof, string param) { int idx = -1; var goalIdx = Array.IndexOf(hof.goals, param); if (goalIdx >= 0) { idx = goalIdx; } var varIdx = Array.IndexOf(hof.variables, param); if (varIdx >= 0) { idx = hof.goals.Length + varIdx; } return(idx); }
private async void Grid_SelectionChanged(object sender, SelectionChangedEventArgs e) { var viewModel = MainGrid.DataContext as CapturefineryWindowViewModel; if (e.AddedItems.Count > 0) { _study = e.AddedItems[0] as StudyInfo; // Display the options pane with automatic height TaskOptions.Visibility = Visibility.Visible; TaskOptions.Height = double.NaN; if (_study != null && viewModel != null) { _hof = viewModel.GetHallOfFame(_study); var max = _hof.solutions.Length; viewModel.MaxItems = max; viewModel.Start = 0; viewModel.Items = max; } } }
public async Task RunTasks(StudyInfo study, HallOfFame hof, HallOfFame complete) { if (hof == null && complete == null) { return; } var toRun = (_useComplete && complete != null) ? complete : hof; _folder = study.Folder + "\\screenshots"; if (!System.IO.Directory.Exists(_folder)) { System.IO.Directory.CreateDirectory(_folder); } // Shouldn't really be necessary _maxItems = toRun.solutions.Length; if ( Start >= 0 && Start < _maxItems && Items >= 0 && Items <= _maxItems && Start + Items <= _maxItems ) { bool waiting = false; int counter = Start; var images = new Bitmap[_maxItems]; var errorImages = new Bitmap[_maxItems]; var runsWithErrors = new List <int>(); Progress = 0; Escape = false; // Pre-load any existing images that come before the chosen range, if this option was selected if (_createAnimations && _loadImages && counter > 0) { LoadExistingImages(images, _captureErrors ? errorImages : null, _folder, 0, counter); } _previousRunType = _dynamoViewModel.HomeSpace.RunSettings.RunType; _dynamoViewModel.HomeSpace.RunSettings.RunType = Dynamo.Models.RunType.Manual; // Define and attach the main post-execution handler ExecutionStateHandler postExecution = async(e) => { DoEvents(); await Task.Delay(3000); waiting = false; if (!_escapePressed) { var isError = false; if (_captureErrors) { // Does the graph contain any nodes in an error state? var errorNodes = (from n in _readyParams.CurrentWorkspaceModel.Nodes where n.State != ElementState.Active && n.State != ElementState.Dead select n); if (errorNodes.Count <NodeModel>() > 0) { isError = true; runsWithErrors.Add(counter); } } var img = SaveScreenshot(GetImageFilename(_folder, counter, isError)); if (isError) { errorImages[counter] = img; } else { images[counter] = img; } counter++; var captured = counter - Start; Progress = 100 * captured / Items; } }; ExecutionEvents.GraphPostExecution += postExecution; if (Items == 0) { Progress = 100; } else { var nodeMap = GetDynamoNodesForInputParameters(toRun.variables, _readyParams.CurrentWorkspaceModel.Nodes); for (int i = Start; i < Start + Items; i++) { if (_escapePressed) { break; } var parameters = toRun.solutions[i]; for (var j = 0; j < toRun.variables.Length; j++) { SetDynamoInputParameter(nodeMap, toRun.variables[j], parameters[toRun.goals.Length + j]); } waiting = true; StartDynamoRun(); while (waiting) { await Task.Delay(1000); } } } _dynamoViewModel.HomeSpace.RunSettings.RunType = _previousRunType; // Post-load any existing images that come after the chosen range, if this option was selected if (_createAnimations && _loadImages && counter + 1 < _maxItems) { LoadExistingImages(images, _captureErrors ? errorImages : null, _folder, counter + 1, _maxItems); } if (!_escapePressed) { if (_createAnimations) { var levels = GetSortLevels(); var order = GetSolutionOrder(toRun, levels); var rootName = StripInvalidFileAndPathCharacters(_rootName); if (!images.All <Bitmap>((b) => b == null)) { SaveAnimation(images, order, _folder + "\\" + rootName + ".gif"); SaveAnimation(images, order, _folder + "\\" + rootName + "-small.gif", 1000); SaveAnimation(images, order, _folder + "\\" + rootName + "-tiny.gif", 500); } if (!errorImages.All <Bitmap>((b) => b == null)) { SaveAnimation(errorImages, order, _folder + "\\" + rootName + "-errors.gif"); SaveAnimation(errorImages, order, _folder + "\\" + rootName + "-errors-small.gif", 1000); SaveAnimation(errorImages, order, _folder + "\\" + rootName + "-errors-tiny.gif", 500); } } // If errors were found in any of the runs, create a new run with just the problematic runs const string errorsSuffix = "-errors"; if (_captureErrors && runsWithErrors.Count > 0 && !study.Folder.EndsWith(errorsSuffix)) { SaveFilteredHallOfFame(study, study.Folder + errorsSuffix, runsWithErrors); OnPropertyChanged("RefineryTasks"); } } foreach (var image in images) { if (image != null) { image.Dispose(); } } foreach (var image in errorImages) { if (image != null) { image.Dispose(); } } DisableExecute(false); ExecutionEvents.GraphPostExecution -= postExecution; var result = MessageBox.Show("Capture complete. Copy output path to the clipboard?", "Confirmation", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { Clipboard.SetText(_folder); } } }
public async Task RunTasks(StudyInfo study, HallOfFame hof = null) { if ( Start >= 0 && Start < _maxItems && Items > 0 && Items <= _maxItems && Start + Items <= _maxItems ) { bool waiting = false; int counter = Start; var images = new List <Bitmap>(); var errorImages = new List <Bitmap>(); var runsWithErrors = new List <int>(); var folder = study.Folder + "\\screenshots"; if (!System.IO.Directory.Exists(folder)) { System.IO.Directory.CreateDirectory(folder); } // Attach a handler to check for the use of Escape InterceptKeys.OnKeyDown += new KeyEventHandler(OnKeyDown); InterceptKeys.Start(); // Pre-load any existing images that come before the chosen range, if this option was selected if (_createAnimations && _loadImages && counter > 0) { LoadExistingImages(images, _captureErrors ? errorImages : null, folder, 0, counter); } // Define and attach the main post-execution handler ExecutionStateHandler postExecution = async(e) => { if (!_escapePressed) { DoEvents(); await Task.Delay(3000); waiting = false; var isError = false; if (_captureErrors) { // Does the graph contain any nodes in an error state? var errorNodes = (from n in _readyParams.CurrentWorkspaceModel.Nodes where n.State != ElementState.Active && n.State != ElementState.Dead select n); if (errorNodes.Count <NodeModel>() > 0) { isError = true; runsWithErrors.Add(counter); } } var img = SaveScreenshot(GetImageFilename(folder, counter, isError)); if (isError) { errorImages.Add(img); } else { images.Add(img); } counter++; } }; ExecutionEvents.GraphPostExecution += postExecution; if (hof == null) { hof = GetHallOfFame(study); } var nodeMap = GetDynamoNodesForInputParameters(hof.variables, _readyParams.CurrentWorkspaceModel.Nodes); for (int i = Start; i < Start + Items; i++) { if (_escapePressed) { break; } var parameters = hof.solutions[i]; for (var j = 0; j < hof.variables.Length; j++) { SetDynamoInputParameter(nodeMap, hof.variables[j], parameters[hof.goals.Length + j]); } waiting = true; StartDynamoRun(); while (waiting) { await Task.Delay(1000); } } // Post-load any existing images that come after the chosen range, if this option was selected if (_createAnimations && _loadImages && counter + 1 < _maxItems) { LoadExistingImages(images, _captureErrors ? errorImages : null, folder, counter + 1, _maxItems); } if (!_escapePressed) { if (_createAnimations) { if (images.Count > 0) { SaveAnimation(images, folder + "\\animation.gif"); SaveAnimation(images, folder + "\\animation-small.gif", 1000); SaveAnimation(images, folder + "\\animation-tiny.gif", 500); } if (errorImages.Count > 0) { SaveAnimation(errorImages, folder + "\\animation-errors.gif"); SaveAnimation(errorImages, folder + "\\animation-errors-small.gif", 1000); SaveAnimation(errorImages, folder + "\\animation-errors-tiny.gif", 500); } } // If errors were found in any of the runs, create a new run with just the problematic runs const string errorsSuffix = "-errors"; if (_captureErrors && runsWithErrors.Count > 0 && !study.Folder.EndsWith(errorsSuffix)) { SaveFilteredHallOfFame(study, study.Folder + errorsSuffix, runsWithErrors); RaisePropertyChanged("RefineryTasks"); } } foreach (var image in images) { image.Dispose(); } foreach (var image in errorImages) { image.Dispose(); } InterceptKeys.Stop(); InterceptKeys.OnKeyDown -= new KeyEventHandler(OnKeyDown); ExecutionEvents.GraphPostExecution -= postExecution; } }