private GeometryExtents <double> AddLayer(MRecipe recipe, MRecipeDeviceLayer layer) { var extents = GeometryExtents <double> .CreateDefaultDouble(); // calculate layer's transform var transform = MRecipe.GetRelativeTransform(recipe, layer); // fetch geometries from pattern file var geometries = _fetchDxfFunc(layer.PatternFilePath); for (int i = 0; i < geometries?.Count; i++) { var clone = (IMarkGeometry)geometries[i].Clone(); clone.Transform(transform); // render geometry AddDefault( clone, DefaultColor ); // update extents extents = GeometryExtents <double> .Combine( extents, clone.Extents ); } return(extents); }
public List <MRecipe> GetRecipe(string idRecipe) { List <MRecipe> recipeList = new List <MRecipe>(); { sqlCon = con.openConnection(); sqlCom = new SqlCommand("select a.Id_Recipe, c.DrugName, b.Qty, b.Subtotal from Recipe.Recipe a join Recipe.RecipeDetail b on a.Id_Recipe = b.Id_Recipe join Recipe.Drug c on b.Id_Drug = c.Id_Drug where a.Id_Recipe = '" + idRecipe + "'", sqlCon); sqlDa = new SqlDataAdapter(sqlCom); DataTable dt = new DataTable(); sqlDa.Fill(dt); if (dt.Rows.Count > 0) { for (int i = 0; i < dt.Rows.Count; i++) { MRecipe recipeData = new MRecipe(); recipeData.IdDrug = dt.Rows[i]["Id_Recipe"].ToString(); recipeData.NamaObat = dt.Rows[i]["DrugName"].ToString(); recipeData.Qty = dt.Rows[i]["Qty"].ToString(); recipeData.Fare = dt.Rows[i]["Subtotal"].ToString(); recipeList.Add(recipeData); } } sqlCon.Close(); } return(recipeList); }
public void Redo() { if (_undoRedoHelper == null) { return; } lock (_undoRedoHelper) { _undoRedoHelper.Pause(); var data = _undoRedoHelper.Redo(); if (data != default(MRecipe)) { _undoRedoHelper.DisposeSubscriptions(); RecipeItemsSource = data; _undoRedoHelper.SaveStateOnPropertyChange(_mRecipe); MRecipe.BeginGetNodes(_mRecipe, (baseNode) => { _undoRedoHelper.SaveStateOnPropertyChange(baseNode); }); } _undoRedoHelper.Resume(); } }
public virtual void AddLayerTiles(MRecipe recipe, MRecipeDeviceLayer layer) { // get layer's transform var transform = MRecipe.GetRelativeTransform(recipe, layer); // update layer's tile info if (layer.TileDescriptions.Count <= 0) { layer.GenerateTileDescriptionsFromSettings( (patternFilePath) => { return(GeometricArithmeticModule.CalculateExtents( _fetchDxfFunc(patternFilePath) )); } ); } // render tiles for (int i = 0; i < layer.TileDescriptions.Count; i++) { var tile = (MarkGeometryRectangle)layer.TileDescriptions[i]; tile.Transform(transform); AddDefault(tile, TileColor); } }
public void GenerateRecipeInfo() { RecipeInfo.Clear(); int index = 0; MRecipe.BeginGetAllLayers(RecipeVm, (layer) => { if (layer.TileDescriptions.Count() <= 0) { layer.GenerateTileDescriptionsFromSettings( GeometricArithmeticModule.CalculateExtents(FetchDXF(layer)) ); } var info = new RecipeProcessEntityInfo() { Index = index++, Layer = layer, EstimatedTime = EstimateProcessTime(layer) }; RecipeInfo.Add(info); }); // fetch recipe's count and extents (RecipeGeometriesCount, RecipeExtents) = MRecipe.CalculateExtents(RecipeVm); }
private void okButton_Click(object sender, RoutedEventArgs e) { var dialog = new SaveFileDialog(); dialog.AddExtension = true; dialog.Title = "Save Recipe"; dialog.Filter = MRecipe.FileFilter; dialog.DefaultExt = MRecipe.DefaultFileExtension; dialog.FileName = Path.GetFileNameWithoutExtension(_viewModel.PatternFilePath); dialog.InitialDirectory = _viewModel.DefaultRecipeDirectory; if (dialog.ShowDialog() != true) { return; } try { Recipe = _viewModel.GenerateRecipe(dialog.FileName); if (Recipe == null) { throw new Exception("Missing or Invalid Parameters"); } DialogResult = true; } catch (Exception exp) { MessageBox.Show( exp.Message, "Error" ); } }
public virtual void AddRecipe(MRecipe recipe) { if (recipe == null) { return; } recipe.BeginGetAllPlates((plate) => AddRecipeNode(recipe, plate)); }
public int CountNumberOfFiducials(MRecipe recipeIn) { int count = 0; MRecipe.BeginGetNodes( recipeIn, (node) => { count += node.Fiducials.Count; } ); return(count); }
public virtual void AddRecipeNode(MRecipe recipe, MRecipeBaseNode recipeNode) { if (recipe == null || recipeNode == null) { return; } var extents = GeometryExtents <double> .CreateDefaultDouble(); MRecipe.BeginGetAllLayers_Parallel(recipeNode, (layer) => { extents = GeometryExtents <double> .Combine( extents, AddLayer(recipe, layer) ); }); // calculate size of fiducial relative to the node var fiducialSize = 0.025 * extents.Hypotenuse; // generate fiducial pattern GenerateFiducialPattern(fiducialSize); // get node's transform var parentsTransform = (recipeNode.Parent as MRecipeBaseNode)?.TransformInfo.ToMatrix4x4() ?? GeometricArithmeticModule.GetDefaultTransformationMatrix(); // render fiducials in parent's reference frame foreach (var fiducial in recipeNode.Fiducials) { var transform = GeometricArithmeticModule.CombineTransformations( GeometricArithmeticModule.GetTranslationTransformationMatrix( fiducial.X, fiducial.Y, fiducial.Z ), parentsTransform ); foreach (var geometry in _fiducialPattern) { var clone = (IMarkGeometry)geometry.Clone(); clone.Transform(transform); AddDefault(clone, FiducialColor); } } }
public void UpdateItemsSource() { if (RecipeItemsSource != null) { _lastSelectedNode = null; _mRecipe = RecipeItemsSource; if (_undoRedoHelper?.IsPaused != true) { _undoRedoHelper = new UndoRedoHelper <MRecipe>(ref _mRecipe); MRecipe.BeginGetNodes(_mRecipe, (baseNode) => { _undoRedoHelper.SaveStateOnPropertyChange(baseNode); }); _undoRedoHelper.SaveState(); } NotifyPropertyChanged(nameof(MRecipe)); } }
public async Task <Matrix4x4> GetAbsoluteTransformFromStageOrigin( IProcessConfigurationTasksHandler taskHandler, ICamToBeam cam2Beam, MRecipe recipe, MRecipeBaseNode recipeNode, CancellationToken ctIn ) { // firstly, find closest parent with fiducials var parent = recipeNode; while ( parent != null && parent.Fiducials.Count <= 0 ) { parent = parent.Parent as MRecipeBaseNode; } if (parent != null) { // recursion - get it's parent's transform var baseTransform = await GetAbsoluteTransformFromStageOrigin( taskHandler, cam2Beam, recipe, parent.Parent as MRecipeBaseNode, ctIn ); var fiducialPoints = new List <MarkGeometryPoint>(); var measuredPoints = new List <MarkGeometryPoint>(); for (int i = 0; i < parent.Fiducials.Count; i++) { var fiducial = parent.Fiducials[i]; if (!_cachedFiducials.ContainsKey(fiducial)) { // estimate stage position var stageLocation = new MarkGeometryPoint( fiducial.X, fiducial.Y, fiducial.Z ); stageLocation.Transform(baseTransform); // goto estimated position if (!await taskHandler.GotoXY( stageLocation.X, stageLocation.Y, ctIn )) { throw new Exception($"Failed to goto the estimated position; origin: {await taskHandler.GetStageOrigin(ctIn)}, fiducial: {(fiducial.X, fiducial.Y)} est: {stageLocation}"); } // find and centre { if (!await cam2Beam.MoveBeamToCamOffset(ctIn)) { throw new Exception($"Failed to move beam to cam offset"); } if (!await taskHandler.MovetoCameraFocus(ctIn)) { throw new Exception($"Failed to move camera to focus"); } await taskHandler.SwitchCameraLedOn(ctIn); // attempt to centre on fiducial if (!await taskHandler.CentreOnVisibleObject(ctIn)) { _logger.Info($"Failed to centre on fiducial"); // ask user to locate fiducials Application.Current.Dispatcher.Invoke( () => { var fidVm = taskHandler.GetNewFidFindViewModel(); var inspectionDialog = new InspectionWindow(fidVm, Application.Current.MainWindow); inspectionDialog.Owner = Application.Current.MainWindow; if (inspectionDialog.ShowDialog() != true) { throw new Exception("Failed to find fiducial"); } // TODO : think about updating the machine's origin } ); } if (!await cam2Beam.MoveCamToBeamOffset(ctIn)) { throw new Exception($"Failed to move camera to beam offset"); } } // read fiducial position var(stgX, stgY, success) = await taskHandler.GetStageXY(ctIn); if (!success) { throw new Exception("Failed to read the current stage position"); } // update cache _cachedFiducials[fiducial] = new MarkGeometryPoint(stgX, stgY); } // update measured points fiducialPoints.Add(new MarkGeometryPoint(fiducial.X, fiducial.Y)); measuredPoints.Add(_cachedFiducials[fiducial]); } // calculate transform from measured fiducials var parentTransform = GeometricArithmeticModule.EstimateTransformationMatrixFromPoints( fiducialPoints, measuredPoints ); return(GeometricArithmeticModule.CombineTransformations( parentTransform, await InvertTransform( taskHandler, parentTransform, MRecipe.GetRelativeTransformFromParent( parent, recipeNode ), ctIn ) )); } var origin = await taskHandler.GetStageOrigin(ctIn); var stageOrigin = GeometricArithmeticModule.GetTranslationTransformationMatrix( origin.X, origin.Y ); return(GeometricArithmeticModule.CombineTransformations( stageOrigin, await InvertTransform( taskHandler, stageOrigin, MRecipe.GetRelativeTransform( recipe, recipeNode ), ctIn ) )); }
public MRecipe GenerateRecipe(string outputFileName) { if ( _geometriesBuffer == null || _geometriesBuffer.Keys.Count <= 0 || !File.Exists(PatternFilePath) ) { throw new Exception("Missing or Invalid pattern"); } var patternName = Path.GetFileNameWithoutExtension(outputFileName); var device = new MRecipeDevice(patternName); var recipe = new MRecipe(new MRecipePlate("Plate", device)); // add fiducials to recipe plate recipe.Plates.First().Fiducials = new ObservableCollection <MFiducialInfo>(Fiducials); if (SeperateLayers) { var dataDirectory = Path.Combine( Path.GetDirectoryName(outputFileName), $"{patternName} Data" ); if (!Directory.Exists(dataDirectory)) { Directory.CreateDirectory(dataDirectory); } foreach (var layerName in _geometriesBuffer?.Keys) { var fileName = Path.Combine( dataDirectory, $"{layerName}.dxf" ); GeometricArithmeticModule.SaveDXF(fileName, _geometriesBuffer[layerName]); var layer = new MRecipeDeviceLayer(layerName); layer.AlignmentType = AlignmentType; layer.PatternFilePath = fileName; layer.ProcessParametersFilePath = ProcessParametersFilePath; layer.TargetProcessMode = TargetProcessMode?.Name.EnglishValue; layer.TileSettings = (MTileSettings)TileSettings.Clone(); device.AddLayer(layer); } recipe.Save( Path.Combine( dataDirectory, $"{patternName}.{MRecipe.DefaultFileExtension}" ) ); } else { var layer = new MRecipeDeviceLayer(patternName); layer.AlignmentType = AlignmentType; layer.PatternFilePath = PatternFilePath; layer.ProcessParametersFilePath = ProcessParametersFilePath; layer.TargetProcessMode = TargetProcessMode?.Name.EnglishValue; layer.TileSettings = (MTileSettings)TileSettings.Clone(); device.AddLayer(layer); recipe.Save( Path.Combine( Path.GetDirectoryName(PatternFilePath), $"{patternName}.{MRecipe.DefaultFileExtension}" ) ); } // update recipe's parents recipe.UpdateParents(); return(recipe); }
public void Render() { _terminableTaskExecutor.CancelCurrentAndRun( (ctIn) => { // reset shader MShader.Reset(); // stop if new render is requested ctIn.ThrowIfCancellationRequested(); // as we only render one layer at a time // choose the closest layer in the recipe tree var layer = GetClosestLayer(); if (layer != null) { // extract device's absolute transform var baseTransform = MRecipe.GetRelativeTransform(RecipeVm, layer); // calculate layer's transform var transform = GeometricArithmeticModule.CombineTransformations( baseTransform, layer.TransformInfo.ToMatrix4x4() ); // fetch pattern var pattern = FetchDXF(layer); for (int j = 0; j < pattern?.Count; j++) { // get copy of geometry var geometry = (IMarkGeometry)pattern[j].Clone(); // apply transform to geometry geometry.Transform(transform); // add geometry MShader.AddDefault(geometry); } // overlay tiles foreach (var tile in layer.TileDescriptions) { var rect = (MarkGeometryRectangle)tile; // apply transform to rect rect.Transform(transform); // add geometry MShader.AddDefault(rect, MGLShader.Violet); } } // stop if new render is requested ctIn.ThrowIfCancellationRequested(); MShader.Render(); UpdateStats(); } ); }
public RunRecipeDialogViewModel(RunRecipeDialogModel modelIn, MRecipe recipe) { _model = modelIn; _terminableTaskExecutor = new TerminableTaskExecutor(); _processTerminableTaskExecutor = new TerminableTaskExecutor(); _dxfCachedLoader = new CachedLoader <List <IMarkGeometry> >(); RecipeInfo = new ObservableCollection <RecipeProcessEntityInfo>(); _fiducialFinder = new FiducialFinder(); _processTimer.Elapsed += _processTimer_Elapsed; IsPaused = false; IsRunning = false; try { IsLoading = true; SelectedSubProcessInfo = null; RecipeVm = recipe; GenerateRecipeInfo(); Render(); } catch (Exception exp) { _model.Log(exp); _model.Log("Failed to load recipe"); } finally { IsLoading = false; } StartRecipeCommand = new DelegateCommand( () => { StartProcess(); } ); RestartCommand = new DelegateCommand( async() => { if (IsRunning) { Abort(); // wait a second for running tasks to stop await Task.Delay(1000); } StartProcess(); } ); PauseContinueCommand = new DelegateCommand( () => { try { if (!IsPaused) { DispatcherMessageBox.ShowBox( "The process will be paused when it is safe to do so.", "Pause Request" ); PrintLog("Process Paused ..."); } else { PrintLog("Continue Process"); } IsPaused = !IsPaused; } finally { } } ); AbortRecipeCommand = new DelegateCommand( () => { Abort(); } ); }
public MRecipe GenerateRecipe(string outputFileName) { if ( _stlModel == null || _stlSlices == null || _stlSlices.Count <= 0 || !File.Exists(PatternFilePath) ) { throw new Exception("Missing or Invalid pattern"); } try { IsLoading = true; string markParametersFilePath = TargetProcessMode?.ProcessParameterFileManager?.FilePath; var recipeName = Path.GetFileNameWithoutExtension(outputFileName); var dataDirectory = Path.Combine( Path.GetDirectoryName(outputFileName), $"{recipeName} Recipe Data" ); // save recipe in it's Data Directory var recipeFilePath = Path.Combine( dataDirectory, Path.GetFileName(outputFileName) ); // overwrite data directory if it exists if (Directory.Exists(dataDirectory)) { Directory.Delete(dataDirectory); } Directory.CreateDirectory(dataDirectory); // copy the marking parameters to the data directory var newMarkParametersFilePath = Path.Combine( dataDirectory, Path.GetFileName(markParametersFilePath) ); // copy the marking parameters to the data directory if (File.Exists(newMarkParametersFilePath)) { File.Delete(newMarkParametersFilePath); } File.Copy(markParametersFilePath, newMarkParametersFilePath); // create device var device = new MRecipeDevice("Slices"); // centre device about it's reference point device.TransformInfo.OffsetX = -StlModelReferencePoint.X; device.TransformInfo.OffsetY = -StlModelReferencePoint.Y; // create template layers so that // they can be updated in parallel for (int i = 0; i < _stlSlices.Count; i++) { device.Layers.Add(new MRecipeDeviceLayer()); } // generate and export DXFs Parallel.For(0, _stlSlices.Count, (i) => { // device - representing slices var layer = device.Layers[i]; layer.Tag = $"Slice {i}"; layer.TargetProcessMode = TargetProcessMode?.Name.EnglishValue; layer.ProcessParametersFilePath = markParametersFilePath; layer.PatternFilePath = Path.Combine(dataDirectory, $"{layer.Tag}.dxf"); layer.TileSettings = TileSettings; for (int j = 0; j < _stlSlices[i].Tiles.Count; j++) { layer.TileDescriptions.Add( new MTileDescription(j, _stlSlices[i].Tiles[j]) ); } _stlSlices[i].SaveAsDXF(layer.PatternFilePath); }); // create recipe var recipe = new MRecipe(new MRecipePlate(recipeName, device)); // set alignment type recipe.Plates[0].AlignmentType = AlignmentType; // add alignment fiducials to recipe plate recipe.Plates[0].Fiducials = new ObservableCollection <MFiducialInfo>(Fiducials); // update recipe's parents recipe.UpdateParents(); recipe.Save(Path.Combine(dataDirectory, recipeFilePath)); return(recipe); } finally { IsLoading = false; } }