diff --git a/Common/Variance/DOE/DOEResults.cs b/Common/Variance/DOE/DOEResults.cs new file mode 100644 index 0000000..7abf483 --- /dev/null +++ b/Common/Variance/DOE/DOEResults.cs @@ -0,0 +1,231 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Variance +{ + public class DOEResults + { + List results; + + public List getResults() + { + return pGetResults(); + } + + List pGetResults() + { + return results; + } + + public DOEResults(string DOEName) + { + pDOEResults(DOEName); + } + + void pDOEResults(string DOEName) + { + results = new List(); + results.Add(new DOEResult(DOEName)); + } + + public void AddResult(string DOEName) + { + pAddResult(DOEName); + } + + void pAddResult(string DOEName) + { + results.Add(new DOEResult(DOEName)); + } + } + + public class DOEResult + { + string DOEName; + + bool headerSet; + + List doeHeaderInformation; + + List cells; + + public List getCells() + { + return pGetCells(); + } + + List pGetCells() + { + return cells; + } + + public List getHeaderInformation() + { + return pGetHeaderInformation(); + } + + List pGetHeaderInformation() + { + return doeHeaderInformation; + } + + public string getName() + { + return pGetName(); + } + + string pGetName() + { + return DOEName; + } + + public DOEResult(string DOEName) + { + pDOEResult(DOEName); + } + + void pDOEResult(string DOEName) + { + this.DOEName = DOEName; + headerSet = false; + cells = new List(); + doeHeaderInformation = new List(); + doeHeaderInformation.Add(""); + } + + public void setDOEHeaderInformation(List headerInformation) + { + pSetDOEHeaderInformation(headerInformation); + } + + void pSetDOEHeaderInformation(List headerInformation) + { + if (!headerSet) + { + doeHeaderInformation = headerInformation.ToList(); + headerSet = true; + } + } + + public void AddCellToDOE(int col, int row) + { + pAddCellToDOE(col, row); + } + + void pAddCellToDOE(int col, int row) + { + cells.Add(new DOECell(col, row)); + } + + public void AddResultToCell(int col, int row, string result) + { + pAddResultToCell(col, row, result); + } + + void pAddResultToCell(int col, int row, string result) + { + for (int index = 0; index < cells.Count(); index++) + { + if ((cells[index].getRowIndex() == row) && (cells[index].getColIndex() == col)) + { + cells[index].AddResultToCell(result); + } + } + } + } + + public class DOECell + { + Int32 colIndex; + Int32 rowIndex; + DOEMeanStdDev results; + + public Int32 getColIndex() + { + return pGetColIndex(); + } + + Int32 pGetColIndex() + { + return colIndex; + } + + public Int32 getRowIndex() + { + return pGetRowIndex(); + } + + Int32 pGetRowIndex() + { + return rowIndex; + } + + public DOEMeanStdDev getResults() + { + return pGetResults(); + } + + DOEMeanStdDev pGetResults() + { + return results; + } + + public DOECell(int col, int row) + { + pDOECell(col, row); + } + + void pDOECell(int col, int row) + { + colIndex = col; + rowIndex = row; + results = new DOEMeanStdDev(); + } + + public void AddResultToCell(string result) + { + pAddResultToCell(result); + } + + void pAddResultToCell(string result) + { + results.AddResult(result); + } + } + + public class DOEMeanStdDev + { + List values; + + public List getValues() + { + return pGetValues(); + } + + List pGetValues() + { + return values; + } + + public DOEMeanStdDev() + { + pDOEMeanStdDev(); + } + + void pDOEMeanStdDev() + { + values = new List(); + } + + public void AddResult(string result) + { + pAddResult(result); + } + + void pAddResult(string result) + { + values.Add(result); + } + } +} diff --git a/Common/Variance/DOE/DOESettings.cs b/Common/Variance/DOE/DOESettings.cs new file mode 100644 index 0000000..f650590 --- /dev/null +++ b/Common/Variance/DOE/DOESettings.cs @@ -0,0 +1,395 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Variance +{ + [Serializable] + public class DOESettings + { + public static string default_comment = ""; + public static double default_colOffset = 0; + public static double default_rowOffset = 0; + public static Int32[] default_layersAffected = new Int32[CentralProperties.maxLayersForMC] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + public static double default_colPitch = 0; + public static double default_rowPitch = 0; + public static Int32 default_cols = 1; + public static Int32 default_rows = 1; + public static Int32 default_specificTile = 0; + public static Int32 default_specificTile_Row = 0; + public static Int32 default_specificTile_Col = 0; + public static Int32 default_listOfTiles = 0; + public static List default_tileList_ColRow = new List { new Int32[2] { 0, 0 } }; + public static string default_trList = ""; + + public enum properties_d { colOffset, rowOffset, colPitch, rowPitch } + + double colOffset; + double rowOffset; + double rowPitch; + double colPitch; + public double getDouble(properties_d p) + { + return pGetDouble(p); + } + + double pGetDouble(properties_d p) + { + double ret = 0; + + switch (p) + { + case properties_d.colOffset: + ret = colOffset; + break; + case properties_d.rowOffset: + ret = rowOffset; + break; + case properties_d.colPitch: + ret = colPitch; + break; + case properties_d.rowPitch: + ret = rowPitch; + break; + } + + return ret; + } + + public void setDouble(properties_d p, double val) + { + pSetDouble(p, val); + } + + void pSetDouble(properties_d p, double val) + { + switch (p) + { + case properties_d.colOffset: + colOffset = val; + break; + case properties_d.rowOffset: + rowOffset = val; + break; + case properties_d.colPitch: + colPitch = val; + break; + case properties_d.rowPitch: + rowPitch = val; + break; + } + } + + public enum properties_i { rows, cols, sTile, sTileRow, sTileCol, uTileList } + + Int32 rows; + Int32 cols; + Int32 specificTile; + Int32 specificTile_Row; + Int32 specificTile_Col; + Int32 listOfTiles; // 0 is inactive, 1 is active. + + public Int32 getInt(properties_i p) + { + return pGetInt(p); + } + + Int32 pGetInt(properties_i p) + { + Int32 ret = 0; + + switch (p) + { + case properties_i.cols: + ret = cols; + break; + case properties_i.rows: + ret = rows; + break; + case properties_i.sTile: + ret = specificTile; + break; + case properties_i.sTileCol: + ret = specificTile_Col; + break; + case properties_i.sTileRow: + ret = specificTile_Row; + break; + case properties_i.uTileList: + ret = listOfTiles; + break; + } + + return ret; + } + + public void setInt(properties_i p, Int32 val) + { + pSetInt(p, val); + } + + void pSetInt(properties_i p, Int32 val) + { + switch (p) + { + case properties_i.cols: + cols = val; + break; + case properties_i.rows: + rows = val; + break; + case properties_i.sTile: + specificTile = val; + break; + case properties_i.sTileCol: + specificTile_Col = val; + break; + case properties_i.sTileRow: + specificTile_Row = val; + break; + case properties_i.uTileList: + listOfTiles = val; + break; + } + } + + Int32[] layersAffected; + + public Int32[] getLayersAffected() + { + return pGetLayersAffected(); + } + + Int32[] pGetLayersAffected() + { + return layersAffected; + } + + public void setLayersAffected(List val) + { + pSetLayersAffected(val); + } + + void pSetLayersAffected(List val) + { + tileList_ColRow = val.ToList(); + } + + public Int32 getLayerAffected(int layer) + { + return pGetLayerAffected(layer); + } + + Int32 pGetLayerAffected(int layer) + { + return layersAffected[layer]; + } + + public void setLayerAffected(int layer, int val) + { + pSetLayerAffected(layer, val); + } + + void pSetLayerAffected(int layer, int val) + { + layersAffected[layer] = val; + } + + List tileList_ColRow; // 2 fields : col, row + + public void resetTileList_ColRow() + { + pResetTileList_ColRow(); + } + + void pResetTileList_ColRow() + { + tileList_ColRow = new List(); + } + + public List getTileList_ColRow() + { + return pGetTileList_ColRow(); + } + + List pGetTileList_ColRow() + { + return tileList_ColRow; + } + + public Int32 getTileList_Value(int list, int index) + { + return pGetTileList_Value(list, index); + } + + Int32 pGetTileList_Value(int list, int index) + { + return tileList_ColRow[list][index]; + } + + public void setTileList_Value(int list, int index, int val) + { + pSetTileList_ColRow(list, index, val); + } + + void pSetTileList_ColRow(int list, int index, int val) + { + tileList_ColRow[list][index] = val; + } + + public void setTileList_ColRow(List val) + { + pSetTileList_ColRow(val); + } + + void pSetTileList_ColRow(List val) + { + tileList_ColRow = val.ToList(); + } + + public void addTileList_Value(int[] val) + { + pAddTileList_Value(val); + } + + void pAddTileList_Value(int[] val) + { + tileList_ColRow.Add(val); + } + + public enum properties_b { iDRM, quilt } + + bool iDRMRunConfigured; + bool OPCRunConfigured; + + public bool getBool(properties_b p) + { + return pGetBool(p); + } + + bool pGetBool(properties_b p) + { + bool ret = false; + switch (p) + { + case properties_b.iDRM: + ret = iDRMRunConfigured; + break; + case properties_b.quilt: + ret = OPCRunConfigured; + break; + } + return ret; + } + + public void setBool(properties_b p, bool val) + { + pSetBool(p, val); + } + + void pSetBool(properties_b p, bool val) + { + switch (p) + { + case properties_b.iDRM: + iDRMRunConfigured = val; + break; + case properties_b.quilt: + OPCRunConfigured = val; + break; + } + } + + public enum properties_s { comment, list } + string comment; + string trList; + + public string getString(properties_s p) + { + return pGetString(p); + } + + string pGetString(properties_s p) + { + string ret = ""; + switch (p) + { + case properties_s.comment: + ret = comment; + break; + case properties_s.list: + ret = trList; + break; + } + return ret; + } + + public void setString(properties_s p, string val) + { + pSetString(p, val); + } + + void pSetString(properties_s p, string val) + { + switch (p) + { + case properties_s.comment: + comment = val; + break; + case properties_s.list: + trList = val; + break; + } + } + + public DOESettings() + { + pDOESettings(); + } + + void pDOESettings() + { + comment = default_comment; + colOffset = default_colOffset; + rowOffset = default_rowOffset; + layersAffected = default_layersAffected; + rowPitch = default_rowPitch; + colPitch = default_colPitch; + rows = default_rows; + cols = default_cols; + specificTile = default_specificTile; + specificTile_Col = default_specificTile_Col; + specificTile_Row = default_specificTile_Row; + listOfTiles = default_listOfTiles; + tileList_ColRow = default_tileList_ColRow; + iDRMRunConfigured = false; + OPCRunConfigured = false; + trList = default_trList; // used for loading, as a container. + } + + public DOESettings(Int32 rP, Int32 cP, Int32 r, Int32 c) + { + pDOESettings(rP, cP, r, c); + } + + void pDOESettings(Int32 rP, Int32 cP, Int32 r, Int32 c) + { + comment = default_comment; + colOffset = default_colOffset; + rowOffset = default_rowOffset; + layersAffected = default_layersAffected; + rowPitch = rP; + colPitch = cP; + rows = r; + cols = c; + specificTile = default_specificTile; + specificTile_Col = default_specificTile_Col; + specificTile_Row = default_specificTile_Row; + listOfTiles = default_listOfTiles; + tileList_ColRow = default_tileList_ColRow; + iDRMRunConfigured = false; + OPCRunConfigured = false; + trList = default_trList; // used for loading, as a container. + } + } +} diff --git a/Common/Variance/UI/MainForm.cs b/Common/Variance/UI/MainForm.cs new file mode 100644 index 0000000..da2c7d8 --- /dev/null +++ b/Common/Variance/UI/MainForm.cs @@ -0,0 +1,1936 @@ +using entropyRNG; +using Error; +using Eto; +using Eto.Drawing; +using Eto.Forms; +using VeldridEto; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Xml.Linq; +using System.Diagnostics; +using Eto.Veldrid; +using Veldrid; + +namespace Variance +{ + /// + /// Your application's main form + /// + public partial class MainForm : Form + { + CommonVars commonVars; + + Entropy entropyControl; + + VarianceContextGUI varianceContext; + + Command quitCommand, helpCommand, aboutCommand, clearLayer, copyLayer, pasteLayer, newSim, openSim, revertSim, saveSim, saveAsSim; + + List notList, booleanList; + + Replay simReplay; + + string helpPath; + bool helpAvailable; + + void setupUIDataContext(List notList_, List booleanList_) + { + DataContext = new UIStringLists + { + subShapeList = commonVars.subshapes, + shapes = commonVars.getAvailableShapes(), + noiseTypeList = commonVars.getNoiseTypes(), + subShapePos = commonVars.getAvailableSubShapePositions(), + tipLocs = commonVars.getAvailableTipsLocations(), + rngTypeList = commonRNG.rngTypes, + externalTypeList = commonVars.getExternalTypes(), + calcModes = commonVars.calcMode_names, + booleanList = booleanList_, + openGLMode = commonVars.getOpenGLModeList(), + notList = notList_, + polyFillList = commonVars.getPolyFillTypes(), + geoCoreStructureList = commonVars.structureList, + geoCoreLDList = commonVars.activeStructure_LayerDataTypeList, + geoCoreStructureList_exp = commonVars.structureList_exp, + subShapesList_exp = commonVars.subShapesList_exp, + geoCoreLDList_exp = commonVars.activeStructure_LayerDataTypeList_exp, + rngMapping = commonVars.rngCustomMapping, + layerNames = commonVars.layerNames, + }; + } + + void loadPrefs() + { + // We have to do this by hand, reading and parsing an XML file. Yay. + string filename = EtoEnvironment.GetFolderPath(EtoSpecialFolder.ApplicationSettings); + filename += System.IO.Path.DirectorySeparatorChar + "variance_prefs.xml"; + + XElement prefs; + try + { + prefs = XElement.Load(filename); + } + catch (Exception) + { + if (System.IO.File.Exists(filename)) + { + ErrorReporter.showMessage_OK("Prefs file exists, but can't be read. Using defaults.", "Preferences Error"); + } + return; // file may not exist (new user) or is inaccessible. We have defaults so can just return without trouble. + } + + try + { + varianceContext.vc.emailAddress = prefs.Descendants("email").Descendants("emailAddress").First().Value; + } + catch (Exception) + { + } + + try + { + varianceContext.vc.emailPwd = prefs.Descendants("email").Descendants("emailPassword").First().Value; + } + catch (Exception) + { + } + + try + { + varianceContext.vc.host = prefs.Descendants("email").Descendants("emailHost").First().Value; + } + catch (Exception) + { + } + + try + { + varianceContext.vc.port = prefs.Descendants("email").Descendants("emailPort").First().Value; + } + catch (Exception) + { + } + + try + { + varianceContext.vc.ssl = Convert.ToBoolean(prefs.Descendants("email").Descendants("emailSSL").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.geoCoreCDVariation = Convert.ToBoolean(prefs.Descendants("geoCore").Descendants("geoCoreCDVariation").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.layerPreviewDOETile = Convert.ToBoolean(prefs.Descendants("geoCore").Descendants("layerPreviewDOETile").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.AA = Convert.ToBoolean(prefs.Descendants("openGL").Descendants("openGLAA").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.FilledPolygons = Convert.ToBoolean(prefs.Descendants("openGL").Descendants("openGLFilledPolygons").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.drawPoints = Convert.ToBoolean(prefs.Descendants("openGL").Descendants("openGLPoints").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.openGLZoomFactor = Convert.ToInt32(prefs.Descendants("openGL").Descendants("openGLZoomFactor").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.BGOpacity = Convert.ToDouble(prefs.Descendants("openGL").Descendants("openGLBGOpacity").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.FGOpacity = Convert.ToDouble(prefs.Descendants("openGL").Descendants("openGLFGOpacity").First().Value); + } + catch (Exception) + { + } + + try + { + varianceContext.vc.friendlyNumber = Convert.ToBoolean(prefs.Descendants("friendlyNumber").First().Value); + } + catch (Exception) + { + } + + varianceContext.vc.rngMappingEquations.Clear(); + varianceContext.vc.rngMappingEquations.Add("Box-Muller"); + try + { + string tempString = prefs.Descendants("rngMappingEquations").First().Value; + string[] equations = tempString.Split(new char[] { ';' }); + for (int i = 0; i < equations.Length; i++) + { + if (equations[i] != "Box-Muller") + { + varianceContext.vc.rngMappingEquations.Add(equations[i]); + } + } + } + catch (Exception) + { + + } + + try + { + string layerCol = "layer1Color"; + varianceContext.vc.colors.layer1_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").Single().Value); + varianceContext.vc.colors.layer1_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").Single().Value); + varianceContext.vc.colors.layer1_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").Single().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer2Color"; + varianceContext.vc.colors.layer2_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer2_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer2_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer3Color"; + varianceContext.vc.colors.layer3_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer3_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer3_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer4Color"; + varianceContext.vc.colors.layer4_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer4_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer4_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer5Color"; + varianceContext.vc.colors.layer5_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer5_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer5_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer6Color"; + varianceContext.vc.colors.layer6_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer6_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer6_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer7Color"; + varianceContext.vc.colors.layer7_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer7_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer7_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer8Color"; + varianceContext.vc.colors.layer8_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer8_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer8_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer9Color"; + varianceContext.vc.colors.layer9_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer9_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer9_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer10Color"; + varianceContext.vc.colors.layer10_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer10_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer10_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer11Color"; + varianceContext.vc.colors.layer11_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer11_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer11_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer12Color"; + varianceContext.vc.colors.layer12_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer12_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer12_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer13Color"; + varianceContext.vc.colors.layer13_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer13_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer13_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer14Color"; + varianceContext.vc.colors.layer14_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer14_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer14_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer15Color"; + varianceContext.vc.colors.layer15_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer15_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer15_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "layer16Color"; + varianceContext.vc.colors.layer16_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.layer16_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.layer16_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "subshape1Color"; + varianceContext.vc.colors.subshape1_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.subshape1_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.subshape1_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "subshape2Color"; + varianceContext.vc.colors.subshape2_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.subshape2_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.subshape2_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "subshape3Color"; + varianceContext.vc.colors.subshape3_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.subshape3_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.subshape3_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "result1Color"; + varianceContext.vc.colors.result_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.result_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.result_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "result2Color"; + varianceContext.vc.colors.result2_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.result2_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.result2_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "result3Color"; + varianceContext.vc.colors.result3_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.result3_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.result3_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "result4Color"; + varianceContext.vc.colors.result4_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.result4_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.result4_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "minImplantColor"; + varianceContext.vc.colors.implantMin_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.implantMin_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.implantMin_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "meanImplantColor"; + varianceContext.vc.colors.implantMean_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.implantMean_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.implantMean_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "maxImplantColor"; + varianceContext.vc.colors.implantMax_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.implantMax_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.implantMax_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "implantResistColor"; + varianceContext.vc.colors.implantResist_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.implantResist_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.implantResist_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "majorColor"; + varianceContext.vc.colors.major_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.major_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.major_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "minorColor"; + varianceContext.vc.colors.minor_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.minor_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.minor_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + try + { + string layerCol = "enabledColor"; + varianceContext.vc.colors.enabled_Color.R = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("R").First().Value); + varianceContext.vc.colors.enabled_Color.G = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("G").First().Value); + varianceContext.vc.colors.enabled_Color.B = Convert.ToInt32(prefs.Descendants("colors").Descendants(layerCol).Descendants("B").First().Value); + } + catch (Exception) + { + } + + varianceContext.vc.colors.rebuildLists(); + } + + void savePrefs() + { + string filename = EtoEnvironment.GetFolderPath(EtoSpecialFolder.ApplicationSettings); + filename += System.IO.Path.DirectorySeparatorChar + "variance_prefs.xml"; + + try + { + XDocument prefsXML = new XDocument( + new XElement("root")); + prefsXML.Root.Add(new XElement("version", CentralProperties.version)); + + XElement emailPrefs = new XElement("email", + new XElement("emailAddress", varianceContext.vc.emailAddress), + new XElement("emailPassword", varianceContext.vc.emailPwd), + new XElement("emailHost", varianceContext.vc.host), + new XElement("emailSSL", varianceContext.vc.ssl), + new XElement("emailPort", varianceContext.vc.port)); + prefsXML.Root.Add(emailPrefs); + + XElement geoCorePrefs = new XElement("geoCore", + new XElement("geoCoreCDVariation", varianceContext.vc.geoCoreCDVariation), + new XElement("layerPreviewDOETile", varianceContext.vc.layerPreviewDOETile)); + prefsXML.Root.Add(geoCorePrefs); + + XElement openGLPrefs = new XElement("openGL", + new XElement("openGLAA", varianceContext.vc.AA), + new XElement("openGLFilledPolygons", varianceContext.vc.FilledPolygons), + new XElement("openGLPoints", varianceContext.vc.drawPoints), + new XElement("openGLZoomFactor", varianceContext.vc.openGLZoomFactor), + new XElement("openGLFGOpacity", varianceContext.vc.FGOpacity), + new XElement("openGLBGOpacity", varianceContext.vc.BGOpacity)); + prefsXML.Root.Add(openGLPrefs); + + prefsXML.Root.Add(new XElement("friendlyNumber", varianceContext.vc.friendlyNumber)); + + string equationString = ""; + for (int i = 0; i < commonVars.rngCustomMapping.Count; i++) + { + if (i > 0) + { + equationString += ";"; + } + equationString += commonVars.rngCustomMapping[i]; + } + XElement rngMappingEquations = new XElement("rngMappingEquations", equationString); // commonVars.rngCustomMapping); + prefsXML.Root.Add(rngMappingEquations); + + XElement colorPrefs = new XElement("colors"); + + XElement layer1Color = new XElement("layer1Color", + new XElement("R", varianceContext.vc.colors.layer1_Color.R), + new XElement("G", varianceContext.vc.colors.layer1_Color.G), + new XElement("B", varianceContext.vc.colors.layer1_Color.B)); + colorPrefs.Add(layer1Color); + + XElement layer2Color = new XElement("layer2Color", + new XElement("R", varianceContext.vc.colors.layer2_Color.R), + new XElement("G", varianceContext.vc.colors.layer2_Color.G), + new XElement("B", varianceContext.vc.colors.layer2_Color.B)); + colorPrefs.Add(layer2Color); + + XElement layer3Color = new XElement("layer3Color", + new XElement("R", varianceContext.vc.colors.layer3_Color.R), + new XElement("G", varianceContext.vc.colors.layer3_Color.G), + new XElement("B", varianceContext.vc.colors.layer3_Color.B)); + colorPrefs.Add(layer3Color); + + XElement layer4Color = new XElement("layer4Color", + new XElement("R", varianceContext.vc.colors.layer4_Color.R), + new XElement("G", varianceContext.vc.colors.layer4_Color.G), + new XElement("B", varianceContext.vc.colors.layer4_Color.B)); + colorPrefs.Add(layer4Color); + + XElement layer5Color = new XElement("layer5Color", + new XElement("R", varianceContext.vc.colors.layer5_Color.R), + new XElement("G", varianceContext.vc.colors.layer5_Color.G), + new XElement("B", varianceContext.vc.colors.layer5_Color.B)); + colorPrefs.Add(layer5Color); + + XElement layer6Color = new XElement("layer6Color", + new XElement("R", varianceContext.vc.colors.layer6_Color.R), + new XElement("G", varianceContext.vc.colors.layer6_Color.G), + new XElement("B", varianceContext.vc.colors.layer6_Color.B)); + colorPrefs.Add(layer6Color); + + XElement layer7Color = new XElement("layer7Color", + new XElement("R", varianceContext.vc.colors.layer7_Color.R), + new XElement("G", varianceContext.vc.colors.layer7_Color.G), + new XElement("B", varianceContext.vc.colors.layer7_Color.B)); + colorPrefs.Add(layer7Color); + + XElement layer8Color = new XElement("layer8Color", + new XElement("R", varianceContext.vc.colors.layer8_Color.R), + new XElement("G", varianceContext.vc.colors.layer8_Color.G), + new XElement("B", varianceContext.vc.colors.layer8_Color.B)); + colorPrefs.Add(layer8Color); + + XElement layer9Color = new XElement("layer9Color", + new XElement("R", varianceContext.vc.colors.layer9_Color.R), + new XElement("G", varianceContext.vc.colors.layer9_Color.G), + new XElement("B", varianceContext.vc.colors.layer9_Color.B)); + colorPrefs.Add(layer9Color); + + XElement layer10Color = new XElement("layer10Color", + new XElement("R", varianceContext.vc.colors.layer10_Color.R), + new XElement("G", varianceContext.vc.colors.layer10_Color.G), + new XElement("B", varianceContext.vc.colors.layer10_Color.B)); + colorPrefs.Add(layer10Color); + + XElement layer11Color = new XElement("layer11Color", + new XElement("R", varianceContext.vc.colors.layer11_Color.R), + new XElement("G", varianceContext.vc.colors.layer11_Color.G), + new XElement("B", varianceContext.vc.colors.layer11_Color.B)); + colorPrefs.Add(layer11Color); + + XElement layer12Color = new XElement("layer12Color", + new XElement("R", varianceContext.vc.colors.layer12_Color.R), + new XElement("G", varianceContext.vc.colors.layer12_Color.G), + new XElement("B", varianceContext.vc.colors.layer12_Color.B)); + colorPrefs.Add(layer12Color); + + XElement layer13Color = new XElement("layer13Color", + new XElement("R", varianceContext.vc.colors.layer13_Color.R), + new XElement("G", varianceContext.vc.colors.layer13_Color.G), + new XElement("B", varianceContext.vc.colors.layer13_Color.B)); + colorPrefs.Add(layer13Color); + + XElement layer14Color = new XElement("layer14Color", + new XElement("R", varianceContext.vc.colors.layer14_Color.R), + new XElement("G", varianceContext.vc.colors.layer14_Color.G), + new XElement("B", varianceContext.vc.colors.layer14_Color.B)); + colorPrefs.Add(layer14Color); + + XElement layer15Color = new XElement("layer15Color", + new XElement("R", varianceContext.vc.colors.layer15_Color.R), + new XElement("G", varianceContext.vc.colors.layer15_Color.G), + new XElement("B", varianceContext.vc.colors.layer15_Color.B)); + colorPrefs.Add(layer15Color); + + XElement layer16Color = new XElement("layer16Color", + new XElement("R", varianceContext.vc.colors.layer16_Color.R), + new XElement("G", varianceContext.vc.colors.layer16_Color.G), + new XElement("B", varianceContext.vc.colors.layer16_Color.B)); + colorPrefs.Add(layer16Color); + + XElement result1Color = new XElement("result1Color", + new XElement("R", varianceContext.vc.colors.result_Color.R), + new XElement("G", varianceContext.vc.colors.result_Color.G), + new XElement("B", varianceContext.vc.colors.result_Color.B)); + colorPrefs.Add(result1Color); + + XElement result2Color = new XElement("result2Color", + new XElement("R", varianceContext.vc.colors.result2_Color.R), + new XElement("G", varianceContext.vc.colors.result2_Color.G), + new XElement("B", varianceContext.vc.colors.result2_Color.B)); + colorPrefs.Add(result2Color); + + XElement result3Color = new XElement("result3Color", + new XElement("R", varianceContext.vc.colors.result3_Color.R), + new XElement("G", varianceContext.vc.colors.result3_Color.G), + new XElement("B", varianceContext.vc.colors.result3_Color.B)); + colorPrefs.Add(result3Color); + + XElement result4Color = new XElement("result4Color", + new XElement("R", varianceContext.vc.colors.result4_Color.R), + new XElement("G", varianceContext.vc.colors.result4_Color.G), + new XElement("B", varianceContext.vc.colors.result4_Color.B)); + colorPrefs.Add(result4Color); + + XElement minImplantColor = new XElement("minImplantColor", + new XElement("R", varianceContext.vc.colors.implantMin_Color.R), + new XElement("G", varianceContext.vc.colors.implantMin_Color.G), + new XElement("B", varianceContext.vc.colors.implantMin_Color.B)); + colorPrefs.Add(minImplantColor); + + XElement meanImplantColor = new XElement("meanImplantColor", + new XElement("R", varianceContext.vc.colors.implantMean_Color.R), + new XElement("G", varianceContext.vc.colors.implantMean_Color.G), + new XElement("B", varianceContext.vc.colors.implantMean_Color.B)); + colorPrefs.Add(meanImplantColor); + + XElement maxImplantColor = new XElement("maxImplantColor", + new XElement("R", varianceContext.vc.colors.implantMax_Color.R), + new XElement("G", varianceContext.vc.colors.implantMax_Color.G), + new XElement("B", varianceContext.vc.colors.implantMax_Color.B)); + colorPrefs.Add(maxImplantColor); + + XElement implantResistColor = new XElement("implantResistColor", + new XElement("R", varianceContext.vc.colors.implantResist_Color.R), + new XElement("G", varianceContext.vc.colors.implantResist_Color.G), + new XElement("B", varianceContext.vc.colors.implantResist_Color.B)); + colorPrefs.Add(implantResistColor); + + XElement subshape1Color = new XElement("subshape1Color", + new XElement("R", varianceContext.vc.colors.subshape1_Color.R), + new XElement("G", varianceContext.vc.colors.subshape1_Color.G), + new XElement("B", varianceContext.vc.colors.subshape1_Color.B)); + colorPrefs.Add(subshape1Color); + + XElement subshape2Color = new XElement("subshape2Color", + new XElement("R", varianceContext.vc.colors.subshape2_Color.R), + new XElement("G", varianceContext.vc.colors.subshape2_Color.G), + new XElement("B", varianceContext.vc.colors.subshape2_Color.B)); + colorPrefs.Add(subshape2Color); + + XElement subshape3Color = new XElement("subshape3Color", + new XElement("R", varianceContext.vc.colors.subshape3_Color.R), + new XElement("G", varianceContext.vc.colors.subshape3_Color.G), + new XElement("B", varianceContext.vc.colors.subshape3_Color.B)); + colorPrefs.Add(subshape3Color); + + XElement enabledColor = new XElement("enabledColor", + new XElement("R", varianceContext.vc.colors.enabled_Color.R), + new XElement("G", varianceContext.vc.colors.enabled_Color.G), + new XElement("B", varianceContext.vc.colors.enabled_Color.B)); + colorPrefs.Add(enabledColor); + + XElement majorColor = new XElement("majorColor", + new XElement("R", varianceContext.vc.colors.major_Color.R), + new XElement("G", varianceContext.vc.colors.major_Color.G), + new XElement("B", varianceContext.vc.colors.major_Color.B)); + colorPrefs.Add(majorColor); + + XElement minorColor = new XElement("minorColor", + new XElement("R", varianceContext.vc.colors.minor_Color.R), + new XElement("G", varianceContext.vc.colors.minor_Color.G), + new XElement("B", varianceContext.vc.colors.minor_Color.B)); + colorPrefs.Add(minorColor); + + prefsXML.Root.Add(colorPrefs); + + prefsXML.Save(filename); + } + catch (Exception) + { + ErrorReporter.showMessage_OK("Failed to save preferences", "Error"); + } + } + + void uiVars() + { + // Figure out host UI element sizes to assist in layout, at least vertically. + // Set controls to null afterwards. + label_Height = 13; // (int)Math.Ceiling(qLabel.Font.MeasureString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWXYZ").Height); + num_Height = 13; // (int)Math.Ceiling(qNum.Font.MeasureString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWXYZ").Height); + checkBox_Height = 13; // (int)Math.Ceiling(qCheckBox.Font.MeasureString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWXYZ").Height); + comboBox_Height = 13; // (int)Math.Ceiling(qDropDown.Font.MeasureString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWXYZ").Height); + radioButton_Height = 13; // (int)Math.Ceiling(qRButton.Font.MeasureString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWXYZ").Height); + + uiScaleFactor = 0.66f; + + simulationOutputGroupBoxHeight = 57; + simulationSettingsGroupBoxHeight = 180; + userGuidanceWidth = 395; + userGuidanceHeight = simulationOutputGroupBoxHeight + simulationSettingsGroupBoxHeight + 22; + + simButtonWidth = 64; + simButtonHeight = 55; + + replayNumWidth = 80; + replayNumHeight = 21; + + multiThreadWarnWidth = 300; + resultFieldWidth = 344; + + previewWidth = 450; + + oneDGuidanceWidth = 271; + + oneDLabelWidth = 132; + + oneDMinInsLblWidth = 100; + + oneDMinInsWidth = 100; + + omitLayerBoxY = 2; + + commentBoxWidth = previewWidth + 2; + commentBoxHeight = 160 - (label_Height * 2); + } + + public MainForm(ref bool doPrompts, VarianceContextGUI _varianceContext) + { + pMainForm(ref doPrompts, _varianceContext); + } + + void pMainForm(ref bool doPrompts, VarianceContextGUI _varianceContext) + { + doPrompts = true; + + // Figure out whether we should display the help menu, if documentation is available. + // string basePath = AppContext.BaseDirectory; // Disabled this as release builds do not seem to populate this field. Use the above complex approach instead. + helpPath = Path.Combine(EtoEnvironment.GetFolderPath(EtoSpecialFolder.ApplicationResources), "Documentation", "index.html"); + helpAvailable = File.Exists(helpPath); + + UI(_varianceContext); + } + + void q() + { + Application.Instance.Quit(); + } + + private bool _veldridReady = false; + public bool VeldridReady + { + get { return _veldridReady; } + private set + { + _veldridReady = value; + + SetUpVeldrid(); + } + } + + private bool _formReady = false; + public bool FormReady + { + get { return _formReady; } + set + { + _formReady = value; + + SetUpVeldrid(); + } + } + + private void SetUpVeldrid() + { + if (!(FormReady && VeldridReady)) + { + return; + } + + viewPort.SetUpVeldrid(); + + // Title = $"Veldrid backend: {vSurface.Backend.ToString()}"; + + viewPort.Clock.Start(); + createVPContextMenu(); + } + + void UI(VarianceContextGUI _varianceContext) + { + if (_varianceContext == null) // safety net. + { + Int32 HTCount = Environment.ProcessorCount; + varianceContext = new VarianceContextGUI(false, "", -1, HTCount, VeldridSurface.PreferredBackend); + } + else + { + varianceContext = _varianceContext; + } + + Shown += (sender, e) => FormReady = true; + + Resizable = true; + Maximizable = true; + + loadPrefs(); + + uiVars(); + + commonVars = new CommonVars(varianceContext.vc); + simReplay = new Replay(ref commonVars); + + geoGBVisible = new bool[CentralProperties.maxLayersForMC]; + subShapeGBVisible = new bool[CentralProperties.maxLayersForMC]; + booleanGBVisible = new bool[CentralProperties.maxLayersForMC]; + + viewport_settings(); + + notList = new List() { "", "!" }; + booleanList = new List() { "&", "|" }; + + mainTable = new TableLayout(); + + setupUIDataContext(notList, booleanList); + + GraphicsDeviceOptions options = new GraphicsDeviceOptions( + false, + Veldrid.PixelFormat.R32_Float, + false, + ResourceBindingModel.Improved); + + vSurface = new VeldridSurface(varianceContext.backend, options); + vSurface.VeldridInitialized += (sender, e) => VeldridReady = true; + + commonVars.titleText += " " + vSurface.Backend.ToString(); + + Title = commonVars.titleText; + + string exeDirectory = ""; + string shaders = ""; + if (Platform.IsMac) + { + // AppContext.BaseDirectory is too simple for the case of the Mac + // projects. When building an app bundle that depends on the Mono + // framework being installed, it properly returns the path of the + // executable in Eto.Veldrid.app/Contents/MacOS. When building an + // app bundle that instead bundles Mono by way of mkbundle, on the + // other hand, it returns the directory containing the .app. + + exeDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); + shaders = Path.Combine("..", "Resources", "shaders"); + } + else + { + exeDirectory = AppContext.BaseDirectory; + shaders = "shaders"; + } + + viewPort = new VeldridDriver(ref mcVPSettings[0], ref vSurface) + { + Surface = vSurface, + ExecutableDirectory = exeDirectory, + ShaderSubdirectory = shaders + }; + + vSurface.Size = new Size(400, 380); + viewPort.updateHostFunc = viewportUpdateHost; + + string viewportToolTipText = "(w/a/s/d) to navigate\r\n(r) to reset\r\n(n/m) to zoom\r\n(f) to freeze/thaw"; + vp = new Panel(); + //vp.Size = new Size(viewPort.Width + 2, viewPort.Height + 2); + if (!Platform.IsMac) // This color setting causes issues on Mac where the viewport doesn't show until the mouse passes over. + { + vp.BackgroundColor = Eto.Drawing.Colors.Black; + } + TableLayout vp_content = new TableLayout(); + vp_content.Rows.Add(new TableRow()); + vp_content.Rows[0].Cells.Add(new TableCell() { Control = vSurface }); + vp.Content = vp_content; + vp.ToolTip = viewportToolTipText; + + vp.Content = vSurface; + + // Splitter and the like. + setup_layout(); + + setup_simPreviewBox(); + + // Configure the tab UI. + setup_tabs(); + + oneDTabSetup(); + + implantTabSetup(); + + twoD_SettingsUISetup(); + twoD_DOEUISetup(); + paSearchUI_setup(); + utilsUISetup(); + + rngLabelIndex = -1; + + commands(); + + TableLayout gadgets_tableLayout = new TableLayout(); + + controls.Content = TableLayout.AutoSized(gadgets_tableLayout, centered: true); + + gadgets_tableLayout.Rows.Add(new TableRow()); + TableCell gtc0 = new TableCell(); + gadgets_tableLayout.Rows[0].Cells.Add(gtc0); + + // Upper section needs a nested layout + + upperGadgets_panel = new Panel(); + gtc0.Control = TableLayout.AutoSized(upperGadgets_panel, centered: true); + + upperGadgets_table = new TableLayout(); + upperGadgets_panel.Content = upperGadgets_table; + + upperGadgets_table.Rows.Add(new TableRow()); + TableCell u_gtc0 = new TableCell(); + + upperGadgets_table.Rows[0].Cells.Add(u_gtc0); + setupOmitLayerCheckboxes(u_gtc0); + upperGadgets_table.Rows[0].Cells.Add(new TableCell() { Control = null }); + + upperGadgets_table.Rows.Add(new TableRow()); + TableCell u_gtc1 = new TableCell(); + upperGadgets_table.Rows[1].Cells.Add(u_gtc1); + setupBGLayerCheckboxes(u_gtc1); + upperGadgets_table.Rows[1].Cells.Add(new TableCell() { Control = null }); + + // Lower section + + gadgets_tableLayout.Rows.Add(new TableRow()); + TableCell gtc2 = new TableCell(); + setupComment(gtc2); + gadgets_tableLayout.Rows[gadgets_tableLayout.Rows.Count - 1].Cells.Add(gtc2); + gadgets_tableLayout.Rows[gadgets_tableLayout.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + // Buttons + gadgets_tableLayout.Rows.Add(new TableRow()); + TableCell gtc3 = new TableCell(); + setup_buttons(gtc3); + gadgets_tableLayout.Rows[gadgets_tableLayout.Rows.Count - 1].Cells.Add(gtc3); + gadgets_tableLayout.Rows[gadgets_tableLayout.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + // Configure checkboxes and zoom gadgets. + gadgets_tableLayout.Rows.Add(new TableRow()); + TableCell gtc4 = new TableCell(); + viewport_gadgets(gtc4); + gadgets_tableLayout.Rows[gadgets_tableLayout.Rows.Count - 1].Cells.Add(gtc4); + gadgets_tableLayout.Rows[gadgets_tableLayout.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + gadgets_tableLayout.Rows[gadgets_tableLayout.Rows.Count - 1].ScaleHeight = true; + + setupGUI(); + + if (varianceContext.vc.xmlFileArg != "") + { + updateStatusLine("Loading project. Please wait."); + string loaderString = commonVars.storage.loadSimulationSettings(currentVersion: CentralProperties.version, + filename: varianceContext.vc.xmlFileArg, + simulationSettings: commonVars.getSimulationSettings(), + simulationSettings_nonSim: commonVars.getSimulationSettings_nonSim(), + listOfSettings: commonVars.getListOfSettings(), + implantSimSettings: commonVars.getImplantSimulationSettings(), + implantSettings_nonSim: commonVars.getImplantSettings_nonSim(), + implantSettings_: commonVars.getImplantSettings(), + nonSimulationSettings_: commonVars.getNonSimulationSettings() + ); + if (loaderString != "") + { + updateStatusLine("Project loading failed."); + ErrorReporter.showMessage_OK(loaderString, "Error during load"); + } + else + { + updateStatusLine("Project loaded successfully"); + commonVars.projectFileName = varianceContext.vc.xmlFileArg; + Title = commonVars.titleText + " - " + commonVars.projectFileName; + } + } + tabControl_main.SelectedIndexChanged += mainTabHandler; + + setReplayControls(); + + globalUIFrozen = false; + layerUIFrozen_exp = false; + entropySettingsChanged(null, EventArgs.Empty); + createVPContextMenu(); + viewPort.reset(); + viewPort.updateViewport(); + + setDefaultIndices(); + do2DLayerUI_exp(0, updateUI: true); + addAllUIHandlers(); + commonVars.setHashes(); + } + + enum layerLookUpOrder { ICV, OCV, SCDU, TCDU, XOL, YOL, HTPV, HTNV, VTPV, VTNV, WOB, LWR, LWR2 } + + void setDefaultIndices() + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + comboBox_geoEqtn_Op[i].SelectedIndex = 0; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_2Layer.Length; i++) + { + comboBox_geoEqtn_Op_2Layer[i].SelectedIndex = 0; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_4Layer.Length; i++) + { + comboBox_geoEqtn_Op_4Layer[i].SelectedIndex = 0; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_8Layer.Length; i++) + { + comboBox_geoEqtn_Op_8Layer[i].SelectedIndex = 0; + } + + comboBox_calcModes.SelectedIndex = 0; + + comboBox_RNG.SelectedIndex = 0; + + comboBox_implantRNG.SelectedIndex = 0; + + try + { + experimental_listBox_layers.SelectedIndex = 0; + } + catch (Exception) + { + + } + } + + void zoomChanged(object sender, EventArgs e) + { + pZoomChanged(); + } + + void pZoomChanged() + { + if (openGLErrorReported) + { + return; + } + if (globalUIFrozen) + { + return; + } + + double zoomValue = 1.0f; + zoomValue = Convert.ToDouble(num_viewportZoom.Value); + if (zoomValue < 0.0001) + { + zoomValue = 0.0001; + } + + viewPort.ovpSettings.setZoomFactor((float)(1.0f / zoomValue)); + + updateViewport(); + } + + void posChanged(object sender, EventArgs e) + { + if (openGLErrorReported) + { + return; + } + if (globalUIFrozen) + { + return; + } + + moveCamera((float)num_viewportX.Value, (float)num_viewportY.Value); + } + + void moveCamera(float x, float y) + { + viewPort.ovpSettings.setCameraPos(x, y); + updateViewport(); + } + + void resetViewPorts() + { + for (int i = 0; i < mcVPSettings.Length; i++) + { + mcVPSettings[i].fullReset(); + } + otkVPSettings_implant.fullReset(); + } + + void viewportUpdateHost() + { + num_viewportZoom.ValueChanged -= zoomChanged; + num_viewportZoom.Value = 1.0f / viewPort.ovpSettings.getZoomFactor(); // use the 'ref' nature of the settings to pull the corresponding zoom value to the UI. + num_viewportX.ValueChanged -= posChanged; + num_viewportY.ValueChanged -= posChanged; + num_viewportX.Value = viewPort.ovpSettings.getCameraX(); + num_viewportY.Value = viewPort.ovpSettings.getCameraY(); + num_viewportX.ValueChanged += posChanged; + num_viewportY.ValueChanged += posChanged; + num_viewportZoom.ValueChanged += zoomChanged; + createVPContextMenu(); + } + + void createVPContextMenu() + { + if (viewPort.dragging) + { + return; + } + // Single viewport now mandates regeneration of the context menu each time, to allow for entry screening. + vp_menu = new ContextMenu(); + + int mainIndex = getMainSelectedIndex(); + int subIndex = getSubTabSelectedIndex(); + int layerIndex = getSelectedLayerIndex(); + + int itemIndex = 0; + int svgIndex = 1; + int layoutIndex = 2; + vp_menu.Items.Add(new ButtonMenuItem { Text = "Reset" }); + vp_menu.Items[itemIndex].Click += delegate + { + viewPort.reset(); + updateViewport(); + }; + itemIndex++; + + var VPMenuDisplayOptionsMenu = vp_menu.Items.GetSubmenu("Display Options"); + itemIndex++; + int displayOptionsSubItemIndex = 0; + VPMenuDisplayOptionsMenu.Items.Add(new ButtonMenuItem { Text = "Toggle AA" }); + VPMenuDisplayOptionsMenu.Items[displayOptionsSubItemIndex].Click += delegate + { + viewPort.ovpSettings.aA(!viewPort.ovpSettings.aA()); + updateViewport(); + }; + displayOptionsSubItemIndex++; + VPMenuDisplayOptionsMenu.Items.Add(new ButtonMenuItem { Text = "Toggle Fill" }); + VPMenuDisplayOptionsMenu.Items[displayOptionsSubItemIndex].Click += delegate + { + viewPort.ovpSettings.drawFilled(!viewPort.ovpSettings.drawFilled()); + if (mainIndex == (int)CommonVars.upperTabNames.Implant) + { + doImplantShadowing(); + } + else + { + switch (subIndex) + { + case (int)CommonVars.twoDTabNames.settings: + case (int)CommonVars.twoDTabNames.paSearch: + entropySettingsChanged(null); + break; + case (int)CommonVars.twoDTabNames.DOE: + doeSettingsChanged(); + break; + default: + generatePreviewPanelContent(getSelectedLayerIndex()); + break; + } + } + updateViewport(); + }; + displayOptionsSubItemIndex++; + VPMenuDisplayOptionsMenu.Items.Add(new ButtonMenuItem { Text = "Toggle Points" }); + VPMenuDisplayOptionsMenu.Items[displayOptionsSubItemIndex].Click += delegate + { + viewPort.ovpSettings.drawPoints(!viewPort.ovpSettings.drawPoints()); + updateViewport(); + }; + displayOptionsSubItemIndex++; + + if (mainIndex != (int)CommonVars.upperTabNames.Implant) + { + if (viewPort.ovpSettings.isLocked()) + { + vp_menu.Items.Add(new ButtonMenuItem { Text = "Thaw" }); + } + else + { + vp_menu.Items.Add(new ButtonMenuItem { Text = "Freeze" }); + } + freezeThawIndex = itemIndex; + vp_menu.Items[itemIndex].Click += delegate + { + viewPort.freeze_thaw(); + }; + itemIndex++; + vp_menu.Items.AddSeparator(); + itemIndex++; + vp_menu.Items.Add(new ButtonMenuItem { Text = "Save bookmark" }); + vp_menu.Items[itemIndex].Click += delegate + { + viewPort.saveLocation(); + }; + itemIndex++; + vp_menu.Items.Add(new ButtonMenuItem { Text = "Load bookmark" }); + vp_menu.Items[itemIndex].Click += delegate + { + viewPort.loadLocation(); + }; + loadBookmarkIndex = itemIndex; + if (!viewPort.savedLocation_valid) + { + vp_menu.Items[loadBookmarkIndex].Enabled = false; + } + itemIndex++; + vp_menu.Items.Add(new ButtonMenuItem { Text = "Use location for all viewports" }); + vp_menu.Items[itemIndex].Click += delegate + { + applyLocationToViewports(viewPort.ovpSettings.getCameraPos()); + }; + itemIndex++; + if (subIndex == (int)CommonVars.twoDTabNames.DOE) + { + vp_menu.Items.Add(new ButtonMenuItem { Text = "Go to bottom left corner" }); + vp_menu.Items[itemIndex].Click += delegate + { + double blX = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colOffset); + double blY = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowOffset); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + subIndex].setCameraPos((float)blX, (float)blY); + }; + itemIndex++; + } + } + vp_menu.Items.AddSeparator(); + itemIndex++; + vp_menu.Items.Add(new ButtonMenuItem { Text = "Zoom Extents" }); + vp_menu.Items[itemIndex].Click += delegate + { + viewPort.zoomExtents(); + }; + itemIndex++; + vp_menu.Items.AddSeparator(); + itemIndex++; + vp_menu.Items.Add(new ButtonMenuItem { Text = "Zoom In" }); + vp_menu.Items[itemIndex].Click += delegate + { + viewPort.zoomIn(-1); + updateViewport(); + }; + itemIndex++; + + var VPMenuZoomInMenu = vp_menu.Items.GetSubmenu("Fast Zoom In"); + itemIndex++; + int zoomInSubItemIndex = 0; + VPMenuZoomInMenu.Items.Add(new ButtonMenuItem { Text = "Zoom In (x5)" }); + VPMenuZoomInMenu.Items[zoomInSubItemIndex].Click += delegate + { + viewPort.fastZoomIn(-50); + updateViewport(); + }; + zoomInSubItemIndex++; + VPMenuZoomInMenu.Items.Add(new ButtonMenuItem { Text = "Zoom In (x10)" }); + VPMenuZoomInMenu.Items[zoomInSubItemIndex].Click += delegate + { + viewPort.fastZoomIn(-100); + updateViewport(); + }; + zoomInSubItemIndex++; + VPMenuZoomInMenu.Items.Add(new ButtonMenuItem { Text = "Zoom In (x50)" }); + VPMenuZoomInMenu.Items[zoomInSubItemIndex].Click += delegate + { + viewPort.fastZoomIn(-500); + updateViewport(); + }; + zoomInSubItemIndex++; + VPMenuZoomInMenu.Items.Add(new ButtonMenuItem { Text = "Zoom In (x100)" }); + VPMenuZoomInMenu.Items[zoomInSubItemIndex].Click += delegate + { + viewPort.fastZoomIn(-1000); + updateViewport(); + }; + zoomInSubItemIndex++; + + vp_menu.Items.AddSeparator(); + itemIndex++; + + vp_menu.Items.Add(new ButtonMenuItem { Text = "Zoom Out" }); + vp_menu.Items[itemIndex].Click += delegate + { + viewPort.zoomOut(-1); + updateViewport(); + }; + itemIndex++; + + var VPMenuZoomOutMenu = vp_menu.Items.GetSubmenu("Fast Zoom Out"); + itemIndex++; + int zoomOutSubItemIndex = 0; + VPMenuZoomOutMenu.Items.Add(new ButtonMenuItem { Text = "Zoom Out (x5)" }); + VPMenuZoomOutMenu.Items[zoomOutSubItemIndex].Click += delegate + { + viewPort.fastZoomOut(-50); + updateViewport(); + }; + zoomOutSubItemIndex++; + VPMenuZoomOutMenu.Items.Add(new ButtonMenuItem { Text = "Zoom Out (x10)" }); + VPMenuZoomOutMenu.Items[zoomOutSubItemIndex].Click += delegate + { + viewPort.fastZoomOut(-100); + updateViewport(); + }; + zoomOutSubItemIndex++; + VPMenuZoomOutMenu.Items.Add(new ButtonMenuItem { Text = "Zoom Out (x50)" }); + VPMenuZoomOutMenu.Items[zoomOutSubItemIndex].Click += delegate + { + viewPort.fastZoomOut(-500); + updateViewport(); + }; + zoomOutSubItemIndex++; + VPMenuZoomOutMenu.Items.Add(new ButtonMenuItem { Text = "Zoom Out (x100)" }); + VPMenuZoomOutMenu.Items[zoomOutSubItemIndex].Click += delegate + { + viewPort.fastZoomOut(-1000); + updateViewport(); + }; + zoomOutSubItemIndex++; + + if (mainIndex != (int)CommonVars.upperTabNames.Implant) + { + if (viewPort.ovpSettings.isLocked()) + { + vp_menu.Items[freezeThawIndex].Text = "Thaw"; + } + else + { + vp_menu.Items[freezeThawIndex].Text = "Freeze"; + } + + if (viewPort.savedLocation_valid) + { + vp_menu.Items[loadBookmarkIndex].Enabled = true; + } + else + { + vp_menu.Items[loadBookmarkIndex].Enabled = false; + } + } + + svgIndex = itemIndex + 1; + + vp_menu.Items.AddSeparator(); + + svgIndex = itemIndex + 1; + vp_menu.Items.Add(new ButtonMenuItem { Text = "Save SVG" }); + vp_menu.Items[svgIndex].Click += delegate + { + saveViewportSVG_File(); + }; + + layoutIndex = svgIndex + 1; + vp_menu.Items.Add(new ButtonMenuItem { Text = "Save Layout" }); + vp_menu.Items[layoutIndex].Click += delegate + { + if ((mainIndex == (int)CommonVars.upperTabNames.twoD) && (subIndex == (int)CommonVars.twoDTabNames.layer)) + { + exportActiveLayerToLayout(); + } + else + { + saveViewportLayout_File(); + } + }; + + viewPort.setContextMenu(ref vp_menu); + } + + void setup_tabs() + { + tabPage2_table = new TableLayout(); + tabPage2 = new TabPage(); + tabPage2.Text = "2D Calculation"; + tabPage2.Content = tabPage2_table; + + tabControl_main.Pages.Add(tabPage2); + + Scrollable tabPage_implant_scrollable = new Scrollable(); + tabPage_implant_table = new TableLayout(); + tabPage_implant_scrollable.Content = tabPage_implant_table; + + tabPage_implant = new TabPage(); + tabPage_implant.Text = "Implant"; + + tabPage_implant.Content = tabPage_implant_scrollable; + + tabControl_main.Pages.Add(tabPage_implant); + + tab_1DCalc = new TabPage(); + tab_1DCalc.Text = "1D Calculation"; + tabControl_main.Pages.Add(tab_1DCalc); + + tabPage_utilities_table = new TableLayout(); + Scrollable tabPage_utilities_scrollable = new Scrollable(); + tabPage_utilities_scrollable.Content = tabPage_utilities_table; + + tabPage_utilities = new TabPage(); + tabPage_utilities.Text = "Utils"; + + tabPage_utilities.Content = tabPage_utilities_scrollable; + + tabControl_main.Pages.Add(tabPage_utilities); + + tabPage2_table.Rows.Add(new TableRow()); + + tabControl_2D_simsettings = new TabControl(); + tabPage2_table.Rows[tabPage2_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = tabControl_2D_simsettings }); + + Scrollable tabPage_2D_Settings_scrollable = new Scrollable(); + tabPage_2D_Settings_table = new TableLayout(); + tabPage_2D_Settings_scrollable.Content = tabPage_2D_Settings_table; + + twoD_LayerUISetup(); + + tabPage_2D_Settings = new TabPage(); + tabPage_2D_Settings.Text = "Settings"; + tabPage_2D_Settings.Content = tabPage_2D_Settings_scrollable; + tabControl_2D_simsettings.Pages.Add(tabPage_2D_Settings); + + Scrollable tabPage_2D_DOE_scrollable = new Scrollable(); + tabPage_2D_DOE_table = new TableLayout(); + tabPage_2D_DOE_scrollable.Content = tabPage_2D_DOE_table; + + tabPage_2D_DOE = new TabPage(); + tabPage_2D_DOE.Text = "DOE"; + + tabPage_2D_DOE.Content = tabPage_2D_DOE_scrollable; + + tabControl_2D_simsettings.Pages.Add(tabPage_2D_DOE); + + + tabPage_2D_PASearch_scrollable = new Scrollable(); + tabPage_2D_PASearch_table = new TableLayout(); + tabPage_2D_PASearch_scrollable.Content = tabPage_2D_PASearch_table; + + tabPage_2D_PASearch = new TabPage(); + tabPage_2D_PASearch.Text = "PA Search"; + + tabPage_2D_PASearch.Content = tabPage_2D_PASearch_scrollable; + + tabControl_2D_simsettings.Pages.Add(tabPage_2D_PASearch); + } + + void setup_layout() + { + // mainPanel is tab UI. + Panel mainPanel = new Panel(); + mainPanel.Size = new Size(920, 800); // force the UI out to contain the panel. Hope this will be redundant eventually with the table UI. + mainPanel.Content = mainTable; + // rightPanel will take viewport and controls. + Panel rightPanel = new Panel(); + Panel mainSplitter = new Panel(); + mainSplitter.Content = new Splitter + { + Orientation = Orientation.Horizontal, + FixedPanel = SplitterFixedPanel.Panel1, + Panel1 = mainPanel, + Panel2 = rightPanel, + }; + + // Controls + controls = new Scrollable(); + + rightPanel.Content = new Splitter + { + Orientation = Orientation.Vertical, + FixedPanel = SplitterFixedPanel.Panel1, + Panel1 = controls, + Panel2 = vp, + }; + + // We need an additional level here to take the status label and progress bar in the lower portion of the UI. + Panel outerPanel_upper = new Panel(); + outerPanel_upper.Content = mainSplitter; + Panel outerPanel_lower = new Panel(); + TableLayout outerPanel_lower_content = new TableLayout(); + TableRow oplc_row0 = new TableRow(); + outerPanel_lower_content.Rows.Add(oplc_row0); + outerPanel_lower.Content = outerPanel_lower_content; + Panel outerPanel = new Panel(); + outerPanel.Content = new Splitter + { + Orientation = Orientation.Vertical, + FixedPanel = SplitterFixedPanel.Panel2, + Panel1 = outerPanel_upper, + Panel2 = outerPanel_lower, + }; + + // Assign the outer panel to the contents. + Content = outerPanel; + + mainTable.Rows.Add(new TableRow()); + + tabControl_main = new TabControl(); + mainTable.Rows[0].Cells.Add(new TableCell() { Control = tabControl_main }); + + // Stick our progress indicator and status label in here. + statusReadout = new Label(); + statusReadout.Text = "Welcome"; + statusReadout.TextAlignment = TextAlignment.Center; + oplc_row0.Cells.Add(new TableCell() { Control = statusReadout, ScaleWidth = true }); + + statusProgressBar = new ProgressBar(); + statusProgressBar.Value = 0; + statusProgressBar.Size = new Size(100, label_Height); + oplc_row0.Cells.Add(new TableCell() { Control = statusProgressBar, ScaleWidth = false }); + } + + void setupComment(TableCell tc) + { + Panel p = new Panel(); + commentBox = new RichTextArea(); + p.Content = commentBox; + tc.Control = TableLayout.AutoSized(p, centered: true); + commentBox.Wrap = true; + commentBox.ReadOnly = false; + commentBox.LostFocus += commentChanged; + setSize(commentBox, commentBoxWidth, commentBoxHeight); + } + + void launchHelp(object sender, EventArgs e) + { + // errorReporter.showMessage_OK(helpPath, "Info"); + if (helpAvailable) + { + System.Diagnostics.Process.Start(helpPath); + } + } + + void commands() + { + Closed += quitHandler; + + quitCommand = new Command { MenuText = "Quit", Shortcut = Application.Instance.CommonModifier | Keys.Q }; + quitCommand.Executed += quit; + Application.Instance.Terminating += quitHandler; // write our prefs out. + + aboutCommand = new Command { MenuText = "About..." }; + aboutCommand.Executed += aboutMe; + + helpCommand = new Command { MenuText = "Help...", Shortcut = Keys.F1 }; + helpCommand.Executed += launchHelp; + + clearLayer = new Command { MenuText = "Clear Layer", ToolBarText = "Clear Layer", Shortcut = Application.Instance.CommonModifier | Keys.X }; + clearLayer.Executed += clearHandler; + + copyLayer = new Command { MenuText = "Copy", ToolBarText = "Copy", Shortcut = Application.Instance.CommonModifier | Keys.C }; + copyLayer.Executed += copyHandler; + + pasteLayer = new Command { MenuText = "Paste", ToolBarText = "Paste", Shortcut = Application.Instance.CommonModifier | Keys.V }; + pasteLayer.Executed += pasteHandler; + + newSim = new Command { MenuText = "New", ToolBarText = "New", Shortcut = Application.Instance.CommonModifier | Keys.N }; + newSim.Executed += newHandler; + + openSim = new Command { MenuText = "Open", ToolBarText = "Open", Shortcut = Application.Instance.CommonModifier | Keys.O }; + openSim.Executed += openHandler; + + revertSim = new Command { MenuText = "Revert", ToolBarText = "Revert", Shortcut = Application.Instance.CommonModifier | Keys.R }; + revertSim.Executed += revertHandler; + revertSim.Enabled = false; + + saveSim = new Command { MenuText = "Save", ToolBarText = "Save", Shortcut = Application.Instance.CommonModifier | Keys.S }; + saveSim.Executed += saveHandler; + + saveAsSim = new Command { MenuText = "Save As", ToolBarText = "Save As", Shortcut = Application.Instance.CommonModifier | Keys.Shift | Keys.S }; + saveAsSim.Executed += saveAsHandler; + + // create menu + Menu = new MenuBar + { + Items = { + //File submenu + new ButtonMenuItem { Text = "&File", Items = { newSim, openSim, revertSim, saveSim, saveAsSim } }, + new ButtonMenuItem { Text = "&Edit", Items = { copyLayer, pasteLayer, clearLayer } }, + }, + /*ApplicationItems = { + // application (OS X) or file menu (others) + new ButtonMenuItem { Text = "&Preferences..." }, + },*/ + QuitItem = quitCommand, + HelpItems = { + helpCommand + }, + AboutItem = aboutCommand + }; + + helpCommand.Enabled = helpAvailable; + } + + void setup_buttons(TableCell tc) + { + Panel p = new Panel(); + tc.Control = TableLayout.AutoSized(p, centered: true); + + TableLayout buttons_table = new TableLayout(); + p.Content = buttons_table; + buttons_table.Rows.Add(new TableRow()); + + btn_singleCPU = new Button(); + btn_singleCPU.Text = "Single\r\nCPU"; + setSize(btn_singleCPU, simButtonWidth, simButtonHeight); + btn_singleCPU.Click += monteCarloSingleThreadEventHandler; + // buttons_table.Rows[0].Cells.Add(new TableCell() { Control = btn_singleCPU }); + + btn_multiCPU = new Button(); + btn_multiCPU.Text = "Multi\r\nCPU"; + setSize(btn_multiCPU, simButtonWidth, simButtonHeight); + btn_multiCPU.Click += monteCarloMultipleThreadEventHandler; + buttons_table.Rows[0].Cells.Add(new TableCell() { Control = btn_multiCPU }); + + btn_Cancel = new Button(); + btn_Cancel.Text = "Cancel"; + setSize(btn_Cancel, simButtonWidth, simButtonHeight); + btn_Cancel.Click += btnCancel; + buttons_table.Rows[0].Cells.Add(new TableCell() { Control = btn_Cancel }); + + btn_STOP = new Button(); + btn_STOP.Text = "STOP"; + setSize(btn_STOP, simButtonWidth, simButtonHeight); + btn_STOP.Click += btnSTOP; + buttons_table.Rows[0].Cells.Add(new TableCell() { Control = btn_STOP }); + } + + void viewport_gadgets(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; // TableLayout.AutoSized(p, centered: true); + + TableLayout viewport_gadgets_tl = new TableLayout(); + p.Content = viewport_gadgets_tl; + viewport_gadgets_tl.Rows.Add(new TableRow()); + + lbl_simPreviewZoom = new Label(); + lbl_simPreviewZoom.Text = "Zoom"; + viewport_gadgets_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_simPreviewZoom }); + + num_viewportZoom = new NumericStepper(); + num_viewportZoom.DecimalPlaces = 2; + num_viewportZoom.Increment = 0.01; + num_viewportZoom.Value = 1.0; + num_viewportZoom.MinValue = 0.001; + setSize(num_viewportZoom, 55, num_Height); + num_viewportZoom.LostFocus += zoomChanged; + viewport_gadgets_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_viewportZoom) }); + + viewport_gadgets_tl.Rows[0].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); // padding + + lbl_viewportPos = new Label(); + lbl_viewportPos.Text = "Position"; + viewport_gadgets_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_viewportPos }); + + num_viewportX = new NumericStepper(); + num_viewportX.DecimalPlaces = 2; + num_viewportX.Increment = 0.01; + num_viewportX.Value = 0; + setSize(num_viewportX, 75, num_Height); + num_viewportX.LostFocus += posChanged; + viewport_gadgets_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_viewportX) }); + + num_viewportY = new NumericStepper(); + num_viewportY.DecimalPlaces = 2; + num_viewportY.Increment = 0.01; + num_viewportY.Value = 0; + setSize(num_viewportY, 75, num_Height); + num_viewportY.LostFocus += posChanged; + viewport_gadgets_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_viewportY) }); + } + + void viewport_settings() + { + mcVPSettings = new OVPSettings[CentralProperties.maxLayersForMC + 1 + 1]; // 16 layers, plus simulation and DOE + for (int i = 0; i < mcVPSettings.Length; i++) + { + mcVPSettings[i] = new OVPSettings(); + mcVPSettings[i].setBaseZoom(0.25f); + mcVPSettings[i].drawFilled(commonVars.getOpenGLProp(CommonVars.properties_gl.fill)); + mcVPSettings[i].drawPoints(commonVars.getOpenGLProp(CommonVars.properties_gl.points)); + mcVPSettings[i].minorGridColor = Color.FromArgb(commonVars.getColors().minor_Color.toArgb()); + mcVPSettings[i].majorGridColor = Color.FromArgb(commonVars.getColors().major_Color.toArgb()); + } + mcVPSettings[mcVPSettings.Length - 2].drawDrawn(true); + mcVPSettings[mcVPSettings.Length - 1].drawDrawn(true); + + otkVPSettings_implant = new OVPSettings(45.0f, 45.0f); + otkVPSettings_implant.setBaseZoom(0.25f); + otkVPSettings_implant.drawDrawn(true); + otkVPSettings_implant.drawFilled(commonVars.getOpenGLProp(CommonVars.properties_gl.fill)); + otkVPSettings_implant.drawPoints(commonVars.getOpenGLProp(CommonVars.properties_gl.points)); + otkVPSettings_implant.minorGridColor = Color.FromArgb(commonVars.getColors().minor_Color.toArgb()); + otkVPSettings_implant.majorGridColor = Color.FromArgb(commonVars.getColors().major_Color.toArgb()); + } + + void setupOmitLayerCheckboxes(TableCell tc) + { + Panel p = new Panel(); + tc.Control = TableLayout.AutoSized(p, centered: true); + + omitLayerBox = new GroupBox(); + + p.Content = omitLayerBox; + omitLayerBox.Text = "Omit layers (Boolean)"; + + TableLayout omitLayerBox_table = new TableLayout(); + omitLayerBox.Content = omitLayerBox_table; + + omitLayerBox_table.Rows.Add(new TableRow()); + omitLayerBox_table.Rows.Add(new TableRow()); + + checkBox_omit_lyr = new CheckBox[CentralProperties.maxLayersForMC]; + int rowIndex = 0; + for (int cb = 0; cb < CentralProperties.maxLayersForMC; cb++) + { + // Don't add a button for our current layer + checkBox_omit_lyr[cb] = new CheckBox(); + checkBox_omit_lyr[cb].Text = (cb + 1).ToString(); + + TableCell tc0 = new TableCell(); + tc0.Control = checkBox_omit_lyr[cb]; + omitLayerBox_table.Rows[rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if ((cb + 1) == CentralProperties.maxLayersForMC / 2) + { + rowIndex++; + } + } + } + + void updateOmitLayerCheckboxes() + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + checkBox_omit_lyr[i].CheckedChanged -= omitLayerCheckboxChanged; + checkBox_omit_lyr[i].Checked = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.omit) == 1; + checkBox_omit_lyr[i].CheckedChanged += omitLayerCheckboxChanged; + } + } + + void setupBGLayerCheckboxes(TableCell tc) + { + Panel p = new Panel(); + tc.Control = TableLayout.AutoSized(p, centered: true); + + bgLayerBox = new GroupBox(); + p.Content = bgLayerBox; + + bgLayerBox.Text = "Background layers"; + + bgLayerBox_table = new TableLayout(); + bgLayerBox.Content = bgLayerBox_table; + bgLayerBox_table.Rows.Add(new TableRow()); + bgLayerBox_table.Rows.Add(new TableRow()); + + checkBox_bg_lyr = new CheckBox[CentralProperties.maxLayersForMC]; + + int rowIndex = 0; + for (int cb = 0; cb < CentralProperties.maxLayersForMC; cb++) + { + // Don't add a button for our current layer + checkBox_bg_lyr[cb] = new CheckBox(); + checkBox_bg_lyr[cb].Text = (cb + 1).ToString(); + + TableCell tc0 = new TableCell(); + tc0.Control = checkBox_bg_lyr[cb]; + bgLayerBox_table.Rows[rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if ((cb + 1) == CentralProperties.maxLayersForMC / 2) + { + rowIndex++; + } + } + } + + void setup_simPreviewBox() + { + simPreviewBox = new GroupBox(); + simPreviewBox.Text = "Simulation Elements"; + + TableLayout simPreviewBox_table = new TableLayout(); + simPreviewBox.Content = simPreviewBox_table; + simPreviewBox_table.Rows.Add(new TableRow()); + + checkBox_displayShapes = new CheckBox(); + checkBox_displayShapes.Text = "Display input shapes for each case"; + simPreviewBox_table.Rows[0].Cells.Add(new TableCell() { Control = checkBox_displayShapes }); + checkBox_displayShapes.Checked = true; + + checkBox_displayResults = new CheckBox(); + checkBox_displayResults.Text = "Display results for each case"; + simPreviewBox_table.Rows[0].Cells.Add(new TableCell() { Control = checkBox_displayResults }); + + simPreviewBox_table.Rows[0].Cells.Add(new TableCell() { Control = null }); + + checkBox_displayResults.Checked = true; + } + + void setSize(Button _control, int width, int height) + { + _control.Width = width; + _control.Height = height; + } + + void setSize(TextArea _control, int width, int height) + { + _control.Width = width; + _control.Height = height; + } + + void setSize(RichTextArea _control, int width, int height) + { + _control.Width = width; + _control.Height = height; + } + + void setSize(CommonControl _control, int width, int height) + { + _control.Width = width; + } + + void setSize(GroupBox _control, int width, int height) + { + _control.Width = width; + _control.Height = height; + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers.cs b/Common/Variance/UI/UIHandlers.cs new file mode 100644 index 0000000..f99a87e --- /dev/null +++ b/Common/Variance/UI/UIHandlers.cs @@ -0,0 +1,439 @@ +using Eto.Drawing; +using Eto.Forms; +using System; + +namespace Variance +{ + public partial class MainForm + { + void aboutMe(object sender, EventArgs e) + { + if (aboutBox == null || !aboutBox.Visible) + { + string creditText = "Version " + commonVars.version + ", " + + "© " + commonVars.author + " 2014-2020" + "\r\n\r\n"; + creditText += varianceContext.vc.licenceName; + creditText += "\r\n\r\n"; + creditText += "Libraries used:\r\n"; + creditText += " Eto.Forms : UI framework\r\n\thttps://github.com/picoe/Eto/wiki\r\n"; + creditText += " Eto.Veldrid : Eto Veldrid viewport\r\n\thttps://github.com/philstopford/Eto.Veldrid\r\n"; + creditText += " DesignLibs : Design libraries\r\n\thttps://github.com/philstopford/DesignLibs_GPL\r\n"; + creditText += " clipperLib : geometry processing, area, SVG output reference\r\n\thttp://sourceforge.net/projects/polyclipping/\r\n"; + creditText += " KD-Sharp : for spacing/enclosure\r\n\thttps://code.google.com/p/kd-sharp/\r\n"; + creditText += " LibTessDotNet : for Delauney triangulation (tone inversion of n polygons)\r\n\thttps://github.com/speps/LibTessDotNet\r\n"; + creditText += " Mersenne Twister : \r\n\thttp://www.centerspace.net/resources/free-stuff/mersenne-twister\r\n"; + creditText += " ExpressionParser : \r\n\thttp://lundin.info/mathparser\r\n"; + creditText += " MiscUtil : \r\n\thttp://yoda.arachsys.com/csharp/miscutil/\r\n"; + aboutBox = new CreditsScreen(this, creditText); + } + Point location = new Point(Location.X + (Width - aboutBox.Width) / 2, + Location.Y + (Height - aboutBox.Height) / 2); + aboutBox.Location = location; + aboutBox.Show(); + } + + void quit(object sender, EventArgs e) + { + savePrefs(); + Application.Instance.Quit(); + } + + void quitHandler(object sender, EventArgs e) + { + savePrefs(); + } + + void suspendUIHandlers() + { + Application.Instance.Invoke(() => + { + globalUIFrozen = true; + suspendImplantUI(); + suspendDOESettingsUI(); + suspendSettingsUI(); + suspendLayerUI_exp(); + }); + } + + void resumeUIHandlers() + { + Application.Instance.Invoke(() => + { + globalUIFrozen = false; + resumeLayerUI_exp(); + resumeSettingsUI(); + resumeDOESettingsUI(); + resumeImplantUI(); + saveEnabler(); + uiFollowChanges(); + }); + } + + void mcPreviewSettingsChanged(object sender, EventArgs e) + { + int tabIndex = getSubTabSelectedIndex(); + if ((tabIndex == (int)CommonVars.twoDTabNames.settings) || (tabIndex == (int)CommonVars.twoDTabNames.paSearch)) + { + upperGadgets_panel.Content = simPreviewBox; + } + if (checkBox_displayResults.Checked == true) + { + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.results, 1); + } + else + { + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.results, 0); + } + if (checkBox_displayShapes.Checked == true) + { + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.shape, 1); + } + else + { + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.shape, 0); + } + + doStatusLine(); + drawSimulationPanelHandler(false); + + if (!commonVars.isSimRunning()) + { + entropyControl.update(commonVars); + } + } + + void mainTabChanged(object sender, EventArgs e) + { + btn_singleCPU.Enabled = false; + + btn_multiCPU.Enabled = false; + btn_STOP.Enabled = false; + + statusProgressBar.Visible = false; + + upperGadgets_panel.Content = new Panel(); + + commentBox.Enabled = false; + + int mainIndex = getMainSelectedIndex(); + + if (mainIndex == (Int32)CommonVars.upperTabNames.Implant) + { + updateImplantUIFromSettings(); + + upperGadgets_panel.Content = simPreviewBox; + + statusProgressBar.Visible = true; + + commentBox.Enabled = true; + + viewPort.changeSettingsRef(ref otkVPSettings_implant); + + } + else //if (tabControl_main.SelectedIndex == (Int32)CommonVars.upperTabNames.twoD) + { + subTabChanged(); + // entropySettingsChanged(sender, e); + } + + if (mainIndex == (Int32)CommonVars.upperTabNames.twoD) + { + upperGadgets_panel.Content = upperGadgets_table; + commentBox.Enabled = true; + } + + if (/*(mainIndex == (Int32)CommonVars.upperTabNames.oneD) ||*/ + (mainIndex == (Int32)CommonVars.upperTabNames.Utilities)) + { + lbl_simPreviewZoom.Visible = false; + lbl_viewportPos.Visible = false; + num_viewportZoom.Visible = false; + num_viewportX.Visible = false; + num_viewportY.Visible = false; + commentBox.Enabled = false; + if (vp != null) + { + vp.Visible = false; + } + } + else + { + lbl_simPreviewZoom.Visible = true; + lbl_viewportPos.Visible = true; + num_viewportZoom.Visible = true; + num_viewportX.Visible = true; + num_viewportY.Visible = true; + if (vp != null) + { + vp.Visible = true; + } + } + if (mainIndex == (Int32)CommonVars.upperTabNames.Utilities) + { + updateUtilsValues(); + } + getComment(); + startButtonCheck(); + } + + void subTabChanged(object sender, EventArgs e) + { + subTabChanged(); + } + + void subTabChanged() + { + int subTabIndex = getSubTabSelectedIndex(); + switch (subTabIndex) + { + case (Int32)CommonVars.twoDTabNames.layer: + listbox_change(); + do2DLayerUI_exp(getSelectedLayerIndex(), updateUI: true); + break; + case (Int32)CommonVars.twoDTabNames.settings: + updateSettingsUIFromSettings(); + break; + case (Int32)CommonVars.twoDTabNames.DOE: + updateDOESettingsUIFromSettings(); + break; + } + entropySettingsChanged(null); + mcPreviewSettingsChanged(null, EventArgs.Empty); + int vpindex = getSubTabSelectedIndex(); + if (vpindex == (int)CommonVars.twoDTabNames.DOE) + { + vpindex = CentralProperties.maxLayersForMC + 1; // layers and simulation viewport. + } + else + { + if (vpindex != (int)CommonVars.twoDTabNames.layer) + { + vpindex = CentralProperties.maxLayersForMC; // layer count + } + else + { + vpindex = getSelectedLayerIndex(); + } + } + viewPort.changeSettingsRef(ref mcVPSettings[vpindex]); + } + + void uiFollowChanges() + { + commonVars.checkChanged(); + revertSim.Enabled = false; + + string title = commonVars.titleText; + + if (commonVars.projectFileName != "") + { + title += " - " + commonVars.projectFileName; + + if (commonVars.isChanged()) + { + title += " *"; + revertSim.Enabled = true; + } + } + + Application.Instance.Invoke(() => + { + Title = title; + }); + } + + void mainTabHandler(object sender, EventArgs e) + { + setGlobalUIValues(); + doStatusLine(); + } + + void doStatusLine() + { + int mainIndex = getMainSelectedIndex(); + int subTabIndex = getSubTabSelectedIndex(); + + switch (mainIndex) + { + case (int)CommonVars.upperTabNames.Implant: + if (!openGLErrorReported) + { + createVPContextMenu(); + viewPort.changeSettingsRef(ref otkVPSettings_implant); + } + updateStatusLine("Configure simulation settings"); + break; + case (int)CommonVars.upperTabNames.twoD: + switch (subTabIndex) + { + case (int)CommonVars.twoDTabNames.settings: + updateStatusLine("Configure simulation settings"); + break; + case (int)CommonVars.twoDTabNames.paSearch: + updateStatusLine("Configure PA search settings."); + break; + case (int)CommonVars.twoDTabNames.DOE: + updateStatusLine("Configure DOE settings."); + break; + default: + updateStatusLine("Configure layer settings"); + break; + } + break; + case (int)CommonVars.upperTabNames.Utilities: + updateStatusLine("Miscellaneous utilities"); + break; + case (int)CommonVars.upperTabNames.oneD: + updateStatusLine("Basic calculation"); + break; + } + } + + void setGlobalUIValues() + { + Application.Instance.Invoke(() => + { + globalUIFrozen = true; + + try + { + // Set the global UI elements (layer, zoom, etc.) here, if appropriate. + // globalUIFrozen being set should avoid issues with event handlers firing. + int mainIndex = getMainSelectedIndex(); + int settingsIndex = getSelectedLayerIndex() + getSubTabSelectedIndex(); + + bool showCheckboxes = true; + if (mainIndex != (int)CommonVars.upperTabNames.twoD) + { + showCheckboxes = false; + } + else + { + if (settingsIndex >= CentralProperties.maxLayersForMC) + { + showCheckboxes = false; + } + } + + if (showCheckboxes) + { + upperGadgets_panel.Content = upperGadgets_table; + setBGLayerCheckboxes(settingsIndex); + } + else + { + upperGadgets_panel.Content = new Panel(); + } + + // Set the zoom level from the viewport settings. + if (mainIndex == (int)CommonVars.upperTabNames.Implant) + { + double[] vals = getImplantViewportCamera(); + num_viewportZoom.Value = vals[2]; + num_viewportX.Value = vals[0]; + num_viewportY.Value = vals[1]; + } + if (mainIndex != (int)CommonVars.upperTabNames.twoD) + { + double[] vals = getViewportCamera(settingsIndex); + num_viewportZoom.Value = vals[2]; + num_viewportX.Value = vals[0]; + num_viewportY.Value = vals[1]; + } + } + catch (Exception) + { + + } + globalUIFrozen = false; + }); + } + + void suspendImplantUI() + { + implantUIFrozen = true; + commonVars.setActiveUI(CommonVars.uiActive.implant, true); + } + + void resumeImplantUI() + { + implantUIFrozen = false; + commonVars.setActiveUI(CommonVars.uiActive.implant, false); + } + + void commentChanged(object sender, EventArgs e) + { + if (globalUIFrozen) + { + return; + } + + int mainIndex = getMainSelectedIndex(); + int subTabIndex = getSubTabSelectedIndex(); + + if (mainIndex == (int)CommonVars.upperTabNames.Implant) + { + commonVars.getImplantSettings().setComment(commentBox.Text); + } + if (mainIndex == (int)CommonVars.upperTabNames.twoD) + { + if (subTabIndex < (int)CommonVars.twoDTabNames.settings) + { + commonVars.getLayerSettings(getSelectedLayerIndex()).setString(EntropyLayerSettings.properties_s.comment, commentBox.Text); + } + + if (subTabIndex == (int)CommonVars.twoDTabNames.settings) + { + commonVars.getSimulationSettings_nonSim().setString(EntropySettings_nonSim.properties_s.comment, commentBox.Text); + } + + if (subTabIndex == (int)CommonVars.twoDTabNames.paSearch) + { + commonVars.getSimulationSettings_nonSim().setString(EntropySettings_nonSim.properties_s.paComment, commentBox.Text); + } + + if (subTabIndex == (int)CommonVars.twoDTabNames.DOE) + { + commonVars.getSimulationSettings().getDOESettings().setString(DOESettings.properties_s.comment, commentBox.Text); + } + } + } + + void getComment() + { + Application.Instance.Invoke(() => + { + globalUIFrozen = true; + commentBox.Text = ""; + + int mainIndex = getMainSelectedIndex(); + int subTabIndex = getSubTabSelectedIndex(); + + if (mainIndex == (int)CommonVars.upperTabNames.Implant) + { + commentBox.Text = commonVars.getImplantSettings_nonSim().getString(EntropySettings_nonSim.properties_s.comment); + } + if (mainIndex == (int)CommonVars.upperTabNames.twoD) + { + if (subTabIndex < (int)CommonVars.twoDTabNames.settings) + { + commentBox.Text = commonVars.getLayerSettings(getSelectedLayerIndex()).getString(EntropyLayerSettings.properties_s.comment); + } + if (subTabIndex == (int)CommonVars.twoDTabNames.settings) + { + commentBox.Text = commonVars.getSimulationSettings_nonSim().getString(EntropySettings_nonSim.properties_s.comment); + } + if (subTabIndex == (int)CommonVars.twoDTabNames.paSearch) + { + commentBox.Text = commonVars.getSimulationSettings_nonSim().getString(EntropySettings_nonSim.properties_s.paComment); + } + if (subTabIndex == (int)CommonVars.twoDTabNames.DOE) + { + commentBox.Text = commonVars.getSimulationSettings().getDOESettings().getString(DOESettings.properties_s.comment); + } + } + globalUIFrozen = false; + }); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_RNG.cs b/Common/Variance/UI/UIHandlers_RNG.cs new file mode 100644 index 0000000..c3483f8 --- /dev/null +++ b/Common/Variance/UI/UIHandlers_RNG.cs @@ -0,0 +1,99 @@ +using Eto.Forms; +using System; + +namespace Variance +{ + public partial class MainForm + { + void hOverlay_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.XOL; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void vOverlay_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.YOL; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void vTipPVar_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.VTPV; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void vTipNVar_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.VTNV; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void hTipPVar_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.HTPV; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void hTipNVar_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.HTNV; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void ICV_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.ICV; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void OCV_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.OCV; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void sCDU_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.SCDU; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void tCDU_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.TCDU; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void wobble_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.WOB; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void lwr_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.LWR; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + + void lwr2_RNG(object sender, EventArgs e) + { + rngLabelIndex = (int)layerLookUpOrder.LWR2; + sourceLabel_RNG = (Label)sender; + customRNGContextMenu(); + } + } +} diff --git a/Common/Variance/UI/UIHandlers_doe.cs b/Common/Variance/UI/UIHandlers_doe.cs new file mode 100644 index 0000000..3b8861a --- /dev/null +++ b/Common/Variance/UI/UIHandlers_doe.cs @@ -0,0 +1,239 @@ +using Eto.Drawing; +using Eto.Forms; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Variance +{ + public partial class MainForm + { + void suspendDOESettingsUI() + { + DOEUIFrozen = true; + commonVars.setActiveUI(CommonVars.uiActive.doe, false); + } + + void resumeDOESettingsUI() + { + DOEUIFrozen = false; + commonVars.setActiveUI(CommonVars.uiActive.doe, true); + } + + void addDOESettingsHandlers() + { + DOEUIFrozen = false; + commonVars.setActiveUI(CommonVars.uiActive.doe, true); + num_DOERows.LostFocus += doeSettingsChanged; + num_DOECols.LostFocus += doeSettingsChanged; + num_DOEColPitch.LostFocus += doeSettingsChanged; + num_DOERowPitch.LostFocus += doeSettingsChanged; + radio_useSpecificTile.CheckedChanged += doeSettingsChanged; + radio_useSpecificTiles.CheckedChanged += doeSettingsChanged; + radioButton_allTiles.CheckedChanged += doeSettingsChanged; + radio_useCSViDRM.CheckedChanged += doeSettingsChanged; + radio_useCSVQuilt.CheckedChanged += doeSettingsChanged; + textBox_useSpecificTiles.LostFocus += doeSettingsChanged; + num_DOESCCol.LostFocus += doeSettingsChanged; + num_DOESCRow.LostFocus += doeSettingsChanged; + num_rowOffset.LostFocus += doeSettingsChanged; + num_colOffset.LostFocus += doeSettingsChanged; + } + + void doeSettingsChanged() + { + if (DOEUIFrozen) + { + return; + } + + Application.Instance.Invoke(() => + { + int layer = getSelectedLayerIndex(); + + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.DOE].clear(); + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(i) == 1) + { + for (int poly = 0; poly < commonVars.getLayerSettings(i).getFileData().Count(); poly++) + { + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.DOE].addBGPolygon( + poly: UIHelper.myPointFArrayToPointFArray(commonVars.getLayerSettings(i).getFileData()[poly]), + polyColor: Color.FromArgb(commonVars.getColors().simPreviewColors[i].toArgb()), + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.bg), + layerIndex: i + ); + } + } + } + + if (!(radio_useCSVQuilt.Checked) || ((radio_useCSVQuilt.Checked) && (!commonVars.getSimulationSettings().getDOESettings().getBool(DOESettings.properties_b.quilt)))) + { + btn_useCSVQuilt.Enabled = false; + groupBox_DOESettings.Enabled = true; + } + + if ((!radio_useCSViDRM.Checked) || ((radio_useCSViDRM.Checked) && (!commonVars.getSimulationSettings().getDOESettings().getBool(DOESettings.properties_b.iDRM)))) + { + btn_useCSViDRM.Enabled = false; + groupBox_DOESettings.Enabled = true; + } + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 0); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTile, 0); + num_DOESCCol.Enabled = false; + num_DOESCRow.Enabled = false; + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.rowPitch, num_DOERowPitch.Value); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.colPitch, num_DOEColPitch.Value); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.rows, Convert.ToInt32(num_DOERows.Value)); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.cols, Convert.ToInt32(num_DOECols.Value)); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.colOffset, num_colOffset.Value); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.rowOffset, num_rowOffset.Value); + num_DOESCCol.MaxValue = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.cols); + num_DOESCRow.MaxValue = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.rows); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTileCol, Convert.ToInt16(num_DOESCCol.Value)); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTileRow, Convert.ToInt16(num_DOESCRow.Value)); + + if ((!radio_useCSViDRM.Checked) && (!radio_useCSVQuilt.Checked)) + { + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.iDRM, false); + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.quilt, false); + if (radioButton_allTiles.Checked) + { + // Nothing to do. + } + + if (radio_useSpecificTile.Checked) + { + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTile, 1); + num_DOESCCol.Enabled = true; + num_DOESCRow.Enabled = true; + } + + if (radio_useSpecificTiles.Checked) + { + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 1); + textBox_useSpecificTiles.Enabled = true; + string tmpString = textBox_useSpecificTiles.Text; + bool entryOK = commonVars.getSimulationSettings().setTileList(tmpString, false); + + if (!entryOK) // failsafe. + { + commonVars.getSimulationSettings().getDOESettings().resetTileList_ColRow(); + commonVars.getSimulationSettings().getDOESettings().addTileList_Value(new Int32[2] { 0, 0 }); + } + + } + } + else + { + if (radio_useCSViDRM.Checked) + { + btn_useCSViDRM.Enabled = true; + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.quilt, false); + // Grid settings come from CSV file. + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 1); + } + if (radio_useCSVQuilt.Checked) + { + btn_useCSVQuilt.Enabled = true; + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.iDRM, false); + // Grid settings come from CSV file. + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 0); + } + groupBox_DOESettings.Enabled = false; + // Failsafe is handled earlier by checking for the iDRM/OPC button, but no 'configured' flag. + } + + Int32 tile = 0; + PointF[] tilePoly = new PointF[5]; + tilePoly[0] = new PointF((float)commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colOffset), (float)commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowOffset)); + tilePoly[1] = new PointF(tilePoly[0].X, (float)(tilePoly[0].Y + commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowPitch))); + tilePoly[2] = new PointF((float)(tilePoly[1].X + commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colPitch)), tilePoly[1].Y); + tilePoly[3] = new PointF(tilePoly[2].X, tilePoly[0].Y); + tilePoly[4] = new PointF(tilePoly[0].X, tilePoly[0].Y); + + if (radioButton_allTiles.Checked || radio_useCSVQuilt.Checked) + { + for (int row = 0; row < commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.rows); row++) + { + int col = 0; + while (col < commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.cols)) + { + Int32 colorIndex = tile % varianceContext.vc.colors.resultColors.Count(); // map our result into the available colors. + PointF[] currentTile = tilePoly.ToArray(); + int length = currentTile.Length; + Parallel.For(0, length, (pt) => + // for (int pt = 0; pt < length; pt++) + { + currentTile[pt].X += (float)(col * commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colPitch)); + currentTile[pt].Y += (float)(row * commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowPitch)); + }); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.DOE].addPolygon( + poly: currentTile, + polyColor: Color.FromArgb(commonVars.getColors().resultColors[colorIndex].toArgb()), + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), + drawn: true, + layerIndex: CentralProperties.maxLayersForMC + colorIndex); + + tile++; + col++; + } + } + } + + if (radio_useSpecificTile.Checked) + { + PointF[] currentTile = tilePoly.ToArray(); + int length = currentTile.Length; + Parallel.For(0, length, (pt) => + // for (int pt = 0; pt < length; pt++) + { + currentTile[pt].X += (float)((commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.sTileCol) - 1) * commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colPitch)); + currentTile[pt].Y += (float)((commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.sTileRow) - 1) * commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowPitch)); + }); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.DOE].addPolygon( + poly: currentTile, + polyColor: Color.FromArgb(commonVars.getColors().resultColors[0].toArgb()), + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), + drawn: true, + layerIndex: CentralProperties.maxLayersForMC + 0); + } + + if (radio_useSpecificTiles.Checked) + { + while (tile < commonVars.getSimulationSettings().getDOESettings().getTileList_ColRow().Count()) + { + Int32 colorIndex = tile % varianceContext.vc.colors.resultColors.Count(); // map our result into the available colors. + Int32 col = commonVars.getSimulationSettings().getDOESettings().getTileList_Value(tile, 0); + Int32 row = commonVars.getSimulationSettings().getDOESettings().getTileList_Value(tile, 1); + PointF[] currentTile = tilePoly.ToArray(); + int length = currentTile.Length; + Parallel.For(0, length, (pt) => + // for (int pt = 0; pt < length; pt++) + { + currentTile[pt].X += (float)(col * commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colPitch)); + currentTile[pt].Y += (float)(row * commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowPitch)); + }); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.DOE].addPolygon( + poly: currentTile, + polyColor: Color.FromArgb(commonVars.getColors().resultColors[colorIndex].toArgb()), + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), + drawn: true, + layerIndex: CentralProperties.maxLayersForMC + colorIndex); + tile++; + } + } + entropyControl.EntropyRun(numberOfCases: 1, csvFile: null, useThreads: false, doPASearch: false); // force a tile extraction run to update tool. + refreshAllPreviewPanels(); + updateViewport(); + }); + } + + void doeSettingsChanged(object sender, EventArgs e) + { + doeSettingsChanged(); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_email.cs b/Common/Variance/UI/UIHandlers_email.cs new file mode 100644 index 0000000..cbf18d7 --- /dev/null +++ b/Common/Variance/UI/UIHandlers_email.cs @@ -0,0 +1,42 @@ +using System; + +namespace Variance +{ + public partial class MainForm + { + bool validateEmailSettings() + { + if ((varianceContext.vc.emailAddress != "") && + (varianceContext.vc.emailPwd != "") && + (varianceContext.vc.host != "") && + (varianceContext.vc.port != "")) + { + return true; + } + return false; + } + + void emailSettingsChanged(object sender, EventArgs e) + { + varianceContext.vc.emailAddress = commonVars.getNonSimulationSettings().emailAddress = text_emailAddress.Text; + varianceContext.vc.host = commonVars.getNonSimulationSettings().host = text_server.Text; + varianceContext.vc.emailPwd = commonVars.getNonSimulationSettings().emailPwd = varianceContext.vc.aes.EncryptToString(text_emailPwd.Text); + varianceContext.vc.port = commonVars.getNonSimulationSettings().port = num_port.Value.ToString(); + varianceContext.vc.ssl = commonVars.getNonSimulationSettings().ssl = (bool)checkBox_SSL.Checked; + + bool emailOK = validateEmailSettings(); + checkBox_EmailCompletion.Enabled = emailOK; + checkBox_perJob.Enabled = emailOK; + button_emailTest.Enabled = emailOK; + + commonVars.getNonSimulationSettings().emailOnCompletion = emailOK; + commonVars.getNonSimulationSettings().emailPerJob = emailOK; + } + + void emailTest(object sender, EventArgs e) + { + Email.Send(varianceContext.vc.host, varianceContext.vc.port, varianceContext.vc.ssl, "Variance Email Test", "Testing 1 2 3", varianceContext.vc.emailAddress, varianceContext.vc.aes.DecryptString(varianceContext.vc.emailPwd)); + } + + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_file.cs b/Common/Variance/UI/UIHandlers_file.cs new file mode 100644 index 0000000..b489d16 --- /dev/null +++ b/Common/Variance/UI/UIHandlers_file.cs @@ -0,0 +1,598 @@ +using Error; +using Eto.Forms; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Variance +{ + public partial class MainForm + { + void saveHandler(object sender, EventArgs e) + { + saveProject(commonVars.projectFileName); + } + + void saveProject(string filename) + { + Application.Instance.Invoke(() => + { + if (filename == "") + { + // Need to request output file location and name. + SaveFileDialog sfd = new SaveFileDialog() + { + Title = "Enter file to save", + Filters = + { + new FileFilter("Variance files", "*.variance"), + new FileFilter("XML Files (*.xml)", ".xml") + } + }; + if (sfd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + filename = sfd.FileName; + } + else + { + saveEnabler(); + return; + } + } + if (commonVars.storage.storeSimulationSettings(filename, + commonVars.getSimulationSettings(), + commonVars.getSimulationSettings_nonSim(), + commonVars.getListOfSettings(), + commonVars.getImplantSimulationSettings(), + commonVars.getImplantSettings_nonSim(), + commonVars.getImplantSettings(), + commonVars.getNonSimulationSettings() + ) + ) + { + commonVars.projectFileName = filename; + } + else + { + MessageBox.Show("Error during save.", "Save failed", MessageBoxButtons.OK); + } + saveEnabler(); + }); + } + + void saveAsHandler(object sender, EventArgs e) + { + saveProject(""); + } + + void saveEnabler() + { + Application.Instance.Invoke(() => + { + if (commonVars.projectFileName == "") + { + //menu_fileSave.Enabled = false; + Title = commonVars.titleText; + } + else + { + Title = commonVars.titleText + " - " + commonVars.projectFileName; + //menu_fileSave.Enabled = true; + } + }); + } + + void openHandler(object sender, EventArgs e) + { + // Need to request input file location and name. + OpenFileDialog ofd = new OpenFileDialog() + { + Title = "Choose file to load", + MultiSelect = false, + Filters = + { + new FileFilter("Variance files", "*.variance"), + new FileFilter("XML Files (*.xml)", ".xml") + } + }; + if (ofd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + pNew(); + doLoad(ofd.FileName); + commonVars.setHashes(); + } + } + + void revertHandler(object sender, EventArgs e) + { + doLoad(commonVars.projectFileName); + } + + void doLoad(string xmlFile) + { + // We suspend/resume the layout here to reduce the overhead from updating the huge number of UI controls. + // We have to toggle this a few times to display progress messages to the user. + Application.Instance.Invoke(() => + { + int mainTabIndex = getMainSelectedIndex(); + int subTabIndex = -1; + if (mainTabIndex == (int)CommonVars.twoDTabNames.layer) + { + subTabIndex = getSubTabSelectedIndex(); + } + suspendUIHandlers(); + updateStatusLine("Loading project. Please wait"); + string loadOK = commonVars.storage.loadSimulationSettings(CentralProperties.version, xmlFile, commonVars.getSimulationSettings(), commonVars.getSimulationSettings_nonSim(), commonVars.getListOfSettings(), commonVars.getImplantSimulationSettings(), commonVars.getImplantSettings_nonSim(), commonVars.getImplantSettings(), commonVars.getNonSimulationSettings()); + if (loadOK == "") + { + updateStatusLine("Project loaded successfully"); + commonVars.projectFileName = xmlFile; + } + else + { + updateStatusLine("Project loading failed."); + } + resumeUIHandlers(); + updateStatusLine("Parsing project data. Please wait"); + if (subTabIndex == (int)CommonVars.twoDTabNames.DOE) + { + doeSettingsChanged(); + } + if (subTabIndex == (int)CommonVars.twoDTabNames.layer) + { + refreshAllPreviewPanels(); + } + if (subTabIndex == (int)CommonVars.twoDTabNames.settings) + { + drawSimulationPanelHandler(false); + set_ui_from_settings(getSelectedLayerIndex()); + updateSettingsUIFromSettings(); + entropySettingsChanged(this, EventArgs.Empty); + } + if (subTabIndex == (int)CommonVars.twoDTabNames.layer) + { + do2DLayerUI_exp(getSelectedLayerIndex(), updateUI: false); + } + if (mainTabIndex == (int)CommonVars.upperTabNames.Implant) + { + updateImplantUIFromSettings(); + doImplantShadowing(null, EventArgs.Empty); + } + resumeUIFromStorage(); + }); + } + + void newHandler(object sender, EventArgs e) + { + Application.Instance.Invoke(() => + { + pNew(); + }); + } + + void pNew() + { + Application.Instance.Invoke(() => + { + int storeIndex = getSelectedLayerIndex(); + suspendUIHandlers(); + commonVars.reset(varianceContext.vc); // use this method to avoid clobbering the observable collections. + for (Int32 layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + setLayerSettings(new EntropyLayerSettings(), layer, gdsOnly: false, resumeUI: true); + commonVars.getGeoCoreHandler(layer).reset(); + } + commonVars.projectFileName = ""; + commonVars.getNonSimulationSettings().emailAddress = varianceContext.vc.emailAddress; + commonVars.getNonSimulationSettings().emailPwd = varianceContext.vc.emailPwd; + commonVars.getNonSimulationSettings().host = varianceContext.vc.host; + commonVars.getNonSimulationSettings().port = varianceContext.vc.port; + commonVars.setOpenGLProp(CommonVars.properties_gl.aa, varianceContext.vc.AA); + commonVars.setGLInt(CommonVars.gl_i.zoom, varianceContext.vc.openGLZoomFactor); + commonVars.setOpacity(CommonVars.opacity_gl.fg, varianceContext.vc.FGOpacity); + commonVars.setOpacity(CommonVars.opacity_gl.bg, varianceContext.vc.BGOpacity); + commonVars.setOpenGLProp(CommonVars.properties_gl.fill, varianceContext.vc.FilledPolygons); + commonVars.setOpenGLProp(CommonVars.properties_gl.points, varianceContext.vc.drawPoints); + commonVars.setGCCDV(varianceContext.vc.geoCoreCDVariation); + commonVars.setLayerPreviewDOETile(varianceContext.vc.layerPreviewDOETile); + commonVars.setFriendly(varianceContext.vc.friendlyNumber); + setupGUI(); + resetViewPorts(); + set2DSelectedIndex(storeIndex); + resumeUIHandlers(); + }); + + replayUIFrozen = true; + simReplay.reset(); + disableReplay(); + setReplayControls(); + replayUIFrozen = false; + resumeUIFromStorage(); + } + + void prepUIForLoad() + { + Application.Instance.Invoke(() => + { + experimental_listBox_layers.SelectedIndexChanged -= listbox_change; + suspendUIHandlers(); + btn_Cancel.Enabled = true; + }); + } + + void prepUIPostLoad() + { + Application.Instance.Invoke(() => + { + btn_Cancel.Enabled = false; + resumeUIHandlers(); + experimental_listBox_layers.SelectedIndexChanged += listbox_change; + }); + } + + void locateDOEResults(object sender, EventArgs e) + { + SelectFolderDialog ofd = new SelectFolderDialog() + { + Title = "Please choose location of DOE results to summarize" + }; + // Need to request output file location and name. + if (ofd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + updateStatusLine("Generating summary file(s)"); + updateStatusLine(UtilityFuncs.summarizeDOEResults(ofd.Directory, Directory.GetFiles(ofd.Directory, "*_summary.txt"))); + } + } + + void abortFileLoad(object sender, EventArgs e) + { + if (commonVars.loadAbort) + { + fileLoad_cancelTS.Cancel(); + } + } + + async void geoFileChooser_Handler_exp(object sender, EventArgs e) + { + Int32 settingsIndex = -1; + + Application.Instance.Invoke(() => + { + // Get our layer. + settingsIndex = getSelectedLayerIndex(); + if (settingsIndex == -1) + { + return; + } + + geoCoreLoadingUI(false); + + startIndeterminateProgress(); + }); + + OpenFileDialog ofd = new OpenFileDialog() + { + Title = "Select GDS or OAS file to Load", + MultiSelect = false, + Filters = + { + new FileFilter("Layout Files (*.gds; *.oas)", ".gds", "*.oas") + } + }; + + if (ofd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + Application.Instance.Invoke(() => + { + suspendUIHandlers(); + }); + + prepUIForLoad(); + + commonVars.loadAbort = false; + System.Timers.Timer timer = new System.Timers.Timer(); + timer.AutoReset = true; + timer.Interval = 100; + timer.Elapsed += new System.Timers.ElapsedEventHandler(abortFileLoad); + + fileLoad_cancelTS = new CancellationTokenSource(); + + bool fileOK = false; + + timer.Start(); + + // The thread abort approach is regarded as an ugly hack and strongly discouraged, but seems to be the only way to abort a long-running single-stage task. + // As the geoCore readers don't necessarily lend themselves well to gentle interruption, the big hammer below is used. + + Task fileLoadTask = Task.Run(() => + { + try + { + using (fileLoad_cancelTS.Token.Register(Thread.CurrentThread.Abort)) + { + fileOK = layoutLoad(settingsIndex, ofd.FileName); + } + } + catch (ThreadAbortException) + { + fileOK = false; + } + finally + { + } + } + , fileLoad_cancelTS.Token); + + try + { + await fileLoadTask; + } + catch (Exception) + { + fileOK = false; + } + + timer.Stop(); + timer.Dispose(); + fileLoad_cancelTS.Dispose(); + fileLoadTask.Dispose(); + + if (fileOK) + { + Application.Instance.Invoke(() => + { + commonVars.getLayerSettings(settingsIndex).setString(EntropyLayerSettings.properties_s.file, commonVars.getGeoCoreHandler(settingsIndex).getFilename()); + // Clear tracking for external point data. + commonVars.getLayerSettings(settingsIndex).setReloaded(false); + try + { + comboBox_layerStructureList_geoCore_exp.SelectedIndex = commonVars.getGeoCoreHandler(settingsIndex).getGeo().activeStructure; + } + catch (Exception) + { + + } + try + { + comboBox_layerLDList_geoCore_exp.SelectedIndex = commonVars.getGeoCoreHandler(settingsIndex).getGeo().activeLD; + } + catch (Exception) + { + + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.structure, comboBox_layerStructureList_geoCore_exp.SelectedIndex); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lD, comboBox_layerLDList_geoCore_exp.SelectedIndex); + + commonVars.getGeoCoreHandler(settingsIndex).setPoints(commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure), commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD)); + }); + } + else + { + commonVars.getGeoCoreHandler(settingsIndex).getGeo().reset(); + } + Application.Instance.Invoke(() => + commonVars.getGeoCoreHandler(settingsIndex).getGeo().updateCollections() + ); + + Application.Instance.Invoke(() => + { + // Refresh layer UI : a little hacky due to the suspended UI elements, but it works. + do2DLayerUI_exp(settingsIndex, updateUI: true); + do2DLayerUI_geoCore_exp(settingsIndex); + prepUIPostLoad(); + resumeUIHandlers(); + }); + } + + Application.Instance.Invoke(() => + { + stopIndeterminateProgress(); + geoCoreLoadingUI(false); + do2DLayerUI_exp(settingsIndex, updateUI: true); + }); + } + + bool layoutLoad(int settingsIndex, string filename) + { + string[] tokens = filename.Split(new char[] { '.' }); + string ext = tokens[tokens.Length - 1].ToUpper(); + + if ((ext == "GDS") || (ext == "OAS")) + { + + if (ext == "GDS") + { + commonVars.getGeoCoreHandler(settingsIndex).updateGeoCoreHandler(filename, geoCoreLib.GeoCore.fileType.gds); + } + + if (ext == "OAS") + { + commonVars.getGeoCoreHandler(settingsIndex).updateGeoCoreHandler(filename, geoCoreLib.GeoCore.fileType.oasis); + } + + return commonVars.getGeoCoreHandler(settingsIndex).isValid(); + } + + return false; + } + + void iDRMFileChooser_Handler(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog() + { + Title = "Select iDRM CSV file to Load", + MultiSelect = false, + Filters = + { + new FileFilter("CSV Files (*.csv)", ".csv") + } + }; + bool reading = false; + if (ofd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + try + { + reading = UtilityFuncs.readiDRMCSVFile(ref commonVars, ofd.FileName); + suspendDOESettingsUI(); + num_colOffset.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colOffset); + num_rowOffset.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowOffset); + num_DOEColPitch.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colPitch); + num_DOERowPitch.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowPitch); + num_DOECols.Value = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.cols); + num_DOERows.Value = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.rows); + resumeDOESettingsUI(); + } + catch (Exception exMsg) + { + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.iDRM, false); + if (reading == true) + { + MessageBox.Show(exMsg.ToString(), "Oops", MessageBoxButtons.OK); + } + else + { + MessageBox.Show("Could not read file", "Oops", MessageBoxButtons.OK); + } + } + } + else + { + if (commonVars.getSimulationSettings().getDOESettings().getBool(DOESettings.properties_b.iDRM)) + { + // Don't change anything. + } + else + { + // Failsafe conditions to avoid downstream fail. + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTile, 0); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 0); + } + } + } + + void QuiltFileChooser_Handler(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog() + { + Title = "Select Quilt CSV file to Load", + MultiSelect = false, + Filters = + { + new FileFilter("CSV Files (*.csv)", ".csv") + } + }; + bool reading = false; + if (ofd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + try + { + reading = UtilityFuncs.readQuiltCSVFile(ref commonVars, ofd.FileName); + suspendDOESettingsUI(); + num_colOffset.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colOffset); + num_rowOffset.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowOffset); + num_DOEColPitch.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colPitch); + num_DOERowPitch.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowPitch); + num_DOECols.Value = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.cols); + num_DOERows.Value = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.rows); + resumeDOESettingsUI(); + doeSettingsChanged(); + } + catch (Exception exMsg) + { + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.iDRM, false); + if (reading == true) + { + MessageBox.Show(exMsg.ToString(), "Oops", MessageBoxButtons.OK); + } + else + { + MessageBox.Show("Could not read file", "Oops", MessageBoxButtons.OK); + } + } + } + else + { + if (commonVars.getSimulationSettings().getDOESettings().getBool(DOESettings.properties_b.iDRM)) + { + // Don't change anything. + } + else + { + // Failsafe conditions to avoid downstream fail. + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTile, 0); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 0); + } + } + } + + void geoCoreLoadingUI(bool status) + { + Application.Instance.Invoke(() => + { + tabControl_main.Enabled = !status; + tabControl_2D_simsettings.Enabled = !status; + }); + } + + void resumeUIFromStorage() + { + Application.Instance.Invoke(() => + { + int mainIndex = getMainSelectedIndex(); + int twoDIndex = -1; + if (mainIndex == (int)CommonVars.upperTabNames.twoD) + { + twoDIndex = getSubTabSelectedIndex(); + switch (twoDIndex) + { + case (int)CommonVars.twoDTabNames.layer: + set_ui_from_settings(getSelectedLayerIndex()); + setOmitLayerCheckboxes_EnableStatus(); + updateOmitLayerCheckboxes(); + break; + case (int)CommonVars.twoDTabNames.settings: + updateSettingsUIFromSettings(); + resumeSettingsUI(); + break; + case (int)CommonVars.twoDTabNames.DOE: + updateDOESettingsUIFromSettings(); + resumeDOESettingsUI(); + break; + } + } + if (mainIndex == (int)CommonVars.upperTabNames.Implant) + { + updateImplantUIFromSettings(); + } + commonVars.setHashes(); + uiFollowChanges(); + }); + } + + void updateLayerNames() + { + experimental_listBox_layers.SelectedIndexChanged -= listbox_change; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + string name = commonVars.getLayerSettings(i).getString(EntropyLayerSettings.properties_s.name); + if (name == "") + { + name = (i + 1).ToString(); + } + commonVars.layerNames[i] = name; + } + experimental_listBox_layers.SelectedIndexChanged += listbox_change; + } + + void stopIndeterminateProgress() + { + Application.Instance.Invoke(() => + { + statusProgressBar.Visible = false; + statusProgressBar.Indeterminate = false; + configProgressBar(0, commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.nCases)); + }); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_geoCore.cs b/Common/Variance/UI/UIHandlers_geoCore.cs new file mode 100644 index 0000000..bbba8fe --- /dev/null +++ b/Common/Variance/UI/UIHandlers_geoCore.cs @@ -0,0 +1,186 @@ +using Eto.Forms; +using geoCoreLib; +using geoLib; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Variance +{ + public partial class MainForm : Form + { + void exportActiveLayerToLayout(object sender, EventArgs e) + { + exportActiveLayerToLayout(); + } + + async void exportActiveLayerToLayout() + { + // Need to request output file location and name. + SaveFileDialog sfd = new SaveFileDialog() + { + Title = "Enter file to save", + Filters = + { + new FileFilter("GDS file", "*.gds"), + new FileFilter("OAS file", "*.oas") + } + }; + if (sfd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + string filename = sfd.FileName; + string[] tokens = filename.Split(new char[] { '.' }); + string ext = tokens[tokens.Length - 1].ToUpper(); + + int type = (int)geoCoreLib.GeoCore.fileType.gds; + + if (ext == "OAS") + { + type = (int)geoCoreLib.GeoCore.fileType.oasis; + } + + Application.Instance.Invoke(() => + { + statusProgressBar.Indeterminate = true; + }); + try + { + await Task.Run(() => + { + toGeoCore(type, filename); + }); + } + catch (Exception) + { + // Handle any task cancelled exception without crashing the tool. The cancellation may occur due to close of the tool whilst evaluation is underway. + } + Application.Instance.Invoke(() => + { + statusProgressBar.Indeterminate = false; + }); + } + } + + object exportLock = new object(); + void toGeoCore(int type, string file) + { + int layerIndex = getSelectedLayerIndex(); + + Monitor.Enter(exportLock); + Stopwatch sw = new Stopwatch(); + try + { + sw.Reset(); + sw.Start(); + Application.Instance.Invoke(() => + { + updateStatusLine("Saving"); + startIndeterminateProgress(); + }); + int scale = 100; // for 0.01 nm resolution + GeoCore g = new GeoCore(); + g.reset(); + GCDrawingfield drawing_ = new GCDrawingfield(""); + drawing_.accyear = (short)DateTime.Now.Year; + drawing_.accmonth = (short)DateTime.Now.Month; + drawing_.accday = (short)DateTime.Now.Day; + drawing_.acchour = (short)DateTime.Now.Hour; + drawing_.accmin = (short)DateTime.Now.Minute; + drawing_.accsec = (short)DateTime.Now.Second; + drawing_.modyear = (short)DateTime.Now.Year; + drawing_.modmonth = (short)DateTime.Now.Month; + drawing_.modday = (short)DateTime.Now.Day; + drawing_.modhour = (short)DateTime.Now.Hour; + drawing_.modmin = (short)DateTime.Now.Minute; + drawing_.modsec = (short)DateTime.Now.Second; + drawing_.databaseunits = 1000 * scale; + drawing_.userunits = 0.001 / scale; + drawing_.libname = "variance"; + + // Register layer names with geoCore. Need to compensate the 1-index for the layer registration. + g.addLayerName("L" + (layerIndex + 1).ToString() + "D0", commonVars.getLayerSettings(layerIndex).getString(EntropyLayerSettings.properties_s.name)); + + GCCell gcell_root = drawing_.addCell(); + gcell_root.accyear = (short)DateTime.Now.Year; + gcell_root.accmonth = (short)DateTime.Now.Month; + gcell_root.accday = (short)DateTime.Now.Day; + gcell_root.acchour = (short)DateTime.Now.Hour; + gcell_root.accmin = (short)DateTime.Now.Minute; + gcell_root.accsec = (short)DateTime.Now.Second; + gcell_root.modyear = (short)DateTime.Now.Year; + gcell_root.modmonth = (short)DateTime.Now.Month; + gcell_root.modday = (short)DateTime.Now.Day; + gcell_root.modhour = (short)DateTime.Now.Hour; + gcell_root.modmin = (short)DateTime.Now.Minute; + gcell_root.modsec = (short)DateTime.Now.Second; + gcell_root.cellName = commonVars.getLayerSettings(layerIndex).getString(EntropyLayerSettings.properties_s.name); + + // Let's get our geometry for the layer. + // We can't use the viewport data here because it might be tessellated, so we need to evaluate the contours for the layer. + List previewShapes = generate_shapes(layerIndex); + + // Set to 1 to avoid problems if there are fewer than 100 patterns. + int updateInterval = Math.Max(1, previewShapes.Count); + double progress = 0; + Application.Instance.Invoke(() => + { + updateProgressBar(progress); + }); + + for (int i = 0; i < previewShapes.Count; i++) + { + List polys = previewShapes[i].getPoints(); + for (int poly = 0; poly < polys.Count; poly++) + { + // No drawn polygons desired. + if (!previewShapes[i].getDrawnPoly(poly)) + { + int length = polys[poly].Length; + GeoLibPoint[] ePoly = new GeoLibPoint[length]; + Parallel.For(0, length, (pt) => + // for (int pt = 0; pt < length; pt++) + { + ePoly[pt] = new GeoLibPoint((int)(polys[poly][pt].X * scale), (int)(polys[poly][pt].Y * scale)); + }); + + gcell_root.addPolygon(ePoly.ToArray(), layerIndex + 1, 0); // layer is 1-index based for output, so need to offset value accordingly. + } + } + } + + g.setDrawing(drawing_); + g.setValid(true); + + switch (type) + { + case (int)GeoCore.fileType.gds: + gds.gdsWriter gw = new gds.gdsWriter(g, file); + gw.statusUpdateUI = updateStatusLine; + gw.progressUpdateUI = updateProgressBar; + gw.save(); + break; + case (int)GeoCore.fileType.oasis: + oasis.oasWriter ow = new oasis.oasWriter(g, file); + ow.statusUpdateUI = updateStatusLine; + ow.progressUpdateUI = updateProgressBar; + ow.save(); + break; + } + } + finally + { + sw.Stop(); + Application.Instance.Invoke(() => + { + updateStatusLine("Done in " + sw.Elapsed.TotalSeconds.ToString("0.00") + " s."); + }); + Monitor.Exit(exportLock); + } + + } + + } +} diff --git a/Common/Variance/UI/UIHandlers_layer.cs b/Common/Variance/UI/UIHandlers_layer.cs new file mode 100644 index 0000000..e78eec0 --- /dev/null +++ b/Common/Variance/UI/UIHandlers_layer.cs @@ -0,0 +1,248 @@ +using color; +using Eto.Drawing; +using Eto.Forms; +using System; + +namespace Variance +{ + public partial class MainForm + { + void listbox_change(object sender, EventArgs e) + { + listbox_change(); + } + + void listbox_change() + { + if (layerUIFrozen_exp) + { + return; + } + + int index = experimental_listBox_layers.SelectedIndex; + + if (index == -1) + { + experimental_listBox_layers.SelectedIndex = 0; + index = 0; + } + + selectedLayer = index; + + set_ui_from_settings(index); + do2DLayerUI_exp(index); + } + + void showDrawn_exp(object sender, EventArgs e) + { + Int32 settingsIndex = getSelectedLayerIndex(); + if (settingsIndex == -1) + { + return; + } + showDrawn_exp(settingsIndex); + } + + void twoDLayerEventHandler_exp(object sender, EventArgs e) + { + if (layerUIFrozen_exp) + { + return; + } + + int index = getSelectedLayerIndex(); + if (index == -1) + { + return; + } + + // Do we need to trigger a large UI redraw? + bool updateUI = false; + try + { + if (comboBox_layerShape_exp == (DropDown)sender) + { + updateUI = true; + } + } + catch (Exception) + { + + } + try + { + if ((checkBox_layer_overlayXReference_Av_exp == (CheckBox)sender) || (checkBox_layer_overlayYReference_Av_exp == (CheckBox)sender)) + { + updateUI = true; + } + } + catch (Exception) + { + + } + + do2DLayerUI_exp(index, updateUI); + } + + void suspendLayerUI_exp() + { + layerUIFrozen_exp = true; + } + + void resumeLayerUI_exp() + { + layerUIFrozen_exp = false; + } + + void customRNGContextMenuHandler(object sender, EventArgs e) + { + int layer = getSelectedLayerIndex(); + int itemIndex = menu_customRNG.Items.IndexOf((MenuItem)sender); + try + { + switch (rngLabelIndex) + { + case (int)layerLookUpOrder.ICV: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.iCV_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.OCV: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.oCV_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.SCDU: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.sCDU_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.TCDU: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.tCDU_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.XOL: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.xOL_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.YOL: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.yOL_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.HTNV: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.hTipNVar_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.HTPV: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.hTipPVar_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.VTNV: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.vTipNVar_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.VTPV: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.vTipPVar_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.WOB: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.wobble_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.LWR: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.lwr_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + case (int)layerLookUpOrder.LWR2: + commonVars.getLayerSettings(layer).setString(EntropyLayerSettings.properties_s.lwr2_RNG, commonVars.rngCustomMapping[itemIndex].ToString()); + break; + } + + if (commonVars.rngCustomMapping[itemIndex] != CommonVars.boxMuller) + { + sourceLabel_RNG.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + sourceLabel_RNG.TextColor = Color.FromArgb(MyColor.Black.toArgb()); + } + } + catch (Exception) + { + + } + } + + void customRNGContextMenu() + { + menu_customRNG = new ContextMenu(); + int itemIndex = 0; + for (int i = 0; i < commonVars.rngCustomMapping.Count; i++) + { + menu_customRNG.Items.Add(new ButtonMenuItem { Text = commonVars.rngCustomMapping[i] }); + menu_customRNG.Items[itemIndex].Click += customRNGContextMenuHandler; + itemIndex++; + } + menu_customRNG.Show(sourceLabel_RNG); + } + + void omitLayerCheckboxChanged(object sender, EventArgs e) + { + // Establish which sender raised the event so that we can push the value to the correct layer. + int index = Array.IndexOf(checkBox_omit_lyr, sender); + setOmitLayer(index, (bool)((CheckBox)sender).Checked); + } + + void setOmitLayer(int index, bool status) + { + if (status) + { + commonVars.getLayerSettings(index).setInt(EntropyLayerSettings.properties_i.omit, 1); + } + else + { + commonVars.getLayerSettings(index).setInt(EntropyLayerSettings.properties_i.omit, 0); + } + uiFollowChanges(); + } + + void bgLayerCheckboxChanged(object sender, EventArgs e) + { + if (globalUIFrozen) + { + return; // flags are being set, so don't respond to them + } + + int twoDIndex = getSelectedLayerIndex(); + + if (twoDIndex < CentralProperties.maxLayersForMC) + { + bgLayerCheckboxChanged(twoDIndex); + } + } + + void bgLayerCheckboxChanged(int settingsIndex) + { + for (int i = 0; i < checkBox_bg_lyr.Length; i++) + { + if (((bool)checkBox_bg_lyr[i].Checked) && checkBox_bg_lyr[i].Enabled) + { + commonVars.getLayerSettings(settingsIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, i, 1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, i, 0); + } + } + showBG(settingsIndex); + } + + void applyLayoutToAll(object sender, EventArgs e) + { + // Get our current selected tab. We don't have to validate it as the only caller is on one of the layer tabs. + int orig = getSelectedLayerIndex(); + + setCopyBuffer(orig); + // Suspend our UI for the duration. + suspendUIHandlers(); + + Int32 index = 0; + while (index < CentralProperties.maxLayersForMC) + { + if (index != orig) + { + commonVars.paste(index, true, false); + } + index++; + } + + commonVars.clearCopy(); + resumeUIHandlers(); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_layerSwitching.cs b/Common/Variance/UI/UIHandlers_layerSwitching.cs new file mode 100644 index 0000000..fb6d26c --- /dev/null +++ b/Common/Variance/UI/UIHandlers_layerSwitching.cs @@ -0,0 +1,399 @@ +using geoCoreLib; +using System; + +namespace Variance +{ + public partial class MainForm + { + void switchSimulationLayersOver(Int32 aIndex, Int32 bIndex) + { + // Extract our related settings for migration to the destination layer. + int a_useForDOE = commonVars.getSimulationSettings().getDOESettings().getLayerAffected(aIndex); + + // Make a copy of our a settings before we clobber them + EntropyLayerSettings aSettings = new EntropyLayerSettings(commonVars.getLayerSettings(aIndex), gdsOnly: false); + + // Need to also backup the 'a' geoCore definitions. + GeoCoreHandler ach = new GeoCoreHandler(); + ach.readValues(commonVars.getGeoCoreHandler(aIndex)); + + // Figure out whether we have inter-layer properties that need to be remapped. + bool compXOLRefA = commonVars.getLayerSettings(bIndex).getInt(EntropyLayerSettings.properties_i.xOL_ref) == aIndex; + bool compXOLCorrA = commonVars.getLayerSettings(bIndex).getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == aIndex; + bool compYOLRefA = commonVars.getLayerSettings(bIndex).getInt(EntropyLayerSettings.properties_i.yOL_ref) == aIndex; + bool compYOLCorrA = commonVars.getLayerSettings(bIndex).getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == aIndex; + bool compXOLAvRefA = commonVars.getLayerSettings(bIndex).getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, aIndex) == 1; + bool compYOLAvRefA = commonVars.getLayerSettings(bIndex).getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, aIndex) == 1; + bool compSCDUCorrA = commonVars.getLayerSettings(bIndex).getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == aIndex; + bool compTCDUCorrA = commonVars.getLayerSettings(bIndex).getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == aIndex; + bool compBoolLyrAA = commonVars.getLayerSettings(bIndex).getInt(EntropyLayerSettings.properties_i.bLayerA) == aIndex; + bool compBoolLyrBA = commonVars.getLayerSettings(bIndex).getInt(EntropyLayerSettings.properties_i.bLayerB) == aIndex; + + bool compXOLRefB = commonVars.getLayerSettings(aIndex).getInt(EntropyLayerSettings.properties_i.xOL_ref) == bIndex; + bool compXOLCorrB = commonVars.getLayerSettings(aIndex).getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == bIndex; + bool compYOLRefB = commonVars.getLayerSettings(aIndex).getInt(EntropyLayerSettings.properties_i.yOL_ref) == bIndex; + bool compYOLCorrB = commonVars.getLayerSettings(aIndex).getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == bIndex; + bool compXOLAvRefB = commonVars.getLayerSettings(aIndex).getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, bIndex) == 1; + bool compYOLAvRefB = commonVars.getLayerSettings(aIndex).getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, bIndex) == 1; + bool compSCDUCorrB = commonVars.getLayerSettings(aIndex).getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == bIndex; + bool compTCDUCorrB = commonVars.getLayerSettings(aIndex).getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == bIndex; + bool compBoolLyrAB = commonVars.getLayerSettings(aIndex).getInt(EntropyLayerSettings.properties_i.bLayerA) == bIndex; + bool compBoolLyrBB = commonVars.getLayerSettings(aIndex).getInt(EntropyLayerSettings.properties_i.bLayerB) == bIndex; + + // Copy from b to a + copy(bIndex); + paste(aIndex); + + // Fix up layer settings. + if (compXOLRefA) + { + commonVars.getLayerSettings(aIndex).setInt(EntropyLayerSettings.properties_i.xOL_ref, bIndex); + } + if (compXOLCorrA) + { + commonVars.getLayerSettings(aIndex).setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, bIndex); + } + if (compYOLRefA) + { + commonVars.getLayerSettings(aIndex).setInt(EntropyLayerSettings.properties_i.yOL_ref, bIndex); + } + if (compYOLCorrA) + { + commonVars.getLayerSettings(aIndex).setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, bIndex); + } + if (compXOLAvRefA) + { + commonVars.getLayerSettings(aIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, bIndex, 1); + } + if (compYOLAvRefA) + { + commonVars.getLayerSettings(aIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, bIndex, 1); + } + if (compSCDUCorrA) + { + commonVars.getLayerSettings(aIndex).setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, bIndex); + } + if (compTCDUCorrA) + { + commonVars.getLayerSettings(aIndex).setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, bIndex); + } + if (compBoolLyrAA) + { + commonVars.getLayerSettings(aIndex).setInt(EntropyLayerSettings.properties_i.bLayerA, bIndex); + } + if (compBoolLyrBA) + { + commonVars.getLayerSettings(aIndex).setInt(EntropyLayerSettings.properties_i.bLayerB, bIndex); + } + + // Since we changed something in the fix-up, we should refresh the layer UI with the modified settings. + // Should not be necessary any more. + // setLayerUIFromSettings(aIndex); + + // Copy from back-up a Settings to b + commonVars.setCopy(aIndex); + commonVars.setLayerSettings(aSettings, bIndex, false, false); + commonVars.getSimulationSettings().getDOESettings().setLayerAffected(layer: bIndex, a_useForDOE); + commonVars.getGeoCoreHandler(bIndex).readValues(ach); + + // Fix up layer settings. + if (compXOLRefB) + { + commonVars.getLayerSettings(bIndex).setInt(EntropyLayerSettings.properties_i.xOL_ref, aIndex); + } + if (compXOLCorrB) + { + commonVars.getLayerSettings(bIndex).setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, aIndex); + } + if (compYOLRefB) + { + commonVars.getLayerSettings(bIndex).setInt(EntropyLayerSettings.properties_i.yOL_ref, aIndex); + } + if (compYOLCorrB) + { + commonVars.getLayerSettings(bIndex).setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, aIndex); + } + if (compXOLAvRefB) + { + commonVars.getLayerSettings(bIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, aIndex, 1); + } + if (compYOLAvRefB) + { + commonVars.getLayerSettings(bIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, aIndex, 1); + } + if (compSCDUCorrB) + { + commonVars.getLayerSettings(bIndex).setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, aIndex); + } + if (compTCDUCorrB) + { + commonVars.getLayerSettings(bIndex).setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, aIndex); + } + if (compBoolLyrAB) + { + commonVars.getLayerSettings(bIndex).setInt(EntropyLayerSettings.properties_i.bLayerA, aIndex); + } + if (compBoolLyrBB) + { + commonVars.getLayerSettings(bIndex).setInt(EntropyLayerSettings.properties_i.bLayerB, aIndex); + } + + commonVars.clearCopy(); + + switchSimulationLayers_FixDeps(aIndex, bIndex); + + // Make a single run when on the right tab, to populate the preview structures, and only if simulation not running. + if (!commonVars.isSimRunning() && (getSubTabSelectedIndex() == (int)CommonVars.twoDTabNames.settings)) + { + entropyControl.update(commonVars); + } + + reviewBooleanInputs(); + + // Set our viewports up. + double[] aViewport = getViewportCamera(aIndex); + setViewportCamera(aIndex, getViewportCamera(bIndex)); + setViewportCamera(bIndex, aViewport); + + drawSimulationPanelHandler(false); + } + + void switchSimulationLayers_FixDeps(int aIndex, int bIndex) + { + bool alreadyFrozen = globalUIFrozen; + + if (!alreadyFrozen) + { + globalUIFrozen = true; + } + + // Scan other layers for dependencies on our remapped layers and adjust as needed. + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if ((i == aIndex) || (i == bIndex)) + { + continue; + } + + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.xOL_ref) == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.xOL_ref, bIndex); + } + + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.yOL_ref) == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.yOL_ref, bIndex); + } + + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, bIndex); + } + + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, bIndex); + } + + if (commonVars.getLayerSettings(i).getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, aIndex) == 1) + { + commonVars.getLayerSettings(i).setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, aIndex, 0); + commonVars.getLayerSettings(i).setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, bIndex, 1); + } + + if (commonVars.getLayerSettings(i).getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, aIndex) == 1) + { + commonVars.getLayerSettings(i).setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, aIndex, 0); + commonVars.getLayerSettings(i).setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, bIndex, 1); + } + + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, bIndex); + } + + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, bIndex); + } + + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, bIndex); + } + + int boolLayer1 = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.bLayerA); + + if (boolLayer1 == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.bLayerA, bIndex); + } + else if (boolLayer1 == bIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.bLayerA, aIndex); + } + + + int boolLayer2 = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.bLayerB); + + if (boolLayer2 == bIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.bLayerB, aIndex); + } + else if (boolLayer2 == aIndex) + { + commonVars.getLayerSettings(i).setInt(EntropyLayerSettings.properties_i.bLayerB, bIndex); + } + } + + if (!alreadyFrozen) + { + globalUIFrozen = false; + } + } + + void switchSimulationLayers12Over(object sender, EventArgs e) + { + switchSimulationLayersOver(0, 1); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers23Over(object sender, EventArgs e) + { + switchSimulationLayersOver(1, 2); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers34Over(object sender, EventArgs e) + { + switchSimulationLayersOver(2, 3); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers56Over(object sender, EventArgs e) + { + switchSimulationLayersOver(4, 5); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers67Over(object sender, EventArgs e) + { + switchSimulationLayersOver(5, 6); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers78Over(object sender, EventArgs e) + { + switchSimulationLayersOver(6, 7); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers910Over(object sender, EventArgs e) + { + switchSimulationLayersOver(8, 9); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1011Over(object sender, EventArgs e) + { + switchSimulationLayersOver(9, 10); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1112Over(object sender, EventArgs e) + { + switchSimulationLayersOver(10, 11); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1213Over(object sender, EventArgs e) + { + switchSimulationLayersOver(11, 12); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1314Over(object sender, EventArgs e) + { + switchSimulationLayersOver(12, 13); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1415Over(object sender, EventArgs e) + { + switchSimulationLayersOver(13, 14); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1516Over(object sender, EventArgs e) + { + switchSimulationLayersOver(14, 15); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers15Over(object sender, EventArgs e) + { + switchSimulationLayersOver(0, 4); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers26Over(object sender, EventArgs e) + { + switchSimulationLayersOver(1, 5); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers37Over(object sender, EventArgs e) + { + switchSimulationLayersOver(2, 6); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers48ver(object sender, EventArgs e) + { + switchSimulationLayersOver(3, 7); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers913Over(object sender, EventArgs e) + { + switchSimulationLayersOver(8, 12); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1014Over(object sender, EventArgs e) + { + switchSimulationLayersOver(9, 13); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1115Over(object sender, EventArgs e) + { + switchSimulationLayersOver(10, 14); + entropySettingsChanged(sender, e); + } + + void switchSimulationLayers1216Over(object sender, EventArgs e) + { + switchSimulationLayersOver(11, 15); + entropySettingsChanged(sender, e); + } + + void switchSimulationAllALayersOver(object sender, EventArgs e) + { + for (int i = 0; i < 4; i++) + { + switchSimulationLayersOver(i, i + 4); + } + entropySettingsChanged(sender, e); + } + + void switchSimulationAllBLayersOver(object sender, EventArgs e) + { + for (int i = 8; i < 12; i++) + { + switchSimulationLayersOver(i, i + 4); + } + entropySettingsChanged(sender, e); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_litho.cs b/Common/Variance/UI/UIHandlers_litho.cs new file mode 100644 index 0000000..1142507 --- /dev/null +++ b/Common/Variance/UI/UIHandlers_litho.cs @@ -0,0 +1,389 @@ +using Eto.Forms; +using System; + +namespace Variance +{ + public partial class MainForm + { + void updateLayerRadioButtons_exp() + { + // Set initial state based on layer enabled mode. + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + // Base enabled status + bool enabled = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1; + + for (int j = 0; j < CentralProperties.maxLayersForMC; j++) + { + // Disable corresponding button for reference layer in UI. + bool colx_enabled = enabled; + if (colx_enabled && (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.xOL_corr) == 1)) + { + // If i depends on j, we cannot allow j to enable dependency on i. First to assert a dependency, in layer order, wins. + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == j) + { + colx_enabled = false; + } + } + xCOLRBs_enabledState[j][i] = colx_enabled; + + bool coly_enabled = enabled; + if (coly_enabled && (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.yOL_corr) == 1)) + { + // If i depends on j, we cannot allow j to enable dependency on i. First to assert a dependency, in layer order, wins. + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == j) + { + coly_enabled = false; + } + } + yCOLRBs_enabledState[j][i] = coly_enabled; + + bool olrx_enabled = enabled; + if (olrx_enabled) + { + // If i depends on j, we cannot allow j to enable dependency on i. First to assert a dependency, in layer order, wins. + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.xOL_ref) == j) + { + olrx_enabled = false; + } + } + xOLRBs_enabledState[j][i] = olrx_enabled; + + bool olry_enabled = enabled; + if (olry_enabled) + { + // If i depends on j, we cannot allow j to enable dependency on i. First to assert a dependency, in layer order, wins. + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.yOL_ref) == j) + { + olry_enabled = false; + } + } + yOLRBs_enabledState[j][i] = olry_enabled; + + bool ccdu_enabled = enabled; + if (ccdu_enabled && (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.CDU_corr) == 1)) + { + // If i depends on j, we cannot allow j to enable dependency on i. First to assert a dependency, in layer order, wins. + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == j) + { + ccdu_enabled = false; + } + } + SCDURBs_enabledState[j][i] = ccdu_enabled; + + bool tcdu_enabled = enabled; + if (tcdu_enabled && (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.tCDU_corr) == 1)) + { + // If i depends on j, we cannot allow j to enable dependency on i. First to assert a dependency, in layer order, wins. + if (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == j) + { + tcdu_enabled = false; + } + } + TCDURBs_enabledState[j][i] = tcdu_enabled; + } + } + } + + void updateLayerCDURadioButtons_exp(int layer) + { + Application.Instance.Invoke(() => + { + // -1 is off, which is the 0th radio button. + int sIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) + 1; + + rB_layer_CCDU_exp[0].Enabled = true; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (i == layer) + { + // No button for current layer, so skip this pass through the loop. + continue; + } + else + { + int bIndex = i + 1; // offset button index by 1 as the 0-index is the 'off' button. + if (i > layer) + { + bIndex = i; // if we are above our layer, decrement (effectively) as we don't have a button for the current layer, so have to compensate the positional index. + } + rB_layer_CCDU_exp[bIndex].Text = (i + 1).ToString(); // add 1 as the arrays are 0-indexed, so the button text need to be compensated. + rB_layer_CCDU_exp[bIndex].Enabled = SCDURBs_enabledState[layer][i]; // don't offset this because the enabled array is matched to the full number of layers. + } + } + + if (sIndex > layer) + { + sIndex--; + } + + rB_layer_CCDU_exp[sIndex].Checked = true; + }); + } + + void updateLayerTCDURadioButtons_exp(int layer) + { + Application.Instance.Invoke(() => + { + // -1 is off, which is the 0th radio button. + int sIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) + 1; + + rB_layer_CTCDU_exp[0].Enabled = true; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (i == layer) + { + // No button for current layer, so skip this pass through the loop. + continue; + } + else + { + int bIndex = i + 1; // offset button index by 1 as the 0-index is the 'off' button. + if (i > layer) + { + bIndex = i; // if we are above our layer, decrement (effectively) as we don't have a button for the current layer, so have to compensate the positional index. + } + rB_layer_CTCDU_exp[bIndex].Text = (i + 1).ToString(); // add 1 as the arrays are 0-indexed, so the button text need to be compensated. + rB_layer_CTCDU_exp[bIndex].Enabled = TCDURBs_enabledState[layer][i]; // don't offset this because the enabled array is matched to the full number of layers. + } + } + + if (sIndex > layer) + { + sIndex--; + } + + rB_layer_CTCDU_exp[sIndex].Checked = true; + }); + } + + void updateLayerOLRXRadioButtons_exp(int layer) + { + Application.Instance.Invoke(() => + { + // -1 is off, which is the 0th radio button. + int sIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.xOL_ref) + 1; + + rB_layer_OLRX_exp[0].Enabled = true; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (i == layer) + { + // No button for current layer, so skip this pass through the loop. + continue; + } + else + { + int bIndex = i + 1; // offset button index by 1 as the 0-index is the 'off' button. + if (i > layer) + { + bIndex = i; // if we are above our layer, decrement (effectively) as we don't have a button for the current layer, so have to compensate the positional index. + } + rB_layer_OLRX_exp[bIndex].Text = (i + 1).ToString(); // add 1 as the arrays are 0-indexed, so the button text need to be compensated. + rB_layer_OLRX_exp[bIndex].Enabled = xOLRBs_enabledState[layer][i]; // don't offset this because the enabled array is matched to the full number of layers. + } + } + + if (sIndex > layer) + { + sIndex--; + } + + rB_layer_OLRX_exp[sIndex].Checked = true; + }); + } + + void updateLayerOLRYRadioButtons_exp(int layer) + { + Application.Instance.Invoke(() => + { + // -1 is off, which is the 0th radio button. + int sIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.yOL_ref) + 1; + + rB_layer_OLRY_exp[0].Enabled = true; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (i == layer) + { + // No button for current layer, so skip this pass through the loop. + continue; + } + else + { + int bIndex = i + 1; // offset button index by 1 as the 0-index is the 'off' button. + if (i > layer) + { + bIndex = i; // if we are above our layer, decrement (effectively) as we don't have a button for the current layer, so have to compensate the positional index. + } + rB_layer_OLRY_exp[bIndex].Text = (i + 1).ToString(); // add 1 as the arrays are 0-indexed, so the button text need to be compensated. + rB_layer_OLRY_exp[bIndex].Enabled = yOLRBs_enabledState[layer][i]; // don't offset this because the enabled array is matched to the full number of layers. + } + } + + if (sIndex > layer) + { + sIndex--; + } + + rB_layer_OLRY_exp[sIndex].Checked = true; + }); + } + + void updateLayerCOLXRadioButtons_exp(int layer) + { + Application.Instance.Invoke(() => + { + // -1 is off, which is the 0th radio button. + int sIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) + 1; + + rB_layer_COLX_exp[0].Enabled = true; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (i == layer) + { + // No button for current layer, so skip this pass through the loop. + continue; + } + else + { + int bIndex = i + 1; // offset button index by 1 as the 0-index is the 'off' button. + if (i > layer) + { + bIndex = i; // if we are above our layer, decrement (effectively) as we don't have a button for the current layer, so have to compensate the positional index. + } + rB_layer_COLX_exp[bIndex].Text = (i + 1).ToString(); // add 1 as the arrays are 0-indexed, so the button text need to be compensated. + rB_layer_COLX_exp[bIndex].Enabled = xCOLRBs_enabledState[layer][i]; // don't offset this because the enabled array is matched to the full number of layers. + } + } + + if (sIndex > layer) + { + sIndex--; + } + + rB_layer_COLX_exp[sIndex].Checked = true; + }); + } + + void updateLayerCOLYRadioButtons_exp(int layer) + { + Application.Instance.Invoke(() => + { + // -1 is off, which is the 0th radio button. + int sIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) + 1; + + rB_layer_COLY_exp[0].Enabled = true; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (i == layer) + { + // No button for current layer, so skip this pass through the loop. + continue; + } + else + { + int bIndex = i + 1; // offset button index by 1 as the 0-index is the 'off' button. + if (i > layer) + { + bIndex = i; // if we are above our layer, decrement (effectively) as we don't have a button for the current layer, so have to compensate the positional index. + } + rB_layer_COLY_exp[bIndex].Text = (i + 1).ToString(); // add 1 as the arrays are 0-indexed, so the button text need to be compensated. + rB_layer_COLY_exp[bIndex].Enabled = yCOLRBs_enabledState[layer][i]; // don't offset this because the enabled array is matched to the full number of layers. + } + } + + if (sIndex > layer) + { + sIndex--; + } + + rB_layer_COLY_exp[sIndex].Checked = true; + }); + } + + void updateLayerBooleanRadioButtons_exp(int layer) + { + Application.Instance.Invoke(() => + { + // -1 is off, which is the 0th radio button. + int sIndex1 = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.bLayerA) + 1; + int sIndex2 = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.bLayerB) + 1; + + rB_layerBooleanA_exp[0].Enabled = true; + rB_layerBooleanB_exp[0].Enabled = true; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (i == layer) + { + continue; + } + else + { + int bIndex = i + 1; + if (i > layer) + { + bIndex = i; + } + rB_layerBooleanA_exp[bIndex].Text = (i + 1).ToString(); + rB_layerBooleanA_exp[bIndex].Enabled = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1; + rB_layerBooleanB_exp[bIndex].Text = (i + 1).ToString(); + rB_layerBooleanB_exp[bIndex].Enabled = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1; + } + } + + if (sIndex1 > layer) + { + sIndex1--; + } + if (sIndex2 > layer) + { + sIndex2--; + } + + rB_layerBooleanA_exp[sIndex1].Checked = true; + rB_layerBooleanB_exp[sIndex2].Checked = true; + }); + } + + void updateAverageOverlayCheckboxes_exp(Int32 index) + { + bool alreadyFrozen = globalUIFrozen; + globalUIFrozen = true; + Application.Instance.Invoke(() => + { + int rowIndex = 0; + int colIndex = 0; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (index == i) + { + cB_layer_OLRX_Av_exp[i].Enabled = false; + cB_layer_OLRX_Av_exp[i].Checked = false; + + cB_layer_OLRY_Av_exp[i].Enabled = false; + cB_layer_OLRY_Av_exp[i].Checked = false; + } + else + { + cB_layer_OLRX_Av_exp[i].Enabled = (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1); + cB_layer_OLRX_Av_exp[i].Checked = ((commonVars.getLayerSettings(index).getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, i) == 1) && (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1)); + + cB_layer_OLRY_Av_exp[i].Enabled = (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1); + cB_layer_OLRY_Av_exp[i].Checked = ((commonVars.getLayerSettings(index).getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, i) == 1) && (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1)); + } + colIndex++; + if (colIndex == CentralProperties.maxLayersForMC / 2) + { + colIndex = 0; + rowIndex++; + } + } + }); + if (!alreadyFrozen) + { + globalUIFrozen = false; + } + } + } +} diff --git a/Common/Variance/UI/UIHandlers_prefs.cs b/Common/Variance/UI/UIHandlers_prefs.cs new file mode 100644 index 0000000..9667597 --- /dev/null +++ b/Common/Variance/UI/UIHandlers_prefs.cs @@ -0,0 +1,387 @@ +using Error; +using Eto; +using Eto.Drawing; +using Eto.Forms; +using System; + +namespace Variance +{ + public partial class MainForm + { + void layerColorChange(Label id, Color colDialogColor) + { + Application.Instance.Invoke(() => + { + if (id == lbl_Layer1Color) + { + lbl_Layer1Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer1_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer2Color) + { + lbl_Layer2Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer2_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer3Color) + { + lbl_Layer3Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer3_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer4Color) + { + lbl_Layer4Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer4_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer5Color) + { + lbl_Layer5Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer5_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer6Color) + { + lbl_Layer6Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer6_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer7Color) + { + lbl_Layer7Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer7_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer8Color) + { + lbl_Layer8Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer8_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer9Color) + { + lbl_Layer9Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer9_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer10Color) + { + lbl_Layer10Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer10_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer11Color) + { + lbl_Layer11Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer11_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer12Color) + { + lbl_Layer12Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer12_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer13Color) + { + lbl_Layer13Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer13_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer14Color) + { + lbl_Layer14Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer14_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer15Color) + { + lbl_Layer15Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer15_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Layer16Color) + { + lbl_Layer16Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.layer16_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Result1Color) + { + lbl_Result1Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.result_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Result2Color) + { + lbl_Result2Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.result2_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Result3Color) + { + lbl_Result3Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.result3_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_Result4Color) + { + lbl_Result4Color.BackgroundColor = colDialogColor; + varianceContext.vc.colors.result4_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_minorGridColor) + { + varianceContext.vc.colors.minor_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_majorGridColor) + { + varianceContext.vc.colors.major_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_enabledColor) + { + varianceContext.vc.colors.enabled_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_ss1Color) + { + varianceContext.vc.colors.subshape1_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_ss2Color) + { + varianceContext.vc.colors.subshape2_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_ss3Color) + { + varianceContext.vc.colors.subshape3_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_implantMinColor) + { + varianceContext.vc.colors.implantMin_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_implantMeanColor) + { + varianceContext.vc.colors.implantMean_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_implantMaxColor) + { + varianceContext.vc.colors.implantMax_Color = UIHelper.colorToMyColor(colDialogColor); + } + if (id == lbl_implantResistColor) + { + varianceContext.vc.colors.implantResist_Color = UIHelper.colorToMyColor(colDialogColor); + } + + varianceContext.vc.colors.rebuildLists(); + commonVars.setColors(varianceContext.vc.colors); + + updateUIColors(); + }); + } + + void layerColorChange(object sender, EventArgs e) + { + if (colUIFrozen) + { + return; + } + + try + { + Label senderLabel = sender as Label; + + if (senderLabel != null) + { + Color sourceColor = Eto.Drawing.Colors.Black; + if (senderLabel == lbl_Layer1Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer1_Color); + } + if (senderLabel == lbl_Layer2Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer2_Color); + } + if (senderLabel == lbl_Layer3Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer3_Color); + } + if (senderLabel == lbl_Layer4Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer4_Color); + } + if (senderLabel == lbl_Layer5Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer5_Color); + } + if (senderLabel == lbl_Layer6Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer6_Color); + } + if (senderLabel == lbl_Layer7Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer7_Color); + } + if (senderLabel == lbl_Layer8Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer8_Color); + } + if (senderLabel == lbl_Layer9Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer9_Color); + } + if (senderLabel == lbl_Layer10Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer10_Color); + } + if (senderLabel == lbl_Layer11Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer11_Color); + } + if (senderLabel == lbl_Layer12Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer12_Color); + } + if (senderLabel == lbl_Layer13Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer13_Color); + } + if (senderLabel == lbl_Layer14Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer14_Color); + } + if (senderLabel == lbl_Layer15Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer15_Color); + } + if (senderLabel == lbl_Layer16Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.layer16_Color); + } + + if (senderLabel == lbl_Result1Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.result_Color); + } + if (senderLabel == lbl_Result2Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.result2_Color); + } + if (senderLabel == lbl_Result3Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.result3_Color); + } + if (senderLabel == lbl_Result4Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.result4_Color); + } + + if (senderLabel == lbl_implantMinColor) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.implantMin_Color); + } + if (senderLabel == lbl_implantMeanColor) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.implantMean_Color); + } + if (senderLabel == lbl_implantMaxColor) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.implantMax_Color); + } + if (senderLabel == lbl_implantResistColor) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.implantResist_Color); + } + + if (senderLabel == lbl_ss1Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.subshape1_Color); + } + if (senderLabel == lbl_ss2Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.subshape2_Color); + } + if (senderLabel == lbl_ss3Color) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.subshape3_Color); + } + + if (senderLabel == lbl_majorGridColor) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.major_Color); + } + if (senderLabel == lbl_minorGridColor) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.minor_Color); + } + + if (senderLabel == lbl_enabledColor) + { + sourceColor = UIHelper.myColorToColor(varianceContext.vc.colors.enabled_Color); + } + + ColorDialog colDialog = new ColorDialog + { + Color = sourceColor + }; + + // Special OS X plumbing. The color picker on that platform is a floating dialog and has no OK/cancel. + if (Platform.IsMac) + { + colDialog.ColorChanged += delegate + { + layerColorChange(senderLabel, colDialog.Color); + }; + } + + DialogResult dR = colDialog.ShowDialog(this); + + if (!Platform.IsMac) + { + if (dR == DialogResult.Ok) + { + layerColorChange(senderLabel, colDialog.Color); + } + } + + //colDialog.Dispose(); + } + } + catch (Exception ec) + { + ErrorReporter.showMessage_OK(ec.ToString(), "Error"); + } + } + + void preferencesChange(object sender, EventArgs e) + { + if (utilsUIFrozen) + { + return; + } + utilsUIFrozen = true; + varianceContext.vc.geoCoreCDVariation = (bool)checkBox_geoCore_enableCDVariation.Checked; + commonVars.setGCCDV((bool)checkBox_geoCore_enableCDVariation.Checked); + varianceContext.vc.layerPreviewDOETile = (bool)checkBox_geoCore_tileLayerPreview.Checked; + commonVars.setLayerPreviewDOETile((bool)checkBox_geoCore_tileLayerPreview.Checked); + varianceContext.vc.AA = (bool)checkBox_OGLAA.Checked; + commonVars.setOpenGLProp(CommonVars.properties_gl.aa, (bool)checkBox_OGLAA.Checked); + varianceContext.vc.FilledPolygons = (bool)checkBox_OGLFill.Checked; + commonVars.setOpenGLProp(CommonVars.properties_gl.fill, (bool)checkBox_OGLFill.Checked); + varianceContext.vc.drawPoints = (bool)checkBox_OGLPoints.Checked; + commonVars.setOpenGLProp(CommonVars.properties_gl.points, (bool)checkBox_OGLPoints.Checked); + varianceContext.vc.openGLZoomFactor = Convert.ToInt32(num_zoomSpeed.Value); + commonVars.setGLInt(CommonVars.gl_i.zoom, (Convert.ToInt32(num_zoomSpeed.Value))); + varianceContext.vc.FGOpacity = num_fgOpacity.Value; + commonVars.setOpacity(CommonVars.opacity_gl.fg, num_fgOpacity.Value); + varianceContext.vc.BGOpacity = num_bgOpacity.Value; + commonVars.setOpacity(CommonVars.opacity_gl.bg, num_bgOpacity.Value); + + for (int i = 0; i < mcVPSettings.Length; i++) + { + mcVPSettings[i].aA(commonVars.getOpenGLProp(CommonVars.properties_gl.aa)); + mcVPSettings[i].setZoomStep(commonVars.getGLInt(CommonVars.gl_i.zoom)); + mcVPSettings[i].drawFilled(commonVars.getOpenGLProp(CommonVars.properties_gl.fill)); + mcVPSettings[i].drawPoints(commonVars.getOpenGLProp(CommonVars.properties_gl.points)); + } + + utilsUIFrozen = false; + refreshAllPreviewPanels(); + updateViewport(); + } + + void resetColors(object sender, EventArgs e) + { + varianceContext.vc.colors.reset(); + commonVars.setColors(varianceContext.vc.colors); + updateUIColors(); + } + + void miscSettingsChanged(object sender, EventArgs e) + { + varianceContext.vc.friendlyNumber = (bool)checkBox_friendlyNumbers.Checked; + commonVars.setFriendly(varianceContext.vc.friendlyNumber); + } + + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_setup.cs b/Common/Variance/UI/UIHandlers_setup.cs new file mode 100644 index 0000000..ccaae0c --- /dev/null +++ b/Common/Variance/UI/UIHandlers_setup.cs @@ -0,0 +1,242 @@ +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm + { + void setupGUI() + { + Application.Instance.Invoke(() => + { + tabControl_main.SelectedIndexChanged += mainTabChanged; + // tabControl_2D_simsettings.SelectedIndexChanged += entropySettingsChanged; + // tabControl_2D_simsettings.SelectedIndexChanged += mcPreviewSettingsChanged; + tabControl_2D_simsettings.SelectedIndexChanged += subTabChanged; + + entropyControl = new Entropy(ref varianceContext.vc, commonVars); + entropyControl.updateStatus = updateStatusLine; + entropyControl.configProgress = configProgressBar; + entropyControl.stepProgress = updateProgressBar; + entropyControl.abortCheckFunc = abortCheck; + entropyControl.clearAbortFlagFunc = clearAbortFlag; + entropyControl.postSimUIFunc = postSimUI; + entropyControl.updateSimUIFunc = updateSimUIST; + entropyControl.updateSimUIMTFunc = updateSimUIMT; + entropyControl.updateProgressBarFunc = updateProgressBar; + entropyControl.updateImplantSimUIFunc = updateImplantSimUIST; + entropyControl.updateImplantSimUIMTFunc = updateImplantSimUIMT; + //mcControl.forceRepaintFunc = forceRepaint; + entropyControl.abortAllRunsFunc = abortAllRuns; + entropyControl.abortCSVFunc = abortCSV; + entropyControl.abortRunFunc = abortRun; + entropyControl.abortRunFuncMT = abortRunMT; + entropyControl.multithreadWarningFunc = displayMultiThreadWarning; + entropyControl.tooManyPolysWarningFunc = tooManyPolysWarning; + entropyControl.simRunningFunc = simRunning; + entropyControl.simRunningUIFunc = simRunningUIFunc; + entropyControl.implantSimRunningUIFunc = simRunningUIFunc; + entropyControl.postSimPASearchUIFunc = paSearchUI_showResults; + + // Set listbox defaults on the settings tab. + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + label_geoEqtn_Op[i].Enabled = false; + comboBox_geoEqtn_Op[i].Enabled = false; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_2Layer.Length; i++) + { + comboBox_geoEqtn_Op_2Layer[i].Enabled = false; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_4Layer.Length; i++) + { + comboBox_geoEqtn_Op_4Layer[i].Enabled = false; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_8Layer.Length; i++) + { + comboBox_geoEqtn_Op_8Layer[i].Enabled = false; + } + + // Chord selection modes. + + checkBox_aChord.Enabled = false; + checkBox_bChord.Enabled = false; + + btn_singleCPU.Enabled = false; + + btn_Cancel.Enabled = false; + + btn_multiCPU.Enabled = false; + btn_STOP.Enabled = false; + statusProgressBar.Visible = false; + + // Configure GDS DOE UI defaults + btn_useCSViDRM.Enabled = false; + btn_useCSVQuilt.Enabled = false; + radioButton_allTiles.Checked = true; + textBox_useSpecificTiles.Enabled = false; + num_DOESCCol.Enabled = false; + num_DOESCRow.Enabled = false; + + updateUIColors(); + + updateUtilsValues(); + + commonVars.storage.setLayerSettings = setLayerSettings; + commonVars.storage.resumeUI = resumeUIFromStorage; + commonVars.storage.prepUI = prepUI; + commonVars.storage.suspendSettingsUI = suspendSettingsUI; + commonVars.storage.suspendDOESettingsUI = suspendDOESettingsUI; + commonVars.storage.updateSettingsUIFromSettings = updateSettingsUIFromSettings; + commonVars.storage.updateDOESettingsUIFromSettings = updateDOESettingsUIFromSettings; + commonVars.storage.loadLayout = layoutLoad; + commonVars.storage.viewportLoad = setViewportCamera; + commonVars.storage.viewportSave = getViewportCamera; + commonVars.storage.suspendImplantUI = suspendImplantUI; + commonVars.storage.updateImplantUIFromSettings = updateImplantUIFromSettings; + commonVars.storage.implantViewportLoad = setImplantViewportCamera; + commonVars.storage.implantViewportSave = getImplantViewportCamera; + + // Push the UI to align to our settings at startup. + updateSettingsUIFromSettings(); + updateDOESettingsUIFromSettings(); + + for (int i = 0; i < checkBox_bg_lyr.Length; i++) + { + checkBox_bg_lyr[i].Checked = false; + checkBox_bg_lyr[i].Enabled = false; + checkBox_omit_lyr[i].Checked = false; + checkBox_omit_lyr[i].Enabled = false; + } + + updateStatusLine(CentralProperties.productName + " " + CentralProperties.version); + }); + } + + void addAllUIHandlers() + { + Application.Instance.Invoke(() => + { + addLayerHandlers_exp(); + addSettingsHandlers(); + addDOESettingsHandlers(); + addOmitHandlers(); + addBGHandlers(); + addPrefsHandlers(); + }); + } + + void addOmitHandlers() + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + checkBox_omit_lyr[i].CheckedChanged += omitLayerCheckboxChanged; + } + } + + void addBGHandlers() + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + checkBox_bg_lyr[i].CheckedChanged += bgLayerCheckboxChanged; + } + } + + void addPrefsHandlers() + { + Application.Instance.Invoke(() => + { + lbl_Layer1Color.MouseDoubleClick += layerColorChange; + lbl_Layer2Color.MouseDoubleClick += layerColorChange; + lbl_Layer3Color.MouseDoubleClick += layerColorChange; + lbl_Layer4Color.MouseDoubleClick += layerColorChange; + lbl_Layer5Color.MouseDoubleClick += layerColorChange; + lbl_Layer6Color.MouseDoubleClick += layerColorChange; + lbl_Layer7Color.MouseDoubleClick += layerColorChange; + lbl_Layer8Color.MouseDoubleClick += layerColorChange; + lbl_Layer9Color.MouseDoubleClick += layerColorChange; + lbl_Layer10Color.MouseDoubleClick += layerColorChange; + lbl_Layer11Color.MouseDoubleClick += layerColorChange; + lbl_Layer12Color.MouseDoubleClick += layerColorChange; + lbl_Layer13Color.MouseDoubleClick += layerColorChange; + lbl_Layer14Color.MouseDoubleClick += layerColorChange; + lbl_Layer15Color.MouseDoubleClick += layerColorChange; + lbl_Layer16Color.MouseDoubleClick += layerColorChange; + + lbl_ss1Color.MouseDoubleClick += layerColorChange; + lbl_ss2Color.MouseDoubleClick += layerColorChange; + lbl_ss3Color.MouseDoubleClick += layerColorChange; + + lbl_minorGridColor.MouseDoubleClick += layerColorChange; + lbl_majorGridColor.MouseDoubleClick += layerColorChange; + + lbl_Result1Color.MouseDoubleClick += layerColorChange; + lbl_Result2Color.MouseDoubleClick += layerColorChange; + lbl_Result3Color.MouseDoubleClick += layerColorChange; + lbl_Result4Color.MouseDoubleClick += layerColorChange; + + lbl_enabledColor.MouseDoubleClick += layerColorChange; + + lbl_implantMinColor.MouseDoubleClick += layerColorChange; + lbl_implantMeanColor.MouseDoubleClick += layerColorChange; + lbl_implantMaxColor.MouseDoubleClick += layerColorChange; + lbl_implantResistColor.MouseDoubleClick += layerColorChange; + + bool emailOK = validateEmailSettings(); + checkBox_EmailCompletion.Enabled = emailOK; + checkBox_perJob.Enabled = emailOK; + button_emailTest.Enabled = emailOK; + button_emailTest.Click += emailTest; + checkBox_geoCore_enableCDVariation.CheckedChanged += preferencesChange; + checkBox_geoCore_tileLayerPreview.CheckedChanged += preferencesChange; + checkBox_OGLAA.CheckedChanged += preferencesChange; + checkBox_OGLFill.CheckedChanged += preferencesChange; + checkBox_OGLPoints.CheckedChanged += preferencesChange; + num_fgOpacity.LostFocus += preferencesChange; + num_bgOpacity.LostFocus += preferencesChange; + num_zoomSpeed.LostFocus += preferencesChange; + + btn_resetColors.Click += resetColors; + }); + } + + void prepUI() + { + /* + Application.Instance.Invoke(() => + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + layer_stateAvOverlayCheckboxes(i, true); + } + }); + */ + } + + bool tooManyPolysWarning() + { + Application.Instance.Invoke(() => + { + if (!commonVars.wasWarningShown()) + { + commonVars.setWarningShown(true); + DialogResult dR = MessageBox.Show("More than 25 polygons involved in at least one layer - are you sure you want to continue?", "This could take a while", MessageBoxButtons.YesNo); + if (dR == DialogResult.No) + { + return true; + } + } + return false; + }); + return true; + } + + void clearAbortFlag() + { + commonVars.runAbort = false; + commonVars.loadAbort = false; + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_simulation.cs b/Common/Variance/UI/UIHandlers_simulation.cs new file mode 100644 index 0000000..e63dbf2 --- /dev/null +++ b/Common/Variance/UI/UIHandlers_simulation.cs @@ -0,0 +1,1134 @@ +using Error; +using Eto; +using Eto.Forms; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Variance +{ + public partial class MainForm + { + bool abortCheck() + { + if (commonVars.runAbort == true) + { + DialogResult dR = MessageBox.Show("Abort saving of results?", "Abort save?", MessageBoxButtons.YesNo); + if (dR != DialogResult.Yes) + { + commonVars.runAbort = false; + } + } + return commonVars.runAbort; + } + + void abortCSV(CancellationTokenSource cancelSource, CancellationToken cancellationToken) + { + if (!commonVars.cancelling) + { + if ((commonVars.runAbort) && (!commonVars.userCancelQuery)) + { + commonVars.userCancelQuery = true; + commonVars.cancelling = true; + // AsyncInvoke causes problems where run is aborted before user can respond to dialog. + Application.Instance.Invoke((() => + { + DialogResult dR = MessageBox.Show("Abort saving of results?", "Abort save?", MessageBoxButtons.YesNo); + if (dR == DialogResult.Yes) + { + updateStatusLine("Aborting saving of results."); + commonVars.runAbort = true; + } + else + { + commonVars.runAbort = false; + } + commonVars.userCancelQuery = false; + })); + + if (commonVars.runAbort) + { + cancelSource.Cancel(); + cancellationToken.ThrowIfCancellationRequested(); + } + } + commonVars.cancelling = false; + } + } + + void abortRun() + { + if (!commonVars.cancelling) + { + if ((commonVars.runAbort) && (!commonVars.userCancelQuery)) + { + Application.Instance.Invoke(() => + { + commonVars.userCancelQuery = true; + commonVars.cancelling = true; + DialogResult dR = MessageBox.Show("Abort and save results so far?", "Abort run?", MessageBoxButtons.YesNo); + if (dR == DialogResult.Yes) + { + commonVars.runAbort = true; + } + else + { + commonVars.runAbort = false; + } + commonVars.userCancelQuery = false; + }); + } + commonVars.cancelling = false; + } + } + + bool abortAllRuns() + { + // if (commonVars.runAbort == true) + { + DialogResult dR = MessageBox.Show("Yes: Abort all runs\r\nNo: Abort just this run", + "Abort all runs?", MessageBoxButtons.YesNo); + if (dR == DialogResult.Yes) + { + return true; + } + } + return false; + } + + void abortRunMT(SimResultPackage resultPackage, CancellationTokenSource cancelSource, CancellationToken cancellationToken) + { + if (!commonVars.cancelling) + { + if ((commonVars.runAbort) && (!commonVars.userCancelQuery)) + { + commonVars.userCancelQuery = true; + commonVars.cancelling = true; + // AsyncInvoke causes problems where run is aborted before user can respond to dialog. + Application.Instance.Invoke((() => + { + DialogResult dR = MessageBox.Show("Abort and save results so far?", "Abort run?", MessageBoxButtons.YesNo); + if (dR == DialogResult.Yes) + { + updateStatusLine("Aborting and saving results so far."); + commonVars.runAbort = true; + } + else + { + commonVars.runAbort = false; + } + commonVars.userCancelQuery = false; + })); + + if (commonVars.runAbort) + { + resultPackage.setState(false); + cancelSource.Cancel(); + cancellationToken.ThrowIfCancellationRequested(); + } + } + commonVars.cancelling = false; + } + } + + void simRunning() + { + commonVars.setSimRunning(true); + } + + void simRunningUIFunc() + { + simRunningUI(); + } + + void launchSimulationRun(bool useThreads) + { + int mode = getMainSelectedIndex(); + int tabIndex = getSubTabSelectedIndex(); + bool doPASearch = ((mode == (Int32)CommonVars.upperTabNames.twoD) && (tabIndex == (Int32)CommonVars.twoDTabNames.paSearch)); + string outFile = null; + + bool fileChosen = false; + if (!doPASearch) + { + string fileDialogTitle = "Select summary file to generate"; + string fileDialogFilter = "TXT Files (*.txt)"; + string fileDialogExt = ".txt"; + if (((mode == (Int32)CommonVars.upperTabNames.twoD) && (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1)) || + ((mode == (Int32)CommonVars.upperTabNames.Implant) && (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1))) + { + fileDialogTitle = "Select CSV file to generate"; + fileDialogFilter = "CSV Files (*.csv)"; + fileDialogExt = ".csv"; + } + + string[] tokens = Path.GetFileName(commonVars.projectFileName).Split(new char[] { '.' }); + string fileName = ""; + for (int i = 0; i < tokens.Length - 2; i++) + { + fileName += tokens[i] + "."; + } + fileName += tokens[tokens.Length - 2]; + + SaveFileDialog sfd = new SaveFileDialog() + { + Title = fileDialogTitle, + Filters = + { + new FileFilter(fileDialogFilter, fileDialogExt) + }, + }; + try + { + sfd.FileName = fileName; + } + catch (Exception) + { + + } + + if (sfd.ShowDialog(this) == DialogResult.Ok) + { + // Will overwrite if already exists. + outFile = sfd.FileName; + + // GTK requester doesn't add the extension, so review and add if needed to avoid a crash later. + if (!outFile.EndsWith(fileDialogExt, StringComparison.CurrentCulture)) + { + outFile += fileDialogExt; + } + + fileChosen = true; + } + } + + if (doPASearch || (!doPASearch && fileChosen)) + { + // Tidy up cruft prior to run. May not be necessary. + GC.Collect(); + + Task.Run(() => + { + if (mode == (Int32)CommonVars.upperTabNames.twoD) + { + entropyControl.EntropyRun(commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.nCases), outFile, useThreads, doPASearch); + } + if (mode == (Int32)CommonVars.upperTabNames.Implant) + { + entropyControl.entropyRun_implant(commonVars.getImplantSimulationSettings().getValue(EntropySettings.properties_i.nCases), outFile, useThreads); + } + } + ); + } + GC.Collect(); + } + + void monteCarloMultipleThreadEventHandler(object sender, EventArgs e) + { + launchSimulationRun(true); + } + + void monteCarloSingleThreadEventHandler(object sender, EventArgs e) + { + launchSimulationRun(false); + } + + void simRunningUI() + { + Application.Instance.Invoke(() => + { + // Disable menu items to avoid trouble. + var menu = Menu; + var menuItems = menu.Items; + for (int i = 0; i < menuItems.Count; i++) + { + menuItems[i].Enabled = false; + } + // Activate stop button to enable run abort. + btn_STOP.Enabled = true; + // Deactivate run button(s) since we're running a batch task. + btn_singleCPU.Enabled = false; + btn_multiCPU.Enabled = false; + // Block out UI elements + groupBox_setOutput.Enabled = false; + groupBox_simSettings.Enabled = false; + groupBox_GeoEqtn.Enabled = false; + groupBox_implant.Enabled = false; + if (commonVars.getReplayMode() == 0) + { + groupBox_replay.Enabled = false; + } + commentBox.Enabled = false; + // Some systems don't appear to like the tab control being disabled, so apply some guarding methods in case. + simRunningTabToFreeze = getSubTabSelectedIndex(); + tabControl_main.SelectedIndexChanged += freezeTabSelection; + tabControl_2D_simsettings.SelectedIndexChanged += freezeTabSelection; + }); + } + + void btnSTOP(object sender, EventArgs e) + { + // Set abort flag. + commonVars.runAbort = true; + } + + void btnCancel(object sender, EventArgs e) + { + // Set abort flag. + commonVars.loadAbort = true; + } + + void displayMultiThreadWarning() + { + Application.Instance.AsyncInvoke(() => + { + lbl_multiThreadResultNote.Text = "Update ~" + (CentralProperties.timer_interval / 1000).ToString() + "s"; + lbl_multiThreadResultNote.Visible = true; + }); + } + + void configProgressBar(int value, int max) + { + if (System.Threading.Thread.CurrentThread == commonVars.mainThreadIndex) + { + statusProgressBar.Value = value; + statusProgressBar.MaxValue = max; + } + else + { + Application.Instance.AsyncInvoke(() => + { + configProgressBar(value, max); + }); + } + } + + void postSimStatusLine() + { + int mainIndex = getMainSelectedIndex(); + int tabIndex = getSubTabSelectedIndex(); + + if (mainIndex != (int)CommonVars.upperTabNames.twoD) + { + return; + } + + if (tabIndex != (int)CommonVars.twoDTabNames.settings) + { + return; + } + + string updateString = ""; + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.shape) == 1) + { + updateString = "Input"; + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.results) == 1) + { + updateString += " and "; + } + } + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.results) == 1) + { + updateString += "Results"; + } + if (updateString != "") + { + updateString += " drawn."; + } + updateStatusLine(updateString); + } + + void postSimUI() + { + if (Platform.IsGtk) + { + Application.Instance.AsyncInvoke(() => + { + postSimUI_2(); + }); + } + else + { + Application.Instance.Invoke(() => + { + postSimUI_2(); + }); + } + } + + void postSimUI_2() + { + // Run complete, deactivate stop button and activate run button(s) again. + commonVars.setSimRunning(false); + if (commonVars.getReplayMode() == 1) + { + return; + } + + lbl_multiThreadResultNote.Visible = false; + btn_STOP.Enabled = false; + // Restore UI elements + groupBox_setOutput.Enabled = true; + groupBox_simSettings.Enabled = true; + groupBox_GeoEqtn.Enabled = true; + groupBox_implant.Enabled = true; + groupBox_replay.Enabled = true; + startButtonCheck(); + commentBox.Enabled = true; + // Some systems don't appear to like the tab control being disabled. Remove the guards here. + tabControl_main.SelectedIndexChanged -= freezeTabSelection; + tabControl_2D_simsettings.SelectedIndexChanged -= freezeTabSelection; + // Re-enable menu items. + var menu = Menu; + var menuItems = menu.Items; + for (int i = 0; i < menuItems.Count; i++) + { + menuItems[i].Enabled = true; + } + } + + void startIndeterminateProgress() + { + Application.Instance.Invoke(() => + { + statusProgressBar.Visible = true; + statusProgressBar.Indeterminate = true; + }); + } + + void startButtonCheck() + { + Application.Instance.Invoke(() => + { + btn_multiCPU.Enabled = false; + btn_singleCPU.Enabled = false; + + if (getMainSelectedIndex() == (Int32)CommonVars.upperTabNames.Implant) + { + btn_multiCPU.Enabled = true; + btn_singleCPU.Enabled = true; + } + else + { + if ((getMainSelectedIndex() == (Int32)CommonVars.upperTabNames.twoD) && ((getSubTabSelectedIndex() == (Int32)CommonVars.twoDTabNames.settings) || (getSubTabSelectedIndex() == (Int32)CommonVars.twoDTabNames.paSearch))) + { + bool aEqtn = commonVars.getLayerSettings(0).getInt(EntropyLayerSettings.properties_i.enabled) == 1; + bool bEqtn = commonVars.getLayerSettings(CentralProperties.maxLayersForMC / 2).getInt(EntropyLayerSettings.properties_i.enabled) == 1; + + for (int i = 1; i < CentralProperties.maxLayersForMC / 2; i++) + { + aEqtn = aEqtn || commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1; + bEqtn = bEqtn || commonVars.getLayerSettings(i + CentralProperties.maxLayersForMC / 2).getInt(EntropyLayerSettings.properties_i.enabled) == 1; + } + + if (aEqtn && bEqtn) + { + btn_singleCPU.Enabled = true; + btn_multiCPU.Enabled = true; + } + else + { + btn_singleCPU.Enabled = false; + btn_multiCPU.Enabled = false; + } + } + } + }); + } + + void doSimSettingsCheck() + { + Application.Instance.Invoke(() => + { + for (int i = 0; i < comboBox_geoEqtn_Op_2Layer.Length; i++) + { + if ((commonVars.getLayerSettings(i * 2).getInt(EntropyLayerSettings.properties_i.enabled) == 1) && (commonVars.getLayerSettings((i * 2) + 1).getInt(EntropyLayerSettings.properties_i.enabled) == 1)) + { + comboBox_geoEqtn_Op_2Layer[i].Enabled = true; + } + else + { + comboBox_geoEqtn_Op_2Layer[i].Enabled = false; + } + } + }); + } + + void suspendSettingsUI() + { + settingsUIFrozen = true; + commonVars.setActiveUI(CommonVars.uiActive.settings, false); + //tabPage_2D_Settings.SuspendLayout(); + } + + void resumeSettingsUI() + { + settingsUIFrozen = false; + commonVars.setActiveUI(CommonVars.uiActive.settings, true); + //tabPage_2D_Settings.ResumeLayout(); + } + + void addSettingsHandlers() + { + Application.Instance.Invoke(() => + { + settingsUIFrozen = false; + commonVars.setActiveUI(CommonVars.uiActive.settings, true); + comboBox_calcModes.SelectedIndexChanged += entropySettingsChanged; + checkBox_withinMode.CheckedChanged += entropySettingsChanged; + checkBox_useShortestEdge.CheckedChanged += entropySettingsChanged; + checkBox_displayResults.CheckedChanged += mcPreviewSettingsChanged; + checkBox_displayShapes.CheckedChanged += mcPreviewSettingsChanged; + num_ssNumOfCases.LostFocus += entropySettingsChanged; + num_ssPrecision.LostFocus += entropySettingsChanged; + num_cornerSegments.LostFocus += entropySettingsChanged; + checkBox_debugCalc.CheckedChanged += entropySettingsChanged; + checkBox_limitCornerPoints.CheckedChanged += entropySettingsChanged; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + comboBox_geoEqtn_Op[i].SelectedIndexChanged += entropySettingsChanged; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_2Layer.Length; i++) + { + comboBox_geoEqtn_Op_2Layer[i].SelectedIndexChanged += entropySettingsChanged; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_4Layer.Length; i++) + { + comboBox_geoEqtn_Op_4Layer[i].SelectedIndexChanged += entropySettingsChanged; + } + + for (int i = 0; i < comboBox_geoEqtn_Op_8Layer.Length; i++) + { + comboBox_geoEqtn_Op_8Layer[i].SelectedIndexChanged += entropySettingsChanged; + } + + checkBox_perPoly.CheckedChanged += entropySettingsChanged; + checkBox_aChord.CheckedChanged += entropySettingsChanged; + checkBox_bChord.CheckedChanged += entropySettingsChanged; + checkBox_external.CheckedChanged += entropySettingsChanged; + comboBox_externalTypes.SelectedIndexChanged += entropySettingsChanged; + checkBox_CSV.CheckedChanged += entropySettingsChanged; + checkBox_LERMode.CheckedChanged += entropySettingsChanged; + comboBox_RNG.SelectedIndexChanged += entropySettingsChanged; + + text_server.LostFocus += emailSettingsChanged; + text_emailAddress.LostFocus += emailSettingsChanged; + text_emailPwd.LostFocus += emailSettingsChanged; + + num_port.LostFocus += emailSettingsChanged; + checkBox_EmailCompletion.CheckedChanged += emailSettingsChanged; + checkBox_perJob.CheckedChanged += emailSettingsChanged; + checkBox_SSL.CheckedChanged += emailSettingsChanged; + + checkBox_friendlyNumbers.CheckedChanged += miscSettingsChanged; + + button_replay.Click += replayLoadCSV; + checkBox_replay.CheckedChanged += replayChanged; + num_replay.LostFocus += replayCaseChanged; + }); + } + + void freezeTabSelection(object sender, EventArgs e) + { + setMainSelectedIndex((Int32)CommonVars.upperTabNames.twoD); + set2DSelectedIndex(simRunningTabToFreeze); + } + + void abUI() + { + Application.Instance.Invoke(() => + { + // A layer + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + label_geoEqtn_Op[i].Text = commonVars.getLayerSettings(i).getString(EntropyLayerSettings.properties_s.name); + // Check layer enable states for boolean menu activation states. + comboBox_geoEqtn_Op[i].Enabled = commonVars.isLayerActive(i); + label_geoEqtn_Op[i].Enabled = commonVars.isLayerActive(i); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_2Layer.Length; i++) + { + if (commonVars.interLayerRelationship_2(i)) + { + comboBox_geoEqtn_Op_2Layer[i].Enabled = true; + } + else + { + comboBox_geoEqtn_Op_2Layer[i].Enabled = false; + } + } + + for (int i = 0; i < comboBox_geoEqtn_Op_4Layer.Length; i++) + { + if (commonVars.interLayerRelationship_4(i)) + { + comboBox_geoEqtn_Op_4Layer[i].Enabled = true; + } + else + { + comboBox_geoEqtn_Op_4Layer[i].Enabled = false; + } + } + }); + } + + void xUI() + { + Application.Instance.Invoke(() => + { + for (int i = 0; i < comboBox_geoEqtn_Op_8Layer.Length; i++) + { + if ( + (((commonVars.getLayerSettings(i * 8).getInt(EntropyLayerSettings.properties_i.enabled) == 1) || (commonVars.getLayerSettings((i * 8) + 1).getInt(EntropyLayerSettings.properties_i.enabled) == 1)) || + ((commonVars.getLayerSettings((i * 8) + 2).getInt(EntropyLayerSettings.properties_i.enabled) == 1) || (commonVars.getLayerSettings((i * 8) + 3).getInt(EntropyLayerSettings.properties_i.enabled) == 1))) + && + (((commonVars.getLayerSettings((i * 8) + 4).getInt(EntropyLayerSettings.properties_i.enabled) == 1) || (commonVars.getLayerSettings((i * 8) + 5).getInt(EntropyLayerSettings.properties_i.enabled) == 1)) || + ((commonVars.getLayerSettings((i * 8) + 6).getInt(EntropyLayerSettings.properties_i.enabled) == 1) || (commonVars.getLayerSettings((i * 8) + 7).getInt(EntropyLayerSettings.properties_i.enabled) == 1))) + ) + { + comboBox_geoEqtn_Op_8Layer[i].Enabled = true; + } + else + { + comboBox_geoEqtn_Op_8Layer[i].Enabled = false; + } + } + }); + } + + void entropySettingsChanged(object sender, EventArgs e) + { + if (settingsUIFrozen) + { + return; + } + + Application.Instance.Invoke(() => + { + entropySettingsChanged(sender); + getComment(); + }); + doStatusLine(); + drawSimulationPanelHandler(false); + updatePASearchUI(); + } + + async void entropySettingsChanged(object sender) + { + bool updateNeeded = false; + + // Force base configuration as the table layout lazy evaluation can result in trouble. + try + { + if (comboBox_calcModes.SelectedIndex < 0) + { + comboBox_calcModes.SelectedIndex = (int)CommonVars.calcModes.area; + } + } + catch (Exception) + { + // Harmless fail in case we're not in the right UI state. + } + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) < 0) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.oType, (int)CommonVars.calcModes.area); + } + + if (commonVars.getReplayMode() == 0) + { + int mainIndex = getMainSelectedIndex(); + int twoDIndex = getSubTabSelectedIndex(); + + btn_singleCPU.Enabled = false; + + btn_multiCPU.Enabled = false; + btn_STOP.Enabled = false; + statusProgressBar.Visible = false; + if (mainIndex != (Int32)CommonVars.upperTabNames.twoD) + { + return; + } + + if (!openGLErrorReported) + { + createVPContextMenu(); + if (twoDIndex != (int)CommonVars.twoDTabNames.paSearch) + { + viewPort.changeSettingsRef(ref mcVPSettings[CentralProperties.maxLayersForMC - 1 + twoDIndex]); + } + else + { + // Link to the simulation viewport to make things easier in the PA search mode, since we can hook into the simulation preview cheaply. + viewPort.changeSettingsRef(ref mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings]); + } + } + + setGlobalUIValues(); + + bool preCheck = !((twoDIndex == (int)CommonVars.twoDTabNames.settings) || (twoDIndex == (int)CommonVars.twoDTabNames.paSearch)); + + var control = sender as TabControl; + if ((control == tabControl_2D_simsettings) && preCheck) + { + return; + } + + commonVars.setWarningShown(false); + + if ((twoDIndex == (int)CommonVars.twoDTabNames.settings) || (twoDIndex == (int)CommonVars.twoDTabNames.paSearch)) + { + startButtonCheck(); + upperGadgets_panel.Content = simPreviewBox; + statusProgressBar.Visible = true; + } + + if (twoDIndex == (int)CommonVars.twoDTabNames.DOE) + { + updateStatusLine("Configure DOE settings."); + } + + // Set update needed flag to cause a re-sim if desired. + // We force the update flag to on and then clear it if the control is not supposed to trigger a re-evaluation. + } + + updateNeeded = true; + + if (commonVars.getReplayMode() == 0) + { + var checkBoxControl = sender as CheckBox; + if ((checkBoxControl == checkBox_external) || (checkBoxControl == checkBox_CSV) || + (checkBoxControl == checkBox_greedyMultiCPU) || (checkBoxControl == checkBox_LERMode)) + { + updateNeeded = false; + } + + var numControl = sender as NumericStepper; + if (numControl == num_ssNumOfCases) + { + updateNeeded = false; + } + + var ddControl = sender as DropDown; + if (ddControl == comboBox_RNG) + { + updateNeeded = false; + } + + // Retrieve our settings. + checkBox_perPoly.Enabled = false; + if (comboBox_calcModes.SelectedIndex == (int)CommonVars.calcModes.area) + { + checkBox_perPoly.Enabled = true; + } + + checkBox_withinMode.Enabled = false; + checkBox_useShortestEdge.Enabled = false; + + abUI(); + + xUI(); + + if ((bool)checkBox_debugCalc.Checked) + { + commonVars.getSimulationSettings().debugCalc = true; + } + else + { + commonVars.getSimulationSettings().debugCalc = false; + } + + if (comboBox_calcModes.SelectedIndex == (int)CommonVars.calcModes.enclosure_spacing_overlap) + { + if ((bool)checkBox_withinMode.Checked) + { + if ((bool)checkBox_useShortestEdge.Checked) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, (int)CommonVars.spacingCalcModes.enclosure); + } + else + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, (int)CommonVars.spacingCalcModes.enclosureOld); + } + } + else + { + if ((bool)checkBox_useShortestEdge.Checked) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, (int)CommonVars.spacingCalcModes.spacing); + } + else + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, (int)CommonVars.spacingCalcModes.spacingOld); + } + } + } + + checkBox_aChord.Enabled = false; + checkBox_bChord.Enabled = false; + + if (comboBox_calcModes.SelectedIndex == (int)CommonVars.calcModes.chord) + { + checkBox_aChord.Enabled = true; + checkBox_bChord.Enabled = true; + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, (int)CommonVars.chordCalcElements.a + (int)CommonVars.chordCalcElements.b); + if ((!(bool)checkBox_aChord.Checked) && (!(bool)checkBox_bChord.Checked)) + { + checkBox_aChord.Checked = true; // force a default if the user is being silly. + } + if (!(bool)checkBox_aChord.Checked) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) - (int)CommonVars.chordCalcElements.a); + + } + if (!(bool)checkBox_bChord.Checked) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) - (int)CommonVars.chordCalcElements.b); + } + } + + if (comboBox_calcModes.SelectedIndex == (int)CommonVars.calcModes.area) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.oType, (int)CommonVars.calcModes.area); + if ((bool)checkBox_perPoly.Checked) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, (int)CommonVars.areaCalcModes.perpoly); + textBox_userGuidance.Text = "The minimum overlap area will be calculated and reported."; + } + else + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.subMode, (int)CommonVars.areaCalcModes.all); + textBox_userGuidance.Text = "The total overlap area of all polygons in the layers will be calculated and reported."; + } + label_AB.Text = "AND"; + } + if (comboBox_calcModes.SelectedIndex == (int)CommonVars.calcModes.enclosure_spacing_overlap) + { + comboBox_calcModes.SelectedIndexChanged -= entropySettingsChanged; + checkBox_withinMode.Enabled = true; + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.oType, (int)CommonVars.calcModes.enclosure_spacing_overlap); + string t = ""; + if ((bool)checkBox_withinMode.Checked) + { + checkBox_useShortestEdge.Enabled = false; + commonVars.calcMode_names[(int)CommonVars.calcModes.enclosure_spacing_overlap] = "Compute Enclosure Distribution"; + label_AB.Text = "Min Enclosure To"; + t = "enclosure"; + } + else + { + checkBox_useShortestEdge.Enabled = true; + commonVars.calcMode_names[(int)CommonVars.calcModes.enclosure_spacing_overlap] = "Compute Spacing Distribution"; + label_AB.Text = "Min Space To"; + t = "spacing"; + } + comboBox_calcModes.SelectedIndex = (int)CommonVars.calcModes.enclosure_spacing_overlap; + comboBox_calcModes.SelectedIndexChanged += entropySettingsChanged; + textBox_userGuidance.Text = "The system will report the minimum " + t + " value between the shapes, as a single value per case.\r\nNote that overlap cases will report a negative value to indicate that they are opposite to the case being evaluated"; + } + if (comboBox_calcModes.SelectedIndex == (int)CommonVars.calcModes.chord) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.oType, (int)CommonVars.calcModes.chord); + label_AB.Text = "Min Chord With"; + textBox_userGuidance.Text = "The system will report multiple chord lengths as : \"AMinTopChord,AMinBottomChord,BMinLeftChord,BMinRightChord\".\r\n\r\nMissing chords or invalid cases for evaluation are reported as 0.0\r\nChords not requested by the user are shown as N/A in the output file.\r\n\r\nShape A is defined by geometric equation A; B is geometric equation B.\r\n\r\nMajor axis : Orient shape A horizontally and B vertically else results will be reversed (top/bottom <> left/right)"; + } + if (comboBox_calcModes.SelectedIndex == (int)CommonVars.calcModes.angle) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.oType, (int)CommonVars.calcModes.angle); + label_AB.Text = "Min Angle With"; + textBox_userGuidance.Text = "The minimum intersection angle will be reported, in degrees. A lack of intersection will yield a 180-degree value in the output"; + } + commonVars.getSimulationSettings().setResolution(Convert.ToDouble(num_ssPrecision.Value)); + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.cSeg, Convert.ToInt32(num_cornerSegments.Value)); + + if ((bool)checkBox_limitCornerPoints.Checked) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.optC, 1); + } + else + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.optC, 0); + } + + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.nCases, Convert.ToInt32(num_ssNumOfCases.Value)); + + if ((bool)checkBox_greedyMultiCPU.Checked) + { + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.greedy, 1); + } + else + { + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.greedy, 0); + } + + if ((bool)checkBox_linkCDUVariation.Checked) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.linkCDU, 1); + } + else + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.linkCDU, 0); + } + + if ((bool)checkBox_LERMode.Checked) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.ler, 1); + } + else + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.ler, 0); + } + + // Store our operators in simulation settings. + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + commonVars.getSimulationSettings().setOperatorValue(EntropySettings.properties_o.layer, i, comboBox_geoEqtn_Op[i].SelectedIndex); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_2Layer.Length; i++) + { + commonVars.getSimulationSettings().setOperatorValue(EntropySettings.properties_o.twoLayer, i, comboBox_geoEqtn_Op_2Layer[i].SelectedIndex); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_4Layer.Length; i++) + { + commonVars.getSimulationSettings().setOperatorValue(EntropySettings.properties_o.fourLayer, i, comboBox_geoEqtn_Op_4Layer[i].SelectedIndex); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_8Layer.Length; i++) + { + commonVars.getSimulationSettings().setOperatorValue(EntropySettings.properties_o.eightLayer, i, comboBox_geoEqtn_Op_8Layer[i].SelectedIndex); + } + + if ((bool)checkBox_external.Checked) + { + comboBox_externalTypes.Enabled = true; + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.external, 1); + commonVars.getImplantSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.externalType, (Int32)CommonVars.external_Type.svg); + } + else + { + comboBox_externalTypes.Enabled = false; + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.external, 0); + } + + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.externalType, comboBox_externalTypes.SelectedIndex); + + if ((bool)checkBox_CSV.Checked) + { + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.csv, 1); + } + else + { + commonVars.getSimulationSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.csv, 0); + } + + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.rngType, comboBox_RNG.SelectedIndex); + + // Ensure we set controls according to run state + if (commonVars.isSimRunning()) + { + btn_singleCPU.Enabled = false; + btn_multiCPU.Enabled = false; + btn_STOP.Enabled = true; + } + } + + // Make a single run when on the right tab, to populate the preview structures, and only if simulation not running. + if (!commonVars.isSimRunning())// && (tabPage_2D_simsettings.SelectedIndex == (int)CommonVars.twoDTabNames.settings)) + { + if (updateNeeded) + { + // Set indeterminate progress bar to show application is thinking. + Application.Instance.Invoke(() => + { + statusProgressBar.Indeterminate = true; + } + ); + entropyControl.update(commonVars); + // Spawn and await background task in case the calculation is long-running. + // Avoids blocking the UI. + // Freeze the UI to avoid cascasing runs. + simRunningUIFunc(); + btn_STOP.Enabled = false; // No ability to abort a single case, so don't mislead the user. They are along for the ride. + + try + { + await Task.Run(() => + { + updateStatusLine("Calculating - please wait"); + if (commonVars.getReplayMode() == 0) + { + entropyControl.EntropyRun(numberOfCases: 1, csvFile: null, useThreads: false, doPASearch: false); + } + else + { + entropyControl.EntropyRun(numberOfCases: 1, csvFile: null, useThreads: false, doPASearch: false, setJobSettings: true, loadedJobSettings: simReplay.getChaosSettings(), replayRow: simReplay.getValue(Replay.properties_i.row), replayCol: simReplay.getValue(Replay.properties_i.col)); + } + }); + } + catch (Exception) + { + // Handle any task cancelled exception without crashing the tool. The cancellation may occur due to close of the tool whilst evaluation is underway. + } + postSimUI(); + // Set the progress bar back to a fixed state + Application.Instance.Invoke(() => + { + statusProgressBar.Indeterminate = false; + } + ); + postSimStatusLine(); + } + } + if (commonVars.getReplayMode() == 0) + { + uiFollowChanges(); + } + } + + void setReplayControls() + { + groupBox_replay.Enabled = true; + button_replay.Enabled = true; + checkBox_replay.Enabled = simReplay.isValid(); + num_replay.Enabled = simReplay.isValid(); + + if (((bool)checkBox_replay.Checked) && (!simReplay.isValid())) + { + checkBox_replay.Checked = false; + // Will trigger event handler and update setup. + } + } + + void replaySuspend() + { + groupBox_replay.Enabled = false; + num_replay.Enabled = false; + checkBox_replay.Enabled = false; + button_replay.Enabled = true; + } + + void replayResume() + { + groupBox_replay.Enabled = true; + num_replay.Enabled = true; + checkBox_replay.Enabled = true; + button_replay.Enabled = false; + } + + void replayLoadCSV(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog() + { + Title = "Select CSV file to Load", + MultiSelect = false, + Filters = + { + new FileFilter("CSV Files (*.csv)", ".csv") + } + }; + if (ofd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + try + { + simReplay.replay_loadCSV(ofd.FileName); + } + catch (Exception) + { + simReplay.reset(); + } + } + + // Configure numeric control. + if (simReplay.getValue(Replay.properties_i.max) < 1) + { + num_replay.MinValue = 0; + num_replay.Value = 0; + num_replay.MaxValue = 0; + } + else + { + num_replay.MaxValue = simReplay.getValue(Replay.properties_i.max); + num_replay.Value = 1; + num_replay.MinValue = 1; + } + + setReplayControls(); + } + + void replayChanged(object sender, EventArgs e) + { + replayChanged(); + } + + void replayChanged() + { + if (replayUIFrozen) + { + return; + } + replayUIFrozen = true; + + if ((bool)checkBox_replay.Checked) + { + enableReplay(); + } + else + { + disableReplay(); + } + + replayUIFrozen = false; + } + + void enableReplay() + { + commonVars.setReplayMode(1); + simRunningUI(); + replayResume(); + replay(); + } + + void disableReplay() + { + postSimUI(); + commonVars.setReplayMode(0); + replaySuspend(); + entropySettingsChanged(null); + } + + void replayCaseChanged(object sender, EventArgs e) + { + if (replayUIFrozen) + { + return; + } + replayUIFrozen = true; + replay(); + replayUIFrozen = false; + } + + void replay() + { + if (!simReplay.isValid()) + { + return; + } + + if (commonVars.getReplayMode() == 1) + { + // Retrieve chaos values from replay. + simReplay.getState(Convert.ToInt32(num_replay.Value)); + + // Update preview with replay state. + entropySettingsChanged(null); + } + + replayChanged(); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_updating.cs b/Common/Variance/UI/UIHandlers_updating.cs new file mode 100644 index 0000000..e24a1a8 --- /dev/null +++ b/Common/Variance/UI/UIHandlers_updating.cs @@ -0,0 +1,1246 @@ +using Eto.Drawing; +using Eto.Forms; +using VeldridEto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Variance +{ + public partial class MainForm + { + void updateImplantPreview() + { + // Update the preview configuration. + otkVPSettings_implant.polyList.Clear(); + otkVPSettings_implant.tessPolyList.Clear(); + otkVPSettings_implant.bgPolyList.Clear(); + otkVPSettings_implant.lineList.Clear(); + // Evaluated resist side. We know there's a single polygon in previewShapes and we know the resist evaluation is the first entry in the resistShapes list. + int limit = entropyControl.getImplantResultPackage().getImplantPreviewResult().getResistShapes()[0].getPoints()[0].Count(); + PointF[] tmpPoints = new PointF[limit]; + Parallel.For(0, limit, (point) => + // for (Int32 point = 0; point < tmpPoints.Count(); point++) + { + tmpPoints[point] = new PointF((float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getResistShapes()[0].getPoints()[0][point].X, + (float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getResistShapes()[0].getPoints()[0][point].Y); + }); + otkVPSettings_implant.addPolygon(tmpPoints, Color.FromArgb(entropyControl.getImplantResultPackage().getImplantPreviewResult().getResistShapes()[0].getColor().toArgb()), (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), false, 0); + + // Background - second item in the resistShapes, but again a single polygon. + limit = entropyControl.getImplantResultPackage().getImplantPreviewResult().getResistShapes()[1].getPoints()[0].Count(); + tmpPoints = new PointF[limit]; + Parallel.For(0, limit, (point) => + // for (Int32 point = 0; point < tmpPoints.Count(); point++) + { + tmpPoints[point] = new PointF((float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getResistShapes()[1].getPoints()[0][point].X, + (float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getResistShapes()[1].getPoints()[0][point].Y); + }); + otkVPSettings_implant.addBGPolygon(tmpPoints, Color.FromArgb(entropyControl.getImplantResultPackage().getImplantPreviewResult().getResistShapes()[1].getColor().toArgb()), (float)commonVars.getOpacity(CommonVars.opacity_gl.bg), 1); + + // Now add our shadowing line. Single polygon in the shadowLine's previewPoints. + limit = entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.shadow).getPoints()[0].Count(); + tmpPoints = new PointF[limit]; + Parallel.For(0, limit, (point) => + // for (Int32 point = 0; point < tmpPoints.Count(); point++) + { + tmpPoints[point] = new PointF((float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.shadow).getPoints()[0][point].X, + (float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.shadow).getPoints()[0][point].Y); + }); + otkVPSettings_implant.addLine(tmpPoints, Color.FromArgb(entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.shadow).getColor().toArgb()), (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), 2); + + // Now add our min shadowing line. Single polygon in the shadowLine's previewPoints. + limit = entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.min).getPoints()[0].Count(); + tmpPoints = new PointF[limit]; + Parallel.For(0, limit, (point) => + // for (Int32 point = 0; point < tmpPoints.Count(); point++) + { + tmpPoints[point] = new PointF((float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.min).getPoints()[0][point].X, + (float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.min).getPoints()[0][point].Y); + }); + otkVPSettings_implant.addLine(tmpPoints, Color.FromArgb(entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.min).getColor().toArgb()), (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), 3); + + // Now add our max shadowing line. Single polygon in the shadowLine's previewPoints. + limit = entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.max).getPoints()[0].Count(); + tmpPoints = new PointF[limit]; + Parallel.For(0, limit, (point) => + // for (Int32 point = 0; point < tmpPoints.Count(); point++) + { + tmpPoints[point] = new PointF((float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.max).getPoints()[0][point].X, + (float)entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.max).getPoints()[0][point].Y); + }); + otkVPSettings_implant.addLine(tmpPoints, Color.FromArgb(entropyControl.getImplantResultPackage().getImplantPreviewResult().getLine(Results_implant.lines.max).getColor().toArgb()), (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), 4); + + Application.Instance.Invoke(() => + { + updateViewport(); + }); + } + + void updateImplantSimUIST(bool doPASearch, SimResultPackage resultPackage, string resultString) + { + string[] resultTokens = resultString.Split(new char[] { ',' }); + updateImplantPreview(); + Application.Instance.Invoke(() => + { + vSurface.Invalidate(); + if (resultTokens.Length == 3) + { + // Preview mode + textBox_implantShadowNom.Text = resultTokens[0]; + textBox_implantShadowMin.Text = resultTokens[1]; + textBox_implantShadowMax.Text = resultTokens[2]; + } + else + if (resultTokens.Length == 2) + { + // MC run + textBox_implantShadowNom.Text = resultString; + textBox_implantShadowMin.Text = ""; + textBox_implantShadowMax.Text = ""; + } + }); + } + + void updateImplantSimUIMT() + { + commonVars.m_timer.Elapsed += new System.Timers.ElapsedEventHandler(updateImplantPreview); + } + + void updateSimUIST(bool doPASearch, SimResultPackage resultPackage, string resultString) + { + if (commonVars.getReplayMode() == 1) + { + resultString += " | replay: " + simReplay.getResult(); + } + commonVars.getSimPreview().updatePreview(resultPackage.getPreviewResult().getSimShapes(), resultPackage.getPreviewResult().getPreviewShapes(), resultPackage.getPreviewResult().getPoints(), resultString); + drawSimulationPanelHandler(doPASearch); + } + + void updateSimUIMT() + { + commonVars.m_timer.Elapsed += new System.Timers.ElapsedEventHandler(updatePreview); + } + + void updateSettingsUIFromSettings() + { + Application.Instance.Invoke(() => + { + if (commonVars.getActiveUI(CommonVars.uiActive.settings)) + { + suspendSettingsUI(); + } + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.results) == 1) + { + checkBox_displayResults.Checked = true; + } + else + { + checkBox_displayResults.Checked = false; + } + + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.ler) == 1) + { + checkBox_LERMode.Checked = true; + } + else + { + checkBox_LERMode.Checked = false; + } + + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.shape) == 1) + { + checkBox_displayShapes.Checked = true; + } + else + { + checkBox_displayShapes.Checked = false; + } + + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.external) == 1) + { + checkBox_external.Checked = true; + } + else + { + checkBox_external.Checked = false; + } + + comboBox_externalTypes.SelectedIndex = commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType); + + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1) + { + checkBox_CSV.Checked = true; + } + else + { + checkBox_CSV.Checked = false; + } + + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.linkCDU) == 1) + { + checkBox_linkCDUVariation.Checked = true; + } + else + { + checkBox_linkCDUVariation.Checked = false; + } + + checkBox_aChord.Enabled = false; + checkBox_bChord.Enabled = false; + checkBox_withinMode.Enabled = false; + checkBox_useShortestEdge.Enabled = false; + checkBox_perPoly.Enabled = false; + + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) < 0) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.oType, 0); + } + + comboBox_calcModes.SelectedIndex = commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType); + + switch (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType)) + { + case (Int32)CommonVars.calcModes.area: + checkBox_perPoly.Enabled = true; + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.areaCalcModes.perpoly) + { + checkBox_perPoly.Checked = true; + } + else + { + checkBox_perPoly.Checked = false; + } + + break; + case (Int32)CommonVars.calcModes.enclosure_spacing_overlap: + checkBox_withinMode.Enabled = true; + + if ((commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacing) || (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacingOld)) + { + checkBox_useShortestEdge.Enabled = true; + } + + if ((commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosure) || (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosureOld)) + { + checkBox_withinMode.Checked = true; + } + else + { + checkBox_withinMode.Checked = false; + } + + if ((commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosure) || (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacing)) + { + checkBox_useShortestEdge.Checked = true; + } + else + { + checkBox_useShortestEdge.Checked = false; + } + break; + case (Int32)CommonVars.calcModes.chord: + checkBox_aChord.Enabled = true; + checkBox_bChord.Enabled = true; + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) != (int)CommonVars.chordCalcElements.b) + { + checkBox_aChord.Checked = true; + } + else + { + checkBox_aChord.Checked = false; + } + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) >= (int)CommonVars.chordCalcElements.b) + { + checkBox_bChord.Checked = true; + } + else + { + checkBox_bChord.Checked = false; + } + break; + case (Int32)CommonVars.calcModes.angle: + break; + } + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + comboBox_geoEqtn_Op[i].SelectedIndex = commonVars.getSimulationSettings().getOperatorValue(EntropySettings.properties_o.layer, i); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_2Layer.Length; i++) + { + comboBox_geoEqtn_Op_2Layer[i].SelectedIndex = commonVars.getSimulationSettings().getOperatorValue(EntropySettings.properties_o.twoLayer, i); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_4Layer.Length; i++) + { + comboBox_geoEqtn_Op_4Layer[i].SelectedIndex = commonVars.getSimulationSettings().getOperatorValue(EntropySettings.properties_o.fourLayer, i); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_8Layer.Length; i++) + { + comboBox_geoEqtn_Op_8Layer[i].SelectedIndex = commonVars.getSimulationSettings().getOperatorValue(EntropySettings.properties_o.eightLayer, i); + } + + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.rngType) < 0) + { + commonVars.getSimulationSettings().setValue(EntropySettings.properties_i.rngType, commonVars.getSimulationSettings().getDefaultValue(EntropySettings.properties_i.rngType)); + } + + comboBox_RNG.SelectedIndex = commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.rngType); + + num_cornerSegments.Value = commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.cSeg); + num_ssNumOfCases.Value = commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.nCases); + num_ssPrecision.Value = commonVars.getSimulationSettings().getResolution(); + + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.optC) == 1) + { + checkBox_limitCornerPoints.Checked = true; + } + else + { + checkBox_limitCornerPoints.Checked = false; + } + + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.greedy) == 1) + { + checkBox_greedyMultiCPU.Checked = true; + } + else + { + checkBox_greedyMultiCPU.Checked = false; + } + + resumeSettingsUI(); + }); + } + + void updateDOESettingsUIFromSettings() + { + Application.Instance.Invoke(() => + { + if (commonVars.getActiveUI(CommonVars.uiActive.doe)) + { + suspendDOESettingsUI(); + } + + num_DOERows.Value = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.rows); + num_DOECols.Value = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.cols); + try + { + num_DOEColPitch.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colPitch); + num_DOERowPitch.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowPitch); + } + catch (Exception) + { + } + + radioButton_allTiles.Checked = true; + + if (commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.sTile) == 1) + { + radio_useSpecificTile.Checked = true; + } + + if (commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.uTileList) == 1) + { + radio_useSpecificTiles.Checked = true; + } + + try + { + num_DOESCCol.Value = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.sTileCol); + num_DOESCRow.Value = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.sTileRow); + } + catch (Exception) + { + } + + try + { + num_rowOffset.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowOffset); + num_colOffset.Value = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colOffset); + } + catch (Exception) + { + } + + try + { + textBox_useSpecificTiles.Text = commonVars.getSimulationSettings().tileListToString(); + } + catch (Exception) + { + } + + if (commonVars.getSimulationSettings().getDOESettings().getBool(DOESettings.properties_b.iDRM)) + { + radio_useCSViDRM.Checked = true; + } + + if (commonVars.getSimulationSettings().getDOESettings().getBool(DOESettings.properties_b.quilt)) + { + radio_useCSVQuilt.Checked = true; + } + + doeSettingsChanged(); + resumeDOESettingsUI(); + }); + } + + void updateImplantUIFromSettings() + { + Application.Instance.Invoke(() => + { + if (commonVars.getActiveUI(CommonVars.uiActive.implant)) + { + suspendImplantUI(); + } + + try + { + num_implantResistCD.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.w); + } + catch (Exception) + { + } + + try + { + num_implantResistCDVar.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.wV); + } + catch (Exception) + { + } + + try + { + num_implantResistHeight.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.h); + } + catch (Exception) + { + } + + try + { + num_implantResistHeightVar.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.hV); + } + catch (Exception) + { + } + + try + { + num_implantResistTopCRR.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.cRR); + } + catch (Exception) + { + } + + try + { + num_implantResistTopCRRVar.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.cV); + } + catch (Exception) + { + } + + try + { + num_implantTiltAngle.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.tilt); + } + catch (Exception) + { + } + + try + { + num_implantTiltAngleVar.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.tiltV); + } + catch (Exception) + { + } + + try + { + num_implantTwistAngle.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.twist); + } + catch (Exception) + { + } + + try + { + num_implantTwistAngleVar.Value = commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.twistV); + } + catch (Exception) + { + } + + try + { + num_implantNumOfCases.Value = commonVars.getImplantSimulationSettings().getValue(EntropySettings.properties_i.nCases); + } + catch (Exception) + { + } + + try + { + num_implantCornerSegments.Value = commonVars.getImplantSimulationSettings().getValue(EntropySettings.properties_i.cSeg); + } + catch (Exception) + { + } + + try + { + checkBox_CSV_implant.Checked = (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1); + } + catch (Exception) + { + } + + try + { + checkBox_external_implant.Checked = ((commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.external) == 1) && (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType) == (Int32)CommonVars.external_Type.svg)); + } + catch (Exception) + { + } + + try + { + comboBox_externalTypes_implant.SelectedIndex = commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType); + } + catch (Exception) + { + } + + try + { + comboBox_implantRNG.SelectedIndex = commonVars.getImplantSimulationSettings().getValue(EntropySettings.properties_i.rngType); + } + catch (Exception) + { + } + + doImplantShadowing(); + resumeImplantUI(); + }); + } + + void updateUtilsValues() + { + Application.Instance.Invoke(() => + { + utilsUIFrozen = true; + num_port.Value = Convert.ToInt32(varianceContext.vc.port); + text_server.Text = varianceContext.vc.host; + text_emailAddress.Text = varianceContext.vc.emailAddress; + try + { + text_emailPwd.Text = varianceContext.vc.aes.DecryptString(varianceContext.vc.emailPwd); + } + catch (Exception) + { + text_emailPwd.Text = ""; + commonVars.getNonSimulationSettings().emailPwd = varianceContext.vc.emailPwd = varianceContext.vc.aes.EncryptToString(""); + } + checkBox_SSL.Checked = varianceContext.vc.ssl; + checkBox_perJob.Checked = varianceContext.vc.perJob; + checkBox_EmailCompletion.Checked = varianceContext.vc.completion; + checkBox_friendlyNumbers.Checked = varianceContext.vc.friendlyNumber; + num_zoomSpeed.Value = varianceContext.vc.openGLZoomFactor; + num_bgOpacity.Value = varianceContext.vc.BGOpacity; + num_fgOpacity.Value = varianceContext.vc.FGOpacity; + checkBox_OGLAA.Checked = varianceContext.vc.AA; + checkBox_OGLFill.Checked = varianceContext.vc.FilledPolygons; + checkBox_OGLPoints.Checked = varianceContext.vc.drawPoints; + checkBox_geoCore_tileLayerPreview.Checked = varianceContext.vc.layerPreviewDOETile; + checkBox_geoCore_enableCDVariation.Checked = varianceContext.vc.geoCoreCDVariation; + utilsUIFrozen = false; + }); + } + + void updateUIColors() + { + Application.Instance.Invoke(() => + { + colUIFrozen = true; + lbl_Layer1Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer1_Color.toArgb()); + lbl_Layer2Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer2_Color.toArgb()); + lbl_Layer3Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer3_Color.toArgb()); + lbl_Layer4Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer4_Color.toArgb()); + lbl_Layer5Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer5_Color.toArgb()); + lbl_Layer6Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer6_Color.toArgb()); + lbl_Layer7Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer7_Color.toArgb()); + lbl_Layer8Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer8_Color.toArgb()); + lbl_Layer9Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer9_Color.toArgb()); + lbl_Layer10Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer10_Color.toArgb()); + lbl_Layer11Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer11_Color.toArgb()); + lbl_Layer12Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer12_Color.toArgb()); + lbl_Layer13Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer13_Color.toArgb()); + lbl_Layer14Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer14_Color.toArgb()); + lbl_Layer15Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer15_Color.toArgb()); + lbl_Layer16Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.layer16_Color.toArgb()); + lbl_Result1Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.result_Color.toArgb()); + lbl_Result2Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.result2_Color.toArgb()); + lbl_Result3Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.result3_Color.toArgb()); + lbl_Result4Color.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.result4_Color.toArgb()); + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + label_geoEqtn_Op[i].TextColor = Color.FromArgb(varianceContext.vc.colors.simPreviewColors[i].toArgb()); + checkBox_bg_lyr[i].TextColor = Color.FromArgb(varianceContext.vc.colors.simPreviewColors[i].toArgb()); + checkBox_omit_lyr[i].TextColor = Color.FromArgb(varianceContext.vc.colors.simPreviewColors[i].toArgb()); + } + + Color ss1Color = Color.FromArgb(varianceContext.vc.colors.subshape1_Color.R, + varianceContext.vc.colors.subshape1_Color.G, + varianceContext.vc.colors.subshape1_Color.B); + + comboBox_layerTipLocations_exp.TextColor = ss1Color; + + num_layer_subshape_hl_exp.TextColor = ss1Color; + num_layer_subshape_vl_exp.TextColor = ss1Color; + num_layer_subshape_ho_exp.TextColor = ss1Color; + num_layer_subshape_vo_exp.TextColor = ss1Color; + + Color ss2Color = Color.FromArgb(varianceContext.vc.colors.subshape2_Color.R, + varianceContext.vc.colors.subshape2_Color.G, + varianceContext.vc.colors.subshape2_Color.B); + + comboBox_layerTipLocations2_exp.TextColor = ss2Color; + + num_layer_subshape2_hl_exp.TextColor = ss2Color; + num_layer_subshape2_vl_exp.TextColor = ss2Color; + num_layer_subshape2_ho_exp.TextColor = ss2Color; + num_layer_subshape2_vo_exp.TextColor = ss2Color; + + Color ss3Color = Color.FromArgb(varianceContext.vc.colors.subshape3_Color.R, + varianceContext.vc.colors.subshape3_Color.G, + varianceContext.vc.colors.subshape3_Color.B); + + comboBox_layerTipLocations3_exp.TextColor = ss3Color; + + num_layer_subshape3_hl_exp.TextColor = ss3Color; + num_layer_subshape3_vl_exp.TextColor = ss3Color; + num_layer_subshape3_ho_exp.TextColor = ss3Color; + num_layer_subshape3_vo_exp.TextColor = ss3Color; + + lbl_ss1Color.BackgroundColor = ss1Color; + lbl_ss2Color.BackgroundColor = ss2Color; + lbl_ss3Color.BackgroundColor = ss3Color; + + lbl_enabledColor.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.enabled_Color.toArgb()); + lbl_majorGridColor.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.major_Color.toArgb()); + lbl_minorGridColor.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.minor_Color.toArgb()); + lbl_implantMinColor.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.implantMin_Color.toArgb()); + lbl_implantMeanColor.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.implantMean_Color.toArgb()); + lbl_implantMaxColor.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.implantMax_Color.toArgb()); + lbl_implantResistColor.BackgroundColor = Color.FromArgb(varianceContext.vc.colors.implantResist_Color.toArgb()); + colUIFrozen = false; + }); + + doImplantShadowing(); + doeSettingsChanged(); + drawSimulationPanelHandler(false); + refreshAllPreviewPanels(); + + updateStatusLine(""); + } + + // Update status line with message. Blanks will reset back. + void updateStatusLine(string message) + { + Application.Instance.AsyncInvoke(() => + { + if (message == "") + { + message = "Version " + commonVars.version; + } + statusReadout.Text = message; + } + ); + } + + void updateProgressBar() + { + if (Thread.CurrentThread == commonVars.mainThreadIndex) + { + if (statusProgressBar.Value < statusProgressBar.MaxValue) + { + statusProgressBar.Value++; + } + } + else + { + Application.Instance.AsyncInvoke(() => + { + updateProgressBar(); + }); + } + } + + void updateProgressBar(Int32 value) + { + if (Thread.CurrentThread == commonVars.mainThreadIndex) + { + if (value > statusProgressBar.MaxValue) + { + value = statusProgressBar.MaxValue; + } + statusProgressBar.Value = value; + } + else + { + Application.Instance.AsyncInvoke(() => + { + updateProgressBar(value); + }); + } + } + + void updateProgressBar(double val) + { + Application.Instance.Invoke(() => + { + statusProgressBar.Indeterminate = false; + if (statusProgressBar.MaxValue < 100) + { + statusProgressBar.MaxValue = 100; + } + if (val > 1) + { + val = 1; + } + if (val < 0) + { + val = 0; + } + statusProgressBar.Value = (int)(val * statusProgressBar.MaxValue); + }); + } + + void updatePreview(object sender, System.Timers.ElapsedEventArgs e) + { + if (Monitor.TryEnter(commonVars.drawingLock)) + { + try + { + if ((entropyControl.sw_Preview.Elapsed.TotalMilliseconds - entropyControl.timeOfLastPreviewUpdate) > commonVars.m_timer.Interval) + { + try + { + Application.Instance.Invoke(() => + { + bool doPASearch = getSubTabSelectedIndex() == (int)CommonVars.twoDTabNames.paSearch; + previewUpdate(doPASearch); + }); + } + catch (Exception) + { + } + } + } + finally + { + Monitor.Exit(commonVars.drawingLock); + } + } + } + + void previewUpdate(bool doPASearch) + { + if ((entropyControl.sw_Preview.Elapsed.TotalMilliseconds - entropyControl.timeOfLastPreviewUpdate) < commonVars.m_timer.Interval) + { + return; + } + + try + { + if (entropyControl.sw.IsRunning) + { + entropyControl.swTime += entropyControl.sw.Elapsed.TotalSeconds; + } + entropyControl.sw.Stop(); + statusProgressBar.Value = entropyControl.currentProgress; + entropyControl.timeOfFlight(entropyControl.swTime, doPASearch); + if (Monitor.TryEnter(varianceContext.vc.previewLock)) + { + try + { + // Update the preview configuration. + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].bgPolyList.Clear(); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].tessPolyList.Clear(); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].polyList.Clear(); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].lineList.Clear(); + if ((commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.results) == 1) || (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.shape) == 1)) + { + commonVars.getSimPreview().updatePreview(entropyControl.getResultPackage()); + } + else + { + commonVars.getSimPreview().updatePreview(entropyControl.getResultPackage().getMeanAndStdDev()); + } + } + finally + { + Monitor.Exit(varianceContext.vc.previewLock); + } + } + drawSimulationPanelHandler(doPASearch); + } + catch (Exception) + { + } + try + { + entropyControl.sw.Reset(); + entropyControl.sw.Start(); + entropyControl.timeOfLastPreviewUpdate = entropyControl.sw_Preview.Elapsed.Milliseconds; + } + catch (Exception) + { + } + } + + void drawSimulationPanelHandler(bool doPASearch) + { + try + { + Int32 totalPoints = 0; + if (!commonVars.isSimRunning()) + { + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].minorGridColor = Color.FromArgb(commonVars.getColors().minor_Color.toArgb()); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].majorGridColor = Color.FromArgb(commonVars.getColors().major_Color.toArgb()); + } + + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].bgPolyList.Clear(); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].polyList.Clear(); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].tessPolyList.Clear(); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].lineList.Clear(); + // Draw our base shapes if user requested + if ((commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.shape) == 1) || (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.results) == 1)) + { + if ((commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.shape) == 1) && (commonVars.getSimPreview().getPreviewShapes().Count() != 0)) + { + for (Int32 layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + for (Int32 poly = 0; poly < commonVars.getSimPreview().getLayerPreviewShapes(layer).Count; poly++) + { + if (commonVars.getSimPreview().getLayerPreviewShapePoly(layer, poly).Count() >= 2)// Only draw if we have valid data to draw. + { + int length = commonVars.getSimPreview().getLayerPreviewShapePoly(layer, poly).Count(); + PointF[] tmpPoints = new PointF[length]; + Parallel.For(0, length, (point) => + // for (Int32 point = 0; point < length; point++) + { + tmpPoints[point] = new PointF((float)commonVars.getSimPreview().getLayerPreviewShapePoly(layer, poly)[point].X, (float)commonVars.getSimPreview().getLayerPreviewShapePoly(layer, poly)[point].Y); + }); + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].addPolygon( + poly: tmpPoints, + polyColor: Color.FromArgb(varianceContext.vc.colors.simPreviewColors[layer].toArgb()), + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.bg), + drawn: false, + layerIndex: layer + ); + } + } + } + } + + if (!commonVars.isSimRunning()) + { + Application.Instance.Invoke(() => + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + label_geoEqtn_Op[i].TextColor = Color.FromArgb(varianceContext.vc.colors.simPreviewColors[i].toArgb()); + } + }); + } + + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.results) == 1) + { + // Draw any boolean points : + for (Int32 poly = 0; poly < commonVars.getSimPreview().getPoints().Count(); poly++) + { + // Only draw if we can make a polygon. + if (commonVars.getSimPreview().getPoints(poly).Count() >= 2) + { + Int32 colorIndex = poly % varianceContext.vc.colors.resultColors.Count(); // map our result into the available colors. + totalPoints += commonVars.getSimPreview().getPoints(poly).Count(); + if ((commonVars.getSimPreview().getPoints(poly).Count() == 2) || (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.chord) || (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.angle) || (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.enclosure_spacing_overlap)) + { + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].addLine( + line: UIHelper.myPointFArrayToPointFArray(commonVars.getSimPreview().getPoints(poly)), + lineColor: Color.FromArgb(varianceContext.vc.colors.resultColors[colorIndex].toArgb()), + alpha: 1.0f,//(float)commonVars.getOpacity(CommonVars.opacity_gl.fg), + layerIndex: CentralProperties.maxLayersForMC + colorIndex + // zBias: 10.0f + ); + } + else + { + mcVPSettings[CentralProperties.maxLayersForMC - 1 + (int)CommonVars.twoDTabNames.settings].addPolygon( + poly: UIHelper.myPointFArrayToPointFArray(commonVars.getSimPreview().getPoints(poly)), + polyColor: Color.FromArgb(varianceContext.vc.colors.resultColors[colorIndex].toArgb()), + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), + drawn: false, + layerIndex: CentralProperties.maxLayersForMC + colorIndex + //zBias: 10.0f + ); + } + } + } + } + } + Application.Instance.Invoke(() => + { + text_ssTotalPoints.Text = totalPoints.ToString(); + if (doPASearch) + { + text_paSearch.Text = commonVars.getSimPreview().getResult(); + } + else + { + text_testArea.Text = commonVars.getSimPreview().getResult(); + } + }); + + if (entropyControl.simJustDone) + { + updateStatusLine(entropyControl.lastSimResultsOverview); + } + else + { + if (!entropyControl.multiCaseSim) + { + postSimStatusLine(); + } + } + } + catch (Exception) + { + // Uncritical failure. + } + Application.Instance.Invoke(() => + { + updateViewport(); + }); + } + + void updateImplantPreview(object sender, System.Timers.ElapsedEventArgs e) + { + if (Monitor.TryEnter(commonVars.implantDrawingLock)) + { + try + { + if ((entropyControl.sw_Preview.Elapsed.TotalMilliseconds - entropyControl.timeOfLastPreviewUpdate) > commonVars.m_timer.Interval) + { + try + { + if (System.Threading.Thread.CurrentThread == commonVars.mainThreadIndex) + { + // also sets commonVars.drawing to 'false' + implantPreviewUpdate(); + } + else + { + Application.Instance.Invoke(() => + { + implantPreviewUpdate(); + }); + } + } + catch (Exception) + { + } + } + } + finally + { + Monitor.Exit(commonVars.implantDrawingLock); + } + } + } + + void implantPreviewUpdate() + { + if ((entropyControl.sw_Preview.Elapsed.TotalMilliseconds - entropyControl.timeOfLastPreviewUpdate) < commonVars.m_timer.Interval) + { + return; + } + try + { + if (entropyControl.sw.IsRunning) + { + entropyControl.swTime += entropyControl.sw.Elapsed.TotalSeconds; + } + entropyControl.sw.Stop(); + statusProgressBar.Value = entropyControl.currentProgress; + entropyControl.timeOfFlight_implant(entropyControl.swTime); + + + if (Monitor.TryEnter(varianceContext.vc.implantPreviewLock)) + { + try + { + textBox_implantShadowNom.Text = entropyControl.getImplantResultPackage().getMeanAndStdDev(); + textBox_implantShadowMin.Text = ""; + textBox_implantShadowMax.Text = ""; + updateImplantPreview(); + } + finally + { + Monitor.Exit(varianceContext.vc.implantPreviewLock); + } + } + Application.Instance.Invoke(() => + { + updateViewport(); + }); + } + catch (Exception) + { + } + try + { + entropyControl.sw.Reset(); + entropyControl.sw.Start(); + entropyControl.timeOfLastPreviewUpdate = entropyControl.sw_Preview.Elapsed.Milliseconds; + } + catch (Exception) + { + } + } + + void showBG(int settingsIndex) + { + viewPort.ovpSettings.bgPolyList.Clear(); + + bool useVPGeometry = false; + + // Now we need to deal with the background setting. + // This is only a viewport construct, to avoid impacting the simulation system. + for (Int32 bgLayer = 0; bgLayer < CentralProperties.maxLayersForMC; bgLayer++) + { + // User requested a background layer for this case. + if (commonVars.getLayerSettings(settingsIndex).getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, bgLayer) == 1) + { + if ((bgLayer != settingsIndex) && (commonVars.getLayerSettings(bgLayer).getInt(EntropyLayerSettings.properties_i.enabled) == 1)) // Don't process our current layer - that would be silly. Also don't process disabled layers. + { + Color tempColor = Color.FromArgb(varianceContext.vc.colors.simPreviewColors[bgLayer].toArgb()); + + if (useVPGeometry) + { + // Make a list to contain our background polys. + List bgPolyList = new List(); + + // We filter out any drawn or background polys in the referenced layer's viewport to retrieve legitimate shapes. + for (int poly = 0; poly < mcVPSettings[bgLayer].polyList.Count; poly++) + { + if (!mcVPSettings[bgLayer].drawnPoly[poly]) + { + bgPolyList.Add(mcVPSettings[bgLayer].polyList[poly]); + } + } + + // Now we need to go through the polygons in the bgLayer. + for (int poly = 0; poly < bgPolyList.Count; poly++) + { + // Push the polygons to the right viewport, with our layer color to show the origin. + viewPort.ovpSettings.addBGPolygon( + poly: bgPolyList[poly].poly, + polyColor: tempColor, + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.bg), + layerIndex: bgLayer + ); + } + } + else + { + List tmp = generate_shapes(bgLayer); + for (int shape = 0; shape < tmp.Count; shape++) + { + for (int poly = 0; poly < tmp[shape].getPoints().Count; poly++) + { + if (!tmp[shape].getDrawnPoly(poly)) + { + viewPort.ovpSettings.addBGPolygon( + poly: UIHelper.myPointFArrayToPointFArray(tmp[shape].getPoints(poly)), + polyColor: tempColor, + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.bg), + layerIndex: bgLayer + ); + } + } + } + } + } + } + } + updateViewport(); + } + + async void generatePreviewPanelContent(int settingsIndex) + { + if (openGLErrorReported) + { + return; + } + + if ((settingsIndex < 0) || (settingsIndex > CentralProperties.maxLayersForMC)) + { + return; + } + + Application.Instance.Invoke(() => + { + updateStatusLine("Reticulating splines."); + }); + startIndeterminateProgress(); + + List previewShapes = new List(); + + try + { + previewShapes = await updateTask(settingsIndex); + } + catch (Exception) + { + // Handle any task cancelled exception without crashing the tool. The cancellation may occur due to close of the tool whilst evaluation is underway. + } + + // Brute force setting, to ensure we're aligned with user preferences that might have changed. + mcVPSettings[settingsIndex].minorGridColor = Color.FromArgb(commonVars.getColors().minor_Color.toArgb()); + mcVPSettings[settingsIndex].majorGridColor = Color.FromArgb(commonVars.getColors().major_Color.toArgb()); + mcVPSettings[settingsIndex].reset(false); + + // Iterate through our shapes + // Note that we also load the viewport poly drawn/enabled state. This allows for background poly filtering later. + for (Int32 i = 0; i < previewShapes.Count; i++) + { + for (Int32 poly = 0; poly < previewShapes[i].getPoints().Count; poly++) + { + mcVPSettings[settingsIndex].addPolygon( + poly: UIHelper.myPointFArrayToPointFArray(previewShapes[i].getPoints()[poly]), + polyColor: Color.FromArgb(previewShapes[i].getColor().toArgb()), + alpha: (float)commonVars.getOpacity(CommonVars.opacity_gl.fg), + drawn: previewShapes[i].getDrawnPoly(poly), + layerIndex: settingsIndex + ); + } + } + + updateViewport(); + stopIndeterminateProgress(); + Application.Instance.Invoke(() => + { + updateStatusLine(""); + }); + } + + Task> updateTask(int settingsIndex) + { + return Task.Run(() => generate_shapes(settingsIndex)); + } + + void updateViewport() + { + Application.Instance.Invoke(() => + { + try + { + createVPContextMenu(); + viewPort.updateViewport(); + vSurface.Invalidate(); + } + catch (Exception) + { + openGLErrorReported = true; + } + }); + } + + void refreshAllPreviewPanels() + { + if (openGLErrorReported) + { + return; + } + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + generatePreviewPanelContent(layer); + } + updateViewport(); + } + + void drawPreviewPanelHandler() + { + if (getMainSelectedIndex() == (int)CommonVars.upperTabNames.twoD) + { + int index = getSelectedLayerIndex(); + // Check that we're in the 2D section and on a tab with a preview panel present for the mcLayers + if ((index >= 0) && (index < CentralProperties.maxLayersForMC)) + { + generatePreviewPanelContent(index); + } + } + } + + // Responsible for generating our preview shapes per the settings. + // Output used by the previewPanelHandler in non-GDS mode. + // All offsets need to be applied here - previewPanel takes what it is given and draws that. + List generate_shapes(Int32 settingsIndex) + { + List previewShapes = new List(); + + string shapeString = ((CentralProperties.typeShapes)commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex)).ToString(); + // User has a shape chosen so we can draw a preview + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (Int32)CommonVars.shapeNames.none) + { + // Drawn curves from combined shapes + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.enabled) == 1) + { + // Draw curves + PreviewShape pShape = new PreviewShape(commonVars, settingsIndex, subShapeIndex: 0, commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.enabled), doPASearch: false, previewMode: true, currentRow: 0, currentCol: 0); + pShape.setColor(varianceContext.vc.colors.enabled_Color); + previewShapes.Add(pShape); + } + // Get the drawn polygons. + if ( + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.rect) || + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) || + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.BOOLEAN) + ) + { + PreviewShape pShape1 = new PreviewShape(commonVars, settingsIndex, subShapeIndex: 0, mode: 0, doPASearch: false, previewMode: true, currentRow: 0, currentCol: 0); + pShape1.setColor(varianceContext.vc.colors.subshape1_Color); + previewShapes.Add(pShape1); + } + else + { + PreviewShape pShape1 = new PreviewShape(commonVars, settingsIndex, subShapeIndex: 0, mode: 0, doPASearch: false, previewMode: true, currentRow: 0, currentCol: 0); + pShape1.setColor(varianceContext.vc.colors.subshape1_Color); + PreviewShape pShape2 = new PreviewShape(commonVars, settingsIndex, subShapeIndex: 1, mode: 0, doPASearch: false, previewMode: true, currentRow: 0, currentCol: 0); + pShape2.setColor(varianceContext.vc.colors.subshape2_Color); + PreviewShape pShape3 = new PreviewShape(commonVars, settingsIndex, subShapeIndex: 2, mode: 0, doPASearch: false, previewMode: true, currentRow: 0, currentCol: 0); + pShape3.setColor(varianceContext.vc.colors.subshape3_Color); + previewShapes.Add(pShape1); + previewShapes.Add(pShape2); + previewShapes.Add(pShape3); + } + } + else + { + // No preview - no shape chosen. + } + return previewShapes; + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHandlers_viewport.cs b/Common/Variance/UI/UIHandlers_viewport.cs new file mode 100644 index 0000000..3b6c73b --- /dev/null +++ b/Common/Variance/UI/UIHandlers_viewport.cs @@ -0,0 +1,351 @@ +using Eto.Drawing; +using Eto.Forms; +using VeldridEto; +using geoCoreLib; +using geoLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Variance +{ + public partial class MainForm + { + void applyLocationToViewports(PointF location) + { + Application.Instance.Invoke(() => + { + int count = mcVPSettings.Length; + // Parallel.For(0, count, (i) => + for (int i = 0; i < count; i++) + { + mcVPSettings[i].setCameraPos(location.X, location.Y); + }//); + }); + } + + void setViewportCamera(int index, double[] parameters) + { + mcVPSettings[index].setCameraPos((float)parameters[0], (float)parameters[1]); + mcVPSettings[index].setZoomFactor((float)parameters[2]); + } + + double[] getViewportCamera(int index) + { + double x = mcVPSettings[index].getCameraX(); + double y = mcVPSettings[index].getCameraY(); + double zoom = mcVPSettings[index].getZoomFactor(); + return new double[] { x, y, zoom }; + } + + void saveViewportSVG_File() + { + SaveFileDialog sfd = new SaveFileDialog() + { + Title = "Enter file to save", + Filters = + { + new FileFilter("SVG Files (*.svg)", ".svg") + } + }; + if (sfd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + saveViewportSVG(ref viewPort.ovpSettings, sfd.FileName); + } + } + + void saveViewportSVG(ref OVPSettings vpSettings, string svgFileName) + { + SVGBuilder svg = new SVGBuilder(); + + // The polygons in the viewport are stored flipped due to drawing convention. We need to flip them here for SVG to match drawn viewport. + + // polys + for (Int32 poly = 0; poly < vpSettings.polyList.Count(); poly++) + { + svg.style.brushClr = UIHelper.colorToMyColor(vpSettings.polyList[poly].color); + svg.style.penClr = UIHelper.colorToMyColor(vpSettings.polyList[poly].color); + GeoLibPointF[] temp = UIHelper.pointFArrayTomyPointFArray(vpSettings.polyList[poly].poly); + int count = temp.Length; + Parallel.For(0, count, (pt) => + // for (int pt = 0; pt < count; pt++) + { + temp[pt].Y = -temp[pt].Y; + }); + svg.AddPolygons(temp); + } + + for (Int32 poly = 0; poly < vpSettings.bgPolyList.Count(); poly++) + { + svg.style.brushClr = UIHelper.colorToMyColor(vpSettings.bgPolyList[poly].color); + svg.style.penClr = UIHelper.colorToMyColor(vpSettings.bgPolyList[poly].color); + GeoLibPointF[] temp = UIHelper.pointFArrayTomyPointFArray(vpSettings.bgPolyList[poly].poly); + int count = temp.Length; + Parallel.For(0, count, (pt) => + // for (int pt = 0; pt < count; pt++) + { + temp[pt].Y = -temp[pt].Y; + }); + svg.AddPolygons(temp); + } + + // lines + for (Int32 line = 0; line < vpSettings.lineList.Count(); line++) + { + svg.style.brushClr = UIHelper.colorToMyColor(vpSettings.lineList[line].color); + svg.style.penClr = UIHelper.colorToMyColor(vpSettings.lineList[line].color); + GeoLibPointF[] temp = UIHelper.pointFArrayTomyPointFArray(vpSettings.lineList[line].poly); + int count = temp.Length; + Parallel.For(0, count, (pt) => + // for (int pt = 0; pt < count; pt++) + { + temp[pt].Y = -temp[pt].Y; + }); + svg.AddPolygons(temp); + } + + svg.SaveToFile(svgFileName); + } + + async void saveViewportLayout_File() + { + SaveFileDialog sfd = new SaveFileDialog() + { + Title = "Enter file to save", + Filters = + { + new FileFilter("GDS file", "*.gds"), + new FileFilter("OAS file", "*.oas") + } + }; + if (sfd.ShowDialog(ParentWindow) == DialogResult.Ok) + { + string filename = sfd.FileName; + string[] tokens = filename.Split(new char[] { '.' }); + string ext = tokens[tokens.Length - 1].ToUpper(); + + int type = (int)GeoCore.fileType.gds; + + if (ext == "OAS") + { + type = (int)GeoCore.fileType.oasis; + } + + bool useLines = false; + bool useBGPolys = false; + if (getMainSelectedIndex() == (int)CommonVars.upperTabNames.twoD) + { + if (getSubTabSelectedIndex() == (int)CommonVars.twoDTabNames.DOE) + { + useLines = true; + useBGPolys = true; + } + else if ((getSubTabSelectedIndex() == (int)CommonVars.twoDTabNames.settings) || (getSubTabSelectedIndex() == (int)CommonVars.twoDTabNames.paSearch)) + { + useLines = true; + } + } + else + { + if (getMainSelectedIndex() == (int)CommonVars.upperTabNames.Implant) + { + useLines = true; + useBGPolys = true; + } + } + + Application.Instance.Invoke(() => + { + statusProgressBar.Indeterminate = true; + }); + try + { + await Task.Run(() => + { + saveViewportLayout(ref viewPort.ovpSettings, useLines, useBGPolys, type, sfd.FileName); + }); + } + catch (Exception) + { + // Handle any task cancelled exception without crashing the tool. The cancellation may occur due to close of the tool whilst evaluation is underway. + } + Application.Instance.Invoke(() => + { + statusProgressBar.Indeterminate = false; + }); + } + } + + void saveViewportLayout(ref OVPSettings vpSettings, bool useLineList, bool useBGPolys, int type, string layoutFileName) + { + int scale = 100; // for 0.01 nm resolution + GeoCore g = new GeoCore(); + g.reset(); + GCDrawingfield drawing_ = new GCDrawingfield(""); + drawing_.accyear = (short)DateTime.Now.Year; + drawing_.accmonth = (short)DateTime.Now.Month; + drawing_.accday = (short)DateTime.Now.Day; + drawing_.acchour = (short)DateTime.Now.Hour; + drawing_.accmin = (short)DateTime.Now.Minute; + drawing_.accsec = (short)DateTime.Now.Second; + drawing_.modyear = (short)DateTime.Now.Year; + drawing_.modmonth = (short)DateTime.Now.Month; + drawing_.modday = (short)DateTime.Now.Day; + drawing_.modhour = (short)DateTime.Now.Hour; + drawing_.modmin = (short)DateTime.Now.Minute; + drawing_.modsec = (short)DateTime.Now.Second; + drawing_.databaseunits = 1000 * scale; + drawing_.userunits = 0.001 / scale; + drawing_.libname = "variance"; + + GCCell gcell_root = drawing_.addCell(); + gcell_root.accyear = (short)DateTime.Now.Year; + gcell_root.accmonth = (short)DateTime.Now.Month; + gcell_root.accday = (short)DateTime.Now.Day; + gcell_root.acchour = (short)DateTime.Now.Hour; + gcell_root.accmin = (short)DateTime.Now.Minute; + gcell_root.accsec = (short)DateTime.Now.Second; + gcell_root.modyear = (short)DateTime.Now.Year; + gcell_root.modmonth = (short)DateTime.Now.Month; + gcell_root.modday = (short)DateTime.Now.Day; + gcell_root.modhour = (short)DateTime.Now.Hour; + gcell_root.modmin = (short)DateTime.Now.Minute; + gcell_root.modsec = (short)DateTime.Now.Second; + gcell_root.cellName = "viewport"; + + List layers = new List(); + + for (Int32 poly = 0; poly < vpSettings.polyList.Count(); poly++) + { + GeoLibPointF[] temp = UIHelper.pointFArrayTomyPointFArray(vpSettings.polyList[poly].poly); + int count = temp.Length; + Parallel.For(0, count, (pt) => + // for (int pt = 0; pt < count; pt++) + { + temp[pt].Y = -temp[pt].Y; + }); + int layerIndex = vpSettings.polySourceIndex[poly]; + if (layers.IndexOf(layerIndex) == -1) + { + layers.Add(layerIndex); + // Register layer names with geoCore. Need to compensate the 1-index for the layer registration. + if (layerIndex < CentralProperties.maxLayersForMC) + { + g.addLayerName("L" + (layerIndex + 1).ToString() + "D0", commonVars.getLayerSettings(layerIndex).getString(EntropyLayerSettings.properties_s.name)); + } + else + { + g.addLayerName("L" + (layerIndex + 1).ToString() + "D0", "result" + (layerIndex - CentralProperties.maxLayersForMC).ToString()); + } + } + + int polyLength = temp.Length; + if (polyLength > 2) + { + GeoLibPoint[] ePoly = new GeoLibPoint[polyLength]; + Parallel.For(0, polyLength, (pt) => + // for (int pt = 0; pt < polyLength; pt++) + { + // Flip Y coordinate to align with the way the geometry is stored for the viewport. + ePoly[pt] = new GeoLibPoint((int)(temp[pt].X * scale), (int)(-temp[pt].Y * scale)); + }); + + gcell_root.addPolygon(ePoly.ToArray(), layerIndex + 1, 0); // layer is 1-index based for output, so need to offset value accordingly. + } + } + + if (useLineList) + { + for (Int32 line = 0; line < vpSettings.lineList.Count(); line++) + { + GeoLibPointF[] temp = UIHelper.pointFArrayTomyPointFArray(vpSettings.lineList[line].poly); + int count = temp.Length; + Parallel.For(0, count, (pt) => + // for (int pt = 0; pt < count; pt++) + { + temp[pt].Y = -temp[pt].Y; + }); + int layerIndex = vpSettings.lineSourceIndex[line]; + if (layers.IndexOf(layerIndex) == -1) + { + layers.Add(layerIndex); + // Register layer names with geoCore. Need to compensate the 1-index for the layer registration. + if (layerIndex < CentralProperties.maxLayersForMC) + { + g.addLayerName("L" + (layerIndex + 1).ToString() + "D0", commonVars.getLayerSettings(layerIndex).getString(EntropyLayerSettings.properties_s.name)); + } + else + { + g.addLayerName("L" + (layerIndex + 1).ToString() + "D0", "result" + (layerIndex - CentralProperties.maxLayersForMC).ToString()); + } + } + + GeoLibPoint[] ePoly = new GeoLibPoint[count]; + Parallel.For(0, count, (pt) => + // for (int pt = 0; pt < count; pt++) + { + // Flip Y coordinate to align with the way the geometry is stored for the viewport. + ePoly[pt] = new GeoLibPoint((int)(temp[pt].X * scale), (int)(-temp[pt].Y * scale)); + }); + + gcell_root.addPath(ePoly.ToArray(), layerIndex + 1, 0); + } + } + + if (useBGPolys) + { + for (Int32 poly = 0; poly < vpSettings.bgPolyList.Count(); poly++) + { + GeoLibPointF[] temp = UIHelper.pointFArrayTomyPointFArray(vpSettings.bgPolyList[poly].poly); + int count = temp.Length; + Parallel.For(0, count, (pt) => + // for (int pt = 0; pt < count; pt++) + { + temp[pt].Y = -temp[pt].Y; + }); + int layerIndex = vpSettings.bgPolySourceIndex[poly]; + if (layers.IndexOf(layerIndex) == -1) + { + layers.Add(layerIndex); + // Register layer names with geoCore. Need to compensate the 1-index for the layer registration. + if (layerIndex < CentralProperties.maxLayersForMC) + { + g.addLayerName("L" + (layerIndex + 1).ToString() + "D0", commonVars.getLayerSettings(layerIndex).getString(EntropyLayerSettings.properties_s.name)); + } + else + { + g.addLayerName("L" + (layerIndex + 1).ToString() + "D0", "result" + (layerIndex - CentralProperties.maxLayersForMC).ToString()); + } + } + + GeoLibPoint[] ePoly = new GeoLibPoint[count]; + Parallel.For(0, count, (pt) => + // for (int pt = 0; pt < count; pt++) + { + // Flip Y coordinate to align with the way the geometry is stored for the viewport. + ePoly[pt] = new GeoLibPoint((int)(temp[pt].X * scale), (int)(-temp[pt].Y * scale)); + }); + + gcell_root.addPolygon(ePoly.ToArray(), layerIndex + 1, 0); + } + } + + g.setDrawing(drawing_); + g.setValid(true); + + switch (type) + { + case (int)GeoCore.fileType.gds: + gds.gdsWriter gw = new gds.gdsWriter(g, layoutFileName); + gw.save(); + break; + case (int)GeoCore.fileType.oasis: + oasis.oasWriter ow = new oasis.oasWriter(g, layoutFileName); + ow.save(); + break; + + } + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/UIHelper.cs b/Common/Variance/UI/UIHelper.cs new file mode 100644 index 0000000..72e1637 --- /dev/null +++ b/Common/Variance/UI/UIHelper.cs @@ -0,0 +1,58 @@ +using color; +using Eto.Drawing; +using geoLib; +using System.Threading.Tasks; + +namespace Variance +{ + public static class UIHelper + { + public static Color myColorToColor(MyColor sourceColor) + { + Color returnColor; + returnColor = Color.FromArgb(sourceColor.R, sourceColor.G, sourceColor.B); + return returnColor; + } + + public static MyColor colorToMyColor(Color sourceColor) + { + return new MyColor(sourceColor.R, sourceColor.G, sourceColor.B); + } + + public static PointF myPointFToPointF(GeoLibPointF sourcePoint) + { + return new PointF((float)sourcePoint.X, (float)sourcePoint.Y); + } + + public static GeoLibPointF pointFTomyPointF(PointF sourcePoint) + { + return new GeoLibPointF(sourcePoint.X, sourcePoint.Y); + } + + public static PointF[] myPointFArrayToPointFArray(GeoLibPointF[] sourceArray) + { + int length = sourceArray.Length; + PointF[] returnArray = new PointF[length]; + Parallel.For(0, length, (i) => + // for (int i = 0; i < length; i++) + { + returnArray[i] = myPointFToPointF(sourceArray[i]); + }); + + return returnArray; + } + + public static GeoLibPointF[] pointFArrayTomyPointFArray(PointF[] sourceArray) + { + int length = sourceArray.Length; + GeoLibPointF[] returnArray = new GeoLibPointF[length]; + Parallel.For(0, length, (i) => + // for (int i = 0; i < length; i++) + { + returnArray[i] = pointFTomyPointF(sourceArray[i]); + }); + + return returnArray; + } + } +} diff --git a/Common/Variance/UI/commonUIVars.cs b/Common/Variance/UI/commonUIVars.cs new file mode 100644 index 0000000..502087a --- /dev/null +++ b/Common/Variance/UI/commonUIVars.cs @@ -0,0 +1,159 @@ +using Eto.Forms; +using VeldridEto; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Threading; +using Eto.Veldrid; + +namespace Variance +{ + public partial class MainForm + { + // Using this for MVVM binding to comboboxes. + // A few of these won't change, but collecting them all together for consistent referencing/binding. + // ObservableCollection used because it sends notification when contents changed, unlike List. + // This allows for updates to the UI. + public class UIStringLists + { + public ObservableCollection[] subShapeList { get; set; } + + public List shapes { get; set; } + + public List tipLocs { get; set; } + + public List subShapePos { get; set; } + + public ObservableCollection calcModes { get; set; } + + public List externalTypeList { get; set; } + + public List rngTypeList { get; set; } + public List noiseTypeList { get; set; } + + public List polyFillList { get; set; } + + public ObservableCollection[] geoCoreStructureList { get; set; } + public ObservableCollection[] geoCoreLDList { get; set; } + + public ObservableCollection geoCoreStructureList_exp { get; set; } + public ObservableCollection geoCoreLDList_exp { get; set; } + + public ObservableCollection subShapesList_exp { get; set; } + + public ObservableCollection layerNames { get; set; } + + public List notList { get; set; } + public List booleanList { get; set; } + public List openGLMode { get; set; } + + public ObservableCollection rngMapping { get; set; } + } + + bool[] geoGBVisible, subShapeGBVisible, booleanGBVisible; + + // Context menu to display when user wants to change the distribution behind an input. + int rngLabelIndex; + Label sourceLabel_RNG; + ContextMenu menu_customRNG; + + int selectedLayer; + + bool settingsUIFrozen, DOEUIFrozen, implantUIFrozen, colUIFrozen, globalUIFrozen, replayUIFrozen, utilsUIFrozen; + + bool openGLErrorReported; + + OVPSettings[] mcVPSettings; + OVPSettings otkVPSettings_implant; + + VeldridSurface vSurface; + VeldridDriver viewPort; + Panel vp; + ContextMenu vp_menu; + int freezeThawIndex, loadBookmarkIndex; + RichTextArea commentBox; + + CreditsScreen aboutBox; + + Panel layerShapeProperties, layerShapeProperties_tcPanel; + + bool layerUIFrozen_exp; + + // Intention here is to prevent cyclical dependencies. Outer list is for each layer, with the arrays then holding the 'enabled' state. + // For example, if layer 1 depends on layer 0 for x overlay ref, we should set xOLRBs_enabledState[0][1] to disabled. + List xCOLRBs_enabledState; + List yCOLRBs_enabledState; + + List xOLRBs_enabledState; + List yOLRBs_enabledState; + + List SCDURBs_enabledState; + List TCDURBs_enabledState; + + // Layer UI element arrays. + // 2D Layer UI stuff. + DropDown comboBox_layerShape_exp; + CheckBox checkBox_Layer_exp, + checkBox_Layer_alignGeometryX_exp, checkBox_Layer_alignGeometryY_exp, checkBox_Layer_ShowDrawn_exp, checkBox_Layer_FlipH_exp, checkBox_Layer_FlipV_exp, + checkBox_layer_edgeSlide_exp; + NumericStepper num_layer_edgeSlideTension_exp; + Label lbl_layer_edgeSlideTension_exp; + TextBox text_layerName_exp; + + TableLayout tabPage_2D_layer_content_exp; + + Int32 simulationOutputGroupBoxHeight, + simulationSettingsGroupBoxHeight, + userGuidanceWidth, userGuidanceHeight, + previewWidth, + oneDGuidanceWidth, + oneDLabelWidth, + oneDMinInsWidth, + oneDMinInsLblWidth, + multiThreadWarnWidth, + resultFieldWidth, + commentBoxWidth, commentBoxHeight, + omitLayerBoxY, + comboBox_Height, + num_Height, + label_Height, + radioButton_Height, + checkBox_Height, + simButtonWidth, simButtonHeight, + replayNumWidth, replayNumHeight + ; + + float uiScaleFactor; + int simRunningTabToFreeze; + + Scrollable controls; + PixelLayout controls_content; + Scrollable tabPage_2D_PASearch_scrollable; + TableLayout mainTable, tabPage2_table, tab_1DCalc_table, tabPage_2D_DOE_table, tabPage_implant_table, tabPage_utilities_table, tabPage_2D_PASearch_table; + + Label statusReadout, lbl_simPreviewZoom, lbl_viewportPos; + + ProgressBar statusProgressBar; + + GroupBox bgLayerBox, omitLayerBox, simPreviewBox; + CheckBox checkBox_displayShapes, checkBox_displayResults; + CheckBox[] checkBox_bg_lyr, checkBox_omit_lyr; + NumericStepper num_viewportZoom, num_viewportX, num_viewportY; + + Button btn_singleCPU, btn_multiCPU, btn_STOP, btn_Cancel; + + TabControl tabControl_main, tabControl_2D_simsettings; + TabPage tab_1DCalc, tabPage2, tabPage_implant, tabPage_utilities, tabPage_2D_Settings, tabPage_2D_DOE, tabPage_2D_PASearch, tabPage_2D_experiment; + + ListBox experimental_listBox_layers; + TableLayout experiment_table; + + TableLayout bgLayerBox_table; + + Panel upperGadgets_panel; + + TableLayout upperGadgets_table; // background and omit. + + CancellationTokenSource fileLoad_cancelTS; + } +} diff --git a/Common/Variance/UI/copyPaste.cs b/Common/Variance/UI/copyPaste.cs new file mode 100644 index 0000000..17bcfd7 --- /dev/null +++ b/Common/Variance/UI/copyPaste.cs @@ -0,0 +1,76 @@ +using System; + +namespace Variance +{ + public partial class MainForm + { + public void setCopyBuffer(int index) + { + copy(index); + } + + void copy(int index) + { + commonVars.setCopy(index); + } + + void copyHandler(object sender, EventArgs e) + { + Int32 tmp = getSelectedLayerIndex(); + if ((tmp >= 0) && (tmp <= (CentralProperties.maxLayersForMC - 1))) // we're on a layer settings page + { + copy(tmp); + } + else + { + commonVars.clearCopy(); // cannot copy from other pages. + } + } + + void pasteHandler(object sender, EventArgs e) + { + Int32 index = getSelectedLayerIndex(); + if ((commonVars.isCopyPrepped()) && ((index >= 0) && (index < CentralProperties.maxLayersForMC))) // we have valid data and are on a valid page. + { + paste(index, updateUI: true); + } + } + + void paste(int index, bool updateUI = false) + { + commonVars.paste(index, gdsOnly: false, updateGeoCoreGeometryFromFile: true); + if (updateUI) + { + set_ui_from_settings(index); + do2DLayerUI_exp(index, updateUI: true); + } + } + + void clearHandler(object sender, EventArgs e) + { + Int32 index = getSelectedLayerIndex(); + if ((index >= 0) && (index < CentralProperties.maxLayersForMC)) // we have valid data and are on a valid page. + { + setLayerSettings(new EntropyLayerSettings(), settingsIndex: index, gdsOnly: false, resumeUI: true); + } + commonVars.getGeoCoreHandler(index).reset(); + } + + public void setLayerSettings(EntropyLayerSettings entropyLayerSettings, int settingsIndex, bool gdsOnly, bool resumeUI, bool updateGeoCoreGeometryFromFile = false) + { + pSetLayerSettings(entropyLayerSettings, settingsIndex, gdsOnly, resumeUI, updateGeoCoreGeometryFromFile); + } + + void pSetLayerSettings(EntropyLayerSettings entropyLayerSettings, int settingsIndex, bool gdsOnly, bool resumeUI, bool updateGeoCoreGeometryFromFile = false) + { + commonVars.setLayerSettings(entropyLayerSettings, settingsIndex, gdsOnly, updateGeoCoreGeometryFromFile); + // Ensure the simulation settings labels are consistent. + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + label_geoEqtn_Op[i].Text = commonVars.getLayerSettings(i).getString(EntropyLayerSettings.properties_s.name); + } + + updateLayerNames(); + } + } +} diff --git a/Common/Variance/UI/creditsScreen.cs b/Common/Variance/UI/creditsScreen.cs new file mode 100644 index 0000000..930fb05 --- /dev/null +++ b/Common/Variance/UI/creditsScreen.cs @@ -0,0 +1,72 @@ +using Eto.Drawing; +using Eto.Forms; +using System; +using System.ComponentModel; + +namespace Variance +{ + public partial class CreditsScreen : Form + { + // public System.Diagnostics.Process p = new System.Diagnostics.Process(); + + RichTextArea textBox_credits; + + public CreditsScreen(Form parent, string textToDisplay) + { + Title = CentralProperties.productName + " " + CentralProperties.version; + TableLayout content = new TableLayout(); + Content = content; + + Size = new Size(600, 430); + + Panel imageHolder = new Panel(); + ImageView image = new ImageView(); + image.Image = resources.images.mcImage(); + imageHolder.Size = image.Image.Size; + imageHolder.Content = image; + content.Rows.Add(new TableRow()); + content.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(imageHolder, centered: true) }); + + content.Rows.Add(new TableRow()); + textBox_credits = new RichTextArea(); + try + { + textBox_credits.Font = SystemFonts.Default(13 * 0.66f); + } + catch (Exception) + { + + } + textBox_credits.Size = new Size(550, 260); + textBox_credits.Wrap = true; + textBox_credits.ReadOnly = true; + textBox_credits.Text = textToDisplay; + textBox_credits.CaretIndex = 0; + + content.Rows[1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(textBox_credits, centered: true) }); + + Resizable = false; + Maximizable = false; + } + + protected override void OnClosing(CancelEventArgs e) + { + this.Visible = false; + e.Cancel = true; + } + + public override void Close() + { + this.Visible = false; + } + + /* + private void linkClicked(object sender, EventArgs e) + { + // Call Process.Start method to open a browser + // with link text as URL. + p = System.Diagnostics.Process.Start("IExplore.exe", e.LinkText); + } + */ + } +} diff --git a/Common/Variance/UI/doeUI.cs b/Common/Variance/UI/doeUI.cs new file mode 100644 index 0000000..bfa842a --- /dev/null +++ b/Common/Variance/UI/doeUI.cs @@ -0,0 +1,337 @@ +using Eto.Drawing; +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm : Form + { + GroupBox groupBox_DOESettings, groupBox_tileSubSet; + + TextBox textBox_useSpecificTiles; + + Button btn_useCSViDRM, btn_useCSVQuilt; + + RadioButton radio_useCSViDRM, radio_useCSVQuilt, radioButton_allTiles, radio_useSpecificTile, radio_useSpecificTiles; + + NumericStepper num_colOffset, num_rowOffset, num_DOEColPitch, num_DOERowPitch, num_DOECols, num_DOERows, + num_DOESCCol, num_DOESCRow; + + Label lbl_colOffset, lbl_rowOffset, lbl_DOEColPitch, lbl_DOERowPitch, lbl_DOECols, lbl_DOERows, + lbl_DOESCCol, lbl_DOESCRow; + + TextArea textBox_userGuidanceDOE; + + void twoD_DOEUISetup() + { + tabPage_2D_DOE_table.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + tabPage_2D_DOE_table.Rows[0].Cells.Add(tc0); + Panel p = new Panel(); + tc0.Control = p; + + TableLayout masterTable = new TableLayout(); + p.Content = masterTable; + + masterTable.Rows.Add(new TableRow()); + + TableCell left_tc = new TableCell(); + masterTable.Rows[0].Cells.Add(left_tc); + TableCell right_tc = new TableCell(); + masterTable.Rows[0].Cells.Add(right_tc); + masterTable.Rows[0].Cells.Add(new TableCell() { Control = null }); + + Panel leftPanel = new Panel(); + TableLayout leftTable = new TableLayout(); + leftPanel.Content = leftTable; + left_tc.Control = leftPanel; + leftTable.Rows.Add(new TableRow()); + TableCell ltc0 = new TableCell(); + leftTable.Rows[0].Cells.Add(ltc0); + leftTable.Rows[0].Cells.Add(new TableCell() { Control = null }); + twoD_DOEUISetup_settings(ltc0); + + leftTable.Rows.Add(new TableRow()); + TableCell ltc1 = new TableCell(); + leftTable.Rows[1].Cells.Add(ltc1); + + twoD_DOEUISetup_tileset(ltc1); + + leftTable.Rows.Add(new TableRow()); //padding + + masterTable.Rows.Add(new TableRow()); // padding + + textBox_userGuidanceDOE = new TextArea(); + textBox_userGuidanceDOE.Wrap = true; + textBox_userGuidanceDOE.ReadOnly = true; + textBox_userGuidanceDOE.Size = new Size(userGuidanceWidth, userGuidanceHeight); + textBox_userGuidanceDOE.Text = "The DOE settings relate to geoCore input layers that have the DOE checkbox set.\r\n\r\n" + + "You can either manually set the DOE grid using the settings here, or load in a CSV file from iDRM that will restore the grid used in that tool.\r\n\r\n" + + "Notes:\r\n\r\n" + + "- The lower left corner of each extracted tile bounding box is placed with respect to the origin.\r\n" + + "- Accurate definition of the DOE grid is important to ensure interaction with other layers is correctly assessed.\r\n" + + "- The DOE grid is common to all input layers.\r\n" + + "- The DOE is run sequentially from lower left to top right, with each tile extracted being evaluated for the full set of cases.\r\n" + + "- Output files are generated with row and column indices to show which tile they came from."; + + right_tc.Control = textBox_userGuidanceDOE; + + tabPage_2D_DOE_table.Rows.Add(new TableRow()); // padding. + } + + void twoD_DOEUISetup_settings(TableCell tc) + { + groupBox_DOESettings = new GroupBox(); + tc.Control = groupBox_DOESettings; + + TableLayout groupBox_DOESettings_table = new TableLayout(); + groupBox_DOESettings.Content = groupBox_DOESettings_table; + groupBox_DOESettings.Text = "Grid Layout Properties"; + + groupBox_DOESettings_table.Rows.Add(new TableRow()); + + lbl_rowOffset = new Label(); + lbl_rowOffset.Text = "Row Offset"; + lbl_rowOffset.ToolTip = "Vertical coordinate of lower left corner of lower left tile in DOE grid."; + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_rowOffset }); + + num_rowOffset = new NumericStepper(); + num_rowOffset.Value = 0; + num_rowOffset.Increment = 1; + num_rowOffset.ToolTip = "Vertical coordinate of lower left corner of lower left tile in DOE grid."; + setSize(num_rowOffset, 80, num_Height); + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_rowOffset) }); + + lbl_colOffset = new Label(); + lbl_colOffset.Text = "Col Offset"; + lbl_colOffset.ToolTip = "Horizontal coordinate of lower left corner of lower left tile in DOE grid."; + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_colOffset }); + + num_colOffset = new NumericStepper(); + num_colOffset.Value = 0; + num_colOffset.Increment = 1; + num_colOffset.ToolTip = "Horizontal coordinate of lower left corner of lower left tile in DOE grid."; + setSize(num_colOffset, 80, num_Height); + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_colOffset) }); + + groupBox_DOESettings_table.Rows.Add(new TableRow()); + + lbl_DOERows = new Label(); + lbl_DOERows.Text = "Rows"; + lbl_DOERows.ToolTip = "Number of rows in DOE grid."; + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_DOERows }); + + num_DOERows = new NumericStepper(); + num_DOERows.Value = 1; + num_DOERows.Increment = 1; + num_DOERows.MinValue = 1; + num_DOERows.ToolTip = "Number of rows in DOE grid."; + setSize(num_DOERows, 80, num_Height); + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_DOERows) }); + + lbl_DOECols = new Label(); + lbl_DOECols.Text = "Cols"; + lbl_DOECols.ToolTip = "Number of columns in DOE grid."; + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_DOECols }); + + num_DOECols = new NumericStepper(); + num_DOECols.Value = 1; + num_DOECols.Increment = 1; + num_DOECols.MinValue = 1; + num_DOECols.ToolTip = "Number of columns in DOE grid."; + setSize(num_DOECols, 80, num_Height); + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_DOECols) }); + + groupBox_DOESettings_table.Rows.Add(new TableRow()); + + lbl_DOERowPitch = new Label(); + lbl_DOERowPitch.Text = "Row Pitch"; + lbl_DOERowPitch.ToolTip = "Row height in DOE grid."; + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_DOERowPitch }); + + num_DOERowPitch = new NumericStepper(); + num_DOERowPitch.Value = 1; + num_DOERowPitch.Increment = 1; + num_DOERowPitch.MinValue = 1; + num_DOERowPitch.ToolTip = "Row height in DOE grid."; + setSize(num_DOERowPitch, 80, num_Height); + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_DOERowPitch) }); + + + lbl_DOEColPitch = new Label(); + lbl_DOEColPitch.Text = "Col Pitch"; + lbl_DOEColPitch.ToolTip = "Column width in DOE grid."; + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_DOEColPitch }); + + num_DOEColPitch = new NumericStepper(); + num_DOEColPitch.Value = 1; + num_DOEColPitch.Increment = 1; + num_DOEColPitch.MinValue = 1; + num_DOEColPitch.ToolTip = "Column width in DOE grid."; + setSize(num_DOEColPitch, 80, num_Height); + + groupBox_DOESettings_table.Rows[groupBox_DOESettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_DOEColPitch) }); + } + + void twoD_DOEUISetup_tileset(TableCell tc) + { + groupBox_tileSubSet = new GroupBox(); + tc.Control = groupBox_tileSubSet; + + Panel p = new Panel(); + TableLayout masterTable = new TableLayout(); + masterTable.Rows.Add(new TableRow()); + p.Content = masterTable; + groupBox_tileSubSet.Content = p; + + Panel p0 = new Panel(); + TableLayout groupBox_tileSubSet_table = new TableLayout(); + p0.Content = groupBox_tileSubSet_table; + masterTable.Rows[0].Cells.Add(new TableCell() { Control = p0 }); + masterTable.Rows[0].Cells.Add(new TableCell() { Control = null }); //padding + groupBox_tileSubSet.Text = "Subset of Tiles"; + + groupBox_tileSubSet_table.Rows.Add(new TableRow()); + + Panel row0 = new Panel(); + groupBox_tileSubSet_table.Rows[groupBox_tileSubSet_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row0 }); + groupBox_tileSubSet_table.Rows[groupBox_tileSubSet_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + TableLayout row0_tl = new TableLayout(); + row0.Content = row0_tl; + row0_tl.Rows.Add(new TableRow()); + + radioButton_allTiles = new RadioButton(); + radioButton_allTiles.Text = "Use All Tiles"; + radioButton_allTiles.Checked = true; + radioButton_allTiles.ToolTip = "Use all tiles in DOE grid.\nStart in lower left, end in upper right."; + + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = radioButton_allTiles }); + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + groupBox_tileSubSet_table.Rows.Add(new TableRow()); + + Panel row1 = new Panel(); + groupBox_tileSubSet_table.Rows[groupBox_tileSubSet_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row1 }); + groupBox_tileSubSet_table.Rows[groupBox_tileSubSet_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + TableLayout row1_tl = new TableLayout(); + row1.Content = row1_tl; + row1_tl.Rows.Add(new TableRow()); + + radio_useSpecificTile = new RadioButton(radioButton_allTiles); + radio_useSpecificTile.Text = "Use Specific Tile"; + radio_useSpecificTile.ToolTip = "Use single tile from DOE grid."; + + row1_tl.Rows[row1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = radio_useSpecificTile }); + + lbl_DOESCRow = new Label(); + lbl_DOESCRow.Text = "Row"; + lbl_DOESCRow.ToolTip = "Row index for tile.\n1 is lowest row."; + + row1_tl.Rows[row1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_DOESCRow }); + + num_DOESCRow = new NumericStepper(); + num_DOESCRow.Value = 1; + num_DOESCRow.Increment = 1; + num_DOESCRow.MinValue = 1; + num_DOESCRow.ToolTip = "Row index for tile.\n1 is lowest row."; + setSize(num_DOESCRow, 80, num_Height); + + row1_tl.Rows[row1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_DOESCRow) }); + + lbl_DOESCCol = new Label(); + lbl_DOESCCol.Text = "Col"; + lbl_DOESCCol.ToolTip = "Column index for tile.\n1 is leftmost column."; + + row1_tl.Rows[row1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_DOESCCol }); + + num_DOESCCol = new NumericStepper(); + num_DOESCCol.Value = 1; + num_DOESCCol.Increment = 1; + num_DOESCCol.MinValue = 1; + num_DOESCCol.ToolTip = "Column index for tile.\n1 is leftmost column."; + setSize(num_DOESCCol, 80, num_Height); + + row1_tl.Rows[row1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_DOESCCol) }); + row1_tl.Rows[row1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + groupBox_tileSubSet_table.Rows.Add(new TableRow()); + + Panel row2 = new Panel(); + groupBox_tileSubSet_table.Rows[groupBox_tileSubSet_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row2 }); + groupBox_tileSubSet_table.Rows[groupBox_tileSubSet_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + TableLayout row2_tl = new TableLayout(); + row2.Content = row2_tl; + row2_tl.Rows.Add(new TableRow()); + + radio_useSpecificTiles = new RadioButton(radioButton_allTiles); + radio_useSpecificTiles.Text = "Use Specific Tiles (col,row;col,row;col;row)"; + radio_useSpecificTiles.ToolTip = "Use these tiles in grid.\nNote syntax.\n1:1 is the lower left tile."; + + row2_tl.Rows[row2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = radio_useSpecificTiles }); + row2_tl.Rows[row2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + row2_tl.Rows.Add(new TableRow()); + + textBox_useSpecificTiles = new TextBox(); + textBox_useSpecificTiles.Width = 200; + textBox_useSpecificTiles.ToolTip = "Use these tiles in grid.\nNote syntax.\n1:1 is the lower left tile."; + + row2_tl.Rows[row2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = textBox_useSpecificTiles }); + row2_tl.Rows[row2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + groupBox_tileSubSet_table.Rows.Add(new TableRow()); + + Panel row3 = new Panel(); + groupBox_tileSubSet_table.Rows[groupBox_tileSubSet_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row3 }); + + TableLayout row3_tl = new TableLayout(); + row3.Content = row3_tl; + row3_tl.Rows.Add(new TableRow()); + + radio_useCSViDRM = new RadioButton(radioButton_allTiles); + radio_useCSViDRM.Text = "Use iDRM CSV"; + radio_useCSViDRM.ToolTip = "Use iDRM CSV output to tag tiles for use in DOE."; + + row3_tl.Rows[row3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = radio_useCSViDRM }); + + btn_useCSViDRM = new Button(); + btn_useCSViDRM.Text = "Choose File"; + btn_useCSViDRM.Click += iDRMFileChooser_Handler; + + row3_tl.Rows[row3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_useCSViDRM) }); + + groupBox_tileSubSet_table.Rows.Add(new TableRow()); + + Panel row4 = new Panel(); + groupBox_tileSubSet_table.Rows[groupBox_tileSubSet_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row4 }); + + TableLayout row4_tl = new TableLayout(); + row4.Content = row4_tl; + row4_tl.Rows.Add(new TableRow()); + + radio_useCSVQuilt = new RadioButton(radioButton_allTiles); + radio_useCSVQuilt.Text = "Use Quilt CSV"; + + row4_tl.Rows[row4_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = radio_useCSVQuilt }); + + btn_useCSVQuilt = new Button(); + btn_useCSVQuilt.Text = "Choose File"; + btn_useCSVQuilt.Click += QuiltFileChooser_Handler; + + row4_tl.Rows[row4_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_useCSVQuilt) }); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/implantUI.cs b/Common/Variance/UI/implantUI.cs new file mode 100644 index 0000000..9a8cb23 --- /dev/null +++ b/Common/Variance/UI/implantUI.cs @@ -0,0 +1,431 @@ +using Eto.Drawing; +using Eto.Forms; +using System; + +namespace Variance +{ + public partial class MainForm : Form + { + NumericStepper num_implantResistCD, num_implantResistCDVar, + num_implantResistHeight, num_implantResistHeightVar, + num_implantResistTopCRR, num_implantResistTopCRRVar, + num_implantTiltAngle, num_implantTiltAngleVar, + num_implantTwistAngle, num_implantTwistAngleVar, + num_implantCornerSegments, num_implantNumOfCases; + + TextBox textBox_implantShadowNom, textBox_implantShadowMin, textBox_implantShadowMax; + + Label lbl_implantResistCD, lbl_implantResistHeight, lbl_implantResistTopCRR, + lbl_implantTiltAngle, + lbl_implantTwistAngle, lbl_implantShadowNom, lbl_implantShadowMin, lbl_implantShadowMax, + lbl_implantCornerSegments, lbl_implantNumOfCases, + lbl_implantNom, lbl_implantVar, lbl_implantRNG; + + GroupBox groupBox_implant; + + CheckBox checkBox_CSV_implant, checkBox_external_implant; + + DropDown comboBox_implantRNG, comboBox_externalTypes_implant; + + void implantTabSetup() + { + groupBox_implant = new GroupBox(); + groupBox_implant.Text = "Implant Conditions"; + tabPage_implant_table.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + tc0.Control = groupBox_implant; + tabPage_implant_table.Rows[0].Cells.Add(tc0); + tabPage_implant_table.Rows[0].Cells.Add(new TableCell() { Control = null }); + tabPage_implant_table.Rows.Add(new TableRow()); + + TableLayout groupBox_implant_table = new TableLayout(); + groupBox_implant.Content = groupBox_implant_table; + + groupBox_implant_table.Rows.Add(new TableRow()); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + Panel row0p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row0p }); + + TableLayout row0ptl = new TableLayout(); + row0p.Content = row0ptl; + row0ptl.Rows.Add(new TableRow()); + + lbl_implantNom = new Label(); + lbl_implantNom.Text = "Nominal"; + row0ptl.Rows[row0ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantNom }); + + lbl_implantVar = new Label(); + lbl_implantVar.Text = "3-sigma"; + row0ptl.Rows[row0ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantVar }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantResistCD = new Label(); + lbl_implantResistCD.Text = "Developed resist CD"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantResistCD }); + + Panel row1p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row1p }); + + TableLayout row1ptl = new TableLayout(); + row1p.Content = row1ptl; + row1ptl.Rows.Add(new TableRow()); + + num_implantResistCD = new NumericStepper(); + num_implantResistCD.Value = 1; + num_implantResistCD.DecimalPlaces = 2; + num_implantResistCD.MinValue = 1; + num_implantResistCD.Increment = 0.1; + num_implantResistCD.LostFocus += doImplantShadowing; + setSize(num_implantResistCD, 50, num_Height); + row1ptl.Rows[row1ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantResistCD) }); + + num_implantResistCDVar = new NumericStepper(); + num_implantResistCDVar.Value = 0; + num_implantResistCDVar.DecimalPlaces = 2; + num_implantResistCDVar.MinValue = 0; + num_implantResistCDVar.Increment = 0.1; + num_implantResistCDVar.LostFocus += doImplantShadowing; + setSize(num_implantResistCDVar, 50, num_Height); + row1ptl.Rows[row1ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantResistCDVar) }); + + row1ptl.Rows[row1ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantResistHeight = new Label(); + lbl_implantResistHeight.Text = "Developed resist height"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantResistHeight }); + + Panel row2p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row2p }); + + TableLayout row2ptl = new TableLayout(); + row2p.Content = row2ptl; + row2ptl.Rows.Add(new TableRow()); + + num_implantResistHeight = new NumericStepper(); + num_implantResistHeight.Value = 1; + num_implantResistHeight.DecimalPlaces = 2; + num_implantResistHeight.MinValue = 1; + num_implantResistHeight.Increment = 0.1; + num_implantResistHeight.LostFocus += doImplantShadowing; + setSize(num_implantResistHeight, 50, num_Height); + row2ptl.Rows[row2ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantResistHeight) }); + + num_implantResistHeightVar = new NumericStepper(); + num_implantResistHeightVar.Value = 0; + num_implantResistHeightVar.DecimalPlaces = 2; + num_implantResistHeightVar.MinValue = 0; + num_implantResistHeightVar.Increment = 0.1; + num_implantResistHeightVar.LostFocus += doImplantShadowing; + setSize(num_implantResistHeightVar, 50, num_Height); + row2ptl.Rows[row2ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantResistHeightVar) }); + + row2ptl.Rows[row2ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantResistTopCRR = new Label(); + lbl_implantResistTopCRR.Text = "Resist Top Corner Rounding"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantResistTopCRR }); + + Panel row3p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row3p }); + + TableLayout row3ptl = new TableLayout(); + row3p.Content = row3ptl; + row3ptl.Rows.Add(new TableRow()); + + num_implantResistTopCRR = new NumericStepper(); + num_implantResistTopCRR.Value = 0; + num_implantResistTopCRR.DecimalPlaces = 2; + num_implantResistTopCRR.MinValue = 0; + num_implantResistTopCRR.Increment = 0.1; + num_implantResistTopCRR.LostFocus += doImplantShadowing; + setSize(num_implantResistTopCRR, 50, num_Height); + row3ptl.Rows[row3ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantResistTopCRR) }); + + num_implantResistTopCRRVar = new NumericStepper(); + num_implantResistTopCRRVar.Value = 0; + num_implantResistTopCRRVar.DecimalPlaces = 2; + num_implantResistTopCRRVar.MinValue = 0; + num_implantResistTopCRRVar.LostFocus += doImplantShadowing; + setSize(num_implantResistTopCRRVar, 50, num_Height); + row3ptl.Rows[row3ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantResistTopCRRVar) }); + + row3ptl.Rows[row3ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantTiltAngle = new Label(); + lbl_implantTiltAngle.Text = "Implant Tilt Angle (deg)"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantTiltAngle }); + + Panel row4p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row4p }); + + TableLayout row4ptl = new TableLayout(); + row4p.Content = row4ptl; + row4ptl.Rows.Add(new TableRow()); + + num_implantTiltAngle = new NumericStepper(); + num_implantTiltAngle.Value = 0; + num_implantTiltAngle.DecimalPlaces = 2; + num_implantTiltAngle.MinValue = 0; + num_implantTiltAngle.MaxValue = 90; + num_implantTiltAngle.LostFocus += doImplantShadowing; + setSize(num_implantTiltAngle, 50, num_Height); + row4ptl.Rows[row4ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantTiltAngle) }); + + num_implantTiltAngleVar = new NumericStepper(); + num_implantTiltAngleVar.Value = 0; + num_implantTiltAngleVar.DecimalPlaces = 2; + num_implantTiltAngleVar.MinValue = 0; + num_implantTiltAngleVar.MaxValue = 90; + num_implantTiltAngleVar.LostFocus += doImplantShadowing; + setSize(num_implantTiltAngleVar, 50, num_Height); + row4ptl.Rows[row4ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantTiltAngleVar) }); + + row4ptl.Rows[row4ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantTwistAngle = new Label(); + lbl_implantTwistAngle.Text = "Implant Twist Angle (deg)"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantTwistAngle }); + + Panel row5p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row5p }); + + TableLayout row5ptl = new TableLayout(); + row5p.Content = row5ptl; + row5ptl.Rows.Add(new TableRow()); + + num_implantTwistAngle = new NumericStepper(); + num_implantTwistAngle.Value = 0; + num_implantTwistAngle.DecimalPlaces = 2; + num_implantTwistAngle.MinValue = 0; + num_implantTwistAngle.LostFocus += doImplantShadowing; + setSize(num_implantTwistAngle, 50, num_Height); + row5ptl.Rows[row5ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantTwistAngle) }); + + num_implantTwistAngleVar = new NumericStepper(); + num_implantTwistAngleVar.Value = 0; + num_implantTwistAngleVar.DecimalPlaces = 2; + num_implantTwistAngleVar.MinValue = 0; + num_implantTwistAngleVar.LostFocus += doImplantShadowing; + setSize(num_implantTwistAngleVar, 50, num_Height); + row5ptl.Rows[row5ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantTwistAngleVar) }); + + row5ptl.Rows[row5ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantCornerSegments = new Label(); + lbl_implantCornerSegments.Text = "Corner Segments"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantCornerSegments }); + + Panel row6p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row6p }); + + TableLayout row6ptl = new TableLayout(); + row6p.Content = row6ptl; + row6ptl.Rows.Add(new TableRow()); + + num_implantCornerSegments = new NumericStepper(); + num_implantCornerSegments.Value = 90; + num_implantCornerSegments.MinValue = 2; + num_implantCornerSegments.Increment = 1; + num_implantCornerSegments.LostFocus += doImplantShadowing; + setSize(num_implantCornerSegments, 80, num_Height); + row6ptl.Rows[row6ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantCornerSegments) }); + + row6ptl.Rows[row6ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantNumOfCases = new Label(); + lbl_implantNumOfCases.Text = "Number of Cases"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantNumOfCases }); + + Panel row7p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row7p }); + + TableLayout row7ptl = new TableLayout(); + row7p.Content = row7ptl; + row7ptl.Rows.Add(new TableRow()); + + num_implantNumOfCases = new NumericStepper(); + num_implantNumOfCases.Value = 25000; + num_implantNumOfCases.DecimalPlaces = 0; + num_implantNumOfCases.MinValue = 1; + num_implantNumOfCases.LostFocus += doImplantShadowing; + setSize(num_implantNumOfCases, 80, num_Height); + + row7ptl.Rows[row7ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_implantNumOfCases) }); + + row7ptl.Rows[row7ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantRNG = new Label(); + lbl_implantRNG.Text = "RNG"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantRNG }); + + Panel row8p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row8p }); + + TableLayout row8ptl = new TableLayout(); + row8p.Content = row8ptl; + row8ptl.Rows.Add(new TableRow()); + + comboBox_implantRNG = new DropDown(); + comboBox_implantRNG.DataContext = DataContext; + comboBox_implantRNG.BindDataContext(c => c.DataStore, (UIStringLists m) => m.rngTypeList); + comboBox_implantRNG.SelectedIndexChanged += doImplantShadowing; + setSize(comboBox_implantRNG, 175, label_Height); + + row8ptl.Rows[row8ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = comboBox_implantRNG }); + + row8ptl.Rows[row8ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + Panel row9p = new Panel(); + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row9p }); + + TableLayout row9ptl = new TableLayout(); + row9p.Content = row9ptl; + row9ptl.Rows.Add(new TableRow()); + + checkBox_CSV_implant = new CheckBox(); + checkBox_CSV_implant.Text = "CSV"; + checkBox_CSV_implant.CheckedChanged += doImplantShadowing; + checkBox_CSV_implant.ToolTip = "Write out a CSV file containing the result for each case and its inputs. Allows for offline deep-dive review."; + + row9ptl.Rows[row9ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_CSV_implant }); + + checkBox_external_implant = new CheckBox(); + checkBox_external_implant.Text = "External"; + checkBox_external_implant.CheckedChanged += doImplantShadowing; + checkBox_external_implant.ToolTip = "Write out a file containing the result for each case and its inputs. Will require significantly more memory."; + + row9ptl.Rows[row9ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_external_implant }); + + comboBox_externalTypes_implant = new DropDown(); + comboBox_externalTypes_implant.DataContext = DataContext; + comboBox_externalTypes_implant.SelectedIndexChanged += doImplantShadowing; + comboBox_externalTypes_implant.BindDataContext(c => c.DataStore, (UIStringLists m) => m.externalTypeList); + comboBox_externalTypes_implant.ToolTip = "Choose your external file type"; + + row9ptl.Rows[row9ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = comboBox_externalTypes_implant }); + + row9ptl.Rows[row9ptl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantShadowNom = new Label(); + lbl_implantShadowNom.Text = "Implant Shadowing (Mean)"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantShadowNom }); + + textBox_implantShadowNom = new TextBox(); + textBox_implantShadowNom.ReadOnly = true; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = textBox_implantShadowNom }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantShadowMin = new Label(); + lbl_implantShadowMin.Text = "Implant Shadowing (Min)"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantShadowMin }); + + textBox_implantShadowMin = new TextBox(); + textBox_implantShadowMin.ReadOnly = true; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = textBox_implantShadowMin }); + + groupBox_implant_table.Rows.Add(new TableRow()); + + lbl_implantShadowMax = new Label(); + lbl_implantShadowMax.Text = "Implant Shadowing (Max)"; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_implantShadowMax }); + + textBox_implantShadowMax = new TextBox(); + textBox_implantShadowMax.ReadOnly = true; + groupBox_implant_table.Rows[groupBox_implant_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = textBox_implantShadowMax }); + } + + void doImplantShadowing(object sender, EventArgs e) + { + if (implantUIFrozen) + { + return; + } + + // Implant properties. + commonVars.getImplantSettings().setComment(commentBox.Text); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.tilt, num_implantTiltAngle.Value); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.tiltV, num_implantTiltAngleVar.Value); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.twist, num_implantTwistAngle.Value); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.twistV, num_implantTwistAngleVar.Value); + + // Shadow structure properties. + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.w, num_implantResistCD.Value); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.wV, num_implantResistCDVar.Value); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.h, num_implantResistHeight.Value); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.hV, num_implantResistHeightVar.Value); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.cRR, num_implantResistTopCRR.Value); + commonVars.getImplantSettings().setDouble(EntropyImplantSettings.properties_d.cV, num_implantResistTopCRRVar.Value); + + commonVars.getImplantSimulationSettings().setResolution(1.0f); + commonVars.getImplantSimulationSettings().setValue(EntropySettings.properties_i.nCases, Convert.ToInt32(num_implantNumOfCases.Value)); + commonVars.getImplantSimulationSettings().setValue(EntropySettings.properties_i.cSeg, Convert.ToInt32(num_implantCornerSegments.Value)); + + if ((bool)checkBox_CSV_implant.Checked) + { + commonVars.getImplantSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.csv, 1); + } + else + { + commonVars.getImplantSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.csv, 0); + } + + if ((bool)checkBox_external_implant.Checked) + { + comboBox_externalTypes_implant.Enabled = true; + commonVars.getImplantSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.external, 1); + commonVars.getImplantSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.externalType, (Int32)CommonVars.external_Type.svg); + } + else + { + comboBox_externalTypes_implant.Enabled = false; + commonVars.getImplantSettings_nonSim().setValue(EntropySettings_nonSim.properties_i.external, 0); + } + + doImplantShadowing(); + + uiFollowChanges(); + } + + void doImplantShadowing() + { + entropyControl.entropyRun_implant(1, null, false); + } + + void setImplantViewportCamera(double[] parameters) + { + otkVPSettings_implant.setCameraPos((float)parameters[0], (float)parameters[1]); + otkVPSettings_implant.setZoomFactor((float)parameters[2]); + + } + + double[] getImplantViewportCamera() + { + double x = otkVPSettings_implant.getCameraX(); + double y = otkVPSettings_implant.getCameraY(); + double zoom = otkVPSettings_implant.getZoomFactor(); + return new double[] { x, y, zoom }; + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/layerUI_common.cs b/Common/Variance/UI/layerUI_common.cs new file mode 100644 index 0000000..a3a5d3c --- /dev/null +++ b/Common/Variance/UI/layerUI_common.cs @@ -0,0 +1,1981 @@ +using color; +using Eto.Drawing; +using Eto.Forms; +using geoLib; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Variance +{ + public partial class MainForm : Form + { + int getMainSelectedIndex() + { + Int32 tmp = -1; + + Application.Instance.Invoke(() => + { + tmp = tabControl_main.SelectedIndex; + }); + + return tmp; + } + + void setMainSelectedIndex(int index) + { + Application.Instance.Invoke(() => + { + tabControl_main.SelectedIndex = index; + }); + } + + int getSubTabSelectedIndex() + { + Int32 tmp = -1; + + Application.Instance.Invoke(() => + { + tmp = tabControl_2D_simsettings.SelectedIndex; + }); + + return tmp; + } + + void setSubTabSelectedIndex(int index) + { + Application.Instance.Invoke(() => + { + tabControl_2D_simsettings.SelectedIndex = index; + }); + } + + int getSelectedLayerIndex() + { + return selectedLayer; + } + + void set2DSelectedIndex(int index) + { + Application.Instance.Invoke(() => + { + selectedLayer = index; + experimental_listBox_layers.SelectedIndex = index; + }); + } + + void goToLayerUI(int index) + { + setMainSelectedIndex((Int32)CommonVars.upperTabNames.twoD); + setSubTabSelectedIndex((Int32)CommonVars.twoDTabNames.layer); + set2DSelectedIndex(index); + set_ui_from_settings(index); + } + + void layer_clampSubShape_exp(double minHLength, double maxHLength, double minVLength, double maxVLength, double minHOffset, double maxHOffset, double minVOffset, double maxVOffset) + { + Application.Instance.Invoke(() => + { + if (num_layer_subshape_hl_exp.Value < minHLength) + { + num_layer_subshape_hl_exp.Value = minHLength; + } + + if (num_layer_subshape_hl_exp.Value > maxHLength) + { + num_layer_subshape_hl_exp.Value = maxHLength; + } + + if (num_layer_subshape_vl_exp.Value < minVLength) + { + num_layer_subshape_vl_exp.Value = minVLength; + } + + if (num_layer_subshape_vl_exp.Value > maxVLength) + { + num_layer_subshape_vl_exp.Value = maxVLength; + } + + if (num_layer_subshape_ho_exp.Value < minHOffset) + { + num_layer_subshape_ho_exp.Value = minHOffset; + } + + if (num_layer_subshape_ho_exp.Value > maxHOffset) + { + num_layer_subshape_ho_exp.Value = maxHOffset; + } + + if (num_layer_subshape_vo_exp.Value < minVOffset) + { + num_layer_subshape_vo_exp.Value = minVOffset; + } + + if (num_layer_subshape_vo_exp.Value > maxVOffset) + { + num_layer_subshape_vo_exp.Value = maxVOffset; + } + }); + } + + void layer_clampSubShape2_exp(double minHLength, double maxHLength, double minVLength, double maxVLength, double minHOffset, double maxHOffset, double minVOffset, double maxVOffset) + { + Application.Instance.Invoke(() => + { + if (num_layer_subshape2_hl_exp.Value < minHLength) + { + num_layer_subshape2_hl_exp.Value = minHLength; + } + + if (num_layer_subshape2_hl_exp.Value > maxHLength) + { + num_layer_subshape2_hl_exp.Value = maxHLength; + } + + if (num_layer_subshape2_vl_exp.Value < minVLength) + { + num_layer_subshape2_vl_exp.Value = minVLength; + } + + if (num_layer_subshape2_vl_exp.Value > maxVLength) + { + num_layer_subshape2_vl_exp.Value = maxVLength; + } + + if (num_layer_subshape2_ho_exp.Value < minHOffset) + { + num_layer_subshape2_ho_exp.Value = minHOffset; + } + + if (num_layer_subshape2_ho_exp.Value > maxHOffset) + { + num_layer_subshape2_ho_exp.Value = maxHOffset; + } + + if (num_layer_subshape2_vo_exp.Value < minVOffset) + { + num_layer_subshape2_vo_exp.Value = minVOffset; + } + + if (num_layer_subshape2_vo_exp.Value > maxVOffset) + { + num_layer_subshape2_vo_exp.Value = maxVOffset; + } + }); + } + + void layer_clampSubShape3_exp(double minHLength, double maxHLength, double minVLength, double maxVLength, double minHOffset, double maxHOffset, double minVOffset, double maxVOffset) + { + Application.Instance.Invoke(() => + { + if (num_layer_subshape3_hl_exp.Value < minHLength) + { + num_layer_subshape3_hl_exp.Value = minHLength; + } + + if (num_layer_subshape3_hl_exp.Value > maxHLength) + { + num_layer_subshape3_hl_exp.Value = maxHLength; + } + + if (num_layer_subshape3_vl_exp.Value < minVLength) + { + num_layer_subshape3_vl_exp.Value = minVLength; + } + + if (num_layer_subshape3_vl_exp.Value > maxVLength) + { + num_layer_subshape3_vl_exp.Value = maxVLength; + } + + if (num_layer_subshape3_ho_exp.Value < minHOffset) + { + num_layer_subshape3_ho_exp.Value = minHOffset; + } + + if (num_layer_subshape3_ho_exp.Value > maxHOffset) + { + num_layer_subshape3_ho_exp.Value = maxHOffset; + } + + if (num_layer_subshape3_vo_exp.Value < minVOffset) + { + num_layer_subshape3_vo_exp.Value = minVOffset; + } + + if (num_layer_subshape3_vo_exp.Value > maxVOffset) + { + num_layer_subshape3_vo_exp.Value = maxVOffset; + } + }); + } + + void addLayerHandlers_exp() + { + layerUIFrozen_exp = false; + button_layer_globalApply_geoCore_exp.Click += applyLayoutToAll; + + checkBox_Layer_exp.CheckedChanged += twoDLayerEventHandler_exp; + text_layerName_exp.LostFocus += twoDLayerEventHandler_exp; + + checkBox_layer_edgeSlide_exp.CheckedChanged += twoDLayerEventHandler_exp; + num_layer_edgeSlideTension_exp.LostFocus += twoDLayerEventHandler_exp; + + checkBox_Layer_FlipH_exp.CheckedChanged += twoDLayerEventHandler_exp; + checkBox_Layer_FlipV_exp.CheckedChanged += twoDLayerEventHandler_exp; + checkBox_Layer_alignGeometryX_exp.CheckedChanged += twoDLayerEventHandler_exp; + checkBox_Layer_alignGeometryY_exp.CheckedChanged += twoDLayerEventHandler_exp; + + comboBox_layerShape_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerSubShapeRef_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerPosSubShape_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + + num_layerGlobalHorOffset_exp.LostFocus += twoDLayerEventHandler_exp; + num_layerGlobalVerOffset_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layer_subshape_hl_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape_vl_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape_ho_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape_vo_exp.LostFocus += twoDLayerEventHandler_exp; + comboBox_layerTipLocations_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + + num_layer_subshape2_hl_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape2_vl_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape2_ho_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape2_vo_exp.LostFocus += twoDLayerEventHandler_exp; + comboBox_layerTipLocations2_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + + num_layer_subshape3_hl_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape3_vl_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape3_ho_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_subshape3_vo_exp.LostFocus += twoDLayerEventHandler_exp; + comboBox_layerTipLocations3_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + + num_layer_lithoLWR_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_lithoLWRFreq_exp.LostFocus += twoDLayerEventHandler_exp; + comboBox_layerLWRNoiseType_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + num_layer_lithoLWR2_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_lithoLWR2Freq_exp.LostFocus += twoDLayerEventHandler_exp; + comboBox_layerLWR2NoiseType_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + cB_layer_LWRPreview_exp.CheckedChanged += twoDLayerEventHandler_exp; + + num_layerSidebias_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layer_lithoCDUTips_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_lithoCDUSide_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layerHTipbias_exp.LostFocus += twoDLayerEventHandler_exp; + num_layerVTipbias_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layerhTipPVar_exp.LostFocus += twoDLayerEventHandler_exp; + num_layerhTipNVar_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layervTipPVar_exp.LostFocus += twoDLayerEventHandler_exp; + num_layervTipNVar_exp.LostFocus += twoDLayerEventHandler_exp; + + num_pitchDepBias_exp.LostFocus += twoDLayerEventHandler_exp; + num_pitchDepBiasIsoDistance_exp.LostFocus += twoDLayerEventHandler_exp; + num_pitchDepBiasSideRays_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layer_lithoICRR_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_lithoICV_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_lithoOCRR_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_lithoOCV_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layer_lithoHorOverlay_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_lithoVerOverlay_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layerRotation_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_lithoWobble_exp.LostFocus += twoDLayerEventHandler_exp; + + num_layer_coeff1_exp.LostFocus += twoDLayerEventHandler_exp; + num_layer_coeff2_exp.LostFocus += twoDLayerEventHandler_exp; + + button_layer_chooseFile_geoCore_exp.Click += geoFileChooser_Handler_exp; + comboBox_layerLDList_geoCore_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerStructureList_geoCore_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerPolyFill_geoCore_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + checkBox_layer_geoCore_shapeEngine_exp.CheckedChanged += twoDLayerEventHandler_exp; + checkBox_layer_geoCore_shapeEngine_perPoly_exp.CheckedChanged += twoDLayerEventHandler_exp; + comboBox_layerTipLocations_geoCore_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + checkBox_layer_geoCore_layoutReference_exp.CheckedChanged += twoDLayerEventHandler_exp; + checkBox_DOELayer_geoCore_exp.CheckedChanged += twoDLayerEventHandler_exp; + + checkBox_Layer_ShowDrawn_exp.CheckedChanged += showDrawn_exp; + + comboBox_layerBooleanOpA_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerBooleanOpB_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerBooleanOpAB_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerTipLocations_boolean_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + rB_layer_COLX_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + rB_layer_COLY_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + rB_layer_OLRX_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + rB_layer_OLRY_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + rB_layer_CCDU_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + rB_layer_CTCDU_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + rB_layerBooleanA_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + rB_layerBooleanB_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + cB_layer_OLRX_Av_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + cB_layer_OLRY_Av_exp[i].CheckedChanged += twoDLayerEventHandler_exp; + } + + checkBox_layer_overlayXReference_Av_exp.CheckedChanged += twoDLayerEventHandler_exp; + checkBox_layer_overlayYReference_Av_exp.CheckedChanged += twoDLayerEventHandler_exp; + } + + void do2DLayerUI_exp(int settingsIndex, bool updateUI = false) + { + Application.Instance.Invoke(() => + { + if (layerUIFrozen_exp) + { + return; + } + + suspendLayerUI_exp(); + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shapeIndex, comboBox_layerShape_exp.SelectedIndex); + + // Set our tab name. + if (text_layerName_exp.Text != "") + { + commonVars.getLayerSettings(settingsIndex).setString(EntropyLayerSettings.properties_s.name, text_layerName_exp.Text); + } + else + { + commonVars.getLayerSettings(settingsIndex).setString(EntropyLayerSettings.properties_s.name, (settingsIndex + 1).ToString()); + } + // We have to deregister the handler here otherwise the name update causes the selectedindexchanged event to fire and everything breaks. + experimental_listBox_layers.SelectedIndexChanged -= listbox_change; + commonVars.layerNames[settingsIndex] = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.name); + experimental_listBox_layers.SelectedIndexChanged += listbox_change; + + experimental_listBox_layers.SelectedIndex = selectedLayer; + + if ((commonVars.getE()) || (commonVars.getL(CommonVars.l.f) != "advanced")) + { + checkBox_layer_geoCore_shapeEngine_exp.Enabled = false; + checkBox_layer_geoCore_shapeEngine_exp.Checked = false; + checkBox_layer_geoCore_shapeEngine_perPoly_exp.Enabled = false; + checkBox_layer_geoCore_shapeEngine_perPoly_exp.Checked = false; + } + + if ((commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) && + !((bool)checkBox_layer_geoCore_shapeEngine_exp.Checked)) + { + checkBox_Layer_FlipH_exp.Checked = false; + checkBox_Layer_FlipV_exp.Checked = false; + checkBox_Layer_alignGeometryX_exp.Checked = false; + checkBox_Layer_alignGeometryY_exp.Checked = false; + + checkBox_Layer_FlipH_exp.Enabled = false; + checkBox_Layer_FlipV_exp.Enabled = false; + checkBox_Layer_alignGeometryX_exp.Enabled = false; + checkBox_Layer_alignGeometryY_exp.Enabled = false; + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.flipH, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.flipV, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.alignX, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.alignY, 0); + } + else + { + checkBox_Layer_FlipH_exp.Enabled = true; + checkBox_Layer_FlipV_exp.Enabled = true; + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.flipH, 0); + if ((bool)checkBox_Layer_FlipH_exp.Checked) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.flipH, 1); + } + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.flipV, 0); + if ((bool)checkBox_Layer_FlipV_exp.Checked) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.flipV, 1); + } + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.alignX, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.alignY, 0); + checkBox_Layer_alignGeometryX_exp.Enabled = false; + checkBox_Layer_alignGeometryY_exp.Enabled = false; + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.flipH) == 1) + { + checkBox_Layer_alignGeometryX_exp.Enabled = true; + if (checkBox_Layer_alignGeometryX_exp.Checked == true) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.alignX, 1); + } + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.flipV) == 1) + { + checkBox_Layer_alignGeometryY_exp.Enabled = true; + if (checkBox_Layer_alignGeometryY_exp.Checked == true) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.alignY, 1); + } + } + } + + do2DLayerUI_edgeSlide_exp(settingsIndex); + + Int32 previousIndex = comboBox_layerSubShapeRef_exp.SelectedIndex; + + if (updateUI) + { + set_shape_type_ui(settingsIndex); + } + if (previousIndex >= commonVars.subshapes[settingsIndex].Count) + { + previousIndex = commonVars.subshapes[settingsIndex].Count - 1; + } + + comboBox_layerSubShapeRef_exp.SelectedIndex = previousIndex; + + comboBox_geoEqtn_Op[settingsIndex].Enabled = false; + + // Enable control requires various checks to ensure it is appropriate. These complicated checks are below and commented. + if ( + ( + // Avoid offering enable options for zero length and height and no shape defined, with a wrapping check in case of layout (where zero height/length are permitted) + (num_layer_subshape_hl_exp.Value != 0) && + (num_layer_subshape_vl_exp.Value != 0) && + ((commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.GEOCORE) && (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.none)) + ) || + ( + // Allow enable for geoCore with valid input. + commonVars.getGeoCoreHandler(settingsIndex).isValid() && (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.GEOCORE) + ) || + ( + // Allow enable for geoCore with reloaded data. + commonVars.getLayerSettings(settingsIndex).isReloaded() && (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.GEOCORE) + ) || + ( + // Allow enable for Boolean type - should probably check input fields here, but we don't for now. + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.BOOLEAN) + ) + ) + { + // Also tweak 'show drawn' here. + checkBox_Layer_exp.Enabled = true; + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.showDrawn, 0); + if (checkBox_Layer_exp.Checked == true) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.enabled, 1); + comboBox_geoEqtn_Op[settingsIndex].Enabled = true; + checkBox_Layer_ShowDrawn_exp.Enabled = true; + if (checkBox_Layer_ShowDrawn_exp.Checked == true) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.showDrawn, 1); + } + } + else + { + checkBox_Layer_ShowDrawn_exp.Enabled = false; + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.enabled, 0); + } + } + else + { + checkBox_Layer_exp.Checked = false; + checkBox_Layer_exp.Enabled = false; + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.enabled, 0); + checkBox_Layer_ShowDrawn_exp.Enabled = false; + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.showDrawn, 0); + } + + doSimSettingsCheck(); + startButtonCheck(); + + textBox_layer_FileLocation_geoCore_exp.Text = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.file); + + comboBox_layerSubShapeRef_exp.Enabled = true; + comboBox_layerPosSubShape_exp.Enabled = true; + + num_layerHTipbias_exp.Enabled = true; + num_layerVTipbias_exp.Enabled = true; + num_layerhTipNVar_exp.Enabled = true; + num_layerhTipPVar_exp.Enabled = true; + num_layervTipNVar_exp.Enabled = true; + num_layervTipPVar_exp.Enabled = true; + + num_layer_lithoICRR_exp.Enabled = true; + num_layer_lithoICV_exp.Enabled = true; + num_layer_lithoCDUSide_exp.Enabled = true; + num_layer_lithoCDUTips_exp.Enabled = true; + groupBox_layer_CDUCorrelation_exp.Enabled = true; + groupBox_layer_TipCDUCorrelation_exp.Enabled = true; + num_layer_lithoLWR_exp.Enabled = true; + num_layer_lithoLWRFreq_exp.Enabled = true; + cB_layer_LWRPreview_exp.Enabled = true; + comboBox_layerLWRNoiseType_exp.Enabled = true; + num_layer_lithoOCRR_exp.Enabled = true; + num_layer_lithoOCV_exp.Enabled = true; + num_layerRotation_exp.Enabled = true; + num_layer_lithoWobble_exp.Enabled = true; + + if (!commonVars.getLayerSettings(settingsIndex).isReloaded()) + { + // We do this to avoid any misfires later. Might not be needed, but seems safer. + GeoLibPointF[] defaultPointArray = new GeoLibPointF[1]; + defaultPointArray[0] = new GeoLibPointF(0, 0); + commonVars.getLayerSettings(settingsIndex).setFileData(new List() { defaultPointArray }); + } + + if ((bool)checkBox_layer_geoCore_shapeEngine_exp.Checked) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.gCSEngine, 1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.gCSEngine, 0); + } + + if ((bool)checkBox_layer_geoCore_shapeEngine_perPoly_exp.Checked) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.perPoly, 1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.perPoly, 0); + } + + if ((bool)checkBox_layer_geoCore_layoutReference_exp.Checked) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.refLayout, 1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.refLayout, 0); + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.GEOCORE) // layout option selected. + { + do2DLayerUI_geoCore_exp(settingsIndex); + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.BOOLEAN) + { + do2DLayerUI_Boolean_exp(settingsIndex); + } + + layer_clampSubShape_exp(minHLength: 0, maxHLength: 1000000, minVLength: 0, maxVLength: 1000000, minHOffset: -1000000, maxHOffset: 1000000, minVOffset: -1000000, maxVOffset: 1000000); + + bool[] warnArray = new bool[] { false, false, false }; + + if ((commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.none) || (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.rect)) + { + layer_clampSubShape2_exp(minHLength: 0, + maxHLength: 1000000, + minVLength: 0, + maxVLength: 1000000, + minHOffset: -1000000, + maxHOffset: 1000000, + minVOffset: -1000000, + maxVOffset: 1000000 + ); + layer_clampSubShape3_exp(minHLength: 0, + maxHLength: 1000000, + minVLength: 0, + maxVLength: 1000000, + minHOffset: -1000000, + maxHOffset: 1000000, + minVOffset: -1000000, + maxVOffset: 1000000 + ); + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.none) + { + num_layer_subshape_hl_exp.Value = 0; + num_layer_subshape_vl_exp.Value = 0; + num_layer_subshape_ho_exp.Value = 0; + num_layer_subshape_vo_exp.Value = 0; + } + + num_layer_subshape2_hl_exp.Value = 0; + num_layer_subshape2_vl_exp.Value = 0; + num_layer_subshape2_ho_exp.Value = 0; + num_layer_subshape2_vo_exp.Value = 0; + + num_layer_subshape3_hl_exp.Value = 0; + num_layer_subshape3_vl_exp.Value = 0; + num_layer_subshape3_ho_exp.Value = 0; + num_layer_subshape3_vo_exp.Value = 0; + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorLength, Convert.ToDecimal(num_layer_subshape2_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset, Convert.ToDecimal(num_layer_subshape2_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerLength, Convert.ToDecimal(num_layer_subshape2_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset, Convert.ToDecimal(num_layer_subshape2_vo_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape1Tip, comboBox_layerTipLocations2_exp.SelectedIndex); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorLength, Convert.ToDecimal(num_layer_subshape3_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset, Convert.ToDecimal(num_layer_subshape3_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerLength, Convert.ToDecimal(num_layer_subshape3_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset, Convert.ToDecimal(num_layer_subshape3_vo_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape2Tip, comboBox_layerTipLocations3_exp.SelectedIndex); + } + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorLength, Convert.ToDecimal(num_layer_subshape_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset, Convert.ToDecimal(num_layer_subshape_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerLength, Convert.ToDecimal(num_layer_subshape_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset, Convert.ToDecimal(num_layer_subshape_vo_exp.Value)); + + warnArray[0] = ((commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) == 0) || (commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) == 0)); + + // Boolean and geoCore have their own handling for this. + if ((commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.GEOCORE) && (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.BOOLEAN)) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape0Tip, comboBox_layerTipLocations_exp.SelectedIndex); + } + + // Subshape 2 offsets contingent on shape selection choice + if ( + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.none) && + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.rect) && + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.GEOCORE) && + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.BOOLEAN) + ) + { + layer_clampSubShape_exp(minHLength: 0.01, maxHLength: 1000000, minVLength: 0.01, maxVLength: 1000000, minHOffset: -1000000, maxHOffset: 1000000, minVOffset: -1000000, maxVOffset: 1000000); + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape1Tip, comboBox_layerTipLocations2_exp.SelectedIndex); + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.Xshape) // Limit offsets of subshape 2 for X-shape. + { + do2DLayerUI_X_exp(settingsIndex); + } + else if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.Tshape) // Disabled horizontal offset of subshape 2 for T-shape. + { + do2DLayerUI_T_exp(settingsIndex); + } + else if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.Lshape) // Disable horizontal and vertical offsets of subshape 2 for L-shape + { + do2DLayerUI_L_exp(settingsIndex); + } + else if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.Ushape) // U-shape + { + do2DLayerUI_U_exp(settingsIndex); + } + else if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.Sshape) // S-shape + { + do2DLayerUI_S_exp(settingsIndex); + } + else + { + num_layer_subshape2_ho_exp.Enabled = true; + num_layer_subshape2_vo_exp.Enabled = true; + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset, Convert.ToDecimal(num_layer_subshape2_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset, Convert.ToDecimal(num_layer_subshape2_vo_exp.Value)); + } + + warnArray[1] = ((commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) == 0) || (commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength) == 0)); + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.Sshape) + { + warnArray[2] = ((commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength) == 0) || (commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength) == 0)); + } + } + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape1Tip, comboBox_layerTipLocations2_exp.SelectedIndex); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape2Tip, comboBox_layerTipLocations3_exp.SelectedIndex); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.subShapeIndex, comboBox_layerSubShapeRef_exp.SelectedIndex); + if (comboBox_layerSubShapeRef_exp.SelectedIndex < 0) + { + comboBox_layerSubShapeRef_exp.SelectedIndex = 0; + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.posIndex, comboBox_layerPosSubShape_exp.SelectedIndex); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.gHorOffset, Convert.ToDecimal(num_layerGlobalHorOffset_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.gVerOffset, Convert.ToDecimal(num_layerGlobalVerOffset_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.rot, Convert.ToDecimal(num_layerRotation_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.wobble, Convert.ToDecimal(num_layer_lithoWobble_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.sBias, Convert.ToDecimal(num_layerSidebias_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.hTBias, Convert.ToDecimal(num_layerHTipbias_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.hTPVar, Convert.ToDecimal(num_layerhTipPVar_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.hTNVar, Convert.ToDecimal(num_layerhTipNVar_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.vTBias, Convert.ToDecimal(num_layerVTipbias_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.vTPVar, Convert.ToDecimal(num_layervTipPVar_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.vTNVar, Convert.ToDecimal(num_layervTipNVar_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.pBias, Convert.ToDecimal(num_pitchDepBias_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.pBiasDist, Convert.ToDecimal(num_pitchDepBiasIsoDistance_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.proxRays, Convert.ToInt32(num_pitchDepBiasSideRays_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.iCR, Convert.ToDecimal(num_layer_lithoICRR_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.oCR, Convert.ToDecimal(num_layer_lithoOCRR_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.iCV, Convert.ToDecimal(num_layer_lithoICV_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.oCV, Convert.ToDecimal(num_layer_lithoOCV_exp.Value)); + + do2DLayerUI_litho_exp(settingsIndex, updateUI); + + // If we have a geoCore layer, and it's tagged for DOE, and we have the layer preview based on the DOE extraction, we need to trigger the tile extraction. + if ((commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.GEOCORE) && (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(settingsIndex) == 1) && (commonVars.getLayerPreviewDOETile())) + { + // Need a tile extraction update + entropyControl.EntropyRun(numberOfCases: 1, csvFile: null, useThreads: false, doPASearch: false); + } + + setBGLayerCheckboxes(settingsIndex); + + // Force line drawing for disabled layer. + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.enabled) == 0) + { + mcVPSettings[settingsIndex].drawDrawn(true); + } + else + { + mcVPSettings[settingsIndex].drawDrawn((bool)checkBox_Layer_ShowDrawn_exp.Checked); + } + + drawPreviewPanelHandler(); + + updatePASearchUI(settingsIndex); + + reviewBooleanInputs(); + setOmitLayerCheckboxes_EnableStatus(); + + // Issue warning about zero dimension + bool warnNeeded = false; + string warningString = "Please choose non-zero width and height for subshape(s): "; + for (int w = 0; w < warnArray.Length; w++) + { + if (warnArray[w]) + { + warnNeeded = true; + warningString += (w + 1).ToString() + " "; + } + } + + if ((commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.GEOCORE) || + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.BOOLEAN) || + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.none)) + { + warnNeeded = false; + } + + if (warnNeeded) + { + updateStatusLine(warningString); + } + else + { + updateStatusLine(""); + } + + reviewComboBoxes(settingsIndex); + + experimental_listBox_layers.SelectedIndex = settingsIndex; + resumeLayerUI_exp(); + customRNGMappingHighlight_exp(settingsIndex); + updateGroupBoxVisibility_exp(settingsIndex); + bgLayerCheckboxChanged(settingsIndex); + uiFollowChanges(); + }); + } + + void set_shape_type_ui(int settingsIndex) + { + // Any configuration beyond the first couple requires a second shape to be defined so we need to display that part of the interface. + if ( + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.none) && + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.rect) && + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.GEOCORE) && + (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (int)CommonVars.shapeNames.BOOLEAN) + ) + { + // Let's display the subshape 2 section if a shape configuration is chosen that requires it. + num_layer_subshape2_hl_exp.Enabled = true; + num_layer_subshape2_vl_exp.Enabled = true; + num_layer_subshape2_ho_exp.Enabled = true; + num_layer_subshape2_vo_exp.Enabled = true; + comboBox_layerTipLocations2_exp.Enabled = true; + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.Sshape) + { + num_layer_subshape3_hl_exp.Enabled = true; + num_layer_subshape3_vl_exp.Enabled = true; + num_layer_subshape3_ho_exp.Enabled = true; + num_layer_subshape3_vo_exp.Enabled = true; + comboBox_layerTipLocations3_exp.Enabled = true; + + commonVars.subshapes[settingsIndex].Clear(); + commonVars.subshapes[settingsIndex].Add("1"); + commonVars.subshapes[settingsIndex].Add("2"); + commonVars.subshapes[settingsIndex].Add("3"); + } + else + { + num_layer_subshape3_hl_exp.Enabled = false; + num_layer_subshape3_vl_exp.Enabled = false; + num_layer_subshape3_ho_exp.Enabled = false; + num_layer_subshape3_vo_exp.Enabled = false; + comboBox_layerTipLocations3_exp.Enabled = false; + + commonVars.subshapes[settingsIndex].Clear(); + commonVars.subshapes[settingsIndex].Add("1"); + commonVars.subshapes[settingsIndex].Add("2"); + } + } + else + { + num_layer_subshape2_hl_exp.Enabled = false; + num_layer_subshape2_vl_exp.Enabled = false; + num_layer_subshape2_ho_exp.Enabled = false; + num_layer_subshape2_vo_exp.Enabled = false; + comboBox_layerTipLocations2_exp.Enabled = false; + + num_layer_subshape3_hl_exp.Enabled = false; + num_layer_subshape3_vl_exp.Enabled = false; + num_layer_subshape3_ho_exp.Enabled = false; + num_layer_subshape3_vo_exp.Enabled = false; + comboBox_layerTipLocations3_exp.Enabled = false; + + // Look at the 1 subshape list for displaying options + commonVars.subshapes[settingsIndex].Clear(); + commonVars.subshapes[settingsIndex].Add("1"); + } + } + + void reviewComboBoxes(int settingsIndex) + { + // Check the stored indices for comboboxes. Workaround for issues imposed by lazy evaluation in table layout, making things awkward as control indices are -1 until/unless drawn. + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shape0Tip) < 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape0Tip, 0); + } + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shape1Tip) < 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape1Tip, 0); + } + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shape2Tip) < 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape2Tip, 0); + } + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.bLayerOpA) < 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.bLayerOpA, 0); + } + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.bLayerOpAB) < 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.bLayerOpAB, 0); + } + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.bLayerOpB) < 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.bLayerOpB, 0); + } + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.fill) < 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.fill, EntropyLayerSettings.getDefaultInt(EntropyLayerSettings.properties_i.fill)); + } + } + + void do2DLayerUI_edgeSlide_exp(int settingsIndex) + { + // Process edge slide UI elements. + if ((commonVars.getE()) || (commonVars.getL(CommonVars.l.f) != "advanced")) + { + checkBox_layer_edgeSlide_exp.Checked = false; + checkBox_layer_edgeSlide_exp.Enabled = false; + num_layer_edgeSlideTension_exp.Enabled = false; + } + else + { + checkBox_layer_edgeSlide_exp.Enabled = true; + num_layer_edgeSlideTension_exp.Enabled = true; + } + + if ((bool)checkBox_layer_edgeSlide_exp.Checked) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.edgeSlide, 1); + num_layer_edgeSlideTension_exp.Enabled = true; + } + else + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.edgeSlide, 0); + num_layer_edgeSlideTension_exp.Enabled = false; + } + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.eTension, (decimal)num_layer_edgeSlideTension_exp.Value); + if (commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.eTension) < 1E-2m) + { + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.eTension, 1E-2m); + } + } + + void do2DLayerUI_Boolean_exp(int settingsIndex) + { + comboBox_layerSubShapeRef_exp.SelectedIndex = 0; + comboBox_layerPosSubShape_exp.SelectedIndex = (int)CommonVars.subShapeLocations.BL; + comboBox_layerSubShapeRef_exp.Enabled = false; + comboBox_layerPosSubShape_exp.Enabled = false; + + geoGBVisible[settingsIndex] = false; + subShapeGBVisible[settingsIndex] = false; + booleanGBVisible[settingsIndex] = true; + + int aIndex = 0; + int bIndex = 0; + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (rB_layerBooleanA_exp[i].Checked) + { + aIndex = i; + } + if (rB_layerBooleanB_exp[i].Checked) + { + bIndex = i; + } + } + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.bLayerA, aIndex - 1); // offset for the 0 case + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.bLayerB, bIndex - 1); // offset for the 0 case + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.bLayerOpA, comboBox_layerBooleanOpA_exp.SelectedIndex); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.bLayerOpB, comboBox_layerBooleanOpB_exp.SelectedIndex); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.bLayerOpAB, comboBox_layerBooleanOpAB_exp.SelectedIndex); + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape0Tip, comboBox_layerTipLocations_boolean_exp.SelectedIndex); + } + + void do2DLayerUI_geoCore_exp(int settingsIndex) + { + if ((varianceContext.vc.geoCoreCDVariation) || (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.gCSEngine) == 1)) + { + groupBox_layer_CDUCorrelation_exp.Enabled = true; // CDU variation permitted. + groupBox_layer_TipCDUCorrelation_exp.Enabled = true; + } + else + { + groupBox_layer_CDUCorrelation_exp.Enabled = false; // no CDU variation permitted. + groupBox_layer_TipCDUCorrelation_exp.Enabled = false; + } + + geoGBVisible[settingsIndex] = true; + subShapeGBVisible[settingsIndex] = false; + booleanGBVisible[settingsIndex] = false; + + // Enable UI elements if layout is valid/loaded. + // Block UI elements if reloaded as we don't have the layout to move to a different structure/layer-datatype. + // Need to check state of this conditional in case 'reference' is selected. + button_layer_globalApply_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid(); + comboBox_layerStructureList_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid() && !commonVars.getLayerSettings(settingsIndex).isReloaded(); + comboBox_layerLDList_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid() && !commonVars.getLayerSettings(settingsIndex).isReloaded(); + comboBox_layerTipLocations_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid(); + checkBox_DOELayer_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid(); + + // Disable subshapes + comboBox_layerSubShapeRef_exp.SelectedIndex = 0; + comboBox_layerPosSubShape_exp.SelectedIndex = (int)CommonVars.subShapeLocations.BL; + comboBox_layerSubShapeRef_exp.Enabled = false; + comboBox_layerPosSubShape_exp.Enabled = false; + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.gCSEngine) == 0) + { + comboBox_layerTipLocations_geoCore_exp.Enabled = false; + // Disable other features. Assuming PV bands are being used. + num_layerHTipbias_exp.Enabled = false; + num_layerVTipbias_exp.Enabled = false; + num_layerhTipNVar_exp.Enabled = false; + num_layerhTipPVar_exp.Enabled = false; + num_layervTipNVar_exp.Enabled = false; + num_layervTipPVar_exp.Enabled = false; + + num_layer_lithoICRR_exp.Enabled = false; + num_layer_lithoICV_exp.Enabled = false; + num_layer_lithoCDUSide_exp.Enabled = commonVars.getGCCDV(); + groupBox_layer_CDUCorrelation_exp.Enabled = commonVars.getGCCDV(); + num_layer_lithoCDUTips_exp.Enabled = false; + groupBox_layer_TipCDUCorrelation_exp.Enabled = false; + num_layer_lithoOCRR_exp.Enabled = false; + num_layer_lithoOCV_exp.Enabled = false; + num_layerRotation_exp.Enabled = false; + num_layer_lithoWobble_exp.Enabled = false; + } + + // Fix subshape menu to meet our needs: + commonVars.subshapes[settingsIndex].Clear(); + commonVars.subshapes[settingsIndex].Add("1"); + comboBox_layerSubShapeRef_exp.SelectedIndex = 0; + comboBox_layerPosSubShape_exp.SelectedIndex = (int)CommonVars.subShapeLocations.BL; + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.gCSEngine) == 0) + { + // Force all values for unsupported properties to 0. Simplifies runtime code. + num_layer_lithoICRR_exp.Value = 0.0; + num_layer_lithoICV_exp.Value = 0.0; + num_layer_lithoOCRR_exp.Value = 0.0; + num_layer_lithoOCV_exp.Value = 0.0; + if (!commonVars.getGCCDV()) + { + num_layer_lithoCDUSide_exp.Value = 0.0; + } + num_layer_lithoCDUTips_exp.Value = 0.0; + num_layerHTipbias_exp.Value = 0.0; + num_layerhTipNVar_exp.Value = 0.0; + num_layerhTipPVar_exp.Value = 0.0; + num_layerVTipbias_exp.Value = 0.0; + num_layervTipNVar_exp.Value = 0.0; + num_layervTipPVar_exp.Value = 0.0; + num_layerRotation_exp.Value = 0.0; + num_layer_lithoWobble_exp.Value = 0.0; + num_layer_subshape_ho_exp.Value = 0.0; + num_layer_subshape2_ho_exp.Value = 0.0; + num_layer_subshape3_ho_exp.Value = 0.0; + num_layer_subshape_vo_exp.Value = 0.0; + num_layer_subshape2_vo_exp.Value = 0.0; + num_layer_subshape3_vo_exp.Value = 0.0; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.gCSEngine) == 1) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape0Tip, comboBox_layerTipLocations_geoCore_exp.SelectedIndex); + } + + // Force update of comboboxes + if (commonVars.getGeoCoreHandler(settingsIndex).isValid())// && (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(settingsIndex) == 1)) + { + // Avoid triggering repaints as we update things. + comboBox_layerPolyFill_geoCore_exp.SelectedIndexChanged -= twoDLayerEventHandler_exp; + comboBox_layerLDList_geoCore_exp.SelectedIndexChanged -= twoDLayerEventHandler_exp; + comboBox_layerStructureList_geoCore_exp.SelectedIndexChanged -= twoDLayerEventHandler_exp; + if (!commonVars.getLayerSettings(settingsIndex).isReloaded()) + { + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.fill, comboBox_layerPolyFill_geoCore_exp.SelectedIndex); + + if (commonVars.getGeoCoreHandler(settingsIndex).isChanged()) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.structure, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lD, 0); + commonVars.getGeoCoreHandler(settingsIndex).setChanged(false); + } + else + { + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure) != comboBox_layerStructureList_geoCore_exp.SelectedIndex) + { + commonVars.getGeoCoreHandler(settingsIndex).setChanged(true); + try + { + comboBox_layerLDList_geoCore_exp.SelectedIndex = 0; // reset selection. + } + catch (Exception) + { + + } + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.structure, comboBox_layerStructureList_geoCore_exp.SelectedIndex); + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD) != comboBox_layerLDList_geoCore_exp.SelectedIndex) + { + commonVars.getGeoCoreHandler(settingsIndex).setChanged(true); + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lD, comboBox_layerLDList_geoCore_exp.SelectedIndex); + } + + if ((commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure) == -1) || (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure) >= commonVars.structureList[settingsIndex].Count())) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.structure, 0); + } + if ((commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD) == -1) || (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD) >= commonVars.getGeoCoreHandler(settingsIndex).getGeo().getStructureLayerDataTypeList()[commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure)].Count())) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lD, 0); + } + + commonVars.getLayerSettings(settingsIndex).setString(EntropyLayerSettings.properties_s.structure, commonVars.structureList[settingsIndex][commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure)]); + commonVars.getLayerSettings(settingsIndex).setString(EntropyLayerSettings.properties_s.lD, commonVars.getGeoCoreHandler(settingsIndex).getGeo().getStructureLayerDataTypeList()[commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure)][commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD)]); + + commonVars.getGeoCoreHandler(settingsIndex).getGeo().updateGeometry(commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure), commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD)); + commonVars.getGeoCoreHandler(settingsIndex).getGeo().updateCollections(); + + // Experimental optimization to try and reduce memory footprint. + commonVars.getGeoCoreHandler(settingsIndex).setPoints(commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure), commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD)); + // Map our points into the layer's file data, if the layer is active. + commonVars.getLayerSettings(settingsIndex).setFileData(commonVars.getGeoCoreHandler(settingsIndex).getGeo().points()); + + try + { + comboBox_layerStructureList_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure); + } + catch (Exception) + { + + } + + try + { + comboBox_layerLDList_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD); + } + catch (Exception) + { + + } + + } + else + { + commonVars.getGeoCoreHandler(settingsIndex).getGeo().structureList_.Clear(); + commonVars.getGeoCoreHandler(settingsIndex).getGeo().structureList_.Add(commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.structure)); + commonVars.getGeoCoreHandler(settingsIndex).getGeo().activeStructure_LayerDataTypeList_.Clear(); + commonVars.getGeoCoreHandler(settingsIndex).getGeo().activeStructure_LayerDataTypeList_.Add(commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.lD)); + comboBox_layerStructureList_geoCore_exp.SelectedIndex = 0; + comboBox_layerLDList_geoCore_exp.SelectedIndex = 0; + } + // Enable repaints for updated things. + comboBox_layerPolyFill_geoCore_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerLDList_geoCore_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + comboBox_layerStructureList_geoCore_exp.SelectedIndexChanged += twoDLayerEventHandler_exp; + + if ((bool)checkBox_DOELayer_geoCore_exp.Checked) + { + commonVars.getSimulationSettings().getDOESettings().setLayerAffected(settingsIndex, 1); + } + else + { + commonVars.getSimulationSettings().getDOESettings().setLayerAffected(settingsIndex, 0); + } + } + } + + void do2DLayerUI_X_exp(int settingsIndex) + { + // Validate our settings and clamp the inputs as needed. + layer_clampSubShape_exp(minHLength: 0.04, + maxHLength: 1000000, + minVLength: 0.04, + maxVLength: 1000000, + minHOffset: -1000000, + maxHOffset: 1000000, + minVOffset: -1000000, + maxVOffset: 1000000 + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorLength, Convert.ToDecimal(num_layer_subshape_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset, Convert.ToDecimal(num_layer_subshape_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerLength, Convert.ToDecimal(num_layer_subshape_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset, Convert.ToDecimal(num_layer_subshape_vo_exp.Value)); + + num_layer_subshape3_hl_exp.Value = 0; + num_layer_subshape3_vl_exp.Value = 0; + num_layer_subshape3_ho_exp.Value = 0; + num_layer_subshape3_vo_exp.Value = 0; + + decimal minSS2VOffset = 1; + decimal maxSS2VOffset = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength); + + decimal minSS2HOffset = -(commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) - commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + decimal maxSS2HOffset = -1; + + decimal minSS2HLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) + (2 * 0.01m); + decimal maxSS2VLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - (2 * 0.01m); + if (maxSS2VLength < 0) + { + maxSS2VLength = 0.02m; + } + + layer_clampSubShape2_exp(minHLength: (double)minSS2HLength, + maxHLength: 1000000, + minVLength: 0.02, + maxVLength: (double)maxSS2VLength, + minHOffset: (double)minSS2HOffset, + maxHOffset: (double)maxSS2HOffset, + minVOffset: (double)minSS2VOffset, + maxVOffset: (double)maxSS2VOffset + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorLength, Convert.ToDecimal(num_layer_subshape2_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerLength, Convert.ToDecimal(num_layer_subshape2_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset, Convert.ToDecimal(num_layer_subshape2_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset, Convert.ToDecimal(num_layer_subshape2_vo_exp.Value)); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorLength, Convert.ToDecimal(num_layer_subshape3_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerLength, Convert.ToDecimal(num_layer_subshape3_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset, Convert.ToDecimal(num_layer_subshape3_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset, Convert.ToDecimal(num_layer_subshape3_vo_exp.Value)); + + num_layer_subshape2_ho_exp.Enabled = true; + num_layer_subshape2_vo_exp.Enabled = true; + } + + void do2DLayerUI_T_exp(int settingsIndex) + { + // Validate our settings and clamp the inputs as needed. + layer_clampSubShape_exp(minHLength: 0.01, + maxHLength: 1000000, + minVLength: 0.04, + maxVLength: 1000000, + minHOffset: -1000000, + maxHOffset: 1000000, + minVOffset: -1000000, + maxVOffset: 1000000 + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorLength, Convert.ToDecimal(num_layer_subshape_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset, Convert.ToDecimal(num_layer_subshape_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerLength, Convert.ToDecimal(num_layer_subshape_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset, Convert.ToDecimal(num_layer_subshape_vo_exp.Value)); + + num_layer_subshape3_hl_exp.Value = 0; + num_layer_subshape3_vl_exp.Value = 0; + num_layer_subshape3_ho_exp.Value = 0; + num_layer_subshape3_vo_exp.Value = 0; + + decimal minSS2HLength = 0.01m; + decimal minSS2VLength = 0.02m; + decimal maxSS2VLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - (2 * 0.01m); + decimal maxSS2VOffset = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength); + + layer_clampSubShape2_exp(minHLength: (double)minSS2HLength, + maxHLength: 1000000, + minVLength: (double)minSS2VLength, + maxVLength: (double)maxSS2VLength, + minHOffset: (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength), + maxHOffset: (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength), + minVOffset: 1, + maxVOffset: (double)maxSS2VOffset + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorLength, Convert.ToDecimal(num_layer_subshape2_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerLength, Convert.ToDecimal(num_layer_subshape2_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset, Convert.ToDecimal(num_layer_subshape2_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset, Convert.ToDecimal(num_layer_subshape2_vo_exp.Value)); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorLength, Convert.ToDecimal(num_layer_subshape3_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerLength, Convert.ToDecimal(num_layer_subshape3_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset, Convert.ToDecimal(num_layer_subshape3_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset, Convert.ToDecimal(num_layer_subshape3_vo_exp.Value)); + + num_layer_subshape2_ho_exp.Enabled = false; + num_layer_subshape2_vo_exp.Enabled = true; + } + + void do2DLayerUI_L_exp(int settingsIndex) + { + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorLength, Convert.ToDecimal(num_layer_subshape_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset, Convert.ToDecimal(num_layer_subshape_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerLength, Convert.ToDecimal(num_layer_subshape_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset, Convert.ToDecimal(num_layer_subshape_vo_exp.Value)); + + num_layer_subshape3_hl_exp.Value = 0; + num_layer_subshape3_vl_exp.Value = 0; + num_layer_subshape3_ho_exp.Value = 0; + num_layer_subshape3_vo_exp.Value = 0; + + decimal minSS2HLength = 0; + decimal minSS2VLength = 0; + decimal maxSS2VLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength); + + decimal minSS2HOffset = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength); + decimal maxSS2HOffset = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength); + decimal minSS2VOffset = 0; + decimal maxSS2VOffset = 0; + + layer_clampSubShape2_exp(minHLength: (double)minSS2HLength, + maxHLength: 1000000, + minVLength: (double)minSS2VLength, + maxVLength: (double)maxSS2VLength, + minHOffset: (double)minSS2HOffset, + maxHOffset: (double)maxSS2HOffset, + minVOffset: (double)minSS2VOffset, + maxVOffset: (double)maxSS2VOffset + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorLength, Convert.ToDecimal(num_layer_subshape2_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerLength, Convert.ToDecimal(num_layer_subshape2_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset, Convert.ToDecimal(num_layer_subshape2_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset, Convert.ToDecimal(num_layer_subshape2_vo_exp.Value)); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorLength, Convert.ToDecimal(num_layer_subshape3_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerLength, Convert.ToDecimal(num_layer_subshape3_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset, Convert.ToDecimal(num_layer_subshape3_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset, Convert.ToDecimal(num_layer_subshape3_vo_exp.Value)); + + num_layer_subshape2_ho_exp.Enabled = false; + num_layer_subshape2_vo_exp.Enabled = false; + } + + void do2DLayerUI_U_exp(int settingsIndex) + { + // Validate our settings and clamp the inputs as needed. + layer_clampSubShape_exp(minHLength: 0.04, + maxHLength: 1000000, + minVLength: 0.04, + maxVLength: 1000000, + minHOffset: -1000000, + maxHOffset: 1000000, + minVOffset: -1000000, + maxVOffset: 1000000 + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorLength, Convert.ToDecimal(num_layer_subshape_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset, Convert.ToDecimal(num_layer_subshape_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerLength, Convert.ToDecimal(num_layer_subshape_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset, Convert.ToDecimal(num_layer_subshape_vo_exp.Value)); + + num_layer_subshape3_hl_exp.Value = 0; + num_layer_subshape3_vl_exp.Value = 0; + num_layer_subshape3_ho_exp.Value = 0; + num_layer_subshape3_vo_exp.Value = 0; + + decimal minSS2HLength = 0.02m; + decimal minSS2VLength = 0.02m; + decimal maxSS2HLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) - 0.02m; + decimal maxSS2VLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - 0.02m; + + decimal ss2HOffset = (commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) - commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) / 2; + decimal ss2VOffset = (commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + + layer_clampSubShape2_exp(minHLength: (double)minSS2HLength, + maxHLength: (double)maxSS2HLength, + minVLength: (double)minSS2VLength, + maxVLength: (double)maxSS2VLength, + minHOffset: (double)ss2HOffset, + maxHOffset: (double)ss2HOffset, + minVOffset: (double)ss2VOffset, + maxVOffset: (double)ss2VOffset + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorLength, Convert.ToDecimal(num_layer_subshape2_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerLength, Convert.ToDecimal(num_layer_subshape2_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset, Convert.ToDecimal(num_layer_subshape2_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset, Convert.ToDecimal(num_layer_subshape2_vo_exp.Value)); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorLength, Convert.ToDecimal(num_layer_subshape3_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerLength, Convert.ToDecimal(num_layer_subshape3_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset, Convert.ToDecimal(num_layer_subshape3_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset, Convert.ToDecimal(num_layer_subshape3_vo_exp.Value)); + + num_layer_subshape2_ho_exp.Enabled = false; + num_layer_subshape2_vo_exp.Enabled = false; + } + + void do2DLayerUI_S_exp(int settingsIndex) + { + // Validate our settings and clamp the inputs as needed. + layer_clampSubShape_exp(minHLength: 0.04, + maxHLength: 1000000, + minVLength: 0.04, + maxVLength: 1000000, + minHOffset: -1000000, + maxHOffset: 1000000, + minVOffset: -1000000, + maxVOffset: 1000000 + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorLength, Convert.ToDecimal(num_layer_subshape_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset, Convert.ToDecimal(num_layer_subshape_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerLength, Convert.ToDecimal(num_layer_subshape_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset, Convert.ToDecimal(num_layer_subshape_vo_exp.Value)); + + decimal minSS2HLength = 0.01m; + decimal maxSS2HLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) - 0.01m; + decimal minSS2VLength = 0.02m; + decimal maxSS2VLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - 0.01m; + decimal ss2HOffset = 0; + decimal minSS2VOffset = 0.01m; + decimal maxSS2VOffset = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength); + layer_clampSubShape2_exp(minHLength: (double)minSS2HLength, + maxHLength: (double)maxSS2HLength, + minVLength: (double)minSS2VLength, + maxVLength: (double)maxSS2VLength, + minHOffset: (double)ss2HOffset, + maxHOffset: (double)ss2HOffset, + minVOffset: (double)minSS2VOffset, + maxVOffset: (double)maxSS2VOffset + ); + + decimal minSS3HLength = 0.01m; + decimal maxSS3HLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) - 0.01m; + decimal minSS3VLength = 0.02m; + decimal maxSS3VLength = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - 0.01m; + decimal ss3HOffset = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) - commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength); + decimal minSS3VOffset = 0.01m; + decimal maxSS3VOffset = commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength) - commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength); + layer_clampSubShape3_exp(minHLength: (double)minSS3HLength, + maxHLength: (double)maxSS3HLength, + minVLength: (double)minSS3VLength, + maxVLength: (double)maxSS3VLength, + minHOffset: (double)ss3HOffset, + maxHOffset: (double)ss3HOffset, + minVOffset: (double)minSS3VOffset, + maxVOffset: (double)maxSS3VOffset + ); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorLength, Convert.ToDecimal(num_layer_subshape2_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerLength, Convert.ToDecimal(num_layer_subshape2_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset, Convert.ToDecimal(num_layer_subshape2_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset, Convert.ToDecimal(num_layer_subshape2_vo_exp.Value)); + + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorLength, Convert.ToDecimal(num_layer_subshape3_hl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerLength, Convert.ToDecimal(num_layer_subshape3_vl_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset, Convert.ToDecimal(num_layer_subshape3_ho_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset, Convert.ToDecimal(num_layer_subshape3_vo_exp.Value)); + + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.shape2Tip, comboBox_layerTipLocations3_exp.SelectedIndex); + + // FIXME: Need some logic here to avoid bisection of the S. + + num_layer_subshape2_ho_exp.Enabled = false; + num_layer_subshape2_vo_exp.Enabled = true; + + num_layer_subshape3_ho_exp.Enabled = false; + num_layer_subshape3_vo_exp.Enabled = true; + } + + void do2DLayerUI_litho_exp(int settingsIndex, bool updateUI) + { + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.lDC1, Convert.ToDecimal(num_layer_coeff1_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.lDC2, Convert.ToDecimal(num_layer_coeff2_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.lwr, Convert.ToDecimal(num_layer_lithoLWR_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.lwrFreq, Convert.ToDecimal(num_layer_lithoLWRFreq_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lwrType, comboBox_layerLWRNoiseType_exp.SelectedIndex); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.lwr2, Convert.ToDecimal(num_layer_lithoLWR2_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.lwr2Freq, Convert.ToDecimal(num_layer_lithoLWR2Freq_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lwr2Type, comboBox_layerLWR2NoiseType_exp.SelectedIndex); + if ((bool)cB_layer_LWRPreview_exp.Checked) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lwrPreview, 1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lwrPreview, 0); + } + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.sCDU, Convert.ToDecimal(num_layer_lithoCDUSide_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.tCDU, Convert.ToDecimal(num_layer_lithoCDUTips_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.xOL, Convert.ToDecimal(num_layer_lithoHorOverlay_exp.Value)); + commonVars.getLayerSettings(settingsIndex).setDecimal(EntropyLayerSettings.properties_decimal.yOL, Convert.ToDecimal(num_layer_lithoVerOverlay_exp.Value)); + + int COLXIndex = 0; + int COLYIndex = 0; + int OLRXIndex = 0; + int OLRYIndex = 0; + int CCDUIndex = 0; + int CTCDUIndex = 0; + bool[] avXIndices = new bool[CentralProperties.maxLayersForMC]; + bool[] avYIndices = new bool[CentralProperties.maxLayersForMC]; + + commonVars.getLayerSettings(settingsIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, settingsIndex, 0); // can never have a self-reference for this, so reset it to avoid trouble. + commonVars.getLayerSettings(settingsIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, settingsIndex, 0); // can never have a self-reference for this, so reset it to avoid trouble. + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (rB_layer_COLX_exp[i].Checked) + { + COLXIndex = i; + } + if (rB_layer_COLY_exp[i].Checked) + { + COLYIndex = i; + } + if (rB_layer_OLRX_exp[i].Checked) + { + OLRXIndex = i; + } + if (rB_layer_OLRY_exp[i].Checked) + { + OLRYIndex = i; + } + if (rB_layer_CCDU_exp[i].Checked) + { + CCDUIndex = i; + } + if (rB_layer_CTCDU_exp[i].Checked) + { + CTCDUIndex = i; + } + + if (i != settingsIndex) + { + if ((bool)cB_layer_OLRX_Av_exp[i].Checked) + { + commonVars.getLayerSettings(settingsIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, i, 1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, i, 0); + } + + if ((bool)cB_layer_OLRY_Av_exp[i].Checked) + { + commonVars.getLayerSettings(settingsIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, i, 1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, i, 0); + } + } + } + + if (COLXIndex == 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.xOL_corr, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, -1); + } + else + { + int xcolRefIndex = Convert.ToInt32(rB_layer_COLX_exp[COLXIndex].Text); + if (xcolRefIndex > settingsIndex) + { + xcolRefIndex--; // compensate for missing radio button for current layer. + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, xcolRefIndex - 1); + } + + if (COLYIndex == 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.yOL_corr, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, -1); + } + else + { + int ycolRefIndex = Convert.ToInt32(rB_layer_COLY_exp[COLYIndex].Text); + if (ycolRefIndex > settingsIndex) + { + ycolRefIndex--; // compensate for missing radio button for current layer. + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.yOL_corr, 1); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, ycolRefIndex - 1); + } + + if (OLRXIndex == 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.xOL_ref, -1); + } + else + { + int xolRefIndex = Convert.ToInt32(rB_layer_OLRX_exp[OLRXIndex].Text); + if (xolRefIndex > settingsIndex) + { + xolRefIndex--; // compensate for missing radio button for current layer. + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.xOL_ref, xolRefIndex - 1); + } + + if (OLRYIndex == 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.yOL_ref, -1); + } + else + { + int yolRefIndex = Convert.ToInt32(rB_layer_OLRY_exp[OLRYIndex].Text); + if (yolRefIndex > settingsIndex) + { + yolRefIndex--; // compensate for missing radio button for current layer. + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.yOL_ref, yolRefIndex - 1); + } + + if (CCDUIndex == 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.CDU_corr, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, -1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.CDU_corr, 1); + int ccduRefIndex = Convert.ToInt32(rB_layer_CCDU_exp[CCDUIndex].Text); + if (ccduRefIndex > settingsIndex) + { + // ccduRefIndex--; // compensate for missing radio button for current layer. + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, ccduRefIndex - 1); + + } + + if (CTCDUIndex == 0) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.tCDU_corr, 0); + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, -1); + } + else + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.tCDU_corr, 1); + int ctcduRefIndex = Convert.ToInt32(rB_layer_CTCDU_exp[CTCDUIndex].Text); + if (ctcduRefIndex > settingsIndex) + { + ctcduRefIndex--; // compensate for missing radio button for current layer. + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, ctcduRefIndex - 1); + } + + // Process the average overlay arrays. + if (checkBox_layer_overlayXReference_Av_exp.Checked == true) + { + if (updateUI) + { + pnl_overlayRefX.Content = groupBox_layer_overlayXReference_Av_exp; + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.xOL_av, 1); + } + else + { + if (updateUI) + { + pnl_overlayRefX.Content = groupBox_layer_overlayXReference_exp; + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.xOL_av, 0); + } + + if ((bool)checkBox_layer_overlayYReference_Av_exp.Checked) + { + if (updateUI) + { + pnl_overlayRefY.Content = groupBox_layer_overlayYReference_Av_exp; + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.yOL_av, 1); + } + else + { + if (updateUI) + { + pnl_overlayRefY.Content = groupBox_layer_overlayYReference_exp; + } + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.yOL_av, 0); + } + } + + void setBGLayerCheckboxes(int settingsIndex) + { + bool alreadyFrozen = globalUIFrozen; + globalUIFrozen = true; + Application.Instance.Invoke(() => + { + int rowIndex = 0; + int colIndex = 0; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (settingsIndex != i) + { + checkBox_bg_lyr[i].Enabled = (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1); + checkBox_bg_lyr[i].Checked = ((commonVars.getLayerSettings(settingsIndex).getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, i) == 1) && (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1)); + } + else + { + checkBox_bg_lyr[i].Enabled = false; + checkBox_bg_lyr[i].Checked = false; + } + colIndex++; + if (colIndex == CentralProperties.maxLayersForMC / 2) + { + colIndex = 0; + rowIndex++; + } + } + }); + if (!alreadyFrozen) + { + globalUIFrozen = false; + } + } + + void reviewBooleanInputs() + { + // Here, we walk the entire UI and reset gadgets, so we should freeze the UI to prevent problems. + bool alreadyFrozen = globalUIFrozen; + globalUIFrozen = true; + + try + { + // Check for 'enabled' status of input layers to Booleans. In case those layers are now disabled, unset the input. + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + int boolLayer = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.bLayerA); + if (boolLayer > -1) + { + bool activeStatus = (commonVars.getLayerSettings(boolLayer).getInt(EntropyLayerSettings.properties_i.enabled) == 1); + + if (!activeStatus) + { + commonVars.getLayerSettings(layer).setInt(EntropyLayerSettings.properties_i.bLayerA, -1); + if (layer == getSelectedLayerIndex()) + { + rB_layerBooleanA_exp[0].Checked = true; + } + checkBox_omit_lyr[boolLayer].Checked = false; + checkBox_omit_lyr[boolLayer].Enabled = false; + } + } + + boolLayer = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.bLayerB); + if (boolLayer > -1) + { + bool activeStatus = (commonVars.getLayerSettings(boolLayer).getInt(EntropyLayerSettings.properties_i.enabled) == 1); + + if (!activeStatus) + { + commonVars.getLayerSettings(layer).setInt(EntropyLayerSettings.properties_i.bLayerB, -1); + if (layer == getSelectedLayerIndex()) + { + rB_layerBooleanB_exp[0].Checked = true; + } + checkBox_omit_lyr[boolLayer].Checked = false; + checkBox_omit_lyr[boolLayer].Enabled = false; + } + } + } + } + catch (Exception) + { + + } + if (!alreadyFrozen) + { + globalUIFrozen = false; + } + } + + void setOmitLayerCheckboxes_EnableStatus() + { + bool[] bLayerStatus = new bool[CentralProperties.maxLayersForMC]; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + bLayerStatus[i] = false; + } + + // We have to scan all layers to check for boolean usage, as there may be more than one user for a given layer. + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + int layerUsedInBoolean = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.bLayerA); + if (layerUsedInBoolean > -1) + { + bLayerStatus[layerUsedInBoolean] = true; + } + layerUsedInBoolean = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.bLayerB); + if (layerUsedInBoolean > -1) + { + bLayerStatus[layerUsedInBoolean] = true; + } + } + + // Set our checkbox enabled status + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + checkBox_omit_lyr[i].Enabled = bLayerStatus[i]; + } + } + + void showDrawn_exp(int settingsIndex) + { + bool showDrawn = (bool)checkBox_Layer_ShowDrawn_exp.Checked; + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.showDrawn, showDrawn ? 1 : 0); + doShowDrawn(settingsIndex); + } + + void doShowDrawn(int settingsIndex) + { + mcVPSettings[settingsIndex].drawDrawn(commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.showDrawn) == 1); + if (!layerUIFrozen_exp) + { + updateViewport(); + } + } + + void updateGroupBoxVisibility_exp(int layer) + { + // Have to force the comboboxes here - seems to be a needed workaround as the table layout does lazy evaluation and we can't rely on these elements knowing their state. + bool alreadyFrozen = layerUIFrozen_exp; + layerUIFrozen_exp = true; + + geoGBVisible[layer] = false; + subShapeGBVisible[layer] = false; + booleanGBVisible[layer] = false; + + if ( + (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (Int32)CommonVars.shapeNames.none) && + (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (Int32)CommonVars.shapeNames.GEOCORE) && + (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shapeIndex) != (Int32)CommonVars.shapeNames.BOOLEAN) + ) + { + subShapeGBVisible[layer] = true; + } + + if (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) + { + geoGBVisible[layer] = true; + } + + if (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.BOOLEAN) + { + booleanGBVisible[layer] = true; + } + + if (subShapeGBVisible[layer]) + { + layerShapeProperties_tcPanel.Content = groupBox_layerSubShapes_exp; + setLayerPropertiesContent(ref layerShapeProperties_tcPanel); + comboBox_layerTipLocations_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shape0Tip); + comboBox_layerTipLocations2_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shape1Tip); + comboBox_layerTipLocations3_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shape2Tip); + } + else if (geoGBVisible[layer]) + { + layerShapeProperties_tcPanel.Content = groupBox_layer_geoCore_exp; + setLayerPropertiesContent(ref layerShapeProperties_tcPanel); + comboBox_layerTipLocations_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shape0Tip); + comboBox_layerPolyFill_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.fill); + try + { + comboBox_layerStructureList_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.structure); + } + catch (Exception) + { + + } + try + { + comboBox_layerLDList_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.lD); + } + catch (Exception) + { + + } + } + else if (booleanGBVisible[layer]) + { + layerShapeProperties_tcPanel.Content = groupBox_layerBoolean_exp; + setLayerPropertiesContent(ref layerShapeProperties_tcPanel); + comboBox_layerTipLocations_boolean_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.shape0Tip); + comboBox_layerBooleanOpA_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.bLayerOpA); + comboBox_layerBooleanOpAB_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.bLayerOpAB); + comboBox_layerBooleanOpB_exp.SelectedIndex = commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.bLayerOpB); + } + else + { + layerShapeProperties_tcPanel.Content = null; + setLayerPropertiesContent(ref layerShapeProperties_tcPanel); + } + + layerUIFrozen_exp = alreadyFrozen; + } + + void customRNGMappingHighlight_exp(int settingsIndex) + { + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.sCDU_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoCDUSide_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoCDUSide_exp.TextColor = SystemColors.ControlText; + } + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.tCDU_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoCDUTips_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoCDUTips_exp.TextColor = SystemColors.ControlText; + } + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.xOL_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoHorOverlay_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoHorOverlay_exp.TextColor = SystemColors.ControlText; + } + lbl_layer_lithoHorOverlay_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.xOL_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.yOL_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoVerOverlay_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoVerOverlay_exp.TextColor = SystemColors.ControlText; + } + lbl_layer_lithoVerOverlay_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.yOL_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.iCV_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoICV_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoICV_exp.TextColor = SystemColors.ControlText; + } + lbl_layer_lithoICV_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.iCV_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.oCV_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoOCV_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoOCV_exp.TextColor = SystemColors.ControlText; + } + lbl_layer_lithoOCV_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.oCV_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.wobble_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoWobble_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoWobble_exp.TextColor = SystemColors.ControlText; + } + lbl_layer_lithoWobble_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.wobble_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.hTipNVar_RNG) != CommonVars.boxMuller) + { + lbl_layerhTipNVar_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layerhTipNVar_exp.TextColor = SystemColors.ControlText; + } + lbl_layerhTipNVar_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.hTipNVar_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.hTipPVar_RNG) != CommonVars.boxMuller) + { + lbl_layerhTipPVar_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layerhTipPVar_exp.TextColor = SystemColors.ControlText; + } + lbl_layerhTipPVar_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.hTipPVar_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.vTipNVar_RNG) != CommonVars.boxMuller) + { + lbl_layervTipNVar_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layervTipNVar_exp.TextColor = SystemColors.ControlText; + } + lbl_layervTipNVar_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.vTipNVar_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.vTipPVar_RNG) != CommonVars.boxMuller) + { + lbl_layervTipPVar_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layervTipPVar_exp.TextColor = SystemColors.ControlText; + } + lbl_layervTipPVar_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.vTipPVar_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.lwr_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoLWR_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoLWR_exp.TextColor = SystemColors.ControlText; + } + lbl_layer_lithoLWR_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.lwr_RNG); + + if (commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.lwr2_RNG) != CommonVars.boxMuller) + { + lbl_layer_lithoLWR2_exp.TextColor = Color.FromArgb(MyColor.OrangeRed.toArgb()); + } + else + { + lbl_layer_lithoLWR2_exp.TextColor = SystemColors.ControlText; + } + lbl_layer_lithoLWR2_exp.ToolTip = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.lwr2_RNG); + } + } +} diff --git a/Common/Variance/UI/layerUI_setup.cs b/Common/Variance/UI/layerUI_setup.cs new file mode 100644 index 0000000..9fa5471 --- /dev/null +++ b/Common/Variance/UI/layerUI_setup.cs @@ -0,0 +1,777 @@ +using Eto.Forms; +using System; +using System.Collections.Generic; + +namespace Variance +{ + public partial class MainForm : Form + { + TableLayout layerProperties_tl; + TableCell layerProperties_tc; + + void twoD_LayerUISetup() + { + rB_layer_OLRX_exp = new RadioButton[CentralProperties.maxLayersForMC]; + rB_layer_OLRY_exp = new RadioButton[CentralProperties.maxLayersForMC]; + + rB_layer_COLX_exp = new RadioButton[CentralProperties.maxLayersForMC]; + rB_layer_COLY_exp = new RadioButton[CentralProperties.maxLayersForMC]; + + rB_layer_CCDU_exp = new RadioButton[CentralProperties.maxLayersForMC]; + rB_layer_CTCDU_exp = new RadioButton[CentralProperties.maxLayersForMC]; + + cB_layer_OLRX_Av_exp = new CheckBox[CentralProperties.maxLayersForMC]; + cB_layer_OLRY_Av_exp = new CheckBox[CentralProperties.maxLayersForMC]; + + xOLRBs_enabledState = new List(); + yOLRBs_enabledState = new List(); + + xCOLRBs_enabledState = new List(); + yCOLRBs_enabledState = new List(); + + SCDURBs_enabledState = new List(); + TCDURBs_enabledState = new List(); + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + xOLRBs_enabledState.Add(new bool[CentralProperties.maxLayersForMC]); + yOLRBs_enabledState.Add(new bool[CentralProperties.maxLayersForMC]); + + xCOLRBs_enabledState.Add(new bool[CentralProperties.maxLayersForMC]); + yCOLRBs_enabledState.Add(new bool[CentralProperties.maxLayersForMC]); + + SCDURBs_enabledState.Add(new bool[CentralProperties.maxLayersForMC]); + TCDURBs_enabledState.Add(new bool[CentralProperties.maxLayersForMC]); + } + + experiment_table = new TableLayout(); + tabPage_2D_experiment = new TabPage(); + tabPage_2D_experiment.Text = "Experiment"; + + tabPage_2D_experiment.Content = experiment_table; + + tabControl_2D_simsettings.Pages.Add(tabPage_2D_experiment); + + TableRow row0 = new TableRow(); + experiment_table.Rows.Add(row0); + + Panel p = new Panel(); + row0.Cells.Add(new TableCell() { Control = p }); + + experimental_listBox_layers = new ListBox(); + experimental_listBox_layers.Width = 55; + experimental_listBox_layers.DataContext = DataContext; + experimental_listBox_layers.BindDataContext(c => c.DataStore, (UIStringLists m) => m.layerNames); + + experimental_listBox_layers.SelectedIndexChanged += listbox_change; + + Scrollable scrollable_twoDLayer = new Scrollable(); + tabPage_2D_layer_content_exp = new TableLayout(); + scrollable_twoDLayer.Content = tabPage_2D_layer_content_exp; + + Splitter sp = new Splitter + { + Orientation = Orientation.Horizontal, + FixedPanel = SplitterFixedPanel.Panel1, + Panel1 = experimental_listBox_layers, + Panel2 = scrollable_twoDLayer, + }; + p.Content = sp; + + twoD_LayerUISetup_exp(); + } + + void twoD_LayerUISetup_exp() + { + Application.Instance.Invoke(() => + { + TableLayout tl = new TableLayout(); + Panel p = new Panel(); + p.Content = tl; + tabPage_2D_layer_content_exp.Rows.Add(new TableRow()); + tabPage_2D_layer_content_exp.Rows[0].Cells.Add(new TableCell() { Control = p }); + tabPage_2D_layer_content_exp.Rows.Add(new TableRow() { ScaleHeight = true }); + + tl.Rows.Add(new TableRow()); + TableCell topRowTC = new TableCell(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(topRowTC); + + TableLayout tl_toprow = new TableLayout(); + Panel tl_panel = new Panel() { Content = tl_toprow }; + topRowTC.Control = tl_panel; + + layerUI_topRow_setup(tl_toprow); + + // Need to inject another table here for the LOP content. + + tl.Rows.Add(new TableRow()); + Panel lop_panel = new Panel(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lop_panel }); + + TableLayout tl_lop = new TableLayout(); + lop_panel.Content = tl_lop; + + tl_lop.Rows.Add(new TableRow()); + + TableCell lopTC = new TableCell(); + tl_lop.Rows[0].Cells.Add(lopTC); + + twoD_LayerUISetup_layoutOriginParameters_exp(lopTC); + + TableCell gadgets2TC = new TableCell(); + tl_lop.Rows[0].Cells.Add(gadgets2TC); + + layerGadgets2(gadgets2TC); + + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); // padding. + + // Bias etch + + tl.Rows.Add(new TableRow()); + TableCell biasEtchTC = new TableCell(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(biasEtchTC); + twoD_LayerUISetup_biasEtch_exp(biasEtchTC); + + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); // padding. + + // Another table needs to be injected + + tl.Rows.Add(new TableRow()); + TableCell lithoTC = new TableCell(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(lithoTC); + twoD_LayerUISetup_litho_exp(lithoTC); + + // Button export + tl.Rows.Add(new TableRow()); + TableCell exportTC = new TableCell(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(exportTC); + + Panel pExportTL = new Panel(); + exportTC.Control = pExportTL; + TableLayout exportTL = new TableLayout(); + pExportTL.Content = exportTL; + exportTL.Rows.Add(new TableRow()); + + Button exportToLayout = new Button(); + exportToLayout.Text = "Export to Layout"; + exportTL.Rows[exportTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(exportToLayout) }); + exportToLayout.Click += exportActiveLayerToLayout; + + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); // padding. + }); + } + + void set_ui_from_settings(int settingsIndex) + { + Application.Instance.Invoke(() => + { + bool alreadyFrozen = layerUIFrozen_exp; + layerUIFrozen_exp = true; + + subShapeGBVisible[settingsIndex] = true; + geoGBVisible[settingsIndex] = false; + booleanGBVisible[settingsIndex] = false; + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.BOOLEAN) + { + booleanGBVisible[settingsIndex] = true; + subShapeGBVisible[settingsIndex] = false; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) + { + geoGBVisible[settingsIndex] = true; + subShapeGBVisible[settingsIndex] = false; + } + + commonVars.subShapesList_exp = commonVars.subshapes[settingsIndex]; + commonVars.structureList_exp = commonVars.structureList[settingsIndex]; + commonVars.activeStructure_LayerDataTypeList_exp = commonVars.activeStructure_LayerDataTypeList[settingsIndex]; + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.edgeSlide) == 1) + { + checkBox_layer_edgeSlide_exp.Checked = true; + num_layer_edgeSlideTension_exp.Enabled = true; + } + else + { + checkBox_layer_edgeSlide_exp.Checked = false; + checkBox_layer_edgeSlide_exp.Enabled = false; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.flipH) == 1) + { + checkBox_Layer_FlipH_exp.Checked = true; + } + else + { + checkBox_Layer_FlipH_exp.Checked = false; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.flipV) == 1) + { + checkBox_Layer_FlipV_exp.Checked = true; + } + else + { + checkBox_Layer_FlipV_exp.Checked = false; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.alignX) == 1) + { + checkBox_Layer_alignGeometryX_exp.Checked = true; + } + else + { + checkBox_Layer_alignGeometryX_exp.Checked = false; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.alignY) == 1) + { + checkBox_Layer_alignGeometryY_exp.Checked = true; + } + else + { + checkBox_Layer_alignGeometryY_exp.Checked = false; + } + + checkBox_Layer_alignGeometryX_exp.Enabled = false; + checkBox_Layer_alignGeometryY_exp.Enabled = false; + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.flipH) == 1) + { + checkBox_Layer_alignGeometryX_exp.Enabled = true; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.flipV) == 1) + { + checkBox_Layer_alignGeometryY_exp.Enabled = true; + } + + text_layerName_exp.Text = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.name); + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.enabled) == 1) + { + checkBox_Layer_exp.Checked = true; + checkBox_Layer_ShowDrawn_exp.Enabled = true; + } + else + { + checkBox_Layer_exp.Checked = false; + checkBox_Layer_ShowDrawn_exp.Enabled = false; + } + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.omit) == 1) + { + checkBox_omit_lyr[settingsIndex].Checked = true; + } + else + { + checkBox_omit_lyr[settingsIndex].Checked = false; + } + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.showDrawn) == 1) + { + checkBox_Layer_ShowDrawn_exp.Checked = true; + } + else + { + checkBox_Layer_ShowDrawn_exp.Checked = false; + } + num_layer_subshape_hl_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength); + num_layer_subshape_vl_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength); + num_layer_subshape_ho_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset); + num_layer_subshape_vo_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset); + num_layer_subshape2_hl_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength); + num_layer_subshape2_vl_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength); + num_layer_subshape2_ho_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset); + num_layer_subshape2_vo_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset); + num_layer_subshape3_hl_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength); + num_layer_subshape3_vl_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength); + num_layer_subshape3_ho_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset); + num_layer_subshape3_vo_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset); + try + { + comboBox_layerShape_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex); + } + catch (Exception) + { + } + + try + { + comboBox_layerPolyFill_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.fill); + } + catch (Exception) + { + // Don't care. + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.gCSEngine) == 1) + { + checkBox_layer_geoCore_shapeEngine_exp.Checked = true; + } + else + { + checkBox_layer_geoCore_shapeEngine_exp.Checked = false; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.perPoly) == 1) + { + checkBox_layer_geoCore_shapeEngine_perPoly_exp.Checked = true; + } + else + { + checkBox_layer_geoCore_shapeEngine_perPoly_exp.Checked = false; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.refLayout) == 1) + { + checkBox_layer_geoCore_layoutReference_exp.Checked = true; + } + else + { + checkBox_layer_geoCore_layoutReference_exp.Checked = false; + } + + if ((commonVars.getE()) || (commonVars.getL(CommonVars.l.f) != "advanced")) + { + checkBox_layer_geoCore_shapeEngine_exp.Checked = false; + checkBox_layer_geoCore_shapeEngine_exp.Enabled = false; + checkBox_layer_geoCore_shapeEngine_perPoly_exp.Checked = false; + checkBox_layer_geoCore_shapeEngine_perPoly_exp.Enabled = false; + } + + // Layout handling + textBox_layer_FileLocation_geoCore_exp.Text = commonVars.getLayerSettings(settingsIndex).getString(EntropyLayerSettings.properties_s.file); + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) + { + if (commonVars.isCopyPrepped()) + { + commonVars.pasteGeoCoreHandler(settingsIndex); + } + try + { + comboBox_layerStructureList_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure); + } + catch (Exception) + { + // Don't care. + } + try + { + comboBox_layerLDList_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD); + } + catch (Exception) + { + } + + // Enable UI elements if layout is valid/loaded. + // Block UI elements if reloaded as we don't have the layout to move to a different structure/layer-datatype. + // Need to check state of this conditional in case 'reference' is selected. + button_layer_globalApply_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid(); + comboBox_layerStructureList_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid() && !commonVars.getLayerSettings(settingsIndex).isReloaded(); + comboBox_layerLDList_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid() && !commonVars.getLayerSettings(settingsIndex).isReloaded(); + comboBox_layerTipLocations_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid(); + } + + try + { + comboBox_layerTipLocations_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shape0Tip); + comboBox_layerTipLocations_geoCore_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shape0Tip); + comboBox_layerTipLocations_boolean_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shape0Tip); + } + catch (Exception) + { + } + try + { + comboBox_layerTipLocations2_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shape1Tip); + } + catch (Exception) + { + } + try + { + comboBox_layerTipLocations3_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.shape2Tip); + } + catch (Exception) + { + } + try + { + comboBox_layerSubShapeRef_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.subShapeIndex); + } + catch (Exception) + { + } + try + { + comboBox_layerPosSubShape_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.posIndex); + } + catch (Exception) + { + } + num_layerGlobalHorOffset_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.gHorOffset); + num_layerGlobalVerOffset_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.gVerOffset); + num_layerRotation_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.rot); + num_layer_lithoWobble_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.wobble); + num_layerSidebias_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.sBias); + num_layerHTipbias_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.hTBias); + num_layerhTipPVar_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.hTPVar); + num_layerhTipNVar_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.hTNVar); + num_layerVTipbias_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.vTBias); + num_layervTipPVar_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.vTPVar); + num_layervTipNVar_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.vTNVar); + num_pitchDepBias_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.pBias); + num_pitchDepBiasIsoDistance_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.pBiasDist); + num_pitchDepBiasSideRays_exp.Value = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.proxRays); + num_layer_lithoICRR_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.iCR); + num_layer_lithoOCRR_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.oCR); + num_layer_lithoICV_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.iCV); + num_layer_lithoOCV_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.oCV); + num_layer_lithoLWR_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lwr); + num_layer_lithoLWRFreq_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lwrFreq); + num_layer_lithoLWR2_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lwr2); + num_layer_lithoLWR2Freq_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lwr2Freq); + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lwrPreview) == 1) + { + cB_layer_LWRPreview_exp.Checked = true; + } + else + { + cB_layer_LWRPreview_exp.Checked = false; + } + try + { + if ((commonVars.getE()) || (commonVars.getL(CommonVars.l.f) != "advanced")) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lwrType, (Int32)CommonVars.noiseIndex.perlin); + } + comboBox_layerLWRNoiseType_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lwrType); + } + catch (Exception) + { + } + try + { + if ((commonVars.getE()) || (commonVars.getL(CommonVars.l.f) != "advanced")) + { + commonVars.getLayerSettings(settingsIndex).setInt(EntropyLayerSettings.properties_i.lwr2Type, (Int32)CommonVars.noiseIndex.perlin); + } + comboBox_layerLWR2NoiseType_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lwr2Type); + } + catch (Exception) + { + } + + num_layer_coeff1_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lDC1); + num_layer_coeff2_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lDC2); + + num_layer_lithoCDUSide_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.sCDU); + num_layer_lithoCDUTips_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.tCDU); + num_layer_lithoHorOverlay_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.xOL); + num_layer_lithoVerOverlay_exp.Value = (double)commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.yOL); + + if (booleanGBVisible[settingsIndex]) + { + comboBox_layerBooleanOpA_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.bLayerOpA); + comboBox_layerBooleanOpB_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.bLayerOpB); + comboBox_layerBooleanOpAB_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.bLayerOpAB); + } + + updateLayerRadioButtons_exp(); + updateLayerCDURadioButtons_exp(settingsIndex); + updateLayerTCDURadioButtons_exp(settingsIndex); + updateLayerCOLXRadioButtons_exp(settingsIndex); + updateLayerCOLYRadioButtons_exp(settingsIndex); + updateLayerOLRXRadioButtons_exp(settingsIndex); + updateLayerOLRYRadioButtons_exp(settingsIndex); + updateLayerBooleanRadioButtons_exp(settingsIndex); + + comboBox_layerSubShapeRef_exp.SelectedIndex = commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.subShapeIndex); + + // Average overlay handling + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.xOL_av) == 1) + { + pnl_overlayRefX.Content = groupBox_layer_overlayXReference_Av_exp; + checkBox_layer_overlayXReference_Av_exp.Checked = true; + } + else + { + pnl_overlayRefX.Content = groupBox_layer_overlayXReference_exp; + checkBox_layer_overlayXReference_Av_exp.Checked = false; + } + + if (commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.yOL_av) == 1) + { + pnl_overlayRefY.Content = groupBox_layer_overlayYReference_Av_exp; + checkBox_layer_overlayYReference_Av_exp.Checked = true; + } + else + { + pnl_overlayRefY.Content = groupBox_layer_overlayYReference_exp; + checkBox_layer_overlayYReference_Av_exp.Checked = false; + } + + updateAverageOverlayCheckboxes_exp(settingsIndex); + + checkBox_DOELayer_geoCore_exp.Enabled = commonVars.getGeoCoreHandler(settingsIndex).isValid(); + checkBox_DOELayer_geoCore_exp.Checked = false; + if (commonVars.getGeoCoreHandler(settingsIndex).isValid()) + { + if (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(settingsIndex) == 1) + { + checkBox_DOELayer_geoCore_exp.Checked = true; + } + } + + do2DLayerUI_exp(settingsIndex, updateUI: true); + updateGroupBoxVisibility_exp(settingsIndex); + + //set_shape_type_ui(settingsIndex); + + layerUIFrozen_exp = alreadyFrozen; + + doShowDrawn(settingsIndex); + viewPort.changeSettingsRef(ref mcVPSettings[settingsIndex]); + }); + } + + void setLayerPropertiesContent(ref Panel _control) + { + try + { + layerProperties_tc.Control = _control; + } + catch (Exception) + { + } + } + + void layerUI_topRow_setup(TableLayout tl) + { + layerShapeProperties = new Panel(); + layerShapeProperties_tcPanel = new Panel(); + + tl.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + tl.Rows[0].Cells.Add(tc0); + + layerGadgets_setup(tc0); + + TableCell tc1 = new TableCell(); + + tl.Rows[0].Cells.Add(tc1); + + layerProperties_tl = new TableLayout(); + layerProperties_tc = new TableCell(); + layerProperties_tl.Rows.Add(new TableRow()); + layerProperties_tl.Rows[0].Cells.Add(layerProperties_tc); + + layerShapeProperties.Content = layerProperties_tl; + + tc1.Control = layerShapeProperties; + + twoD_LayerUISetup_boolean_exp(); + + + twoD_LayerUISetup_subShape_exp(); + + twoD_LayerUISetup_geoCore_exp(); + } + + void layerGadgets_setup(TableCell tc) + { + TableLayout layerGadgets_table = new TableLayout(); + + layerGadgets_table.Rows.Add(new TableRow()); + + layerGadgets_row1(layerGadgets_table); + layerGadgets_row2(layerGadgets_table); + layerGadgets_row3(layerGadgets_table); + + Panel p = new Panel(); + p.Content = layerGadgets_table; + tc.Control = p; + } + + void layerGadgets_row1(TableLayout layerGadgets_table) + { + // Outer table, row 1 + TableRow gadgets_tr0 = new TableRow(); + layerGadgets_table.Rows.Add(gadgets_tr0); + gadgets_tr0.Cells.Add(new TableCell()); + + // Table layout within row 1 + TableLayout row0_tl = new TableLayout(); + gadgets_tr0.Cells[0].Control = row0_tl; + row0_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell gadgets_tr0_0 = new TableCell(); + row0_tl.Rows[0].Cells.Add(gadgets_tr0_0); + + TableLayout gadgets_tr0_0_tl = new TableLayout(); + gadgets_tr0_0.Control = gadgets_tr0_0_tl; + + gadgets_tr0_0_tl.Rows.Add(new TableRow()); + + checkBox_Layer_exp = new CheckBox(); + checkBox_Layer_exp.Text = "Enabled"; + checkBox_Layer_exp.ToolTip = "If checked, include the layer in the simulation"; + gadgets_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = checkBox_Layer_exp }); + + text_layerName_exp = new TextBox(); + text_layerName_exp.ToolTip = "Layer name. If blank, the layer number will be used"; + gadgets_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = text_layerName_exp }); + gadgets_tr0_0_tl.Rows[0].Cells[gadgets_tr0_0_tl.Rows[0].Cells.Count - 1].ScaleWidth = true; + } + + void layerGadgets_row2(TableLayout layerGadgets_table) + { + // Outer table, row 2 + TableRow gadgets_tr1 = new TableRow(); + layerGadgets_table.Rows.Add(gadgets_tr1); + gadgets_tr1.Cells.Add(new TableCell()); + + // Table layout within row 2 + TableLayout row1_tl = new TableLayout(); + gadgets_tr1.Cells[0].Control = row1_tl; + row1_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell gadgets_tr1_0 = new TableCell(); + row1_tl.Rows[0].Cells.Add(gadgets_tr1_0); + + TableLayout gadgets_tr1_0_tl = new TableLayout(); + gadgets_tr1_0.Control = gadgets_tr1_0_tl; + + gadgets_tr1_0_tl.Rows.Add(new TableRow()); + + comboBox_layerShape_exp = new DropDown(); + comboBox_layerShape_exp.DataContext = DataContext; + comboBox_layerShape_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.shapes); + comboBox_layerShape_exp.SelectedIndex = 0; + comboBox_layerShape_exp.ToolTip = "Type of shape to generate"; + gadgets_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = comboBox_layerShape_exp }); + } + + void layerGadgets_row3(TableLayout layerGadgets_table) + { + // Outer table, row 3 + TableRow gadgets_tr2 = new TableRow(); + layerGadgets_table.Rows.Add(gadgets_tr2); + gadgets_tr2.Cells.Add(new TableCell()); + + // Table layout within row 3 + TableLayout row2_tl = new TableLayout(); + gadgets_tr2.Cells[0].Control = row2_tl; + row2_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell gadgets_tr2_0 = new TableCell(); + row2_tl.Rows[0].Cells.Add(gadgets_tr2_0); + + TableLayout gadgets_tr2_0_tl = new TableLayout(); + gadgets_tr2_0.Control = gadgets_tr2_0_tl; + + gadgets_tr2_0_tl.Rows.Add(new TableRow()); + + checkBox_layer_edgeSlide_exp = new CheckBox(); + checkBox_layer_edgeSlide_exp.Text = "Edge Slide"; + checkBox_layer_edgeSlide_exp.Width = 90; + checkBox_layer_edgeSlide_exp.ToolTip = "If checked, apply tension to each edge for the contour generation"; + gadgets_tr2_0_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(checkBox_layer_edgeSlide_exp) }); + if (EntropyLayerSettings.getDefaultInt(EntropyLayerSettings.properties_i.edgeSlide) == 1) + { + checkBox_layer_edgeSlide_exp.Checked = true; + } + + lbl_layer_edgeSlideTension_exp = new Label(); + lbl_layer_edgeSlideTension_exp.Text = "Tension"; + lbl_layer_edgeSlideTension_exp.Width = 50; + lbl_layer_edgeSlideTension_exp.ToolTip = "Amount of tension to apply, to pull the midpoint towards the longer edge"; + gadgets_tr2_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_edgeSlideTension_exp }); + gadgets_tr2_0_tl.Rows[0].Cells[gadgets_tr2_0_tl.Rows[0].Cells.Count - 1].ScaleWidth = true; + + num_layer_edgeSlideTension_exp = new NumericStepper(); + num_layer_edgeSlideTension_exp.DecimalPlaces = 2; + num_layer_edgeSlideTension_exp.Increment = 0.1; + num_layer_edgeSlideTension_exp.Value = (double)EntropyLayerSettings.getDefaultDecimal(EntropyLayerSettings.properties_decimal.eTension); + num_layer_edgeSlideTension_exp.MinValue = 0.01; + setSize(num_layer_edgeSlideTension_exp, 55, num_Height); + num_layer_edgeSlideTension_exp.ToolTip = "Amount of tension to apply, to pull the midpoint towards the longer edge"; + gadgets_tr2_0_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_edgeSlideTension_exp) }); + num_layer_edgeSlideTension_exp.Enabled = true; + + if (EntropyLayerSettings.getDefaultInt(EntropyLayerSettings.properties_i.edgeSlide) == 0) + { + num_layer_edgeSlideTension_exp.Enabled = false; + } + } + + void layerGadgets2(TableCell tc) + { + TableLayout layerGadgets2_table = new TableLayout(); + layerGadgets2_table.Rows.Add(new TableRow()); + + layerGadgets2_row1(layerGadgets2_table); + + Panel p = new Panel(); + p.Content = layerGadgets2_table; + tc.Control = p; + } + + void layerGadgets2_row1(TableLayout layerGadgets2_table) + { + // Outer table, row 2 + TableRow gadgets_tr1 = new TableRow(); + layerGadgets2_table.Rows.Add(gadgets_tr1); + gadgets_tr1.Cells.Add(new TableCell()); + + // Table layout within row 2 + TableLayout row1_tl = new TableLayout(); + gadgets_tr1.Cells[0].Control = row1_tl; + row1_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell gadgets_tr1_0 = new TableCell(); + row1_tl.Rows[0].Cells.Add(gadgets_tr1_0); + + TableLayout gadgets_tr1_0_tl = new TableLayout(); + gadgets_tr1_0.Control = TableLayout.AutoSized(gadgets_tr1_0_tl); + + TableLayout flipAign_tl = new TableLayout(); + flipAign_tl.Rows.Add(new TableRow()); + + checkBox_Layer_FlipH_exp = new CheckBox(); + checkBox_Layer_FlipH_exp.Text = "Flip H"; + checkBox_Layer_FlipH_exp.ToolTip = "Flip shape horizontally"; + flipAign_tl.Rows[flipAign_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_Layer_FlipH_exp }); + + checkBox_Layer_alignGeometryX_exp = new CheckBox(); + checkBox_Layer_alignGeometryX_exp.Text = "Align X"; + checkBox_Layer_alignGeometryX_exp.ToolTip = "Centers the flipped shape on the non-flipped shape in X"; + flipAign_tl.Rows[flipAign_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_Layer_alignGeometryX_exp }); + + flipAign_tl.Rows.Add(new TableRow()); + + checkBox_Layer_FlipV_exp = new CheckBox(); + checkBox_Layer_FlipV_exp.Text = "Flip V"; + checkBox_Layer_FlipV_exp.ToolTip = "Flip shape vertically"; + flipAign_tl.Rows[flipAign_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_Layer_FlipV_exp }); + + checkBox_Layer_alignGeometryY_exp = new CheckBox(); + checkBox_Layer_alignGeometryY_exp.Text = "Align Y"; + checkBox_Layer_alignGeometryY_exp.ToolTip = "Centers the flipped shape on the non-flipped shape in Y"; + flipAign_tl.Rows[flipAign_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_Layer_alignGeometryY_exp }); + + gadgets_tr1_0_tl.Rows.Add(new TableRow()); + gadgets_tr1_0_tl.Rows[gadgets_tr1_0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(flipAign_tl) }); + + gadgets_tr1_0_tl.Rows.Add(new TableRow()); + + checkBox_Layer_ShowDrawn_exp = new CheckBox(); + checkBox_Layer_ShowDrawn_exp.Text = "Show Drawn"; + checkBox_Layer_ShowDrawn_exp.ToolTip = "Show drawn shape for the contour"; + gadgets_tr1_0_tl.Rows[gadgets_tr1_0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_Layer_ShowDrawn_exp }); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/layerUI_setup_bias.cs b/Common/Variance/UI/layerUI_setup_bias.cs new file mode 100644 index 0000000..a5bfb70 --- /dev/null +++ b/Common/Variance/UI/layerUI_setup_bias.cs @@ -0,0 +1,237 @@ +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm : Form + { + // 2D Layer Bias Etch + GroupBox groupBox_layer_etchandbias_exp; + NumericStepper num_layerSidebias_exp, num_layerHTipbias_exp, num_layerVTipbias_exp, num_layerhTipNVar_exp, num_layervTipNVar_exp, num_layerhTipPVar_exp, num_layervTipPVar_exp, + num_pitchDepBias_exp, num_pitchDepBiasIsoDistance_exp, num_pitchDepBiasSideRays_exp; + Label lbl_layerSidebias_exp, lbl_layerHTipbias_exp, lbl_layerVTipbias_exp, lbl_layerhTipNVar_exp, lbl_layervTipNVar_exp, lbl_layerhTipPVar_exp, lbl_layervTipPVar_exp, + lbl_pitchDepBias_exp, lbl_pitchDepBiasIsoDistance_exp, lbl_pitchDepBiasSideRays_exp; + + void twoD_LayerUISetup_biasEtch_exp(TableCell tc) + { + Application.Instance.Invoke(() => + { + groupBox_layer_etchandbias_exp = new GroupBox(); + groupBox_layer_etchandbias_exp.Text = "Bias and Etch Parameters"; + TableLayout groupBox_layer_etchandbias_table = new TableLayout(); + groupBox_layer_etchandbias_exp.Content = groupBox_layer_etchandbias_table; + + TableLayout t = new TableLayout(); + t.Rows.Add(new TableRow()); + t.Rows[0].Cells.Add(new TableCell() { Control = groupBox_layer_etchandbias_exp }); + t.Rows[0].Cells.Add(new TableCell() { Control = new Panel(), ScaleWidth = true }); + + Panel p = new Panel(); + p.Content = t; + tc.Control = p; + + bias_row1(groupBox_layer_etchandbias_table); + bias_row2(groupBox_layer_etchandbias_table); + + }); + } + + void bias_row1(TableLayout groupBox_layer_etchandbias_table) + { + // Outer table, row 1 + TableRow biasEtch_tr0 = new TableRow(); + groupBox_layer_etchandbias_table.Rows.Add(biasEtch_tr0); + biasEtch_tr0.Cells.Add(new TableCell()); + + // Table layout within row 1 + TableLayout row0_tl = new TableLayout(); + biasEtch_tr0.Cells[0].Control = row0_tl; + row0_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell biasEtch_tr0_0 = new TableCell(); + row0_tl.Rows[0].Cells.Add(biasEtch_tr0_0); + + TableLayout biasEtch_tr0_0_tl = new TableLayout(); + biasEtch_tr0_0.Control = biasEtch_tr0_0_tl; + + biasEtch_tr0_0_tl.Rows.Add(new TableRow()); + + lbl_layerSidebias_exp = new Label(); + lbl_layerSidebias_exp.Text = "Side Bias (Edge)"; + lbl_layerSidebias_exp.Width = 90; + lbl_layerSidebias_exp.ToolTip = "Bias applied to each edge that is not defined as a tip."; + biasEtch_tr0_0_tl.Rows[0].Cells.Add(new TableCell()); + biasEtch_tr0_0_tl.Rows[0].Cells[0].Control = lbl_layerSidebias_exp; + + num_layerSidebias_exp = new NumericStepper(); + num_layerSidebias_exp.Increment = 0.1; + num_layerSidebias_exp.DecimalPlaces = 2; + num_layerSidebias_exp.ToolTip = "Bias applied to each edge that is not defined as a tip."; + setSize(num_layerSidebias_exp, 55, num_Height); + biasEtch_tr0_0_tl.Rows[0].Cells.Add(new TableCell()); + biasEtch_tr0_0_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layerSidebias_exp); + + bias_row1_2(biasEtch_tr0_0_tl); + } + + void bias_row1_2(TableLayout outerTable) + { + TableLayout nestedTable = new TableLayout(); + outerTable.Rows[0].Cells.Add(new TableCell() { Control = nestedTable }); + + nestedTable.Rows.Add(new TableRow()); + + lbl_layerHTipbias_exp = new Label(); + lbl_layerHTipbias_exp.Text = "Horizontal tip bias"; + lbl_layerHTipbias_exp.ToolTip = "Bias applied to each subshape edge that is a left or right tip."; + nestedTable.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerHTipbias_exp }); + + num_layerHTipbias_exp = new NumericStepper(); + num_layerHTipbias_exp.Increment = 0.1; + num_layerHTipbias_exp.DecimalPlaces = 2; + num_layerHTipbias_exp.ToolTip = "Bias applied to each subshape edge that is a left or right tip."; + setSize(num_layerHTipbias_exp, 55, num_Height); + nestedTable.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layerHTipbias_exp) }); + + lbl_layerhTipPVar_exp = new Label(); + lbl_layerhTipPVar_exp.Text = "Var +"; + lbl_layerhTipPVar_exp.MouseDoubleClick += hTipPVar_RNG; + lbl_layerhTipPVar_exp.ToolTip = "Positive 3-sigma bias variation for left/right tips."; + nestedTable.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerhTipPVar_exp }); + + num_layerhTipPVar_exp = new NumericStepper(); + num_layerhTipPVar_exp.Increment = 0.1; + num_layerhTipPVar_exp.DecimalPlaces = 2; + num_layerhTipPVar_exp.MinValue = 0; + num_layerhTipPVar_exp.ToolTip = "Positive 3-sigma bias variation for left/right tips."; + setSize(num_layerhTipPVar_exp, 55, num_Height); + nestedTable.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layerhTipPVar_exp) }); + + lbl_layerhTipNVar_exp = new Label(); + lbl_layerhTipNVar_exp.Text = "-"; + lbl_layerhTipNVar_exp.MouseDoubleClick += hTipNVar_RNG; + lbl_layerhTipNVar_exp.ToolTip = "Negative 3-sigma bias variation for left/right tips."; + nestedTable.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerhTipNVar_exp }); + + num_layerhTipNVar_exp = new NumericStepper(); + num_layerhTipNVar_exp.Increment = 0.1; + num_layerhTipNVar_exp.DecimalPlaces = 2; + num_layerhTipNVar_exp.MinValue = 0; + num_layerhTipNVar_exp.ToolTip = "Negative 3-sigma bias variation for left/right tips."; + setSize(num_layerhTipNVar_exp, 55, num_Height); + nestedTable.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layerhTipNVar_exp) }); + + nestedTable.Rows[0].Cells.Add(new TableCell() { Control = null }); + + nestedTable.Rows.Add(new TableRow()); + + lbl_layerVTipbias_exp = new Label(); + lbl_layerVTipbias_exp.Text = "Vertical tip bias"; + lbl_layerVTipbias_exp.ToolTip = "Bias applied to each subshape edge that is a top or bottom tip."; + nestedTable.Rows[1].Cells.Add(new TableCell() { Control = lbl_layerVTipbias_exp }); + + num_layerVTipbias_exp = new NumericStepper(); + num_layerVTipbias_exp.Increment = 0.1; + num_layerVTipbias_exp.DecimalPlaces = 2; + num_layerVTipbias_exp.ToolTip = "Bias applied to each subshape edge that is a top or bottom tip."; + setSize(num_layerVTipbias_exp, 55, num_Height); + nestedTable.Rows[1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layerVTipbias_exp) }); + + lbl_layervTipPVar_exp = new Label(); + lbl_layervTipPVar_exp.Text = "Var +"; + lbl_layervTipPVar_exp.MouseDoubleClick += vTipPVar_RNG; + lbl_layervTipPVar_exp.ToolTip = "Positive 3-sigma bias variation for top/bottom tips."; + nestedTable.Rows[1].Cells.Add(new TableCell() { Control = lbl_layervTipPVar_exp }); + + num_layervTipPVar_exp = new NumericStepper(); + num_layervTipPVar_exp.Increment = 0.1; + num_layervTipPVar_exp.DecimalPlaces = 2; + num_layervTipPVar_exp.MinValue = 0; + num_layervTipPVar_exp.ToolTip = "Positive 3-sigma bias variation for top/bottom tips."; + setSize(num_layervTipPVar_exp, 55, num_Height); + nestedTable.Rows[1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layervTipPVar_exp) }); + + lbl_layervTipNVar_exp = new Label(); + lbl_layervTipNVar_exp.Text = "-"; + lbl_layervTipNVar_exp.MouseDoubleClick += vTipNVar_RNG; + lbl_layervTipNVar_exp.ToolTip = "Negative 3-sigma bias variation for top/bottom tips."; + nestedTable.Rows[1].Cells.Add(new TableCell() { Control = lbl_layervTipNVar_exp }); + + num_layervTipNVar_exp = new NumericStepper(); + num_layervTipNVar_exp.Increment = 0.1; + num_layervTipNVar_exp.DecimalPlaces = 2; + num_layervTipNVar_exp.MinValue = 0; + num_layervTipNVar_exp.ToolTip = "Negative 3-sigma bias variation for top/bottom tips."; + setSize(num_layervTipNVar_exp, 55, num_Height); + nestedTable.Rows[1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layervTipNVar_exp) }); + + nestedTable.Rows[1].Cells.Add(new TableCell() { Control = null }); + } + + void bias_row2(TableLayout groupBox_layer_etchandbias_table) + { + // Outer table, row 2 + TableRow biasEtch_tr1 = new TableRow(); + groupBox_layer_etchandbias_table.Rows.Add(biasEtch_tr1); + biasEtch_tr1.Cells.Add(new TableCell()); + + // Table layout within row 2 + TableLayout row1_tl = new TableLayout(); + biasEtch_tr1.Cells[0].Control = row1_tl; + row1_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell biasEtch_tr1_0 = new TableCell(); + row1_tl.Rows[0].Cells.Add(biasEtch_tr1_0); + + TableLayout biasEtch_tr1_0_tl = new TableLayout(); + biasEtch_tr1_0.Control = biasEtch_tr1_0_tl; + + biasEtch_tr1_0_tl.Rows.Add(new TableRow()); + + lbl_pitchDepBias_exp = new Label(); + lbl_pitchDepBias_exp.Text = "Proximity bias"; + lbl_pitchDepBias_exp.Width = 90; + lbl_pitchDepBias_exp.ToolTip = "Maximum bias to be applied to edges based on visibility-based space to nearest edges."; + biasEtch_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_pitchDepBias_exp }); + + num_pitchDepBias_exp = new NumericStepper(); + num_pitchDepBias_exp.Increment = 0.1; + num_pitchDepBias_exp.DecimalPlaces = 2; + num_pitchDepBias_exp.ToolTip = "Maximum bias to be applied to edges based on visibility-based space to nearest edges."; + setSize(num_pitchDepBias_exp, 55, num_Height); + biasEtch_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_pitchDepBias_exp) }); + + lbl_pitchDepBiasIsoDistance_exp = new Label(); + lbl_pitchDepBiasIsoDistance_exp.Text = "Isolated edge distance"; + lbl_pitchDepBiasIsoDistance_exp.Width = 150; + lbl_pitchDepBiasIsoDistance_exp.ToolTip = "Distance from nearest feature (in-layer) when edge is considered isolated and gets full proximity-dependent bias applied."; + biasEtch_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_pitchDepBiasIsoDistance_exp }); + + num_pitchDepBiasIsoDistance_exp = new NumericStepper(); + num_pitchDepBiasIsoDistance_exp.Increment = 0.1; + num_pitchDepBiasIsoDistance_exp.DecimalPlaces = 2; + num_pitchDepBiasIsoDistance_exp.ToolTip = "Distance from nearest feature (in-layer) when edge is considered isolated and gets full proximity-dependent bias applied."; + setSize(num_pitchDepBiasIsoDistance_exp, 55, num_Height); + biasEtch_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_pitchDepBiasIsoDistance_exp) }); + + lbl_pitchDepBiasSideRays_exp = new Label(); + lbl_pitchDepBiasSideRays_exp.Text = "Side Rays"; + lbl_pitchDepBiasSideRays_exp.Width = 80; + lbl_pitchDepBiasSideRays_exp.ToolTip = "Number of additional rays to fire each side of main ray."; + biasEtch_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_pitchDepBiasSideRays_exp }); + + num_pitchDepBiasSideRays_exp = new NumericStepper(); + num_pitchDepBiasSideRays_exp.Increment = 1; + num_pitchDepBiasSideRays_exp.MinValue = 0; + num_pitchDepBiasSideRays_exp.Value = 2; + num_pitchDepBiasSideRays_exp.DecimalPlaces = 0; + num_pitchDepBiasSideRays_exp.ToolTip = "Number of additional rays to fire each side of main ray."; + setSize(num_pitchDepBiasSideRays_exp, 55, num_Height); + biasEtch_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_pitchDepBiasSideRays_exp) }); + + biasEtch_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = new Panel() }); + biasEtch_tr1_0_tl.Rows[0].Cells[biasEtch_tr1_0_tl.Rows[0].Cells.Count - 1].ScaleWidth = true; + } + } +} diff --git a/Common/Variance/UI/layerUI_setup_boolean.cs b/Common/Variance/UI/layerUI_setup_boolean.cs new file mode 100644 index 0000000..07836dd --- /dev/null +++ b/Common/Variance/UI/layerUI_setup_boolean.cs @@ -0,0 +1,200 @@ +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm : Form + { + // 2D Layer Boolean + GroupBox groupBox_layerBoolean_exp; + DropDown comboBox_layerBooleanOpAB_exp, comboBox_layerBooleanOpA_exp, comboBox_layerBooleanOpB_exp, comboBox_layerTipLocations_boolean_exp; + RadioButton[] rB_layerBooleanA_exp, rB_layerBooleanB_exp; + Label lbl_layerTipLocations_boolean_exp; + + void twoD_LayerUISetup_boolean_exp() + { + Application.Instance.Invoke(() => + { + groupBox_layerBoolean_exp = new GroupBox(); + TableLayout groupBox_layerBoolean_table = new TableLayout(); + groupBox_layerBoolean_exp.Content = groupBox_layerBoolean_table; + groupBox_layerBoolean_exp.Text = "Boolean"; + + rB_layerBooleanA_exp = new RadioButton[CentralProperties.maxLayersForMC]; + rB_layerBooleanB_exp = new RadioButton[CentralProperties.maxLayersForMC]; + + boolean_table(groupBox_layerBoolean_table); + + layerShapeProperties_tcPanel.Content = groupBox_layerBoolean_exp; + + setLayerPropertiesContent(ref layerShapeProperties_tcPanel); + }); + } + + void boolean_table(TableLayout groupBox_layerBoolean_table) + { + // Outer table, row 1 + TableRow boolean_tr0 = new TableRow(); + groupBox_layerBoolean_table.Rows.Add(boolean_tr0); + boolean_tr0.Cells.Add(new TableCell()); + + // Table layout within row 1 + TableLayout row0_tl = new TableLayout(); + boolean_tr0.Cells[0].Control = row0_tl; + row0_tl.Rows.Add(new TableRow()); + + boolean_row0(row0_tl); + + // Outer table, row 2 + TableRow boolean_tr1 = new TableRow(); + groupBox_layerBoolean_table.Rows.Add(boolean_tr1); + + // Table layout within row 2 + TableLayout row1_tl = new TableLayout(); + boolean_tr1.Cells.Add(new TableCell() { Control = row1_tl }); + row1_tl.Rows.Add(new TableRow()); + + boolean_row1(row1_tl); + + // Outer table, row 3 + TableRow boolean_tr2 = new TableRow(); + groupBox_layerBoolean_table.Rows.Add(boolean_tr2); + + // Table layout within row 3 + TableLayout row2_tl = new TableLayout(); + boolean_tr2.Cells.Add(new TableCell() { Control = row2_tl }); + row2_tl.Rows.Add(new TableRow()); + + boolean_row2(row2_tl); + + // Outer table, row 4 + TableRow boolean_tr3 = new TableRow(); + groupBox_layerBoolean_table.Rows.Add(boolean_tr3); + + // Table layout within row 4 + TableLayout row3_tl = new TableLayout(); + boolean_tr3.Cells.Add(new TableCell() { Control = row3_tl }); + row3_tl.Rows.Add(new TableRow()); + + boolean_row3(row3_tl); + } + + void boolean_row0(TableLayout row0_tl) + { + row0_tl.Rows.Add(new TableRow()); + + comboBox_layerBooleanOpA_exp = new DropDown(); + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(comboBox_layerBooleanOpA_exp) }); + comboBox_layerBooleanOpA_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.notList); + + Panel p = new Panel(); + TableLayout boolATable = new TableLayout(); + p.Content = boolATable; + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = p }); + + TableRow boolA_tr0 = new TableRow(); + boolATable.Rows.Add(boolA_tr0); + TableRow boolA_tr1 = new TableRow(); + boolATable.Rows.Add(boolA_tr1); + + rB_layerBooleanA_exp[0] = new RadioButton(); + rB_layerBooleanA_exp[0].Text = "0"; + rB_layerBooleanA_exp[0].Checked = true; + + TableCell rB_boolA_0tc = new TableCell(); + rB_boolA_0tc.Control = rB_layerBooleanA_exp[0]; + + boolATable.Rows[0].Cells.Add(rB_boolA_0tc); + + int button = 1; + int rowIndex = 0; + for (int rb = 1; rb < CentralProperties.maxLayersForMC; rb++) + { + rB_layerBooleanA_exp[button] = new RadioButton(rB_layerBooleanA_exp[0]); + rB_layerBooleanA_exp[button].Text = button.ToString(); + rB_layerBooleanA_exp[button].Checked = false; + TableCell tc0 = new TableCell(); + tc0.Control = rB_layerBooleanA_exp[button]; + boolATable.Rows[rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (button + 1 == CentralProperties.maxLayersForMC / 2) + { + rowIndex++; + } + button++; + } + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + } + + void boolean_row1(TableLayout row1_tl) + { + row1_tl.Rows.Add(new TableRow()); + + comboBox_layerBooleanOpAB_exp = new DropDown(); + row1_tl.Rows[row1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(comboBox_layerBooleanOpAB_exp) }); + comboBox_layerBooleanOpAB_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.booleanList); + + row1_tl.Rows[row1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + } + + void boolean_row2(TableLayout row2_tl) + { + row2_tl.Rows.Add(new TableRow()); + + comboBox_layerBooleanOpB_exp = new DropDown(); + row2_tl.Rows[row2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(comboBox_layerBooleanOpB_exp) }); + comboBox_layerBooleanOpB_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.notList); + + Panel p = new Panel(); + TableLayout boolBTable = new TableLayout(); + p.Content = boolBTable; + row2_tl.Rows[row2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = p }); + + TableRow boolB_tr0 = new TableRow(); + boolBTable.Rows.Add(boolB_tr0); + TableRow boolB_tr1 = new TableRow(); + boolBTable.Rows.Add(boolB_tr1); + + rB_layerBooleanB_exp[0] = new RadioButton(); + rB_layerBooleanB_exp[0].Text = "0"; + rB_layerBooleanB_exp[0].Checked = true; + + TableCell rB_boolB_0tc = new TableCell(); + rB_boolB_0tc.Control = rB_layerBooleanB_exp[0]; + + boolBTable.Rows[0].Cells.Add(rB_boolB_0tc); + + int button = 1; + int rowIndex = 0; + for (int rb = 1; rb < CentralProperties.maxLayersForMC; rb++) + { + rB_layerBooleanB_exp[button] = new RadioButton(rB_layerBooleanB_exp[0]); + rB_layerBooleanB_exp[button].Text = button.ToString(); + rB_layerBooleanB_exp[button].Checked = false; + TableCell tc0 = new TableCell(); + tc0.Control = rB_layerBooleanB_exp[button]; + boolBTable.Rows[rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (button + 1 == CentralProperties.maxLayersForMC / 2) + { + rowIndex++; + } + button++; + } + row2_tl.Rows[row2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + } + + void boolean_row3(TableLayout row3_tl) + { + row3_tl.Rows.Add(new TableRow()); + + lbl_layerTipLocations_boolean_exp = new Label(); + lbl_layerTipLocations_boolean_exp.Text = "Tip Locs"; + row3_tl.Rows[row3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTipLocations_boolean_exp }); + + comboBox_layerTipLocations_boolean_exp = new DropDown(); + row3_tl.Rows[row3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(comboBox_layerTipLocations_boolean_exp) }); + comboBox_layerTipLocations_boolean_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.tipLocs); + row3_tl.Rows[row3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + } + } +} diff --git a/Common/Variance/UI/layerUI_setup_geocore.cs b/Common/Variance/UI/layerUI_setup_geocore.cs new file mode 100644 index 0000000..73b5fc2 --- /dev/null +++ b/Common/Variance/UI/layerUI_setup_geocore.cs @@ -0,0 +1,201 @@ +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm : Form + { + // 2D Layer GeoCore + GroupBox groupBox_layer_lithography_exp; + GroupBox groupBox_layer_geoCore_exp; + Button button_layer_chooseFile_geoCore_exp, button_layer_globalApply_geoCore_exp; + DropDown comboBox_layerLDList_geoCore_exp, comboBox_layerStructureList_geoCore_exp, comboBox_layerPolyFill_geoCore_exp, comboBox_layerTipLocations_geoCore_exp; + Label lbl_layerLD_geoCore_exp, lbl_layerCell_geoCore_exp, lbl_layerTipLocations_geoCore_exp; + TextBox textBox_layer_FileLocation_geoCore_exp; + CheckBox checkBox_DOELayer_geoCore_exp, checkBox_layer_geoCore_shapeEngine_exp, checkBox_layer_geoCore_shapeEngine_perPoly_exp, checkBox_layer_geoCore_layoutReference_exp; + + void twoD_LayerUISetup_geoCore_exp() + { + Application.Instance.Invoke(() => + { + groupBox_layer_geoCore_exp = new GroupBox(); + TableLayout groupBox_layer_geoCore_table = new TableLayout(); + groupBox_layer_geoCore_exp.Content = groupBox_layer_geoCore_table; + groupBox_layer_geoCore_exp.Text = "Layout Controls"; + + geocore_table(groupBox_layer_geoCore_table); + + layerShapeProperties_tcPanel.Content = groupBox_layer_geoCore_exp; + + setLayerPropertiesContent(ref layerShapeProperties_tcPanel); + }); + } + + void geocore_table(TableLayout groupBox_layer_geoCore_table) + { + // Outer table, row 1 + TableRow geocore_tr0 = new TableRow(); + groupBox_layer_geoCore_table.Rows.Add(geocore_tr0); + geocore_tr0.Cells.Add(new TableCell()); + + geocore_row0(geocore_tr0.Cells[0]); + + TableRow geocore_tr1 = new TableRow(); + groupBox_layer_geoCore_table.Rows.Add(geocore_tr1); + geocore_tr1.Cells.Add(new TableCell()); + + geocore_row1(geocore_tr1.Cells[0]); + } + + void geocore_row0(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; + + TableLayout tl = new TableLayout(); + p.Content = tl; + + tl.Rows.Add(new TableRow()); + + TableCell tr0_0 = new TableCell(); + tl.Rows[0].Cells.Add(tr0_0); + + geocore_row0_0(tr0_0); + + TableCell tr0_1 = new TableCell(); + tl.Rows[0].Cells.Add(tr0_1); + + geocore_row0_1(tr0_1); + } + + void geocore_row0_0(TableCell tc) + { + TableLayout tl = new TableLayout(); + Panel p = new Panel(); + p.Content = tl; + + tc.Control = p; + + TableRow tr0 = new TableRow(); + tl.Rows.Add(tr0); + + TableLayout tr0_tl = new TableLayout(); + tr0.Cells.Add(new TableCell() { Control = tr0_tl }); + tr0_tl.Rows.Add(new TableRow()); + + button_layer_chooseFile_geoCore_exp = new Button(); + button_layer_chooseFile_geoCore_exp.Text = "Choose File"; + button_layer_chooseFile_geoCore_exp.ToolTip = "Browse for GDS or Oasis file"; + tr0_tl.Rows[0].Cells.Add(new TableCell() { Control = button_layer_chooseFile_geoCore_exp }); + + checkBox_DOELayer_geoCore_exp = new CheckBox(); + checkBox_DOELayer_geoCore_exp.Text = "DOE"; + checkBox_DOELayer_geoCore_exp.Width = 60; + checkBox_DOELayer_geoCore_exp.ToolTip = "This is a DOE layout, to be used with tile extraction."; + tr0_tl.Rows[0].Cells.Add(new TableCell() { Control = checkBox_DOELayer_geoCore_exp }); + + checkBox_layer_geoCore_shapeEngine_exp = new CheckBox(); + checkBox_layer_geoCore_shapeEngine_exp.Text = "Contour"; + checkBox_layer_geoCore_shapeEngine_exp.Width = 75; + checkBox_layer_geoCore_shapeEngine_exp.ToolTip = "Use layout polygons as inputs for contour generation"; + tr0_tl.Rows[0].Cells.Add(new TableCell() { Control = checkBox_layer_geoCore_shapeEngine_exp }); + + checkBox_layer_geoCore_shapeEngine_perPoly_exp = new CheckBox(); + checkBox_layer_geoCore_shapeEngine_perPoly_exp.Text = "Per-Poly"; + checkBox_layer_geoCore_shapeEngine_perPoly_exp.Width = 75; + checkBox_layer_geoCore_shapeEngine_perPoly_exp.ToolTip = "Rotation per-polyon"; + tr0_tl.Rows[0].Cells.Add(new TableCell() { Control = checkBox_layer_geoCore_shapeEngine_perPoly_exp }); + + TableRow tr1 = new TableRow(); + tl.Rows.Add(tr1); + + TableLayout tr1_tl = new TableLayout(); + tr1.Cells.Add(new TableCell() { Control = tr1_tl }); + tr1_tl.Rows.Add(new TableRow()); + + button_layer_globalApply_geoCore_exp = new Button(); + button_layer_globalApply_geoCore_exp.Text = "Apply To All"; + button_layer_globalApply_geoCore_exp.ToolTip = "Use this geoCore input in all layers of the simulation."; + tr1_tl.Rows[0].Cells.Add(new TableCell() { Control = button_layer_globalApply_geoCore_exp }); + + checkBox_layer_geoCore_layoutReference_exp = new CheckBox(); + checkBox_layer_geoCore_layoutReference_exp.Text = "Reference"; + checkBox_layer_geoCore_layoutReference_exp.Width = 75; + checkBox_layer_geoCore_layoutReference_exp.ToolTip = "Reference the layout file"; + tr1_tl.Rows[0].Cells.Add(new TableCell() { Control = checkBox_layer_geoCore_layoutReference_exp }); + + tr1_tl.Rows[0].Cells.Add(new TableCell() { ScaleWidth = true }); + + TableRow tr2 = new TableRow(); + tl.Rows.Add(tr2); + + TableLayout tr2_tl = new TableLayout(); + tr2.Cells.Add(new TableCell() { Control = tr2_tl }); + tr2_tl.Rows.Add(new TableRow()); + + comboBox_layerPolyFill_geoCore_exp = new DropDown(); + comboBox_layerPolyFill_geoCore_exp.Width = 88; + comboBox_layerPolyFill_geoCore_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.polyFillList); + tr2_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(comboBox_layerPolyFill_geoCore_exp) }); + + tr2_tl.Rows[0].Cells.Add(new TableCell() { ScaleWidth = true }); + } + + void geocore_row0_1(TableCell tc) + { + Panel p = new Panel(); + + TableLayout tl = new TableLayout(); + p.Content = tl; + + tc.Control = p; + + TableRow tr0 = new TableRow(); + tl.Rows.Add(tr0); + + lbl_layerCell_geoCore_exp = new Label(); + lbl_layerCell_geoCore_exp.Text = "Cell"; + tr0.Cells.Add(new TableCell() { Control = lbl_layerCell_geoCore_exp }); + + comboBox_layerStructureList_geoCore_exp = new DropDown(); + comboBox_layerStructureList_geoCore_exp.Enabled = false; + comboBox_layerStructureList_geoCore_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.geoCoreStructureList_exp); + tr0.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(comboBox_layerStructureList_geoCore_exp) }); + + TableRow tr1 = new TableRow(); + tl.Rows.Add(tr1); + + lbl_layerLD_geoCore_exp = new Label(); + lbl_layerLD_geoCore_exp.Text = "L/D"; + tr1.Cells.Add(new TableCell() { Control = lbl_layerLD_geoCore_exp }); + + comboBox_layerLDList_geoCore_exp = new DropDown(); + comboBox_layerLDList_geoCore_exp.Enabled = false; + comboBox_layerLDList_geoCore_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.geoCoreLDList_exp); + tr1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(comboBox_layerLDList_geoCore_exp) }); + } + + void geocore_row1(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; + + TableLayout tl = new TableLayout(); + p.Content = tl; + + tl.Rows.Add(new TableRow()); + + lbl_layerTipLocations_geoCore_exp = new Label(); + lbl_layerTipLocations_geoCore_exp.Text = "Tip Locs"; + tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerTipLocations_geoCore_exp }); + + comboBox_layerTipLocations_geoCore_exp = new DropDown(); + comboBox_layerTipLocations_geoCore_exp.Enabled = false; + tl.Rows[0].Cells.Add(new TableCell() { Control = comboBox_layerTipLocations_geoCore_exp }); + comboBox_layerTipLocations_geoCore_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.tipLocs); + + textBox_layer_FileLocation_geoCore_exp = new TextBox(); + textBox_layer_FileLocation_geoCore_exp.ReadOnly = true; + tl.Rows[0].Cells.Add(new TableCell() { Control = textBox_layer_FileLocation_geoCore_exp, ScaleWidth = true }); + } + } +} diff --git a/Common/Variance/UI/layerUI_setup_litho.cs b/Common/Variance/UI/layerUI_setup_litho.cs new file mode 100644 index 0000000..1267b1a --- /dev/null +++ b/Common/Variance/UI/layerUI_setup_litho.cs @@ -0,0 +1,968 @@ +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm : Form + { + // 2D Layer Litho + NumericStepper num_layer_lithoICRR_exp, num_layer_lithoOCRR_exp, num_layer_lithoCDUSide_exp, num_layer_lithoHorOverlay_exp, num_layer_lithoVerOverlay_exp, + num_layer_lithoICV_exp, num_layer_lithoOCV_exp, num_layer_lithoCDUTips_exp, num_layer_lithoLWR_exp, num_layer_lithoLWRFreq_exp, num_layer_lithoLWR2_exp, num_layer_lithoLWR2Freq_exp, num_layer_lithoWobble_exp, num_layer_coeff1_exp, num_layer_coeff2_exp; + Label lbl_layer_lithoICRR_exp, lbl_layer_lithoOCRR_exp, lbl_layer_lithoCDUSide_exp, lbl_layer_lithoHorOverlay_exp, lbl_layer_lithoVerOverlay_exp, + lbl_layer_lithoICV_exp, lbl_layer_lithoOCV_exp, lbl_layer_lithoCDUTips_exp, lbl_layer_lithoLWR_exp, lbl_layer_lithoLWRFreq_exp, lbl_layer_lithoLWR2_exp, lbl_layer_lithoLWR2Freq_exp, lbl_layer_lithoWobble_exp, lbl_layer_coeff1_exp, lbl_layer_coeff2_exp; + GroupBox groupBox_layer_overlayYReference_exp, groupBox_layer_overlayXReference_exp, + groupBox_layer_overlayYReference_Av_exp, groupBox_layer_overlayXReference_Av_exp, + groupBox_layer_overlayYCorrelation_exp, groupBox_layer_overlayXCorrelation_exp, + groupBox_layer_CDUCorrelation_exp, groupBox_layer_TipCDUCorrelation_exp; + + RadioButton[] rB_layer_OLRX_exp, rB_layer_OLRY_exp, rB_layer_COLX_exp, rB_layer_COLY_exp, rB_layer_CCDU_exp, rB_layer_CTCDU_exp; + CheckBox checkBox_layer_overlayXReference_Av_exp, checkBox_layer_overlayYReference_Av_exp, cB_layer_LWRPreview_exp; + + CheckBox[] cB_layer_OLRX_Av_exp, cB_layer_OLRY_Av_exp; + + DropDown comboBox_layerLWRNoiseType_exp, comboBox_layerLWR2NoiseType_exp; + + TableLayout groupBox_layer_overlayXReference_Av_table, groupBox_layer_overlayYReference_Av_table; + + Panel pnl_overlayRefX, pnl_overlayRefY; + + void twoD_LayerUISetup_litho_exp(TableCell tc) + { + Application.Instance.Invoke(() => + { + groupBox_layer_lithography_exp = new GroupBox(); + groupBox_layer_lithography_exp.Text = "Lithography Parameters"; + TableLayout groupBox_layer_lithography_table = new TableLayout(); + groupBox_layer_lithography_exp.Content = groupBox_layer_lithography_table; + + TableLayout t = new TableLayout(); + t.Rows.Add(new TableRow()); + t.Rows[0].Cells.Add(new TableCell() { Control = groupBox_layer_lithography_exp }); + t.Rows[0].Cells.Add(new TableCell() { Control = new Panel(), ScaleWidth = true }); + + Panel p = new Panel(); + p.Content = t; + tc.Control = p; + + litho_row1(groupBox_layer_lithography_table); + litho_row2(groupBox_layer_lithography_table); + litho_row3(groupBox_layer_lithography_table); + litho_row4(groupBox_layer_lithography_table); + litho_row5(groupBox_layer_lithography_table); + litho_row6(groupBox_layer_lithography_table); + litho_row7(groupBox_layer_lithography_table); + litho_row8(groupBox_layer_lithography_table); + }); + } + + // ICR, LWR + void litho_row1(TableLayout groupBox_layer_lithography_table) + { + // Outer table, row 1 + TableRow lit_tr0 = new TableRow(); + groupBox_layer_lithography_table.Rows.Add(lit_tr0); + lit_tr0.Cells.Add(new TableCell()); + + // Table layout within row 1 + TableLayout row0_tl = new TableLayout(); + lit_tr0.Cells[0].Control = row0_tl; + row0_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lit_tr0_0 = new TableCell(); + row0_tl.Rows[0].Cells.Add(lit_tr0_0); + + TableLayout lit_tr0_0_tl = new TableLayout(); + lit_tr0_0.Control = lit_tr0_0_tl; + + lit_tr0_0_tl.Rows.Add(new TableRow()); + + lbl_layer_lithoICRR_exp = new Label(); + lbl_layer_lithoICRR_exp.Text = "Inner Radius"; + lbl_layer_lithoICRR_exp.ToolTip = "Inner vertex (concave) corner rounding radius."; + lit_tr0_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr0_0_tl.Rows[0].Cells[0].Control = lbl_layer_lithoICRR_exp; + lit_tr0_0_tl.Rows[0].Cells[0].ScaleWidth = true; + + num_layer_lithoICRR_exp = new NumericStepper(); + num_layer_lithoICRR_exp.Increment = 0.1; + num_layer_lithoICRR_exp.DecimalPlaces = 2; + num_layer_lithoICRR_exp.MinValue = 0; + num_layer_lithoICRR_exp.ToolTip = "Inner vertex (concave) corner rounding radius."; + setSize(num_layer_lithoICRR_exp, 55, (int)(label_Height * uiScaleFactor)); + lit_tr0_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr0_0_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layer_lithoICRR_exp); + + TableCell lit_tr0_1 = new TableCell(); + lit_tr0.Cells.Add(lit_tr0_1); + + TableLayout lit_tr0_1_tl = new TableLayout(); + lit_tr0_1.Control = lit_tr0_1_tl; + + lit_tr0_1_tl.Rows.Add(new TableRow()); + + lbl_layer_lithoICV_exp = new Label(); + lbl_layer_lithoICV_exp.Text = "Var"; + lbl_layer_lithoICV_exp.MouseDoubleClick += ICV_RNG; + lbl_layer_lithoICV_exp.ToolTip = "3-sigma inner vertex (concave) corner rounding radius variation."; + lit_tr0_1_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr0_1_tl.Rows[0].Cells[0].Control = lbl_layer_lithoICV_exp; + + num_layer_lithoICV_exp = new NumericStepper(); + num_layer_lithoICV_exp.Increment = 0.1; + num_layer_lithoICV_exp.DecimalPlaces = 2; + num_layer_lithoICV_exp.MinValue = 0; + num_layer_lithoICV_exp.ToolTip = "3-sigma inner vertex (concave) corner rounding radius variation."; + setSize(num_layer_lithoICV_exp, 55, (int)(label_Height * uiScaleFactor)); + lit_tr0_1_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr0_1_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layer_lithoICV_exp); + + TableCell lit_tr0_2 = new TableCell(); + lit_tr0.Cells.Add(lit_tr0_2); + + Panel p = new Panel(); + lit_tr0_2.Control = p; + + TableLayout ptl = new TableLayout(); + p.Content = ptl; + + ptl.Rows.Add(new TableRow()); + + ptl.Rows.Add(new TableRow()); + ptl.Rows[0].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + TableCell tc0 = new TableCell(); + TableCell tc1 = new TableCell(); + ptl.Rows[0].Cells.Add(tc0); + ptl.Rows[0].Cells.Add(tc1); + + Panel p1 = new Panel(); + Panel p2 = new Panel(); + tc0.Control = p1; + tc1.Control = p2; + + TableLayout tc0tl = new TableLayout(); + TableLayout tc1tl = new TableLayout(); + p1.Content = tc0tl; + p2.Content = tc1tl; + + tc0tl.Rows.Add(new TableRow()); + tc1tl.Rows.Add(new TableRow()); + + + lbl_layer_lithoWobble_exp = new Label(); + lbl_layer_lithoWobble_exp.Text = "Wobble"; + lbl_layer_lithoWobble_exp.MouseDoubleClick += wobble_RNG; + lbl_layer_lithoWobble_exp.ToolTip = "3-sigma rotational variation."; + tc0tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_lithoWobble_exp }); + + num_layer_lithoWobble_exp = new NumericStepper(); + num_layer_lithoWobble_exp.Increment = 0.1; + num_layer_lithoWobble_exp.DecimalPlaces = 2; + num_layer_lithoWobble_exp.MinValue = 0; + num_layer_lithoWobble_exp.ToolTip = "3-sigma rotational variation."; + setSize(num_layer_lithoWobble_exp, 55, (int)(label_Height * uiScaleFactor)); + tc0tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_lithoWobble_exp) }); + + lbl_layer_lithoLWR_exp = new Label(); + lbl_layer_lithoLWR_exp.Text = "LWR"; + lbl_layer_lithoLWR_exp.MouseDoubleClick += lwr_RNG; + lbl_layer_lithoLWR_exp.ToolTip = "3-sigma line width roughness. Mapped to edge by setting in simulation settings."; + tc1tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_lithoLWR_exp }); + + tc0tl.Rows[0].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + + num_layer_lithoLWR_exp = new NumericStepper(); + num_layer_lithoLWR_exp.Increment = 0.1; + num_layer_lithoLWR_exp.DecimalPlaces = 2; + num_layer_lithoLWR_exp.MinValue = 0; + num_layer_lithoLWR_exp.ToolTip = "3-sigma line width roughness. Mapped to edge by setting in simulation settings."; + setSize(num_layer_lithoLWR_exp, 55, (int)(label_Height * uiScaleFactor)); + tc1tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_lithoLWR_exp) }); + + lbl_layer_lithoLWRFreq_exp = new Label(); + lbl_layer_lithoLWRFreq_exp.Text = "Freq"; + lbl_layer_lithoLWRFreq_exp.ToolTip = "Frequency of LWR"; + tc1tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_lithoLWRFreq_exp }); + + num_layer_lithoLWRFreq_exp = new NumericStepper(); + num_layer_lithoLWRFreq_exp.Increment = 0.1; + num_layer_lithoLWRFreq_exp.DecimalPlaces = 2; + num_layer_lithoLWRFreq_exp.Value = 0.1; + num_layer_lithoLWRFreq_exp.MinValue = 0.01; + num_layer_lithoLWRFreq_exp.ToolTip = "Frequency of LWR"; + setSize(num_layer_lithoLWRFreq_exp, 55, num_Height); + tc1tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_lithoLWRFreq_exp) }); + + comboBox_layerLWRNoiseType_exp = new DropDown(); + comboBox_layerLWRNoiseType_exp.DataContext = DataContext; + comboBox_layerLWRNoiseType_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.noiseTypeList); + comboBox_layerLWRNoiseType_exp.SelectedIndex = 0; + comboBox_layerLWRNoiseType_exp.ToolTip = "Noise type for LWR"; + lit_tr0.Cells.Add(new TableCell() { Control = comboBox_layerLWRNoiseType_exp }); + + cB_layer_LWRPreview_exp = new CheckBox(); + cB_layer_LWRPreview_exp.Text = "Show"; + cB_layer_LWRPreview_exp.ToolTip = "Preview of LWR"; + lit_tr0.Cells.Add(new TableCell() { Control = cB_layer_LWRPreview_exp }); + } + + // OCR, LWR2 + void litho_row2(TableLayout groupBox_layer_lithography_table) + { + // Outer table, row 2 + TableRow lit_tr1 = new TableRow(); + groupBox_layer_lithography_table.Rows.Add(lit_tr1); + lit_tr1.Cells.Add(new TableCell()); + + // Table layout within row 2 + TableLayout row1_tl = new TableLayout(); + lit_tr1.Cells[0].Control = row1_tl; + row1_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lit_tr1_0 = new TableCell(); + row1_tl.Rows[0].Cells.Add(lit_tr1_0); + + TableLayout lit_tr1_0_tl = new TableLayout(); + lit_tr1_0.Control = lit_tr1_0_tl; + + lit_tr1_0_tl.Rows.Add(new TableRow()); + + lbl_layer_lithoOCRR_exp = new Label(); + lbl_layer_lithoOCRR_exp.Text = "Outer Radius"; + lbl_layer_lithoOCRR_exp.ToolTip = "Outer vertex (concave) corner rounding radius."; + lit_tr1_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr1_0_tl.Rows[0].Cells[0].Control = lbl_layer_lithoOCRR_exp; + lit_tr1_0_tl.Rows[0].Cells[0].ScaleWidth = true; + + num_layer_lithoOCRR_exp = new NumericStepper(); + num_layer_lithoOCRR_exp.Increment = 0.1; + num_layer_lithoOCRR_exp.DecimalPlaces = 2; + num_layer_lithoOCRR_exp.MinValue = 0; + num_layer_lithoOCRR_exp.ToolTip = "Outer vertex (concave) corner rounding radius."; + setSize(num_layer_lithoOCRR_exp, 55, (int)(label_Height * uiScaleFactor)); + lit_tr1_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr1_0_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layer_lithoOCRR_exp); + + TableCell lit_tr1_1 = new TableCell(); + lit_tr1.Cells.Add(lit_tr1_1); + + TableLayout lit_tr1_1_tl = new TableLayout(); + lit_tr1_1.Control = lit_tr1_1_tl; + + lit_tr1_1_tl.Rows.Add(new TableRow()); + + lbl_layer_lithoOCV_exp = new Label(); + lbl_layer_lithoOCV_exp.Text = "Var"; + lbl_layer_lithoOCV_exp.MouseDoubleClick += ICV_RNG; + lbl_layer_lithoOCV_exp.ToolTip = "3-sigma outer vertex (concave) corner rounding radius variation."; + lit_tr1_1_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr1_1_tl.Rows[0].Cells[0].Control = lbl_layer_lithoOCV_exp; + + num_layer_lithoOCV_exp = new NumericStepper(); + num_layer_lithoOCV_exp.Increment = 0.1; + num_layer_lithoOCV_exp.DecimalPlaces = 2; + num_layer_lithoOCV_exp.MinValue = 0; + num_layer_lithoOCV_exp.ToolTip = "3-sigma outer vertex (concave) corner rounding radius variation."; + setSize(num_layer_lithoOCV_exp, 55, (int)(label_Height * uiScaleFactor)); + lit_tr1_1_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr1_1_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layer_lithoOCV_exp); + + TableCell lit_tr1_2 = new TableCell(); + lit_tr1.Cells.Add(lit_tr1_2); + + Panel p = new Panel(); + lit_tr1_2.Control = p; + + TableLayout ptl = new TableLayout(); + p.Content = ptl; + + ptl.Rows.Add(new TableRow()); + + ptl.Rows[0].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + + lbl_layer_lithoLWR2_exp = new Label(); + lbl_layer_lithoLWR2_exp.Text = "LWR2"; + lbl_layer_lithoLWR2_exp.MouseDoubleClick += lwr2_RNG; + lbl_layer_lithoLWR2_exp.ToolTip = "3-sigma line width roughness. Mapped to edge by setting in simulation settings."; + ptl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_lithoLWR2_exp }); + + num_layer_lithoLWR2_exp = new NumericStepper(); + num_layer_lithoLWR2_exp.Increment = 0.1; + num_layer_lithoLWR2_exp.DecimalPlaces = 2; + num_layer_lithoLWR2_exp.MinValue = 0; + num_layer_lithoLWR2_exp.ToolTip = "3-sigma line width roughness. Mapped to edge by setting in simulation settings."; + setSize(num_layer_lithoLWR2_exp, 55, (int)(label_Height * uiScaleFactor)); + ptl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_lithoLWR2_exp) }); + + lbl_layer_lithoLWR2Freq_exp = new Label(); + lbl_layer_lithoLWR2Freq_exp.Text = "Freq"; + lbl_layer_lithoLWR2Freq_exp.ToolTip = "Frequency of LWR2"; + ptl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_lithoLWR2Freq_exp }); + + num_layer_lithoLWR2Freq_exp = new NumericStepper(); + num_layer_lithoLWR2Freq_exp.Increment = 0.1; + num_layer_lithoLWR2Freq_exp.DecimalPlaces = 2; + num_layer_lithoLWR2Freq_exp.Value = 0.1; + num_layer_lithoLWR2Freq_exp.MinValue = 0.01; + num_layer_lithoLWR2Freq_exp.ToolTip = "Frequency of LWR2"; + setSize(num_layer_lithoLWR2Freq_exp, 55, num_Height); + ptl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_lithoLWR2Freq_exp) }); + + comboBox_layerLWR2NoiseType_exp = new DropDown(); + comboBox_layerLWR2NoiseType_exp.Width = 120; + comboBox_layerLWR2NoiseType_exp.DataContext = DataContext; + comboBox_layerLWR2NoiseType_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.noiseTypeList); + comboBox_layerLWR2NoiseType_exp.SelectedIndex = 0; + comboBox_layerLWR2NoiseType_exp.ToolTip = "Noise type for LWR2"; + lit_tr1.Cells.Add(new TableCell() { Control = comboBox_layerLWR2NoiseType_exp }); + + lit_tr1.Cells.Add(new TableCell() { Control = null }); + } + + // SCDU, lens distortion + void litho_row3(TableLayout groupBox_layer_lithography_table) + { + // Outer table, row 3 + TableRow lit_tr2 = new TableRow(); + groupBox_layer_lithography_table.Rows.Add(lit_tr2); + lit_tr2.Cells.Add(new TableCell()); + + // Table layout within row 3 + TableLayout row2_tl = new TableLayout(); + lit_tr2.Cells[0].Control = row2_tl; + row2_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lit_tr2_0 = new TableCell(); + row2_tl.Rows[0].Cells.Add(lit_tr2_0); + + TableLayout lit_tr2_0_tl = new TableLayout(); + lit_tr2_0.Control = lit_tr2_0_tl; + + lit_tr2_0_tl.Rows.Add(new TableRow()); + + lbl_layer_lithoCDUSide_exp = new Label(); + lbl_layer_lithoCDUSide_exp.Text = "Side CDU"; + lbl_layer_lithoCDUSide_exp.MouseDoubleClick += sCDU_RNG; + lbl_layer_lithoCDUSide_exp.ToolTip = "3-sigma CD variation applied to non-tip sides."; + lit_tr2_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr2_0_tl.Rows[0].Cells[0].Control = lbl_layer_lithoCDUSide_exp; + lit_tr2_0_tl.Rows[0].Cells[0].ScaleWidth = true; + + num_layer_lithoCDUSide_exp = new NumericStepper(); + num_layer_lithoCDUSide_exp.Increment = 0.1; + num_layer_lithoCDUSide_exp.DecimalPlaces = 2; + num_layer_lithoCDUSide_exp.MinValue = 0; + num_layer_lithoCDUSide_exp.ToolTip = "3-sigma CD variation applied to non-tip sides."; + setSize(num_layer_lithoCDUSide_exp, 55, num_Height); + lit_tr2_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr2_0_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layer_lithoCDUSide_exp); + + lit_tr2.Cells.Add(new TableCell()); + + TableCell lit_tr2_1 = new TableCell(); + lit_tr2.Cells.Add(lit_tr2_1); + + Panel p = new Panel(); + lit_tr2_1.Control = p; + + TableLayout ptl = new TableLayout(); + p.Content = ptl; + ptl.Rows.Add(new TableRow()); + TableCell ptc = new TableCell(); + ptl.Rows[0].Cells.Add(ptc); + + groupBox_layer_CDUCorrelation_exp = new GroupBox(); + TableLayout groupBox_layer_CDUCorrelation_content = new TableLayout(); + groupBox_layer_CDUCorrelation_exp.Text = "Side CDU Correlation"; + groupBox_layer_CDUCorrelation_exp.Content = groupBox_layer_CDUCorrelation_content; + ptc.Control = groupBox_layer_CDUCorrelation_exp;//, x, y); + + TableRow ccdu_tr0 = new TableRow(); + groupBox_layer_CDUCorrelation_content.Rows.Add(ccdu_tr0); + TableRow ccdu_tr1 = new TableRow(); + groupBox_layer_CDUCorrelation_content.Rows.Add(ccdu_tr1); + + rB_layer_CCDU_exp[0] = new RadioButton(); + rB_layer_CCDU_exp[0].Text = "0"; + rB_layer_CCDU_exp[0].Checked = true; + + TableCell rB_layer_CCDU_0tc = new TableCell(); + rB_layer_CCDU_0tc.Control = rB_layer_CCDU_exp[0]; + + groupBox_layer_CDUCorrelation_content.Rows[0].Cells.Add(rB_layer_CCDU_0tc); + + int rB_CCDU = 1; + int ccdu_rowIndex = 0; + for (int rb = 1; rb < CentralProperties.maxLayersForMC; rb++) + { + rB_layer_CCDU_exp[rB_CCDU] = new RadioButton(rB_layer_CCDU_exp[0]); + rB_layer_CCDU_exp[rB_CCDU].Text = rB_CCDU.ToString(); + rB_layer_CCDU_exp[rB_CCDU].Checked = false; + TableCell tc0 = new TableCell(); + tc0.Control = rB_layer_CCDU_exp[rB_CCDU]; + groupBox_layer_CDUCorrelation_content.Rows[ccdu_rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (rB_CCDU + 1 == CentralProperties.maxLayersForMC / 2) + { + ccdu_rowIndex++; + } + rB_CCDU++; + } + + + Panel p2 = new Panel(); + TableLayout ltl = new TableLayout(); + p2.Content = ltl; + lit_tr2.Cells.Add(new TableCell() { Control = p2 }); + + ltl.Rows.Add(new TableRow()); + + lbl_layer_coeff1_exp = new Label(); + lbl_layer_coeff1_exp.Text = "Lens k1"; + lbl_layer_coeff1_exp.ToolTip = "Lens k1"; + ltl.Rows[ltl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layer_coeff1_exp }); + + num_layer_coeff1_exp = new NumericStepper(); + num_layer_coeff1_exp.Increment = 0.1; + num_layer_coeff1_exp.DecimalPlaces = 2; + num_layer_coeff1_exp.Value = 0.0; + num_layer_coeff1_exp.ToolTip = "Lens k1"; + setSize(num_layer_coeff1_exp, 55, num_Height); + ltl.Rows[ltl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_coeff1_exp) }); + + ltl.Rows[ltl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + + ltl.Rows.Add(new TableRow()); + + lbl_layer_coeff2_exp = new Label(); + lbl_layer_coeff2_exp.Text = "Lens k2"; + lbl_layer_coeff2_exp.ToolTip = "Lens k2"; + ltl.Rows[ltl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layer_coeff2_exp }); + + num_layer_coeff2_exp = new NumericStepper(); + num_layer_coeff2_exp.Increment = 0.1; + num_layer_coeff2_exp.DecimalPlaces = 2; + num_layer_coeff2_exp.Value = 0.0; + num_layer_coeff2_exp.ToolTip = "Lens k2"; + setSize(num_layer_coeff2_exp, 55, num_Height); + ltl.Rows[ltl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_coeff2_exp) }); + + ltl.Rows[ltl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + } + + // TCDU + void litho_row4(TableLayout groupBox_layer_lithography_table) + { + // Outer table, row 4 + TableRow lit_tr3 = new TableRow(); + groupBox_layer_lithography_table.Rows.Add(lit_tr3); + lit_tr3.Cells.Add(new TableCell()); + + // Table layout within row 4 + TableLayout row3_tl = new TableLayout(); + lit_tr3.Cells[0].Control = row3_tl; + row3_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lit_tr3_0 = new TableCell(); + row3_tl.Rows[0].Cells.Add(lit_tr3_0); + + TableLayout lit_tr3_0_tl = new TableLayout(); + lit_tr3_0.Control = lit_tr3_0_tl; + + lit_tr3_0_tl.Rows.Add(new TableRow()); + + lbl_layer_lithoCDUTips_exp = new Label(); + lbl_layer_lithoCDUTips_exp.Text = "Tips CDU"; + lbl_layer_lithoCDUTips_exp.MouseDoubleClick += tCDU_RNG; + lbl_layer_lithoCDUTips_exp.ToolTip = "3-sigma CD variation applied to tip sides."; + lit_tr3_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr3_0_tl.Rows[0].Cells[0].Control = lbl_layer_lithoCDUTips_exp; + lit_tr3_0_tl.Rows[0].Cells[0].ScaleWidth = true; + + num_layer_lithoCDUTips_exp = new NumericStepper(); + num_layer_lithoCDUTips_exp.Increment = 0.1; + num_layer_lithoCDUTips_exp.DecimalPlaces = 2; + num_layer_lithoCDUTips_exp.MinValue = 0; + num_layer_lithoCDUTips_exp.ToolTip = "3-sigma CD variation applied to tip sides."; + setSize(num_layer_lithoCDUTips_exp, 55, num_Height); + lit_tr3_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr3_0_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layer_lithoCDUTips_exp); + + lit_tr3.Cells.Add(new TableCell()); + + TableCell lit_tr3_1 = new TableCell(); + lit_tr3.Cells.Add(lit_tr3_1); + + Panel p = new Panel(); + lit_tr3_1.Control = p; + + TableLayout ptl = new TableLayout(); + p.Content = ptl; + ptl.Rows.Add(new TableRow()); + TableCell ptc = new TableCell(); + ptl.Rows[0].Cells.Add(ptc); + + groupBox_layer_TipCDUCorrelation_exp = new GroupBox(); + TableLayout groupBox_layer_TipCDUCorrelation_content = new TableLayout(); + groupBox_layer_TipCDUCorrelation_exp.Text = "Tip CDU Correlation"; + groupBox_layer_TipCDUCorrelation_exp.Content = groupBox_layer_TipCDUCorrelation_content; + ptc.Control = groupBox_layer_TipCDUCorrelation_exp; + + TableRow tcdu_tr0 = new TableRow(); + groupBox_layer_TipCDUCorrelation_content.Rows.Add(tcdu_tr0); + TableRow tcdu_tr1 = new TableRow(); + groupBox_layer_TipCDUCorrelation_content.Rows.Add(tcdu_tr1); + + rB_layer_CTCDU_exp[0] = new RadioButton(); + rB_layer_CTCDU_exp[0].Text = "0"; + rB_layer_CTCDU_exp[0].Checked = true; + + TableCell rB_layer_CTCDU_0tc = new TableCell(); + rB_layer_CTCDU_0tc.Control = rB_layer_CTCDU_exp[0]; + + groupBox_layer_TipCDUCorrelation_content.Rows[0].Cells.Add(rB_layer_CTCDU_0tc); + + int rB_CTCDU = 1; + int ctcdu_rowIndex = 0; + for (int rb = 1; rb < CentralProperties.maxLayersForMC; rb++) + { + rB_layer_CTCDU_exp[rB_CTCDU] = new RadioButton(rB_layer_CTCDU_exp[0]); + rB_layer_CTCDU_exp[rB_CTCDU].Text = rB_CTCDU.ToString(); + rB_layer_CTCDU_exp[rB_CTCDU].Checked = false; + TableCell tc0 = new TableCell(); + tc0.Control = rB_layer_CTCDU_exp[rB_CTCDU]; + groupBox_layer_TipCDUCorrelation_content.Rows[ctcdu_rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (rB_CTCDU + 1 == CentralProperties.maxLayersForMC / 2) + { + ctcdu_rowIndex++; + } + rB_CTCDU++; + } + } + + // XOL, XOLR + void litho_row5(TableLayout groupBox_layer_lithography_table) + { + // Outer table, row 5 + TableRow lit_tr4 = new TableRow(); + groupBox_layer_lithography_table.Rows.Add(lit_tr4); + lit_tr4.Cells.Add(new TableCell()); + + // Table layout within row 5 + TableLayout row4_tl = new TableLayout(); + lit_tr4.Cells[0].Control = row4_tl; + row4_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lit_tr4_0 = new TableCell(); + row4_tl.Rows[0].Cells.Add(lit_tr4_0); + + TableLayout lit_tr4_0_tl = new TableLayout(); + lit_tr4_0.Control = lit_tr4_0_tl; + + lit_tr4_0_tl.Rows.Add(new TableRow()); + + lbl_layer_lithoHorOverlay_exp = new Label(); + lbl_layer_lithoHorOverlay_exp.Text = "Hor Overlay"; + lbl_layer_lithoHorOverlay_exp.MouseDoubleClick += hOverlay_RNG; + lbl_layer_lithoHorOverlay_exp.ToolTip = "3-sigma horizontal overlay."; + lit_tr4_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr4_0_tl.Rows[0].Cells[0].Control = lbl_layer_lithoHorOverlay_exp; + lit_tr4_0_tl.Rows[0].Cells[0].ScaleWidth = true; + + num_layer_lithoHorOverlay_exp = new NumericStepper(); + num_layer_lithoHorOverlay_exp.Increment = 0.1; + num_layer_lithoHorOverlay_exp.DecimalPlaces = 2; + num_layer_lithoHorOverlay_exp.MinValue = 0; + num_layer_lithoHorOverlay_exp.ToolTip = "3-sigma horizontal overlay."; + setSize(num_layer_lithoHorOverlay_exp, 55, num_Height); + lit_tr4_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr4_0_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layer_lithoHorOverlay_exp); + + TableCell lit_tr4_1 = new TableCell(); + lit_tr4.Cells.Add(lit_tr4_1); + + TableLayout lit_tr4_1_tl = new TableLayout(); + lit_tr4_1.Control = lit_tr4_1_tl; + + lit_tr4_1_tl.Rows.Add(new TableRow()); + + checkBox_layer_overlayXReference_Av_exp = new CheckBox(); + checkBox_layer_overlayXReference_Av_exp.Text = "Av"; + checkBox_layer_overlayXReference_Av_exp.ToolTip = "Use the average displaced location of layers as a reference for horizontal overlay"; + lit_tr4_1_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr4_1_tl.Rows[0].Cells[0].Control = TableLayout.AutoSized(checkBox_layer_overlayXReference_Av_exp); + + TableCell lit_tr4_2 = new TableCell(); + lit_tr4.Cells.Add(lit_tr4_2); + + groupBox_layer_overlayXReference_exp = new GroupBox(); + TableLayout groupBox_layer_overlayXReference_table = new TableLayout(); + groupBox_layer_overlayXReference_exp.Text = "X Overlay Reference"; + groupBox_layer_overlayXReference_exp.Content = groupBox_layer_overlayXReference_table; + pnl_overlayRefX = new Panel(); + lit_tr4_2.Control = pnl_overlayRefX; + pnl_overlayRefX.Content = groupBox_layer_overlayXReference_exp; + + TableRow olrx_tr0 = new TableRow(); + groupBox_layer_overlayXReference_table.Rows.Add(olrx_tr0); + TableRow olrx_tr1 = new TableRow(); + groupBox_layer_overlayXReference_table.Rows.Add(olrx_tr1); + + rB_layer_OLRX_exp[0] = new RadioButton(); + rB_layer_OLRX_exp[0].Text = "0"; + rB_layer_OLRX_exp[0].Checked = true; + + TableCell rB_layer_OLRX_0tc = new TableCell(); + rB_layer_OLRX_0tc.Control = rB_layer_OLRX_exp[0]; + + groupBox_layer_overlayXReference_table.Rows[0].Cells.Add(rB_layer_OLRX_0tc); + + int rB_OLRX = 1; + int olrx_rowIndex = 0; + for (int rb = 1; rb < CentralProperties.maxLayersForMC; rb++) + { + rB_layer_OLRX_exp[rB_OLRX] = new RadioButton(rB_layer_OLRX_exp[0]); + rB_layer_OLRX_exp[rB_OLRX].Text = rB_OLRX.ToString(); + rB_layer_OLRX_exp[rB_OLRX].Checked = false; + TableCell tc0 = new TableCell(); + tc0.Control = rB_layer_OLRX_exp[rB_OLRX]; + groupBox_layer_overlayXReference_table.Rows[olrx_rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (rB_OLRX + 1 == CentralProperties.maxLayersForMC / 2) + { + olrx_rowIndex++; + } + rB_OLRX++; + } + + groupBox_layer_overlayXReference_Av_exp = new GroupBox(); + groupBox_layer_overlayXReference_Av_table = new TableLayout(); + groupBox_layer_overlayXReference_Av_exp.Text = "X Overlay References"; + groupBox_layer_overlayXReference_Av_exp.Content = groupBox_layer_overlayXReference_Av_table; + + TableRow avolrx_tr0 = new TableRow(); + groupBox_layer_overlayXReference_Av_table.Rows.Add(avolrx_tr0); + TableRow avolrx_tr1 = new TableRow(); + groupBox_layer_overlayXReference_Av_table.Rows.Add(avolrx_tr1); + + int avolrx_rowIndex = 0; + for (int cb = 0; cb < CentralProperties.maxLayersForMC; cb++) + { + // Don't add a button for our current layer + cB_layer_OLRX_Av_exp[cb] = new CheckBox(); + cB_layer_OLRX_Av_exp[cb].Text = (cb + 1).ToString(); + + TableCell tc0 = new TableCell(); + tc0.Control = cB_layer_OLRX_Av_exp[cb]; + groupBox_layer_overlayXReference_Av_table.Rows[avolrx_rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (cb + 1 == CentralProperties.maxLayersForMC / 2) + { + avolrx_rowIndex++; + } + } + } + + // COLX + void litho_row6(TableLayout groupBox_layer_lithography_table) + { + // Outer table, row 6 + TableRow lit_tr5 = new TableRow(); + groupBox_layer_lithography_table.Rows.Add(lit_tr5); + lit_tr5.Cells.Add(new TableCell()); + + // Table layout within row 6 + TableLayout row5_tl = new TableLayout(); + lit_tr5.Cells[0].Control = row5_tl; + row5_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lit_tr5_0 = new TableCell(); + row5_tl.Rows[0].Cells.Add(lit_tr5_0); + + TableLayout lit_tr5_0_tl = new TableLayout(); + lit_tr5_0.Control = lit_tr5_0_tl; + + lit_tr5_0_tl.Rows.Add(new TableRow()); + + lit_tr5_0_tl.Rows.Add(new TableRow()); + + Panel p1 = new Panel(); + lit_tr5_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr5_0_tl.Rows[0].Cells[0].Control = p1; + + Panel p2 = new Panel(); + lit_tr5_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr5_0_tl.Rows[0].Cells[1].Control = p2; + + TableCell lit_tr5_1 = new TableCell(); + lit_tr5.Cells.Add(lit_tr5_1); + + TableLayout lit_tr5_1_tl = new TableLayout(); + lit_tr5_1.Control = lit_tr5_1_tl; + + lit_tr5_1_tl.Rows.Add(new TableRow()); + + Panel p3 = new Panel(); + lit_tr5_1_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr5_1_tl.Rows[0].Cells[0].Control = p3; + + TableCell lit_tr5_2 = new TableCell(); + lit_tr5.Cells.Add(lit_tr5_2); + + groupBox_layer_overlayXCorrelation_exp = new GroupBox(); + TableLayout groupBox_layer_overlayXCorrelation_content = new TableLayout(); + groupBox_layer_overlayXCorrelation_exp.Text = "X Overlay Correlation"; + groupBox_layer_overlayXCorrelation_exp.Content = groupBox_layer_overlayXCorrelation_content; + lit_tr5_2.Control = groupBox_layer_overlayXCorrelation_exp; + + TableRow olcx_tr0 = new TableRow(); + groupBox_layer_overlayXCorrelation_content.Rows.Add(olcx_tr0); + TableRow olcx_tr1 = new TableRow(); + groupBox_layer_overlayXCorrelation_content.Rows.Add(olcx_tr1); + + rB_layer_COLX_exp[0] = new RadioButton(); + rB_layer_COLX_exp[0].Text = "0"; + rB_layer_COLX_exp[0].Checked = true; + + TableCell rB_layer_COLX_0tc = new TableCell(); + rB_layer_COLX_0tc.Control = rB_layer_COLX_exp[0]; + + groupBox_layer_overlayXCorrelation_content.Rows[0].Cells.Add(rB_layer_COLX_0tc); + + int rB_COLX = 1; + int colx_rowIndex = 0; + for (int rb = 1; rb < CentralProperties.maxLayersForMC; rb++) + { + rB_layer_COLX_exp[rB_COLX] = new RadioButton(rB_layer_COLX_exp[0]); + rB_layer_COLX_exp[rB_COLX].Text = rB_COLX.ToString(); + rB_layer_COLX_exp[rB_COLX].Checked = false; + TableCell tc0 = new TableCell(); + tc0.Control = rB_layer_COLX_exp[rB_COLX]; + groupBox_layer_overlayXCorrelation_content.Rows[colx_rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (rB_COLX + 1 == CentralProperties.maxLayersForMC / 2) + { + colx_rowIndex++; + } + rB_COLX++; + } + } + + // YOL, YOLR + void litho_row7(TableLayout groupBox_layer_lithography_table) + { + // Outer table, row 7 + TableRow lit_tr6 = new TableRow(); + groupBox_layer_lithography_table.Rows.Add(lit_tr6); + lit_tr6.Cells.Add(new TableCell()); + + // Table layout within row 7 + TableLayout row6_tl = new TableLayout(); + lit_tr6.Cells[0].Control = row6_tl; + row6_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lit_tr6_0 = new TableCell(); + row6_tl.Rows[0].Cells.Add(lit_tr6_0); + + TableLayout lit_tr6_0_tl = new TableLayout(); + lit_tr6_0.Control = lit_tr6_0_tl; + + lit_tr6_0_tl.Rows.Add(new TableRow()); + + lbl_layer_lithoVerOverlay_exp = new Label(); + lbl_layer_lithoVerOverlay_exp.Text = "Ver Overlay"; + lbl_layer_lithoVerOverlay_exp.MouseDoubleClick += hOverlay_RNG; + lbl_layer_lithoVerOverlay_exp.Width = 86; + lbl_layer_lithoVerOverlay_exp.ToolTip = "3-sigma horizontal overlay."; + lit_tr6_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr6_0_tl.Rows[0].Cells[0].Control = lbl_layer_lithoVerOverlay_exp; + lit_tr6_0_tl.Rows[0].Cells[0].ScaleWidth = true; + + num_layer_lithoVerOverlay_exp = new NumericStepper(); + num_layer_lithoVerOverlay_exp.Increment = 0.1; + num_layer_lithoVerOverlay_exp.DecimalPlaces = 2; + num_layer_lithoVerOverlay_exp.MinValue = 0; + num_layer_lithoVerOverlay_exp.ToolTip = "3-sigma vertical overlay."; + setSize(num_layer_lithoVerOverlay_exp, 55, num_Height); + lit_tr6_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr6_0_tl.Rows[0].Cells[1].Control = TableLayout.AutoSized(num_layer_lithoVerOverlay_exp); + + TableCell lit_tr6_1 = new TableCell(); + lit_tr6.Cells.Add(lit_tr6_1); + + TableLayout lit_tr6_1_tl = new TableLayout(); + lit_tr6_1.Control = lit_tr6_1_tl; + + lit_tr6_1_tl.Rows.Add(new TableRow()); + + checkBox_layer_overlayYReference_Av_exp = new CheckBox(); + checkBox_layer_overlayYReference_Av_exp.Text = "Av"; + checkBox_layer_overlayYReference_Av_exp.ToolTip = "Use the average displaced location of layers as a reference for vertical overlay"; + lit_tr6_1_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr6_1_tl.Rows[0].Cells[0].Control = TableLayout.AutoSized(checkBox_layer_overlayYReference_Av_exp); + + TableCell lit_tr6_2 = new TableCell(); + lit_tr6.Cells.Add(lit_tr6_2); + + groupBox_layer_overlayYReference_exp = new GroupBox(); + TableLayout groupBox_layer_overlayYReference_content = new TableLayout(); + groupBox_layer_overlayYReference_exp.Text = "Y Overlay Reference"; + groupBox_layer_overlayYReference_exp.Content = groupBox_layer_overlayYReference_content; + pnl_overlayRefY = new Panel(); + lit_tr6_2.Control = pnl_overlayRefY; + + TableRow olry_tr0 = new TableRow(); + groupBox_layer_overlayYReference_content.Rows.Add(olry_tr0); + TableRow olry_tr1 = new TableRow(); + groupBox_layer_overlayYReference_content.Rows.Add(olry_tr1); + + rB_layer_OLRY_exp[0] = new RadioButton(); + rB_layer_OLRY_exp[0].Text = "0"; + rB_layer_OLRY_exp[0].Checked = true; + + TableCell rB_layer_OLRY_0tc = new TableCell(); + rB_layer_OLRY_0tc.Control = rB_layer_OLRY_exp[0]; + + groupBox_layer_overlayYReference_content.Rows[0].Cells.Add(rB_layer_OLRY_0tc); + + int rB_OLRY = 1; + int olry_rowIndex = 0; + for (int rb = 1; rb < CentralProperties.maxLayersForMC; rb++) + { + // Don't add a button for our current layer + rB_layer_OLRY_exp[rB_OLRY] = new RadioButton(rB_layer_OLRY_exp[0]); + rB_layer_OLRY_exp[rB_OLRY].Text = rB_OLRY.ToString(); + rB_layer_OLRY_exp[rB_OLRY].Checked = false; + TableCell tc0 = new TableCell(); + tc0.Control = rB_layer_OLRY_exp[rB_OLRY]; + groupBox_layer_overlayYReference_content.Rows[olry_rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (rB_OLRY + 1 == CentralProperties.maxLayersForMC / 2) + { + olry_rowIndex++; + } + rB_OLRY++; + } + + groupBox_layer_overlayYReference_Av_exp = new GroupBox(); + groupBox_layer_overlayYReference_Av_table = new TableLayout(); + groupBox_layer_overlayYReference_Av_exp.Text = "Y Overlay References"; + groupBox_layer_overlayYReference_Av_exp.Content = groupBox_layer_overlayYReference_Av_table; + + TableRow avolry_tr0 = new TableRow(); + groupBox_layer_overlayYReference_Av_table.Rows.Add(avolry_tr0); + TableRow avolry_tr1 = new TableRow(); + groupBox_layer_overlayYReference_Av_table.Rows.Add(avolry_tr1); + + int avolry_rowIndex = 0; + for (int cb = 0; cb < CentralProperties.maxLayersForMC; cb++) + { + // Don't add a button for our current layer + cB_layer_OLRY_Av_exp[cb] = new CheckBox(); + cB_layer_OLRY_Av_exp[cb].Text = (cb + 1).ToString(); + + TableCell tc0 = new TableCell(); + tc0.Control = cB_layer_OLRY_Av_exp[cb]; + groupBox_layer_overlayYReference_Av_table.Rows[avolry_rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if ((cb + 1) == CentralProperties.maxLayersForMC / 2) + { + avolry_rowIndex++; + } + } + pnl_overlayRefY.Content = groupBox_layer_overlayYReference_exp; + } + + // COLY + void litho_row8(TableLayout groupBox_layer_lithography_table) + { + // Outer table, row 8 + TableRow lit_tr7 = new TableRow(); + groupBox_layer_lithography_table.Rows.Add(lit_tr7); + lit_tr7.Cells.Add(new TableCell()); + + // Table layout within row 8 + TableLayout row7_tl = new TableLayout(); + lit_tr7.Cells[0].Control = row7_tl; + row7_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lit_tr7_0 = new TableCell(); + row7_tl.Rows[0].Cells.Add(lit_tr7_0); + + TableLayout lit_tr7_0_tl = new TableLayout(); + lit_tr7_0.Control = lit_tr7_0_tl; + + lit_tr7_0_tl.Rows.Add(new TableRow()); + + lit_tr7_0_tl.Rows.Add(new TableRow()); + + Panel p1 = new Panel(); + lit_tr7_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr7_0_tl.Rows[0].Cells[0].Control = p1; + + Panel p2 = new Panel(); + lit_tr7_0_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr7_0_tl.Rows[0].Cells[1].Control = p2; + + TableCell lit_tr7_1 = new TableCell(); + lit_tr7.Cells.Add(lit_tr7_1); + + TableLayout lit_tr7_1_tl = new TableLayout(); + lit_tr7_1.Control = lit_tr7_1_tl; + + lit_tr7_1_tl.Rows.Add(new TableRow()); + + Panel p3 = new Panel(); + lit_tr7_1_tl.Rows[0].Cells.Add(new TableCell()); + lit_tr7_1_tl.Rows[0].Cells[0].Control = p3; + + TableCell lit_tr7_2 = new TableCell(); + lit_tr7.Cells.Add(lit_tr7_2); + + groupBox_layer_overlayYCorrelation_exp = new GroupBox(); + TableLayout groupBox_layer_overlayYCorrelation_content = new TableLayout(); + groupBox_layer_overlayYCorrelation_exp.Text = "Y Overlay Correlation"; + groupBox_layer_overlayYCorrelation_exp.Content = groupBox_layer_overlayYCorrelation_content; + lit_tr7_2.Control = groupBox_layer_overlayYCorrelation_exp; + + TableRow olcy_tr0 = new TableRow(); + groupBox_layer_overlayYCorrelation_content.Rows.Add(olcy_tr0); + TableRow olcy_tr1 = new TableRow(); + groupBox_layer_overlayYCorrelation_content.Rows.Add(olcy_tr1); + + rB_layer_COLY_exp[0] = new RadioButton(); + rB_layer_COLY_exp[0].Text = "0"; + rB_layer_COLY_exp[0].Checked = true; + + TableCell rB_layer_COLY_0tc = new TableCell(); + rB_layer_COLY_0tc.Control = rB_layer_COLY_exp[0]; + + groupBox_layer_overlayYCorrelation_content.Rows[0].Cells.Add(rB_layer_COLY_0tc); + + int rB_COLY = 1; + int coly_rowIndex = 0; + for (int rb = 1; rb < CentralProperties.maxLayersForMC; rb++) + { + rB_layer_COLY_exp[rB_COLY] = new RadioButton(rB_layer_COLY_exp[0]); + rB_layer_COLY_exp[rB_COLY].Text = rB_COLY.ToString(); + rB_layer_COLY_exp[rB_COLY].Checked = false; + TableCell tc0 = new TableCell(); + tc0.Control = rB_layer_COLY_exp[rB_COLY]; + groupBox_layer_overlayYCorrelation_content.Rows[coly_rowIndex].Cells.Add(tc0); + // Wrap our positioning. + if (rB_COLY + 1 == CentralProperties.maxLayersForMC / 2) + { + coly_rowIndex++; + } + rB_COLY++; + } + } + } +} diff --git a/Common/Variance/UI/layerUI_setup_lop.cs b/Common/Variance/UI/layerUI_setup_lop.cs new file mode 100644 index 0000000..f0e9261 --- /dev/null +++ b/Common/Variance/UI/layerUI_setup_lop.cs @@ -0,0 +1,150 @@ +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm : Form + { + // 2D Layer Layout Origin Parameters + GroupBox groupBox_layer_LOP_exp; + DropDown comboBox_layerSubShapeRef_exp, comboBox_layerPosSubShape_exp; + Label lbl_layerSubShapeRef_exp, lbl_layerGlobalHorOffset_exp, lbl_layerGlobalVerOffset_exp, lbl_layerRotation_exp, lbl_layerPosSubShape_exp; + NumericStepper num_layerGlobalHorOffset_exp, num_layerGlobalVerOffset_exp, num_layerRotation_exp; + + void twoD_LayerUISetup_layoutOriginParameters_exp(TableCell tc) + { + Application.Instance.Invoke(() => + { + groupBox_layer_LOP_exp = new GroupBox(); + groupBox_layer_LOP_exp.Text = "Layout Origin Parameters"; + TableLayout groupBox_layer_LOP_table = new TableLayout(); + groupBox_layer_LOP_exp.Content = groupBox_layer_LOP_table; + + TableLayout t = new TableLayout(); + t.Rows.Add(new TableRow()); + t.Rows[0].Cells.Add(new TableCell() { Control = groupBox_layer_LOP_exp }); + t.Rows[0].Cells.Add(new TableCell() { Control = new Panel(), ScaleWidth = true }); + + Panel p = new Panel(); + p.Content = t; + tc.Control = p; + + lop_row1(groupBox_layer_LOP_table); + lop_row2(groupBox_layer_LOP_table); + }); + } + + void lop_row1(TableLayout groupBox_layer_LOP_table) + { + // Outer table, row 1 + TableRow lop_tr0 = new TableRow(); + groupBox_layer_LOP_table.Rows.Add(lop_tr0); + lop_tr0.Cells.Add(new TableCell()); + + // Table layout within row 1 + TableLayout row0_tl = new TableLayout(); + lop_tr0.Cells[0].Control = row0_tl; + row0_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lop_tr0_0 = new TableCell(); + row0_tl.Rows[0].Cells.Add(lop_tr0_0); + + TableLayout lop_tr0_0_tl = new TableLayout(); + lop_tr0_0.Control = lop_tr0_0_tl; + + lop_tr0_0_tl.Rows.Add(new TableRow()); + + lbl_layerSubShapeRef_exp = new Label(); + lbl_layerSubShapeRef_exp.Text = "Subshape Reference"; + lbl_layerSubShapeRef_exp.Width = 120; + lbl_layerSubShapeRef_exp.ToolTip = "Which subshape to use for placement with respect to the world origin"; + lop_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerSubShapeRef_exp }); + + comboBox_layerSubShapeRef_exp = new DropDown(); + comboBox_layerSubShapeRef_exp.DataContext = DataContext; + comboBox_layerSubShapeRef_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.subShapesList_exp); + comboBox_layerSubShapeRef_exp.SelectedIndex = 0; + comboBox_layerSubShapeRef_exp.ToolTip = "Which subshape to use for placement with respect to the world origin"; + lop_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = comboBox_layerSubShapeRef_exp }); + + lop_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = null }); + + lbl_layerPosSubShape_exp = new Label(); + lbl_layerPosSubShape_exp.Text = "Position inside Subshape"; + lbl_layerPosSubShape_exp.Width = 140; + lbl_layerPosSubShape_exp.ToolTip = "Which element of the subshape to use for placement with respect to the world origin"; + lop_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerPosSubShape_exp }); + + comboBox_layerPosSubShape_exp = new DropDown(); + comboBox_layerPosSubShape_exp.DataContext = DataContext; + comboBox_layerPosSubShape_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.subShapePos); + comboBox_layerPosSubShape_exp.SelectedIndex = (int)CommonVars.subShapeLocations.BL; + comboBox_layerPosSubShape_exp.ToolTip = "Which element of the subshape to use for placement with respect to the world origin"; + lop_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = comboBox_layerPosSubShape_exp }); + + } + + void lop_row2(TableLayout groupBox_layer_LOP_table) + { + // Outer table, row 1 + TableRow lop_tr1 = new TableRow(); + groupBox_layer_LOP_table.Rows.Add(lop_tr1); + lop_tr1.Cells.Add(new TableCell()); + + // Table layout within row 1 + TableLayout row1_tl = new TableLayout(); + lop_tr1.Cells[0].Control = row1_tl; + row1_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell lop_tr1_0 = new TableCell(); + row1_tl.Rows[0].Cells.Add(lop_tr1_0); + + TableLayout lop_tr1_0_tl = new TableLayout(); + lop_tr1_0.Control = lop_tr1_0_tl; + + lop_tr1_0_tl.Rows.Add(new TableRow()); + + lbl_layerGlobalHorOffset_exp = new Label(); + lbl_layerGlobalHorOffset_exp.Text = "Global Hor Offset"; + lbl_layerGlobalHorOffset_exp.Width = 120; + lbl_layerGlobalHorOffset_exp.ToolTip = "Horizontal offset from the world origin"; + lop_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerGlobalHorOffset_exp }); + + num_layerGlobalHorOffset_exp = new NumericStepper(); + num_layerGlobalHorOffset_exp.Increment = 0.1; + num_layerGlobalHorOffset_exp.DecimalPlaces = 2; + setSize(num_layerGlobalHorOffset_exp, 55, num_Height); + num_layerGlobalHorOffset_exp.ToolTip = "Horizontal offset from the world origin"; + lop_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layerGlobalHorOffset_exp) }); + + lbl_layerGlobalVerOffset_exp = new Label(); + lbl_layerGlobalVerOffset_exp.Text = "Global Ver Offset"; + lbl_layerGlobalVerOffset_exp.Width = 120; + lbl_layerGlobalVerOffset_exp.ToolTip = "Horizontal offset from the world origin"; + lop_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerGlobalVerOffset_exp }); + + num_layerGlobalVerOffset_exp = new NumericStepper(); + num_layerGlobalVerOffset_exp.Increment = 0.1; + num_layerGlobalVerOffset_exp.DecimalPlaces = 2; + setSize(num_layerGlobalVerOffset_exp, 55, num_Height); + num_layerGlobalVerOffset_exp.ToolTip = "Horizontal offset from the world origin"; + lop_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layerGlobalVerOffset_exp) }); + + lbl_layerRotation_exp = new Label(); + lbl_layerRotation_exp.Text = "Rotation"; + lbl_layerRotation_exp.Width = 70; + lbl_layerRotation_exp.ToolTip = "Counter-clockwise rotation around center of bounding box of shape"; + lop_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layerRotation_exp }); + + num_layerRotation_exp = new NumericStepper(); + num_layerRotation_exp.Increment = 0.1; + num_layerRotation_exp.DecimalPlaces = 2; + setSize(num_layerRotation_exp, 55, num_Height); + num_layerRotation_exp.ToolTip = "Counter-clockwise rotation around center of bounding box of shape"; + lop_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layerRotation_exp) }); + + lop_tr1_0_tl.Rows[0].Cells.Add(new TableCell() { Control = null }); + } + } +} diff --git a/Common/Variance/UI/layerUI_setup_subshape.cs b/Common/Variance/UI/layerUI_setup_subshape.cs new file mode 100644 index 0000000..02b2505 --- /dev/null +++ b/Common/Variance/UI/layerUI_setup_subshape.cs @@ -0,0 +1,257 @@ +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm : Form + { + // 2D Layer Shapes + GroupBox groupBox_layerSubShapes_exp; + NumericStepper num_layer_subshape_hl_exp, num_layer_subshape2_hl_exp, num_layer_subshape3_hl_exp, + num_layer_subshape_ho_exp, num_layer_subshape2_ho_exp, num_layer_subshape3_ho_exp, + num_layer_subshape_vl_exp, num_layer_subshape2_vl_exp, num_layer_subshape3_vl_exp, + num_layer_subshape_vo_exp, num_layer_subshape2_vo_exp, num_layer_subshape3_vo_exp; + Label lbl_layer_subshape_hl_exp, lbl_layer_subshape_ho_exp, lbl_layer_subshape_vl_exp, lbl_layer_subshape_vo_exp, lbl_layerTipLocations_exp; + DropDown comboBox_layerTipLocations_exp, comboBox_layerTipLocations2_exp, comboBox_layerTipLocations3_exp; + + void twoD_LayerUISetup_subShape_exp() + { + Application.Instance.Invoke(() => + { + groupBox_layerSubShapes_exp = new GroupBox(); + TableLayout groupBox_layerSubShapes_table = new TableLayout(); + groupBox_layerSubShapes_exp.Content = groupBox_layerSubShapes_table; + groupBox_layerSubShapes_exp.Text = "SubShapes"; + + subshapes_row1(groupBox_layerSubShapes_table); + + layerShapeProperties_tcPanel.Content = groupBox_layerSubShapes_exp; + + setLayerPropertiesContent(ref layerShapeProperties_tcPanel); + }); + } + + void subshapes_row1(TableLayout groupBox_layerSubShapes_table) + { + // Outer table, row 1 + TableRow subshapes_tr0 = new TableRow(); + groupBox_layerSubShapes_table.Rows.Add(subshapes_tr0); + subshapes_tr0.Cells.Add(new TableCell()); + + // Table layout within row 1 + TableLayout row0_tl = new TableLayout(); + subshapes_tr0.Cells[0].Control = row0_tl; + row0_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell sunshapes_tr0_0 = new TableCell(); + row0_tl.Rows[0].Cells.Add(sunshapes_tr0_0); + + TableLayout subshapes_tr0_0_tl = new TableLayout(); + sunshapes_tr0_0.Control = subshapes_tr0_0_tl; + + subshapes_tr0_0_tl.Rows.Add(new TableRow()); + + lbl_layer_subshape_hl_exp = new Label(); + lbl_layer_subshape_hl_exp.Text = "Hor. Length"; + subshapes_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_subshape_hl_exp }); + + TableLayout row0_1 = new TableLayout(); + Panel pr0 = new Panel() { Content = row0_1 }; + subshapes_tr0_0_tl.Rows[0].Cells.Add(new TableCell() { Control = pr0 }); + subshapes_tr0_0_tl.Rows[0].Cells[1].ScaleWidth = true; + + subshapes_row0_1(row0_1); + + subshapes_tr0_0_tl.Rows.Add(new TableRow()); + + lbl_layer_subshape_ho_exp = new Label(); + lbl_layer_subshape_ho_exp.Text = "Hor. Offset"; + subshapes_tr0_0_tl.Rows[1].Cells.Add(new TableCell() { Control = lbl_layer_subshape_ho_exp }); + + TableLayout row1_1 = new TableLayout(); + Panel pr1 = new Panel() { Content = row1_1 }; + subshapes_tr0_0_tl.Rows[1].Cells.Add(new TableCell() { Control = pr1 }); + subshapes_tr0_0_tl.Rows[1].Cells[1].ScaleWidth = true; + + subshapes_row1_1(row1_1); + + subshapes_tr0_0_tl.Rows.Add(new TableRow()); + + lbl_layerTipLocations_exp = new Label(); + lbl_layerTipLocations_exp.Text = "Tip Locs"; + subshapes_tr0_0_tl.Rows[2].Cells.Add(new TableCell() { Control = lbl_layerTipLocations_exp }); + + TableLayout row2_1 = new TableLayout(); + Panel pr2 = new Panel() { Content = row2_1 }; + subshapes_tr0_0_tl.Rows[2].Cells.Add(new TableCell() { Control = pr2 }); + subshapes_tr0_0_tl.Rows[2].Cells[1].ScaleWidth = true; + + subshapes_row2_1(row2_1); + } + + void subshapes_row0_1(TableLayout row0_1) + { + int numWidth = 55; + + row0_1.Rows.Add(new TableRow()); + + num_layer_subshape_hl_exp = new NumericStepper(); + num_layer_subshape_hl_exp.Increment = 0.1; + num_layer_subshape_hl_exp.DecimalPlaces = 2; + num_layer_subshape_hl_exp.MinValue = 0; + setSize(num_layer_subshape_hl_exp, numWidth, num_Height); + + row0_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape_hl_exp) }); + + num_layer_subshape2_hl_exp = new NumericStepper(); + num_layer_subshape2_hl_exp.Increment = 0.1; + num_layer_subshape2_hl_exp.DecimalPlaces = 2; + num_layer_subshape2_hl_exp.MinValue = 0; + setSize(num_layer_subshape2_hl_exp, numWidth, num_Height); + + row0_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape2_hl_exp) }); + + num_layer_subshape3_hl_exp = new NumericStepper(); + num_layer_subshape3_hl_exp.Increment = 0.1; + num_layer_subshape3_hl_exp.DecimalPlaces = 2; + num_layer_subshape3_hl_exp.MinValue = 0; + setSize(num_layer_subshape3_hl_exp, numWidth, num_Height); + + row0_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape3_hl_exp) }); + + row0_1.Rows[0].Cells.Add(new TableCell() { Control = new Panel() }); + row0_1.Rows[0].Cells[row0_1.Rows[0].Cells.Count - 1].ScaleWidth = true; + + lbl_layer_subshape_vl_exp = new Label(); + lbl_layer_subshape_vl_exp.Text = "Ver. Length"; + + row0_1.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_subshape_vl_exp }); + + num_layer_subshape_vl_exp = new NumericStepper(); + num_layer_subshape_vl_exp.Increment = 0.1; + num_layer_subshape_vl_exp.DecimalPlaces = 2; + num_layer_subshape_vl_exp.MinValue = 0; + setSize(num_layer_subshape_vl_exp, numWidth, num_Height); + + row0_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape_vl_exp) }); + + num_layer_subshape2_vl_exp = new NumericStepper(); + num_layer_subshape2_vl_exp.Increment = 0.1; + num_layer_subshape2_vl_exp.DecimalPlaces = 2; + num_layer_subshape2_vl_exp.MinValue = 0; + setSize(num_layer_subshape2_vl_exp, numWidth, num_Height); + + row0_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape2_vl_exp) }); + + num_layer_subshape3_vl_exp = new NumericStepper(); + num_layer_subshape3_vl_exp.Increment = 0.1; + num_layer_subshape3_vl_exp.DecimalPlaces = 2; + num_layer_subshape3_vl_exp.MinValue = 0; + setSize(num_layer_subshape3_vl_exp, numWidth, num_Height); + + row0_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape3_vl_exp) }); + } + + void subshapes_row1_1(TableLayout row1_1) + { + int numWidth = 55; + + row1_1.Rows.Add(new TableRow()); + + num_layer_subshape_ho_exp = new NumericStepper(); + num_layer_subshape_ho_exp.Increment = 0.1; + num_layer_subshape_ho_exp.DecimalPlaces = 2; + setSize(num_layer_subshape_ho_exp, numWidth, num_Height); + + row1_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape_ho_exp) }); + + num_layer_subshape2_ho_exp = new NumericStepper(); + num_layer_subshape2_ho_exp.Increment = 0.1; + num_layer_subshape2_ho_exp.DecimalPlaces = 2; + setSize(num_layer_subshape2_ho_exp, numWidth, num_Height); + + row1_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape2_ho_exp) }); + + num_layer_subshape3_ho_exp = new NumericStepper(); + num_layer_subshape3_ho_exp.Increment = 0.1; + num_layer_subshape3_ho_exp.DecimalPlaces = 2; + setSize(num_layer_subshape3_ho_exp, numWidth, num_Height); + + row1_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape3_ho_exp) }); + + row1_1.Rows[0].Cells.Add(new TableCell() { Control = new Panel() }); + row1_1.Rows[0].Cells[row1_1.Rows[0].Cells.Count - 1].ScaleWidth = true; + + lbl_layer_subshape_vo_exp = new Label(); + lbl_layer_subshape_vo_exp.Text = "Ver. Offset"; + + row1_1.Rows[0].Cells.Add(new TableCell() { Control = lbl_layer_subshape_vo_exp }); + + num_layer_subshape_vo_exp = new NumericStepper(); + num_layer_subshape_vo_exp.Increment = 0.1; + num_layer_subshape_vo_exp.DecimalPlaces = 2; + setSize(num_layer_subshape_vo_exp, numWidth, num_Height); + + row1_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape_vo_exp) }); + + num_layer_subshape2_vo_exp = new NumericStepper(); + num_layer_subshape2_vo_exp.Increment = 0.1; + num_layer_subshape2_vo_exp.DecimalPlaces = 2; + setSize(num_layer_subshape2_vo_exp, numWidth, num_Height); + + row1_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape2_vo_exp) }); + + num_layer_subshape3_vo_exp = new NumericStepper(); + num_layer_subshape3_vo_exp.Increment = 0.1; + num_layer_subshape3_vo_exp.DecimalPlaces = 2; + setSize(num_layer_subshape3_vo_exp, numWidth, num_Height); + + row1_1.Rows[0].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_layer_subshape3_vo_exp) }); + } + + void subshapes_row2_1(TableLayout row2_1) + { + row2_1.Rows.Add(new TableRow()); + + comboBox_layerTipLocations_exp = new DropDown(); + + row2_1.Rows[0].Cells.Add(new TableCell() { Control = comboBox_layerTipLocations_exp }); + + comboBox_layerTipLocations_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.tipLocs); + + comboBox_layerTipLocations2_exp = new DropDown(); + + row2_1.Rows[0].Cells.Add(new TableCell() { Control = comboBox_layerTipLocations2_exp }); + + comboBox_layerTipLocations2_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.tipLocs); + + comboBox_layerTipLocations3_exp = new DropDown(); + + row2_1.Rows[0].Cells.Add(new TableCell() { Control = comboBox_layerTipLocations3_exp }); + + comboBox_layerTipLocations3_exp.BindDataContext(c => c.DataStore, (UIStringLists m) => m.tipLocs); + } + + void subshapes_row2(TableLayout groupBox_layerSubShapes_table) + { + // Outer table, row 2 + TableRow subshapes_tr1 = new TableRow(); + groupBox_layerSubShapes_table.Rows.Add(subshapes_tr1); + subshapes_tr1.Cells.Add(new TableCell()); + + // Table layout within row 2 + TableLayout row1_tl = new TableLayout(); + subshapes_tr1.Cells[0].Control = row1_tl; + row1_tl.Rows.Add(new TableRow()); + + // Table layout within cell. + TableCell sunshapes_tr1_0 = new TableCell(); + row1_tl.Rows[0].Cells.Add(sunshapes_tr1_0); + + TableLayout subshapes_tr1_0_tl = new TableLayout(); + sunshapes_tr1_0.Control = subshapes_tr1_0_tl; + + subshapes_tr1_0_tl.Rows.Add(new TableRow()); + } + } +} diff --git a/Common/Variance/UI/oneDUI.cs b/Common/Variance/UI/oneDUI.cs new file mode 100644 index 0000000..79d9875 --- /dev/null +++ b/Common/Variance/UI/oneDUI.cs @@ -0,0 +1,922 @@ +using Eto.Forms; +using System; + +namespace Variance +{ + public partial class MainForm : Form + { + // 1D UI stuff + Label lbl_1D_Guidance, lbl_minins, lbl_nSigmaRule1D, lbl_threeSigmaRule1D, lbl_fourSigmaRule1D, lbl_sigmaEdgeTol1D, + lbl_threeSigmaEdgeTol1D, lbl_fourSigmaEdgeTol1D, + lbl_layerOnePhys, lbl_layerOneDrawn, lbl_layerOneBias, lbl_layerOneAddVar, lbl_layerOneLWR, lbl_layerOneCDU, + lbl_layerOneOverlayX, lbl_layerOneOverlayY, lbl_layerOneName, + lbl_layerTwoPhys, lbl_layerTwoDrawn, lbl_layerTwoBias, lbl_layerTwoAddVar, lbl_layerTwoLWR, lbl_layerTwoCDU, + lbl_layerTwoOverlayX, lbl_layerTwoOverlayY, lbl_layerTwoName; + TextBox text_minins, text_nSigmaEdgeTol1D, text_nSigmaRule1D, text_fourSigmaRule1D, text_threeSigmaRule1D, + input_nsigma1D, text_fourSigmaEdgeTol1D, text_threeSigmaEdgeTol1D, + text_layerOnePhys, text_layerOneDrawn, text_layerOneBias, text_layerOneAddVar, text_layerOneLWR, text_layerOneCDU, + text_layerOneOverlayX, text_layerOneOverlayY, text_layerOneName, + text_layerTwoPhys, text_layerTwoDrawn, text_layerTwoBias, text_layerTwoAddVar, text_layerTwoLWR, text_layerTwoCDU, + text_layerTwoOverlayX, text_layerTwoOverlayY, text_layerTwoName; + GroupBox groupBox_layerOne1D, groupBox_layerTwo1D, groupBox_results_1D; + + void InitializeTooltips_1D() + { + string xOverlay = "X overlay in nm"; + text_layerOneOverlayX.ToolTip = xOverlay; + lbl_layerOneOverlayX.ToolTip = xOverlay; + text_layerTwoOverlayX.ToolTip = xOverlay; + lbl_layerTwoOverlayX.ToolTip = xOverlay; + + string yOverlay = "Y overlay in nm"; + text_layerOneOverlayY.ToolTip = yOverlay; + lbl_layerOneOverlayY.ToolTip = yOverlay; + text_layerTwoOverlayY.ToolTip = yOverlay; + lbl_layerTwoOverlayY.ToolTip = yOverlay; + + string CDU = "CDU (per shape) in nm"; + text_layerOneCDU.ToolTip = CDU; + lbl_layerOneCDU.ToolTip = CDU; + text_layerTwoCDU.ToolTip = CDU; + lbl_layerTwoCDU.ToolTip = CDU; + + string LWR = "LWR (not LER!) in nm"; + text_layerOneLWR.ToolTip = LWR; + lbl_layerOneLWR.ToolTip = LWR; + text_layerTwoLWR.ToolTip = LWR; + lbl_layerTwoLWR.ToolTip = LWR; + + string miscVar = "Other variation in nm"; + text_layerOneAddVar.ToolTip = miscVar; + lbl_layerOneAddVar.ToolTip = miscVar; + text_layerTwoAddVar.ToolTip = miscVar; + lbl_layerTwoAddVar.ToolTip = miscVar; + + string bias = "Bias in nm"; + text_layerOneBias.ToolTip = bias; + lbl_layerOneBias.ToolTip = bias; + text_layerTwoBias.ToolTip = bias; + lbl_layerTwoBias.ToolTip = bias; + + string drawn = "Drawn width in nm"; + text_layerOneDrawn.ToolTip = drawn; + lbl_layerOneDrawn.ToolTip = drawn; + text_layerTwoDrawn.ToolTip = drawn; + lbl_layerTwoDrawn.ToolTip = drawn; + + string minins = "Minimum insulator in nm"; + text_minins.ToolTip = minins; + lbl_minins.ToolTip = minins; + + string nSigma = "Desired sigma value"; + input_nsigma1D.ToolTip = nSigma; + } + + void oneDTabSetup() + { + // 1D tab + tab_1DCalc_table = new TableLayout(); + + tab_1DCalc.Content = new Scrollable() { Content = TableLayout.AutoSized(tab_1DCalc_table, centered: true) }; + + tab_1DCalc_table.Rows.Add(new TableRow()); + lbl_1D_Guidance = new Label(); + lbl_1D_Guidance.Text = "All inputs should be 3-sigma values"; + lbl_1D_Guidance.Width = oneDGuidanceWidth; + tab_1DCalc_table.Rows[tab_1DCalc_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(lbl_1D_Guidance, centered: true) }); + + Panel oneDLayers_pnl = new Panel(); + tab_1DCalc_table.Rows.Add(new TableRow()); + tab_1DCalc_table.Rows[tab_1DCalc_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(oneDLayers_pnl, centered: true) }); + + oneDLayers_setup(ref oneDLayers_pnl); + + Panel minIns_pnl = new Panel(); + tab_1DCalc_table.Rows.Add(new TableRow()); + tab_1DCalc_table.Rows[tab_1DCalc_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = minIns_pnl }); + + TableLayout minIns_table = new TableLayout(); + minIns_pnl.Content = TableLayout.AutoSized(minIns_table, centered: true); + minIns_table.Rows.Add(new TableRow()); + + lbl_minins = new Label(); + lbl_minins.Width = oneDMinInsLblWidth; + lbl_minins.Text = "Minimum Insulator"; + minIns_table.Rows[minIns_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_minins }); + + text_minins = new TextBox(); + text_minins.Width = oneDMinInsWidth; + minIns_table.Rows[minIns_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_minins }); + text_minins.LostFocus += oneDEventHandler; + minIns_table.Rows[minIns_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding. + + // Image + Panel oneDImagePanel = new Panel(); + ImageView oneDImage = new ImageView(); + oneDImage.Image = resources.images.oneDImage(); + oneDImagePanel.Size = oneDImage.Image.Size; + oneDImagePanel.Content = oneDImage; + tab_1DCalc_table.Rows.Add(new TableRow()); + tab_1DCalc_table.Rows[tab_1DCalc_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(oneDImagePanel, centered: true) }); + + tab_1DCalc_table.Rows.Add(new TableRow()); + + Panel results_panel = new Panel(); + TableLayout results_tl = new TableLayout(); + results_panel.Content = results_tl; + results_tl.Rows.Add(new TableRow()); + + groupBox_results_1D = new GroupBox(); + results_tl.Rows[0].Cells.Add(new TableCell() { Control = groupBox_results_1D }); + results_tl.Rows[0].Cells.Add(new TableCell() { Control = null }); + + tab_1DCalc_table.Rows[tab_1DCalc_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(results_panel, centered: true) }); + + groupBox_results_1D.Text = "RESULTS"; + + TableLayout groupBox_results_1D_table = new TableLayout(); + groupBox_results_1D.Content = groupBox_results_1D_table; + + groupBox_results_1D_table.Rows.Add(new TableRow()); + + Panel left0 = new Panel(); + Panel right0 = new Panel(); + groupBox_results_1D_table.Rows[groupBox_results_1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = left0 }); + groupBox_results_1D_table.Rows[groupBox_results_1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = right0 }); + + TableLayout l0_tl = new TableLayout(); + left0.Content = l0_tl; + + l0_tl.Rows.Add(new TableRow()); + + Label lbl_threeSigmaEdgeTol1D_prefix = new Label(); + lbl_threeSigmaEdgeTol1D_prefix.Text = "3"; + + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_threeSigmaEdgeTol1D_prefix }); + + lbl_threeSigmaEdgeTol1D = new Label(); + lbl_threeSigmaEdgeTol1D.Text = "Sigma Edge Tolerance"; + + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_threeSigmaEdgeTol1D }); + + text_threeSigmaEdgeTol1D = new TextBox(); + text_threeSigmaEdgeTol1D.Width = 100; + text_threeSigmaEdgeTol1D.ReadOnly = true; + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_threeSigmaEdgeTol1D }); + + l0_tl.Rows.Add(new TableRow()); + + Label lbl_fourSigmaEdgeTol1D_prefix = new Label(); + lbl_fourSigmaEdgeTol1D_prefix.Text = "4"; + + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_fourSigmaEdgeTol1D_prefix }); + + lbl_fourSigmaEdgeTol1D = new Label(); + lbl_fourSigmaEdgeTol1D.Text = "Sigma Edge Tolerance"; + + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_fourSigmaEdgeTol1D }); + + text_fourSigmaEdgeTol1D = new TextBox(); + text_fourSigmaEdgeTol1D.Width = 100; + text_fourSigmaEdgeTol1D.ReadOnly = true; + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_fourSigmaEdgeTol1D }); + + l0_tl.Rows.Add(new TableRow()); + + input_nsigma1D = new TextBox(); + input_nsigma1D.Text = ""; + input_nsigma1D.Width = 20; + input_nsigma1D.TextChanged += oneDEventHandler; + + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = input_nsigma1D }); + + lbl_sigmaEdgeTol1D = new Label(); + lbl_sigmaEdgeTol1D.Text = "Sigma Edge Tolerance"; + + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_sigmaEdgeTol1D }); + + text_nSigmaEdgeTol1D = new TextBox(); + text_nSigmaEdgeTol1D.Width = 100; + text_nSigmaEdgeTol1D.ReadOnly = true; + l0_tl.Rows[l0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_nSigmaEdgeTol1D }); + + + TableLayout r0_tl = new TableLayout(); + right0.Content = r0_tl; + + r0_tl.Rows.Add(new TableRow()); + + Label lbl_threeSigmaRule1D_prefix = new Label(); + lbl_threeSigmaRule1D_prefix.Text = "3"; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_threeSigmaRule1D_prefix }); + + lbl_threeSigmaRule1D = new Label(); + lbl_threeSigmaRule1D.Text = "Sigma Rule"; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_threeSigmaRule1D }); + + text_threeSigmaRule1D = new TextBox(); + text_threeSigmaRule1D.Width = 100; + text_threeSigmaRule1D.ReadOnly = true; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_threeSigmaRule1D }); + + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + r0_tl.Rows.Add(new TableRow()); + + Label lbl_fourSigmaRule1D_prefix = new Label(); + lbl_fourSigmaRule1D_prefix.Text = "3"; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_fourSigmaRule1D_prefix }); + + lbl_fourSigmaRule1D = new Label(); + lbl_fourSigmaRule1D.Text = "Sigma Rule"; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_fourSigmaRule1D }); + + text_fourSigmaRule1D = new TextBox(); + text_fourSigmaRule1D.Width = 100; + text_fourSigmaRule1D.ReadOnly = true; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_fourSigmaRule1D }); + + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + r0_tl.Rows.Add(new TableRow()); + + Label lbl_nSigmaRule1D_prefix = new Label(); + lbl_nSigmaRule1D_prefix.Text = "n"; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_nSigmaRule1D_prefix }); + + lbl_nSigmaRule1D = new Label(); + lbl_nSigmaRule1D.Text = "Sigma Rule"; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_nSigmaRule1D }); + + text_nSigmaRule1D = new TextBox(); + text_nSigmaRule1D.Width = 100; + text_nSigmaRule1D.ReadOnly = true; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_nSigmaRule1D }); + + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + InitializeTooltips_1D(); + } + + void oneDLayers_setup(ref Panel oneDLayers_pnl) + { + TableLayout oneDLayers_table = new TableLayout(); + oneDLayers_pnl.Content = oneDLayers_table; + oneDLayers_table.Rows.Add(new TableRow()); + + // Layer 1 group box for 1D. + groupBox_layerOne1D = new GroupBox(); + groupBox_layerOne1D.Text = "LAYER #1"; + TableLayout groupBox_layerOne1D_table = new TableLayout(); + groupBox_layerOne1D.Content = groupBox_layerOne1D_table; + oneDLayers_table.Rows[0].Cells.Add(new TableCell() { Control = groupBox_layerOne1D }); + + // Layer 2 group box for 1D. + groupBox_layerTwo1D = new GroupBox(); + groupBox_layerTwo1D.Text = "LAYER #2"; + TableLayout groupBox_layerTwo1D_table = new TableLayout(); + groupBox_layerTwo1D.Content = groupBox_layerTwo1D_table; + oneDLayers_table.Rows[0].Cells.Add(new TableCell() { Control = groupBox_layerTwo1D }); + + oneDLayer1_setup(groupBox_layerOne1D_table); + + oneDLayer2_setup(groupBox_layerTwo1D_table); + + oneDLayers_table.Rows[0].Cells.Add(new TableCell() { Control = null }); // Padding + + } + + void oneDLayer1_setup(TableLayout groupBox_layerOne1D_table) + { + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOneName = new Label(); + lbl_layerOneName.Width = oneDLabelWidth; + lbl_layerOneName.Text = "Name"; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOneName, ScaleWidth = true }); + + text_layerOneName = new TextBox(); + text_layerOneName.Width = 100; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOneName }); + + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOneOverlayX = new Label(); + lbl_layerOneOverlayX.Width = oneDLabelWidth; + lbl_layerOneOverlayX.Text = "Overlay X"; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOneOverlayX, ScaleWidth = true }); + + text_layerOneOverlayX = new TextBox(); + text_layerOneOverlayX.Width = 100; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOneOverlayX }); + text_layerOneOverlayX.LostFocus += oneDEventHandler; + + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOneOverlayY = new Label(); + lbl_layerOneOverlayY.Width = oneDLabelWidth; + lbl_layerOneOverlayY.Text = "Overlay Y"; + + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOneOverlayY, ScaleWidth = true }); + + text_layerOneOverlayY = new TextBox(); + text_layerOneOverlayY.Width = 100; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOneOverlayY }); + text_layerOneOverlayY.LostFocus += oneDEventHandler; + + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOneCDU = new Label(); + lbl_layerOneCDU.Width = oneDLabelWidth; + lbl_layerOneCDU.Text = "CDU"; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOneCDU, ScaleWidth = true }); + + text_layerOneCDU = new TextBox(); + text_layerOneCDU.Width = 100; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOneCDU }); + text_layerOneCDU.LostFocus += oneDEventHandler; + + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOneLWR = new Label(); + lbl_layerOneLWR.Width = oneDLabelWidth; + lbl_layerOneLWR.Text = "LWR"; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOneLWR, ScaleWidth = true }); + + text_layerOneLWR = new TextBox(); + text_layerOneLWR.Width = 100; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOneLWR }); + text_layerOneLWR.LostFocus += oneDEventHandler; + + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOneAddVar = new Label(); + lbl_layerOneAddVar.Width = oneDLabelWidth; + lbl_layerOneAddVar.Text = "Other variation"; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOneAddVar, ScaleWidth = true }); + + text_layerOneAddVar = new TextBox(); + text_layerOneAddVar.Width = 100; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOneAddVar }); + text_layerOneAddVar.LostFocus += oneDEventHandler; + + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOneBias = new Label(); + lbl_layerOneBias.Width = oneDLabelWidth; + lbl_layerOneBias.Text = "Bias"; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOneBias, ScaleWidth = true }); + + text_layerOneBias = new TextBox(); + text_layerOneBias.Width = 100; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOneBias }); + text_layerOneBias.LostFocus += oneDEventHandler; + + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOneDrawn = new Label(); + lbl_layerOneDrawn.Width = oneDLabelWidth; + lbl_layerOneDrawn.Text = "Drawn"; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOneDrawn, ScaleWidth = true }); + + text_layerOneDrawn = new TextBox(); + text_layerOneDrawn.Width = 100; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOneDrawn }); + text_layerOneDrawn.LostFocus += oneDEventHandler; + + groupBox_layerOne1D_table.Rows.Add(new TableRow()); + + lbl_layerOnePhys = new Label(); + lbl_layerOnePhys.Width = oneDLabelWidth; + lbl_layerOnePhys.Text = "Physical"; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerOnePhys, ScaleWidth = true }); + + text_layerOnePhys = new TextBox(); + text_layerOnePhys.Width = 100; + text_layerOnePhys.ReadOnly = true; + groupBox_layerOne1D_table.Rows[groupBox_layerOne1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerOnePhys }); + } + + void oneDLayer2_setup(TableLayout groupBox_layerTwo1D_table) + { + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoName = new Label(); + lbl_layerTwoName.Width = oneDLabelWidth; + lbl_layerTwoName.Text = "Name"; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoName, ScaleWidth = true }); + + text_layerTwoName = new TextBox(); + text_layerTwoName.Width = 100; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoName }); + + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoOverlayX = new Label(); + lbl_layerTwoOverlayX.Width = oneDLabelWidth; + lbl_layerTwoOverlayX.Text = "Overlay X"; + + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoOverlayX, ScaleWidth = true }); + + text_layerTwoOverlayX = new TextBox(); + text_layerTwoOverlayX.Width = 100; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoOverlayX }); + text_layerTwoOverlayX.LostFocus += oneDEventHandler; + + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoOverlayY = new Label(); + lbl_layerTwoOverlayY.Width = oneDLabelWidth; + lbl_layerTwoOverlayY.Text = "Overlay Y"; + + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoOverlayY, ScaleWidth = true }); + + text_layerTwoOverlayY = new TextBox(); + text_layerTwoOverlayY.Width = 100; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoOverlayY }); + text_layerTwoOverlayY.LostFocus += oneDEventHandler; + + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoCDU = new Label(); + lbl_layerTwoCDU.Width = oneDLabelWidth; + lbl_layerTwoCDU.Text = "CDU"; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoCDU, ScaleWidth = true }); + + text_layerTwoCDU = new TextBox(); + text_layerTwoCDU.Width = 100; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoCDU }); + text_layerTwoCDU.LostFocus += oneDEventHandler; + + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoLWR = new Label(); + lbl_layerTwoLWR.Width = oneDLabelWidth; + lbl_layerTwoLWR.Text = "LWR"; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoLWR, ScaleWidth = true }); + + text_layerTwoLWR = new TextBox(); + text_layerTwoLWR.Width = 100; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoLWR }); + text_layerTwoLWR.LostFocus += oneDEventHandler; + + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoAddVar = new Label(); + lbl_layerTwoAddVar.Width = oneDLabelWidth; + lbl_layerTwoAddVar.Text = "Other variation"; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoAddVar, ScaleWidth = true }); + + text_layerTwoAddVar = new TextBox(); + text_layerTwoAddVar.Width = 100; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoAddVar }); + text_layerTwoAddVar.LostFocus += oneDEventHandler; + + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoBias = new Label(); + lbl_layerTwoBias.Width = oneDLabelWidth; + lbl_layerTwoBias.Text = "Bias"; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoBias, ScaleWidth = true }); + + text_layerTwoBias = new TextBox(); + text_layerTwoBias.Width = 100; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoBias }); + text_layerTwoBias.LostFocus += oneDEventHandler; + + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoDrawn = new Label(); + lbl_layerTwoDrawn.Width = oneDLabelWidth; + lbl_layerTwoDrawn.Text = "Drawn"; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoDrawn, ScaleWidth = true }); + + text_layerTwoDrawn = new TextBox(); + text_layerTwoDrawn.Width = 100; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoDrawn }); + text_layerTwoDrawn.LostFocus += oneDEventHandler; + + groupBox_layerTwo1D_table.Rows.Add(new TableRow()); + + lbl_layerTwoPhys = new Label(); + lbl_layerTwoPhys.Width = oneDLabelWidth; + lbl_layerTwoPhys.Text = "Physical"; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_layerTwoPhys, ScaleWidth = true }); + + text_layerTwoPhys = new TextBox(); + text_layerTwoPhys.Width = 100; + text_layerTwoPhys.ReadOnly = true; + groupBox_layerTwo1D_table.Rows[groupBox_layerTwo1D_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_layerTwoPhys }); + } + + void oneDEventHandler(object sender, EventArgs e) + { + do1DPhysical(); + do1DCalculation(); + } + + void do1DPhysical() + { + int layer1OK1; + int layer1OK2; + int layer2OK1; + int layer2OK2; + double layer1Bias = 0.0f; + double layer1Drawn = 0.0f; + double layer2Bias = 0.0f; + double layer2Drawn = 0.0f; + try + { + layer1Bias = double.Parse(text_layerOneBias.Text); + layer1OK1 = 1; + } + catch (ArgumentNullException) + { + layer1OK1 = 0; + } + catch (FormatException) + { + layer1OK1 = 0; + } + try + { + layer1Drawn = double.Parse(text_layerOneDrawn.Text); + layer1OK2 = 1; + } + catch (ArgumentNullException) + { + layer1OK2 = 0; + } + catch (FormatException) + { + layer1OK2 = 0; + } + try + { + layer2Bias = double.Parse(text_layerTwoBias.Text); + layer2OK1 = 1; + } + catch (ArgumentNullException) + { + layer2OK1 = 0; + } + catch (FormatException) + { + layer2OK1 = 0; + } + try + { + layer2Drawn = double.Parse(text_layerTwoDrawn.Text); + layer2OK2 = 1; + } + catch (ArgumentNullException) + { + layer2OK2 = 0; + } + catch (FormatException) + { + layer2OK2 = 0; + } + double physicalValueLayer1 = (layer1OK2 * layer1Drawn) + (layer1OK1 * layer1Bias); + double physicalValueLayer2 = (layer2OK2 * layer2Drawn) + (layer2OK1 * layer2Bias); + + if (physicalValueLayer1 != 0.0f) + { + text_layerOnePhys.Text = physicalValueLayer1.ToString(); + } + else + { + text_layerOnePhys.Text = ""; + } + if (physicalValueLayer2 != 0.0f) + { + text_layerTwoPhys.Text = physicalValueLayer2.ToString(); + } + else + { + text_layerTwoPhys.Text = ""; + } + } + + void do1DCalculation() + { + Boolean inputValid = true; + Boolean nSigmaReq = false; + + // Take our inputs and validate the conversion to double in each case. + // No magic here.\ + double nSigmaValue = 0.0f; + double layer1OverlayX = 0.0f; + double layer1OverlayY = 0.0f; + double layer2OverlayX = 0.0f; + double layer2OverlayY = 0.0f; + double layer1CDU = 0.0f; + double layer1LWR = 0.0f; + double layer2CDU = 0.0f; + double layer2LWR = 0.0f; + double layer1Bias = 0.0f; + double layer2Bias = 0.0f; + double layer1AddVar = 0.0f; + double layer2AddVar = 0.0f; + double minIns = 0.0f; + + try + { + nSigmaValue = double.Parse(input_nsigma1D.Text); + nSigmaReq = true; + } + catch (ArgumentNullException) + { + nSigmaReq = false; + } + catch (FormatException) + { + nSigmaReq = false; + } + + try + { + layer1OverlayX = double.Parse(text_layerOneOverlayX.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer1OverlayY = double.Parse(text_layerOneOverlayY.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer1CDU = double.Parse(text_layerOneCDU.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + try + { + layer1LWR = double.Parse(text_layerOneLWR.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + if (!inputValid) + { + reset1DFields(); + return; + } + try + { + layer1AddVar = double.Parse(text_layerOneAddVar.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer1Bias = double.Parse(text_layerOneBias.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer2OverlayX = double.Parse(text_layerTwoOverlayX.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer2OverlayY = double.Parse(text_layerTwoOverlayY.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer2CDU = double.Parse(text_layerTwoCDU.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer2LWR = double.Parse(text_layerTwoLWR.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer2AddVar = double.Parse(text_layerTwoAddVar.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + layer2Bias = double.Parse(text_layerTwoBias.Text); + } + catch (ArgumentNullException) + { + inputValid = false; + } + catch (FormatException) + { + inputValid = false; + } + + if (!inputValid) + { + reset1DFields(); + return; + } + + try + { + minIns = double.Parse(text_minins.Text); + } + catch (ArgumentNullException) + { + } + catch (FormatException) + { + } + + + // OK - if we have invalid input, let's blank our output targets. + if (inputValid == true) + { + double threeSigma = UtilityFuncs.do1DCalculation_3sig( + layer1OverlayX, layer1OverlayY, layer1CDU, layer1LWR, layer1Bias, layer1AddVar, + layer2OverlayX, layer2OverlayY, layer2CDU, layer2LWR, layer2Bias, layer2AddVar, minIns); + double threeSigmaEdge = UtilityFuncs.do1DCalculation_3sig_edge( + layer1OverlayX, layer1OverlayY, layer1CDU, layer1LWR, layer1AddVar, + layer2OverlayX, layer2OverlayY, layer2CDU, layer2LWR, layer2AddVar); + text_threeSigmaRule1D.Text = threeSigma.ToString("0.##"); + text_threeSigmaEdgeTol1D.Text = threeSigmaEdge.ToString("0.##"); + + double fourSigma = UtilityFuncs.do1DCalculation_4sig( + layer1OverlayX, layer1OverlayY, layer1CDU, layer1LWR, layer1Bias, layer1AddVar, + layer2OverlayX, layer2OverlayY, layer2CDU, layer2LWR, layer2Bias, layer2AddVar, minIns); + double fourSigmaEdge = (4 * threeSigmaEdge) / 3; + + text_fourSigmaRule1D.Text = fourSigma.ToString("0.##"); + text_fourSigmaEdgeTol1D.Text = fourSigmaEdge.ToString("0.##"); + if (nSigmaReq == true) + { + double nSigma = UtilityFuncs.do1DCalculation_nsig(nSigmaValue, + layer1OverlayX, layer1OverlayY, layer1CDU, layer1LWR, layer1Bias, layer1AddVar, + layer2OverlayX, layer2OverlayY, layer2CDU, layer2LWR, layer2Bias, layer2AddVar, minIns); + double nSigmaEdge = (nSigmaValue * threeSigmaEdge) / 3; + text_nSigmaRule1D.Text = nSigma.ToString("0.##"); + text_nSigmaEdgeTol1D.Text = nSigmaEdge.ToString("0.##"); + } + else + { + text_nSigmaRule1D.Text = ""; + } + } + else + { + reset1DFields(); + } + + } + + void reset1DFields() + { + text_threeSigmaRule1D.Text = ""; + text_fourSigmaRule1D.Text = ""; + text_nSigmaRule1D.Text = ""; + text_threeSigmaEdgeTol1D.Text = ""; + text_fourSigmaEdgeTol1D.Text = ""; + text_nSigmaEdgeTol1D.Text = ""; + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/paSearchUI.cs b/Common/Variance/UI/paSearchUI.cs new file mode 100644 index 0000000..77b19a2 --- /dev/null +++ b/Common/Variance/UI/paSearchUI.cs @@ -0,0 +1,328 @@ +using Eto.Forms; +using System; + +namespace Variance +{ + public partial class MainForm : Form + { + Label[] lbl_paSearchLayers, lbl_paSearchPAs; + CheckBox[,] cb_searchPA; + NumericStepper[,] num_searchPA_UpperLimit; + TextBox[,] text_searchPA_Result; + + GroupBox[] groupBox_passCaseValues; + CheckBox[] cb_passCaseValues; + NumericStepper[] num_passCaseValues; + RadioButton[,] rb_passValueRadioButtons; + + Label lbl_passCase, lbl_paSearch_readOut; + NumericStepper num_passCase; + TextBox text_paSearch; + + TableLayout resultFilter_table; + + bool paSearchUIFrozen; + + void paSearchUI_setup() + { + paSearchUIFrozen = true; + + lbl_paSearchLayers = new Label[CentralProperties.maxLayersForMC]; + lbl_paSearchPAs = new Label[PASearch.paNames.Length]; + cb_searchPA = new CheckBox[lbl_paSearchLayers.Length, lbl_paSearchPAs.Length]; + num_searchPA_UpperLimit = new NumericStepper[lbl_paSearchLayers.Length, lbl_paSearchPAs.Length]; + text_searchPA_Result = new TextBox[lbl_paSearchLayers.Length, lbl_paSearchPAs.Length]; + + tabPage_2D_PASearch_table.Rows.Add(new TableRow()); + + Panel row0 = new Panel(); + tabPage_2D_PASearch_table.Rows[tabPage_2D_PASearch_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row0 }); + paSearchUI_setup_row0(ref row0); + + tabPage_2D_PASearch_table.Rows.Add(new TableRow()); + + Panel row1 = new Panel(); + tabPage_2D_PASearch_table.Rows[tabPage_2D_PASearch_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row1 }); + paSearchUI_setup_row1(ref row1); + + tabPage_2D_PASearch_table.Rows.Add(new TableRow()); + + Panel row2 = new Panel(); + tabPage_2D_PASearch_table.Rows[tabPage_2D_PASearch_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row2 }); + paSearchUI_setup_row2(ref row2); + + tabPage_2D_PASearch_table.Rows.Add(new TableRow()); // padding. + + updatePASearchUI(); + + paSearchUIFrozen = false; + } + + void paSearchUI_setup_row0(ref Panel p) + { + TableLayout row0_tl = new TableLayout(); + p.Content = row0_tl; + row0_tl.Rows.Add(new TableRow()); + + lbl_passCase = new Label(); + lbl_passCase.Text = "Pass Cases to Find"; + lbl_passCase.ToolTip = "Minimum number of pass cases to find."; + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_passCase }); + + num_passCase = new NumericStepper(); + num_passCase.Increment = 1; + num_passCase.MinValue = 1; + num_passCase.Value = 25000; + num_passCase.LostFocus += paSearchUI_Handler; + num_passCase.ToolTip = "Minimum number of pass cases to find."; + setSize(num_passCase, 80, num_Height); + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_passCase) }); + + lbl_paSearch_readOut = new Label(); + lbl_paSearch_readOut.Text = "Last result:"; + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_paSearch_readOut }); + + text_paSearch = new TextBox(); + text_paSearch.ReadOnly = true; + text_paSearch.Width = resultFieldWidth; + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_paSearch }); + + row0_tl.Rows[row0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + } + + void paSearchUI_setup_row1(ref Panel p) + { + resultFilter_table = new TableLayout(); + p.Content = resultFilter_table; + resultFilter_table.Rows.Add(new TableRow()); + + // Chords provide 4 entries, so we need 4 potential limiting values. + groupBox_passCaseValues = new GroupBox[4]; + cb_passCaseValues = new CheckBox[4]; + num_passCaseValues = new NumericStepper[4]; + rb_passValueRadioButtons = new RadioButton[4, 2]; + Panel[] passCaseValues_pnl = new Panel[4]; + + for (int passCaseVal = 0; passCaseVal < cb_passCaseValues.Length; passCaseVal++) + { + var i = passCaseVal; // for event handler binding. + + groupBox_passCaseValues[passCaseVal] = new GroupBox(); + groupBox_passCaseValues[passCaseVal].Text = "Filter result " + passCaseVal.ToString(); + + passCaseValues_pnl[passCaseVal] = new Panel(); + passCaseValues_pnl[passCaseVal].Content = groupBox_passCaseValues[passCaseVal]; + + TableLayout tl = new TableLayout(); + groupBox_passCaseValues[passCaseVal].Content = tl; + + tl.Rows.Add(new TableRow()); + + cb_passCaseValues[passCaseVal] = new CheckBox(); + cb_passCaseValues[passCaseVal].Text = ""; + cb_passCaseValues[i].CheckedChanged += paSearchUI_Handler; + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = cb_passCaseValues[passCaseVal] }); + + rb_passValueRadioButtons[passCaseVal, 0] = new RadioButton(); + rb_passValueRadioButtons[passCaseVal, 0].Text = "Min"; + rb_passValueRadioButtons[passCaseVal, 0].Checked = true; + rb_passValueRadioButtons[passCaseVal, 0].Enabled = false; + rb_passValueRadioButtons[i, 0].CheckedChanged += paSearchUI_Handler; + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = rb_passValueRadioButtons[i, 0] }); + + rb_passValueRadioButtons[passCaseVal, 1] = new RadioButton(rb_passValueRadioButtons[passCaseVal, 0]); + rb_passValueRadioButtons[passCaseVal, 1].Text = "Max"; + rb_passValueRadioButtons[passCaseVal, 1].Enabled = false; + rb_passValueRadioButtons[i, 1].CheckedChanged += paSearchUI_Handler; + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = rb_passValueRadioButtons[i, 1] }); + + num_passCaseValues[passCaseVal] = new NumericStepper(); + num_passCaseValues[passCaseVal].DecimalPlaces = 2; + num_passCaseValues[passCaseVal].Increment = 0.01f; + setSize(num_passCaseValues[passCaseVal], 55, num_Height); + num_passCaseValues[passCaseVal].Enabled = false; + num_passCaseValues[i].LostFocus += paSearchUI_Handler; + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_passCaseValues[passCaseVal]) }); + + resultFilter_table.Rows[resultFilter_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = passCaseValues_pnl[passCaseVal] }); + } + resultFilter_table.Rows[resultFilter_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + } + + void paSearchUI_setup_row2(ref Panel p) + { + TableLayout tabPage_2D_PASearch_bigTable = new TableLayout(); + p.Content = tabPage_2D_PASearch_bigTable; + + tabPage_2D_PASearch_bigTable.Rows.Add(new TableRow()); // header row + + tabPage_2D_PASearch_bigTable.Rows[0].Cells.Add(new TableCell() { Control = null }); // blank, for row header + + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + lbl_paSearchLayers[layer] = new Label(); + lbl_paSearchLayers[layer].Text = (layer + 1).ToString(); + lbl_paSearchLayers[layer].TextColor = UIHelper.myColorToColor(commonVars.getColors().simPreviewColors[layer]); + lbl_paSearchLayers[layer].TextAlignment = TextAlignment.Center; + + tabPage_2D_PASearch_bigTable.Rows[0].Cells.Add(new TableCell() { Control = lbl_paSearchLayers[layer] }); + } + + for (int pa = 0; pa < PASearch.paNames.Length; pa++) + { + TableRow tr = new TableRow(); + + lbl_paSearchPAs[pa] = new Label(); + lbl_paSearchPAs[pa].Text = PASearch.paNames[pa]; + tr.Cells.Add(new TableCell() { Control = lbl_paSearchPAs[pa] }); + + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + Panel bTc_p = new Panel(); + TableLayout tmp_tl = new TableLayout(); + bTc_p.Content = tmp_tl; + + // Upper row of tmp_tl + tmp_tl.Rows.Add(new TableRow()); + Panel tc0p = new Panel(); + tmp_tl.Rows[0].Cells.Add(new TableCell() { Control = tc0p }); + + TableLayout tc0p_tl = new TableLayout(); + tc0p.Content = tc0p_tl; + tc0p_tl.Rows.Add(new TableRow()); + + TableCell tc_ur_0 = new TableCell(); + cb_searchPA[layer, pa] = new CheckBox(); + cb_searchPA[layer, pa].Text = ""; + cb_searchPA[layer, pa].CheckedChanged += paSearchUI_Handler; + cb_searchPA[layer, pa].ToolTip = "Layer " + (pa + 1).ToString() + ": " + PASearch.paNames[pa]; + tc_ur_0.Control = cb_searchPA[layer, pa]; + tc0p_tl.Rows[0].Cells.Add(tc_ur_0); + + TableCell tc_ur_1 = new TableCell(); + num_searchPA_UpperLimit[layer, pa] = new NumericStepper(); + num_searchPA_UpperLimit[layer, pa].Increment = 0.01f; + num_searchPA_UpperLimit[layer, pa].DecimalPlaces = 2; + if (!commonVars.getPASearch().paAllowsNegativeValues(pa)) + { + num_searchPA_UpperLimit[layer, pa].MinValue = 0; + } + num_searchPA_UpperLimit[layer, pa].TextColor = UIHelper.myColorToColor(commonVars.getColors().simPreviewColors[layer]); + num_searchPA_UpperLimit[layer, pa].ToolTip = "Layer " + (layer + 1).ToString() + ": " + PASearch.paNames[pa]; + + setSize(num_searchPA_UpperLimit[layer, pa], 55, label_Height * 2); + num_searchPA_UpperLimit[layer, pa].LostFocus += paSearchUI_Handler; + tc_ur_1.Control = TableLayout.AutoSized(num_searchPA_UpperLimit[layer, pa]); + + tc0p_tl.Rows[0].Cells.Add(tc_ur_1); + + // Lower row of tmp_tl + tmp_tl.Rows.Add(new TableRow()); + + text_searchPA_Result[layer, pa] = new TextBox(); + text_searchPA_Result[layer, pa].ReadOnly = true; + text_searchPA_Result[layer, pa].Width = 55 * 2; + text_searchPA_Result[layer, pa].TextColor = UIHelper.myColorToColor(commonVars.getColors().simPreviewColors[layer]); + text_searchPA_Result[layer, pa].ToolTip = "Layer " + (layer + 1).ToString() + ": " + PASearch.paNames[pa]; + tmp_tl.Rows[1].Cells.Add(new TableCell() { Control = text_searchPA_Result[layer, pa] }); + + tr.Cells.Add(new TableCell() { Control = bTc_p }); + } + tabPage_2D_PASearch_bigTable.Rows.Add(tr); + } + } + + void paSearchUI_Handler(object sender, EventArgs e) + { + updatePASearchUI(); + } + + void updatePASearchUI(int layer) + { + bool[] paEnabledState = commonVars.getPASearch().getEnabledState(commonVars.getLayerSettings(layer)); + for (int i = 0; i < paEnabledState.Length; i++) + { + cb_searchPA[layer, i].Enabled = paEnabledState[i]; + if (!paEnabledState[i]) + { + cb_searchPA[layer, i].Checked = false; + } + num_searchPA_UpperLimit[layer, i].Enabled = (bool)cb_searchPA[layer, i].Checked; + commonVars.getPASearch().setUpperLimit(layer, i, (decimal)num_searchPA_UpperLimit[layer, i].Value); + + commonVars.getPASearch().setPASearchable(layer, i, (bool)cb_searchPA[layer, i].Checked); + } + } + + void updatePASearchUI() + { + if (paSearchUIFrozen) + { + return; + } + + paSearchUIFrozen = true; + + commonVars.getPASearch().numberofPassCases = (Int32)num_passCase.Value; + + for (int i = 0; i < groupBox_passCaseValues.Length; i++) + { + num_passCaseValues[i].Enabled = (bool)cb_passCaseValues[i].Checked; + rb_passValueRadioButtons[i, 0].Enabled = (bool)cb_passCaseValues[i].Checked; + rb_passValueRadioButtons[i, 1].Enabled = (bool)cb_passCaseValues[i].Checked; + + commonVars.getPASearch().filterValues[i] = num_passCaseValues[i].Value; + commonVars.getPASearch().filterIsMaxValue[i] = rb_passValueRadioButtons[i, 1].Checked; + } + + bool chordMode = commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.chord; + for (int i = 0; i < groupBox_passCaseValues.Length; i++) + { + if (!chordMode) + { + groupBox_passCaseValues[i].Enabled = chordMode; + cb_passCaseValues[i].Checked = false; + } + commonVars.getPASearch().useFilter[i] = (bool)cb_passCaseValues[i].Checked; + } + if (!chordMode) + { + groupBox_passCaseValues[0].Enabled = true; + cb_passCaseValues[0].Checked = true; + commonVars.getPASearch().useFilter[0] = true; + } + + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + updatePASearchUI(layer); + } + + paSearchUIFrozen = false; + } + + void paSearchUI_showResults(SimResultPackage resultPackage) + { + commonVars.getPASearch().calculateMeanAndStdDev(resultPackage); + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + for (int pa = 0; pa < PASearch.paNames.Length; pa++) + { + Application.Instance.Invoke(() => + { + if (commonVars.getPASearch().isPASearchable(layer, pa)) + { + text_searchPA_Result[layer, pa].Text = "x:" + commonVars.getPASearch().getMeanValue(layer, pa) + ", s:" + commonVars.getPASearch().getSDValue(layer, pa); + } + else + { + text_searchPA_Result[layer, pa].Text = ""; + } + }); + } + } + + updateProgressBar(resultPackage.getListOfResults().Count); + updateStatusLine("PA Search for " + resultPackage.getListOfResults().Count.ToString() + " results in " + resultPackage.runTime.ToString("0.##") + " seconds."); + } + } +} \ No newline at end of file diff --git a/Common/Variance/UI/simulationUI.cs b/Common/Variance/UI/simulationUI.cs new file mode 100644 index 0000000..35a4b16 --- /dev/null +++ b/Common/Variance/UI/simulationUI.cs @@ -0,0 +1,841 @@ +using color; +using Eto.Forms; + +namespace Variance +{ + public partial class MainForm : Form + { + Button btn_Switch12, btn_Switch23, btn_Switch34, btn_Switch56, btn_Switch67, btn_Switch78, + btn_Switch910, btn_Switch1011, btn_Switch1112, btn_Switch1314, btn_Switch1415, btn_Switch1516, + btn_Switch15, btn_Switch26, btn_Switch37, btn_Switch48, btn_Switch913, btn_Switch1014, btn_Switch1115, btn_Switch1216, btn_SwitchA, btn_SwitchB; + + DropDown[] comboBox_geoEqtn_Op; // container to simplify access to the menus programmatically. + DropDown[] comboBox_geoEqtn_Op_2Layer; + DropDown[] comboBox_geoEqtn_Op_4Layer; + DropDown[] comboBox_geoEqtn_Op_8Layer; + DropDown comboBox_calcModes, comboBox_RNG, comboBox_externalTypes; + + Label[] label_geoEqtn_Op; // container to simplify access to the menus programmatically. + Label label_AB, lbl_multiThreadResultNote, lbl_ssNumOfCases, lbl_ssPrecision, + lbl_cornerSegments, lbl_rng, lbl_ssTotalPoints, lbl_testArea; + + GroupBox groupBox_setOutput, groupBox_GeoEqtn, groupBox_GeoEqtnA, groupBox_GeoEqtnB, groupBox_simSettings; + + CheckBox checkBox_withinMode, checkBox_useShortestEdge, checkBox_aChord, checkBox_bChord, + checkBox_limitCornerPoints, checkBox_greedyMultiCPU, checkBox_linkCDUVariation, + checkBox_LERMode, checkBox_external, checkBox_CSV, checkBox_debugCalc, + checkBox_perPoly; + + TextArea textBox_userGuidance; + TextBox text_ssTotalPoints, text_testArea; + + NumericStepper num_ssPrecision, num_cornerSegments, num_ssNumOfCases; + + CheckBox checkBox_replay; + + GroupBox groupBox_replay; + + Button button_replay; + + NumericStepper num_replay; + + TableLayout tabPage_2D_Settings_table; + + void twoD_SettingsUISetup() + { + tabPage_2D_Settings_table.Rows.Add(new TableRow()); + + TableCell upper_tc = new TableCell(); + tabPage_2D_Settings_table.Rows[tabPage_2D_Settings_table.Rows.Count - 1].Cells.Add(upper_tc); + + twoD_SettingsUISetup_upperRow(upper_tc); + + tabPage_2D_Settings_table.Rows.Add(new TableRow()); + + Panel p = new Panel(); + tabPage_2D_Settings_table.Rows[tabPage_2D_Settings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(p, centered: true) }); + + TableLayout nestedTL = new TableLayout(); + p.Content = nestedTL; + + nestedTL.Rows.Add(new TableRow()); + + TableCell geo_tc = new TableCell(); + nestedTL.Rows[nestedTL.Rows.Count - 1].Cells.Add(geo_tc); + twoD_SettingsUI_geoEqtn(geo_tc); + + nestedTL.Rows.Add(new TableRow()); + TableCell replay_tc = new TableCell(); + nestedTL.Rows[nestedTL.Rows.Count - 1].Cells.Add(replay_tc); + twoD_SettingsUI_replay(replay_tc); + + nestedTL.Rows.Add(new TableRow()); + TableCell results_tc = new TableCell(); + nestedTL.Rows[nestedTL.Rows.Count - 1].Cells.Add(results_tc); + twoD_SettingsUI_results(results_tc); + + lbl_multiThreadResultNote = new Label(); + lbl_multiThreadResultNote.TextColor = UIHelper.myColorToColor(MyColor.Red); + lbl_multiThreadResultNote.Width = multiThreadWarnWidth; + lbl_multiThreadResultNote.TextAlignment = TextAlignment.Left; + lbl_multiThreadResultNote.Text = "Update frequency readout"; + lbl_multiThreadResultNote.Visible = false; + + Panel p2 = new Panel(); + TableLayout t2 = new TableLayout(); + p2.Content = t2; + t2.Rows.Add(new TableRow()); + + + TableCell updates_tc = new TableCell(); + updates_tc.Control = p2; + nestedTL.Rows.Add(new TableRow()); + nestedTL.Rows[nestedTL.Rows.Count - 1].Cells.Add(updates_tc); + + t2.Rows[t2.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_multiThreadResultNote }); + t2.Rows[t2.Rows.Count - 1].Cells.Add(new TableCell()); // padding + + nestedTL.Rows.Add(new TableRow()); // padding + } + + void twoD_SettingsUISetup_upperRow(TableCell tc) + { + Panel p = new Panel(); + TableLayout tl = new TableLayout(); + p.Content = tl; + tc.Control = p; + + tl.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(tc0); + + TableCell tc1 = new TableCell(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(tc1); + + Panel p2 = new Panel(); + TableLayout tl2 = new TableLayout(); + p2.Content = tl2; + tc0.Control = p2; + + tl2.Rows.Add(new TableRow()); + TableCell t2c0 = new TableCell(); + tl2.Rows[tl2.Rows.Count - 1].Cells.Add(t2c0); + twoD_SettingsUI_setOutput(); + t2c0.Control = groupBox_setOutput; + + tl2.Rows.Add(new TableRow()); + TableCell t2c1 = new TableCell(); + tl2.Rows[tl2.Rows.Count - 1].Cells.Add(t2c1); + twoD_SettingsUI_sim(); + t2c1.Control = groupBox_simSettings; + + textBox_userGuidance = new TextArea(); + setSize(textBox_userGuidance, userGuidanceWidth, userGuidanceHeight); + textBox_userGuidance.Wrap = true; + textBox_userGuidance.ReadOnly = true; + textBox_userGuidance.Text = "Testing 1 2 3"; + tc1.Control = textBox_userGuidance; + } + + void twoD_SettingsUI_setOutput() + { + groupBox_setOutput = new GroupBox(); + TableLayout groupBox_setOutput_table = new TableLayout(); + groupBox_setOutput.Content = groupBox_setOutput_table; + groupBox_setOutput.Text = "Set Output Controls"; + + groupBox_setOutput_table.Rows.Add(new TableRow()); + Panel row0Pnl = new Panel(); + groupBox_setOutput_table.Rows[groupBox_setOutput_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row0Pnl }); + TableLayout row0TL = new TableLayout(); + row0Pnl.Content = row0TL; + row0TL.Rows.Add(new TableRow()); + + comboBox_calcModes = new DropDown(); + comboBox_calcModes.Width = 400; + comboBox_calcModes.BindDataContext(c => c.DataStore, (UIStringLists m) => m.calcModes); + row0TL.Rows[row0TL.Rows.Count - 1].Cells.Add(comboBox_calcModes); + + groupBox_setOutput_table.Rows.Add(new TableRow()); + Panel row1Pnl = new Panel(); + groupBox_setOutput_table.Rows[groupBox_setOutput_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row1Pnl }); + TableLayout row1TL = new TableLayout(); + row1Pnl.Content = row1TL; + row1TL.Rows.Add(new TableRow()); + + checkBox_withinMode = new CheckBox(); + checkBox_withinMode.Text = "Enclosure"; + checkBox_withinMode.ToolTip = "Report minimum enclosure rather than minimum spacing value."; + row1TL.Rows[row1TL.Rows.Count - 1].Cells.Add(checkBox_withinMode); + + checkBox_useShortestEdge = new CheckBox(); + checkBox_useShortestEdge.Text = "Short Edge"; + checkBox_useShortestEdge.ToolTip = "Use shortest edge of overlap for raycast.\nUsed for cases where A-to-B cannot be guaranteed.\nImposes some calculation overhead."; + row1TL.Rows[row1TL.Rows.Count - 1].Cells.Add(checkBox_useShortestEdge); + + checkBox_aChord = new CheckBox(); + checkBox_aChord.Text = "T/B"; + checkBox_aChord.Checked = true; + checkBox_aChord.ToolTip = "Evaluate top/bottom chord lengths. Report 'N/A' if not chosen."; + row1TL.Rows[row1TL.Rows.Count - 1].Cells.Add(checkBox_aChord); + + checkBox_bChord = new CheckBox(); + checkBox_bChord.Text = "L/R"; + checkBox_bChord.Checked = true; + checkBox_bChord.ToolTip = "Evaluate left/right chord lengths. Report 'N/A' if not chosen."; + row1TL.Rows[row1TL.Rows.Count - 1].Cells.Add(checkBox_bChord); + + checkBox_perPoly = new CheckBox(); + checkBox_perPoly.Text = "Per-Poly"; + checkBox_perPoly.ToolTip = "Assess each polygon from overlap, to report minimum overlap area."; + row1TL.Rows[row1TL.Rows.Count - 1].Cells.Add(checkBox_perPoly); + } + + void twoD_SettingsUI_sim() + { + groupBox_simSettings = new GroupBox(); + TableLayout groupBox_simSettings_table = new TableLayout(); + groupBox_simSettings.Content = groupBox_simSettings_table; + groupBox_simSettings.Text = "Simulation Settings"; + + groupBox_simSettings_table.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + groupBox_simSettings_table.Rows[groupBox_simSettings_table.Rows.Count - 1].Cells.Add(tc0); + + twoD_SettingsUI_sim_row0(tc0); + + groupBox_simSettings_table.Rows.Add(new TableRow()); + TableCell tc1 = new TableCell(); + groupBox_simSettings_table.Rows[groupBox_simSettings_table.Rows.Count - 1].Cells.Add(tc1); + + Panel tc1_p = new Panel(); + tc1.Control = tc1_p; + TableLayout tc1_tl = new TableLayout(); + tc1_p.Content = tc1_tl; + + tc1_tl.Rows.Add(new TableRow()); + + checkBox_linkCDUVariation = new CheckBox(); + checkBox_linkCDUVariation.Text = "Link variation for tip and side CDU"; + checkBox_linkCDUVariation.ToolTip = "Allow for independent tip and side CDU variation, if enabled."; + tc1_tl.Rows[tc1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_linkCDUVariation }); + + checkBox_CSV = new CheckBox(); + checkBox_CSV.Text = "CSV"; + checkBox_CSV.ToolTip = "Write out a CSV file containing the result for each case and its inputs. Allows for offline deep-dive review."; + tc1_tl.Rows[tc1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_CSV }); + + checkBox_external = new CheckBox(); + checkBox_external.Text = "External"; + checkBox_external.ToolTip = "Write out a file containing the result for each case and its inputs. Will require significantly more memory."; + tc1_tl.Rows[tc1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_external }); + + comboBox_externalTypes = new DropDown(); + comboBox_externalTypes.DataContext = DataContext; + comboBox_externalTypes.BindDataContext(c => c.DataStore, (UIStringLists m) => m.externalTypeList); + comboBox_externalTypes.ToolTip = "Choose your external file type"; + tc1_tl.Rows[tc1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = comboBox_externalTypes }); + + tc1_tl.Rows[tc1_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_simSettings_table.Rows.Add(new TableRow()); + TableCell tc2 = new TableCell(); + groupBox_simSettings_table.Rows[groupBox_simSettings_table.Rows.Count - 1].Cells.Add(tc2); + + Panel tc2_p = new Panel(); + tc2.Control = tc2_p; + TableLayout tc2_tl = new TableLayout(); + tc2_p.Content = tc2_tl; + + tc2_tl.Rows.Add(new TableRow()); + + lbl_rng = new Label(); + lbl_rng.Text = "RNG"; + lbl_rng.ToolTip = "Choice of random number generators. Cryptographic is 10% slower, but more rigorous."; + tc2_tl.Rows[tc2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_rng }); + + comboBox_RNG = new DropDown(); + comboBox_RNG.DataContext = DataContext; + comboBox_RNG.BindDataContext(c => c.DataStore, (UIStringLists m) => m.rngTypeList); + comboBox_RNG.ToolTip = "Choice of random number generators. Cryptographic is 10% slower, but more rigorous."; + tc2_tl.Rows[tc2_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = comboBox_RNG }); + + groupBox_simSettings_table.Rows.Add(new TableRow()); + TableCell tc3 = new TableCell(); + groupBox_simSettings_table.Rows[groupBox_simSettings_table.Rows.Count - 1].Cells.Add(tc3); + + groupBox_simSettings_table.Rows[groupBox_simSettings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + Panel tc3_p = new Panel(); + tc3.Control = tc3_p; + TableLayout tc3_tl = new TableLayout(); + tc3_p.Content = tc3_tl; + + tc3_tl.Rows.Add(new TableRow()); + + checkBox_debugCalc = new CheckBox(); + checkBox_debugCalc.Text = "Debug"; + checkBox_debugCalc.ToolTip = "Enable debug (calculation engine support depending)."; + tc3_tl.Rows[tc3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_debugCalc }); + + tc3_tl.Rows[tc3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null, ScaleWidth = true }); + + lbl_ssTotalPoints = new Label(); + lbl_ssTotalPoints.Text = "Total # points"; + tc3_tl.Rows[tc3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_ssTotalPoints }); + + text_ssTotalPoints = new TextBox(); + text_ssTotalPoints.ReadOnly = true; + tc3_tl.Rows[tc3_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_ssTotalPoints }); + + + groupBox_simSettings_table.Rows.Add(new TableRow()); // padding + } + + void twoD_SettingsUI_sim_row0(TableCell tc) + { + Panel rp0 = new Panel(); + tc.Control = rp0; + TableLayout r0_tl = new TableLayout(); + rp0.Content = r0_tl; + r0_tl.Rows.Add(new TableRow()); + + lbl_ssNumOfCases = new Label(); + lbl_ssNumOfCases.Text = "Number of Cases"; + lbl_ssNumOfCases.ToolTip = "Total number of cases to evaluate."; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_ssNumOfCases }); + + num_ssNumOfCases = new NumericStepper(); + num_ssNumOfCases.Value = 25000; + num_ssNumOfCases.Increment = 1; + num_ssNumOfCases.MinValue = 1; + setSize(num_ssNumOfCases, 80, num_Height); + num_ssNumOfCases.ToolTip = "Total number of cases to evaluate."; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_ssNumOfCases) }); + + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + checkBox_greedyMultiCPU = new CheckBox(); + checkBox_greedyMultiCPU.Text = "All CPUs (multi CPU)"; + checkBox_greedyMultiCPU.ToolTip = "In multi-threaded runs, use all cores on system, rather than leaving one idle"; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_greedyMultiCPU }); + + r0_tl.Rows.Add(new TableRow()); + + lbl_ssPrecision = new Label(); + lbl_ssPrecision.Text = "Resolution (nm)"; + lbl_ssPrecision.ToolTip = "Spacing interval for points on edges."; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_ssPrecision }); + + num_ssPrecision = new NumericStepper(); + num_ssPrecision.Value = 1.0; + num_ssPrecision.Increment = 0.1; + num_ssPrecision.MinValue = 0.01; + num_ssPrecision.DecimalPlaces = 2; + num_ssPrecision.ToolTip = "Spacing interval for points on edges."; + setSize(num_ssPrecision, 80, num_Height); + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_ssPrecision) }); + + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + checkBox_LERMode = new CheckBox(); + checkBox_LERMode.Text = "LER as LWR/sqrt(2)"; + checkBox_LERMode.ToolTip = "Define LER as LWR/1.414 instead of LWR/2."; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_LERMode }); + + r0_tl.Rows.Add(new TableRow()); + + lbl_cornerSegments = new Label(); + lbl_cornerSegments.Text = "Corner Segments"; + lbl_cornerSegments.ToolTip = "Number of segments to create in corners."; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_cornerSegments }); + + num_cornerSegments = new NumericStepper(); + num_cornerSegments.Value = 90; + num_cornerSegments.Increment = 1; + num_cornerSegments.MinValue = 2; + setSize(num_cornerSegments, 60, num_Height); + num_cornerSegments.ToolTip = "Number of segments to create in corners."; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_cornerSegments) }); + + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + checkBox_limitCornerPoints = new CheckBox(); + checkBox_limitCornerPoints.Text = "Optimize corner pt density"; + checkBox_limitCornerPoints.ToolTip = "Prevent points in corners being spaced more closely than the resolution limit for edges."; + r0_tl.Rows[r0_tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_limitCornerPoints }); + } + + void twoD_SettingsUI_geoEqtn(TableCell tc) + { + Panel p = new Panel(); + TableLayout tl = new TableLayout(); + p.Content = tl; + tc.Control = TableLayout.AutoSized(p, centered: true); + + tl.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + tl.Rows[0].Cells.Add(tc0); + + comboBox_geoEqtn_Op = new DropDown[CentralProperties.maxLayersForMC]; + label_geoEqtn_Op = new Label[CentralProperties.maxLayersForMC]; + comboBox_geoEqtn_Op_2Layer = new DropDown[CentralProperties.maxLayersForMC / 2]; + comboBox_geoEqtn_Op_4Layer = new DropDown[comboBox_geoEqtn_Op_2Layer.Length / 2]; + comboBox_geoEqtn_Op_8Layer = new DropDown[comboBox_geoEqtn_Op_4Layer.Length / 2]; + + groupBox_GeoEqtn = new GroupBox(); + tc0.Control = groupBox_GeoEqtn; + tl.Rows[0].Cells.Add(new TableCell() { Control = null }); + + TableLayout groupBox_GeoEqtn_table = new TableLayout(); + groupBox_GeoEqtn.Content = groupBox_GeoEqtn_table; + groupBox_GeoEqtn.Text = "Geometric Equation"; + + TableRow tr0 = new TableRow(); + groupBox_GeoEqtn_table.Rows.Add(tr0); + + groupBox_GeoEqtnA = new GroupBox(); + TableLayout groupBox_GeoEqtnA_table = new TableLayout(); + groupBox_GeoEqtnA.Content = groupBox_GeoEqtnA_table; + groupBox_GeoEqtnA.Text = "Geometric Equation A"; + tr0.Cells.Add(new TableCell() { Control = groupBox_GeoEqtnA }); + + TableRow tr1 = new TableRow(); + groupBox_GeoEqtn_table.Rows.Add(tr1); + + label_AB = new Label(); + label_AB.Text = "testing 1 2 3"; + label_AB.TextAlignment = TextAlignment.Center; + tr1.Cells.Add(new TableCell() { Control = label_AB }); + + TableRow tr2 = new TableRow(); + groupBox_GeoEqtn_table.Rows.Add(tr2); + + groupBox_GeoEqtnB = new GroupBox(); + TableLayout groupBox_GeoEqtnB_table = new TableLayout(); + groupBox_GeoEqtnB.Content = groupBox_GeoEqtnB_table; + groupBox_GeoEqtnB.Text = "Geometric Equation B"; + tr2.Cells.Add(new TableCell() { Control = groupBox_GeoEqtnB }); + + for (int i = 0; i < comboBox_geoEqtn_Op_8Layer.Length; i++) + { + comboBox_geoEqtn_Op_8Layer[i] = new DropDown(); + comboBox_geoEqtn_Op_8Layer[i].Width = 40; + comboBox_geoEqtn_Op_8Layer[i].BindDataContext(c => c.DataStore, (UIStringLists m) => m.booleanList); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_4Layer.Length; i++) + { + comboBox_geoEqtn_Op_4Layer[i] = new DropDown(); + comboBox_geoEqtn_Op_4Layer[i].Width = 40; + comboBox_geoEqtn_Op_4Layer[i].BindDataContext(c => c.DataStore, (UIStringLists m) => m.booleanList); + } + + for (int i = 0; i < comboBox_geoEqtn_Op_2Layer.Length; i++) + { + comboBox_geoEqtn_Op_2Layer[i] = new DropDown(); + comboBox_geoEqtn_Op_2Layer[i].Width = 40; + comboBox_geoEqtn_Op_2Layer[i].BindDataContext(c => c.DataStore, (UIStringLists m) => m.booleanList); + } + + for (int i = 0; i < comboBox_geoEqtn_Op.Length; i++) + { + comboBox_geoEqtn_Op[i] = new DropDown(); + comboBox_geoEqtn_Op[i].Width = 40; + comboBox_geoEqtn_Op[i].BindDataContext(c => c.DataStore, (UIStringLists m) => m.notList); + + label_geoEqtn_Op[i] = new Label(); + label_geoEqtn_Op[i].TextColor = UIHelper.myColorToColor(commonVars.getColors().simPreviewColors[i]); + label_geoEqtn_Op[i].Text = commonVars.getLayerSettings(i).getString(EntropyLayerSettings.properties_s.name); + label_geoEqtn_Op[i].Width = 50; + + var i2 = i; + + label_geoEqtn_Op[i2].MouseDoubleClick += delegate + { + goToLayerUI(i2); + }; + + } + + groupBox_GeoEqtnA_table.Rows.Add(new TableRow()); + TableCell a_tc = new TableCell(); + groupBox_GeoEqtnA_table.Rows[0].Cells.Add(a_tc); + twoD_SettingsUI_geoEqtnA(a_tc); + + groupBox_GeoEqtnB_table.Rows.Add(new TableRow()); + TableCell b_tc = new TableCell(); + groupBox_GeoEqtnB_table.Rows[0].Cells.Add(b_tc); + twoD_SettingsUI_geoEqtnB(b_tc); + } + + void twoD_SettingsUI_geoEqtnA(TableCell tc) + { + Panel p = new Panel(); + + tc.Control = p; + + TableLayout outer_tl = new TableLayout(); + p.Content = outer_tl; + TableRow row0 = new TableRow(); + outer_tl.Rows.Add(row0); + aRow0(row0); + + TableRow row1 = new TableRow(); + outer_tl.Rows.Add(row1); + aRow1(row1); + + TableRow row2 = new TableRow(); + outer_tl.Rows.Add(row2); + aRow2(row2); + + TableRow padding = new TableRow(); + padding.ScaleHeight = true; + outer_tl.Rows.Add(padding); + } + + void aRow0(TableRow row0) + { + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[0] }); + row0.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[0] }); + + btn_Switch12 = new Button(); + setSize(btn_Switch12, 10, 18); + btn_Switch12.Click += switchSimulationLayers12Over; + row0.Cells.Add(new TableCell() { Control = btn_Switch12 }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_2Layer[0] }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[1] }); + row0.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[1] }); + + btn_Switch23 = new Button(); + setSize(btn_Switch23, 10, 18); + btn_Switch23.Click += switchSimulationLayers23Over; + row0.Cells.Add(new TableCell() { Control = btn_Switch23 }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_4Layer[0] }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[2] }); + row0.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[2] }); + + btn_Switch34 = new Button(); + setSize(btn_Switch34, 10, 18); + btn_Switch34.Click += switchSimulationLayers34Over; + row0.Cells.Add(new TableCell() { Control = btn_Switch34 }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_2Layer[1] }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[3] }); + row0.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[3] }); + } + + void aRow1(TableRow row1) + { + row1.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_8Layer[0] }); + + btn_Switch15 = new Button(); + setSize(btn_Switch15, 38, 10); + btn_Switch15.Click += switchSimulationLayers15Over; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_Switch15) }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + btn_Switch26 = new Button(); + setSize(btn_Switch26, 38, 10); + btn_Switch26.Click += switchSimulationLayers26Over; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_Switch26) }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + btn_Switch37 = new Button(); + setSize(btn_Switch37, 38, 10); + btn_Switch37.Click += switchSimulationLayers37Over; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_Switch37) }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + btn_Switch48 = new Button(); + setSize(btn_Switch48, 38, 10); + btn_Switch48.Click += switchSimulationLayers48ver; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_Switch48) }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + btn_SwitchA = new Button(); + setSize(btn_SwitchA, 38, 10); + btn_SwitchA.Click += switchSimulationAllALayersOver; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_SwitchA) }); + } + + void aRow2(TableRow row2) + { + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[4] }); + row2.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[4] }); + + btn_Switch56 = new Button(); + setSize(btn_Switch56, 10, 18); + btn_Switch56.Click += switchSimulationLayers56Over; + row2.Cells.Add(new TableCell() { Control = btn_Switch56 }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_2Layer[2] }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[5] }); + row2.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[5] }); + + btn_Switch67 = new Button(); + setSize(btn_Switch67, 10, 18); + btn_Switch67.Click += switchSimulationLayers67Over; + row2.Cells.Add(new TableCell() { Control = btn_Switch67 }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_4Layer[1] }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[6] }); + row2.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[6] }); + + btn_Switch78 = new Button(); + setSize(btn_Switch78, 10, 18); + btn_Switch78.Click += switchSimulationLayers78Over; + row2.Cells.Add(new TableCell() { Control = btn_Switch78 }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_2Layer[3] }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[7] }); + row2.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[7] }); + } + + void twoD_SettingsUI_geoEqtnB(TableCell tc) + { + Panel p = new Panel(); + + tc.Control = p; + + TableLayout outer_tl = new TableLayout(); + p.Content = outer_tl; + TableRow row0 = new TableRow(); + outer_tl.Rows.Add(row0); + bRow0(row0); + + TableRow row1 = new TableRow(); + outer_tl.Rows.Add(row1); + bRow1(row1); + + TableRow row2 = new TableRow(); + outer_tl.Rows.Add(row2); + bRow2(row2); + + TableRow padding = new TableRow(); + padding.ScaleHeight = true; + outer_tl.Rows.Add(padding); + } + + void bRow0(TableRow row0) + { + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[8] }); + row0.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[8] }); + + btn_Switch910 = new Button(); + setSize(btn_Switch910, 10, 18); + btn_Switch910.Click += switchSimulationLayers910Over; + row0.Cells.Add(new TableCell() { Control = btn_Switch910 }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_2Layer[4] }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[9] }); + row0.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[9] }); + + btn_Switch1011 = new Button(); + setSize(btn_Switch1011, 10, 18); + btn_Switch1011.Click += switchSimulationLayers1011Over; + row0.Cells.Add(new TableCell() { Control = btn_Switch1011 }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_4Layer[2] }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[10] }); + row0.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[10] }); + + btn_Switch1112 = new Button(); + setSize(btn_Switch1112, 10, 18); + btn_Switch1112.Click += switchSimulationLayers1112Over; + row0.Cells.Add(new TableCell() { Control = btn_Switch1112 }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_2Layer[5] }); + + row0.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[11] }); + row0.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[11] }); + + } + + void bRow1(TableRow row1) + { + row1.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_8Layer[1] }); + + btn_Switch913 = new Button(); + setSize(btn_Switch913, 38, 10); + btn_Switch913.Click += switchSimulationLayers913Over; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_Switch913) }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + btn_Switch1014 = new Button(); + setSize(btn_Switch1014, 38, 10); + btn_Switch1014.Click += switchSimulationLayers26Over; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_Switch1014) }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + btn_Switch1115 = new Button(); + setSize(btn_Switch1115, 38, 10); + btn_Switch1115.Click += switchSimulationLayers1115Over; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_Switch1115) }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + btn_Switch1216 = new Button(); + setSize(btn_Switch1216, 38, 10); + btn_Switch1216.Click += switchSimulationLayers1216Over; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_Switch1216) }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + row1.Cells.Add(new TableCell() { Control = null }); + + btn_SwitchB = new Button(); + setSize(btn_SwitchB, 38, 10); + btn_SwitchB.Click += switchSimulationAllBLayersOver; + row1.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(btn_SwitchB) }); + } + + void bRow2(TableRow row2) + { + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[12] }); + row2.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[12] }); + + btn_Switch1314 = new Button(); + setSize(btn_Switch1314, 10, 18); + btn_Switch1314.Click += switchSimulationLayers1314Over; + row2.Cells.Add(new TableCell() { Control = btn_Switch1314 }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_2Layer[6] }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[13] }); + row2.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[13] }); + + btn_Switch1415 = new Button(); + setSize(btn_Switch1415, 10, 18); + btn_Switch1415.Click += switchSimulationLayers1415Over; + row2.Cells.Add(new TableCell() { Control = btn_Switch1415 }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_4Layer[3] }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[14] }); + row2.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[14] }); + + btn_Switch1516 = new Button(); + setSize(btn_Switch1516, 10, 18); + btn_Switch1516.Click += switchSimulationLayers1516Over; + row2.Cells.Add(new TableCell() { Control = btn_Switch1516 }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op_2Layer[7] }); + + row2.Cells.Add(new TableCell() { Control = comboBox_geoEqtn_Op[15] }); + row2.Cells.Add(new TableCell() { Control = label_geoEqtn_Op[15] }); + } + + void twoD_SettingsUI_replay(TableCell tc) + { + Panel p = new Panel(); + TableLayout tl = new TableLayout(); + p.Content = tl; + tc.Control = tc.Control = p; //TableLayout.AutoSized(p, centered: true); + + tl.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + tl.Rows[0].Cells.Add(tc0); + + groupBox_replay = new GroupBox(); + tc0.Control = groupBox_replay; + tl.Rows[0].Cells.Add(new TableCell() { Control = null }); + + TableLayout groupBox_replay_table = new TableLayout(); + TableRow tr0 = new TableRow(); + groupBox_replay_table.Rows.Add(tr0); + groupBox_replay.Content = groupBox_replay_table; + groupBox_replay.Text = "Replay"; + + button_replay = new Button(); + button_replay.Text = "Load CSV File"; + button_replay.ToolTip = "Load CSV file generated from a run using this project file.\n\rThis will allow replay of the cases."; + // setSize(button_replay, replayButtonWidth, replayButtonHeight); + tr0.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(button_replay) }); + + checkBox_replay = new CheckBox(); + checkBox_replay.Text = "Enable"; + checkBox_replay.ToolTip = "Enable replay using a CSV file from the loaded project"; + tr0.Cells.Add(new TableCell() { Control = checkBox_replay }); + + num_replay = new NumericStepper(); + num_replay.MinValue = 0; + num_replay.MaxValue = 0; + num_replay.Increment = 1; + num_replay.ToolTip = "Which case to view from the loaded CSV file"; + setSize(num_replay, replayNumWidth, replayNumHeight); + tr0.Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_replay) }); + + tr0.Cells.Add(new TableCell() { Control = null }); // padding + } + + void twoD_SettingsUI_results(TableCell tc) + { + Panel p = new Panel(); + tc.Control = TableLayout.AutoSized(p); + + TableLayout tl = new TableLayout(); + tl.Rows.Add(new TableRow()); + + lbl_testArea = new Label(); + lbl_testArea.Text = "Result for this run"; + lbl_testArea.TextAlignment = TextAlignment.Left; + tl.Rows[0].Cells.Add(new TableCell() { Control = lbl_testArea }); + + text_testArea = new TextBox(); + text_testArea.ReadOnly = true; + setSize(text_testArea, 470, 10); + text_testArea.Text = "N/A"; + + tl.Rows[0].Cells.Add(new TableCell() { Control = text_testArea }); + + p.Content = tl; + } + } +} diff --git a/Common/Variance/UI/utilsUI.cs b/Common/Variance/UI/utilsUI.cs new file mode 100644 index 0000000..7be61e9 --- /dev/null +++ b/Common/Variance/UI/utilsUI.cs @@ -0,0 +1,1178 @@ +using Error; +using Eto.Forms; +using info.lundin.math; +using System; + +namespace Variance +{ + public partial class MainForm : Form + { + TextBox text_server, text_emailAddress, text_rngMapping; + + NumericStepper num_port, num_zoomSpeed, num_fgOpacity, num_bgOpacity; + + PasswordBox text_emailPwd; + + CheckBox checkBox_EmailCompletion, checkBox_perJob, checkBox_SSL, + checkBox_geoCore_enableCDVariation, checkBox_geoCore_tileLayerPreview, + checkBox_OGLAA, checkBox_OGLFill, checkBox_OGLPoints, + checkBox_friendlyNumbers; + + Button button_emailTest, utilitiesBtn_Summary, btn_resetColors, btn_rngMapping_Add, btn_rngMapping_Edit, btn_rngMapping_Remove; + + Label lbl_Layer1Color, lbl_Layer2Color, lbl_Layer3Color, lbl_Layer4Color, + lbl_Layer5Color, lbl_Layer6Color, lbl_Layer7Color, lbl_Layer8Color, + lbl_Layer9Color, lbl_Layer10Color, lbl_Layer11Color, lbl_Layer12Color, + lbl_Layer13Color, lbl_Layer14Color, lbl_Layer15Color, lbl_Layer16Color, + lbl_Result1Color, lbl_Result2Color, lbl_Result3Color, lbl_Result4Color, + lbl_ss1Color, lbl_ss2Color, lbl_ss3Color, + lbl_implantMinColor, lbl_implantMeanColor, lbl_implantMaxColor, lbl_implantResistColor, + lbl_enabledColor, lbl_majorGridColor, lbl_minorGridColor, + lbl_Layer1Color_name, lbl_Layer2Color_name, lbl_Layer3Color_name, lbl_Layer4Color_name, + lbl_Layer5Color_name, lbl_Layer6Color_name, lbl_Layer7Color_name, lbl_Layer8Color_name, + lbl_Layer9Color_name, lbl_Layer10Color_name, lbl_Layer11Color_name, lbl_Layer12Color_name, + lbl_Layer13Color_name, lbl_Layer14Color_name, lbl_Layer15Color_name, lbl_Layer16Color_name, + lbl_Result1Color_name, lbl_Result2Color_name, lbl_Result3Color_name, lbl_Result4Color_name, + lbl_ss1Color_name, lbl_ss2Color_name, lbl_ss3Color_name, + lbl_implantMinColor_name, lbl_implantMeanColor_name, lbl_implantMaxColor_name, lbl_implantResistColor_name, + lbl_enabledColor_name, lbl_majorGridColor_name, lbl_minorGridColor_name, + lbl_emailAddress, lbl_emailPwd, lbl_server, lbl_port, lbl_zoomSpeed, lbl_fgOpacity, lbl_bgOpacity; + + ListBox listBox_rngCustomMapping; + + GroupBox groupBox_utilities, groupBox_settings, groupBox_email, groupBox_openGL, prefs_geoCore, groupBox_rng, groupBox_misc; + + void utilsUISetup() + { + settings_utilsUISetup(); + } + + void utils_utilsUISetup(TableCell tc) + { + groupBox_utilities = new GroupBox(); + TableLayout groupBox_utilities_table = new TableLayout(); + groupBox_utilities.Text = "Utilities"; + groupBox_utilities.Content = groupBox_utilities_table; + + groupBox_utilities_table.Rows.Add(new TableRow()); + + utilitiesBtn_Summary = new Button(); + utilitiesBtn_Summary.Text = "Create summary of DOE results"; + groupBox_utilities_table.Rows[groupBox_utilities_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(utilitiesBtn_Summary) }); + utilitiesBtn_Summary.Click += locateDOEResults; + + tc.Control = groupBox_utilities; + } + + void settings_utilsUISetup() + { + groupBox_settings = new GroupBox(); + TableLayout groupBox_settings_table = new TableLayout(); + groupBox_settings.Text = "Settings"; + groupBox_settings.Content = groupBox_settings_table; + + tabPage_utilities_table.Rows.Add(new TableRow()); + tabPage_utilities_table.Rows[tabPage_utilities_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = groupBox_settings }); + tabPage_utilities_table.Rows[tabPage_utilities_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding; + + tabPage_utilities_table.Rows.Add(new TableRow()); // padding + + groupBox_settings_table.Rows.Add(new TableRow()); + Panel row0Panel = new Panel(); + groupBox_settings_table.Rows[groupBox_settings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row0Panel }); + + TableLayout row0tl = new TableLayout(); + row0Panel.Content = row0tl; + row0tl.Rows.Add(new TableRow()); + TableCell settingsTC = new TableCell(); + row0tl.Rows[row0tl.Rows.Count - 1].Cells.Add(settingsTC); + row0tl.Rows[row0tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + utils_utilsUISetup(settingsTC); + + groupBox_settings_table.Rows.Add(new TableRow()); + Panel row1Panel = new Panel(); + groupBox_settings_table.Rows[groupBox_settings_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row1Panel }); + + TableLayout row1tl = new TableLayout(); + row1Panel.Content = row1tl; + row1tl.Rows.Add(new TableRow()); + + TableCell leftTC = new TableCell(); + Panel leftPanel = new Panel(); + leftTC.Control = leftPanel; + row1tl.Rows[row1tl.Rows.Count - 1].Cells.Add(leftTC); + + TableLayout leftTL = new TableLayout(); + leftPanel.Content = leftTL; + + TableCell rightTC = new TableCell(); + Panel rightPanel = new Panel(); + rightTC.Control = rightPanel; + row1tl.Rows[row1tl.Rows.Count - 1].Cells.Add(rightTC); + + TableLayout rightTL = new TableLayout(); + rightPanel.Content = rightTL; + + row1tl.Rows[row1tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); //padding + + // Left-hand side. + leftTL.Rows.Add(new TableRow()); + TableCell lRow0 = new TableCell(); + leftTL.Rows[leftTL.Rows.Count - 1].Cells.Add(lRow0); + leftTL.Rows[leftTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + email_settings_utilsUISetup(lRow0); + + leftTL.Rows.Add(new TableRow()); + TableCell lRow1 = new TableCell(); + leftTL.Rows[leftTL.Rows.Count - 1].Cells.Add(lRow1); + leftTL.Rows[leftTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + geoCore_settings_utilsUISetup(lRow1); + + leftTL.Rows.Add(new TableRow()); + TableCell lRow2 = new TableCell(); + leftTL.Rows[leftTL.Rows.Count - 1].Cells.Add(lRow2); + leftTL.Rows[leftTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + rng_customMappingSetup(lRow2); + + leftTL.Rows.Add(new TableRow()); // padding + + rightTL.Rows.Add(new TableRow()); + TableCell rRow0 = new TableCell(); + rightTL.Rows[rightTL.Rows.Count - 1].Cells.Add(rRow0); + rightTL.Rows[rightTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + openGL_settings_utilsUISetup(rRow0); + + rightTL.Rows.Add(new TableRow()); + TableCell rRow1 = new TableCell(); + rightTL.Rows[rightTL.Rows.Count - 1].Cells.Add(rRow1); + rightTL.Rows[rightTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + misc_settings_utilsUISetup(rRow1); + + groupBox_settings_table.Rows.Add(new TableRow()); // padding + } + + void email_settings_utilsUISetup(TableCell tc) + { + groupBox_email = new GroupBox(); + TableLayout groupBox_email_table = new TableLayout(); + groupBox_email.Text = "Email Settings"; + groupBox_email.Content = groupBox_email_table; + + tc.Control = groupBox_email; + + groupBox_email_table.Rows.Add(new TableRow()); + + Panel row0 = new Panel(); + groupBox_email_table.Rows[groupBox_email_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row0 }); + + TableLayout row0tl = new TableLayout(); + row0.Content = row0tl; + row0tl.Rows.Add(new TableRow()); + + lbl_emailAddress = new Label(); + lbl_emailAddress.Text = "Address"; + row0tl.Rows[row0tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_emailAddress }); + + text_emailAddress = new TextBox(); + row0tl.Rows[row0tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_emailAddress }); + + groupBox_email_table.Rows.Add(new TableRow()); + + Panel row1 = new Panel(); + groupBox_email_table.Rows[groupBox_email_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row1 }); + + TableLayout row1tl = new TableLayout(); + row1.Content = row1tl; + row1tl.Rows.Add(new TableRow()); + + lbl_emailPwd = new Label(); + lbl_emailPwd.Text = "Password"; + row1tl.Rows[row1tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_emailPwd }); + + text_emailPwd = new PasswordBox(); + row1tl.Rows[row1tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_emailPwd }); + + groupBox_email_table.Rows.Add(new TableRow()); + + Panel row2 = new Panel(); + groupBox_email_table.Rows[groupBox_email_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row2 }); + + TableLayout row2tl = new TableLayout(); + row2.Content = row2tl; + row2tl.Rows.Add(new TableRow()); + + lbl_server = new Label(); + lbl_server.Text = "Server"; + row2tl.Rows[row2tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_server }); + + text_server = new TextBox(); + row2tl.Rows[row2tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = text_server }); + + groupBox_email_table.Rows.Add(new TableRow()); + + Panel row3 = new Panel(); + groupBox_email_table.Rows[groupBox_email_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row3 }); + + TableLayout row3tl = new TableLayout(); + row3.Content = row3tl; + row3tl.Rows.Add(new TableRow()); + + checkBox_SSL = new CheckBox(); + checkBox_SSL.Text = "SSL"; + row3tl.Rows[row3tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_SSL }); + + lbl_port = new Label(); + lbl_port.Text = "Port"; + row3tl.Rows[row3tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_port }); + + num_port = new NumericStepper(); + num_port.MinValue = 1; + num_port.Value = 587; + num_port.Increment = 1; + setSize(num_port, 70, label_Height); + row3tl.Rows[row3tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_port) }); + + row3tl.Rows[row3tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + groupBox_email_table.Rows.Add(new TableRow()); + + Panel row4 = new Panel(); + groupBox_email_table.Rows[groupBox_email_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = row4 }); + + TableLayout row4tl = new TableLayout(); + row4.Content = row4tl; + row4tl.Rows.Add(new TableRow()); + + checkBox_EmailCompletion = new CheckBox(); + checkBox_EmailCompletion.Text = "On Completion"; + row4tl.Rows[row4tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_EmailCompletion }); + + checkBox_perJob = new CheckBox(); + checkBox_perJob.Text = "Per Job"; + row4tl.Rows[row4tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_perJob }); + + button_emailTest = new Button(); + button_emailTest.Text = "Test"; + row4tl.Rows[row4tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(button_emailTest) }); + + row4tl.Rows[row4tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + } + + void geoCore_settings_utilsUISetup(TableCell tc) + { + prefs_geoCore = new GroupBox(); + TableLayout prefs_geoCore_table = new TableLayout(); + prefs_geoCore.Text = "GDS/Oasis"; + prefs_geoCore.Content = prefs_geoCore_table; + tc.Control = prefs_geoCore; + + prefs_geoCore_table.Rows.Add(new TableRow()); + checkBox_geoCore_enableCDVariation = new CheckBox(); + checkBox_geoCore_enableCDVariation.Text = "Allow CD/bias variation"; + prefs_geoCore_table.Rows[prefs_geoCore_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_geoCore_enableCDVariation }); + prefs_geoCore_table.Rows[prefs_geoCore_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + prefs_geoCore_table.Rows.Add(new TableRow()); + checkBox_geoCore_tileLayerPreview = new CheckBox(); + checkBox_geoCore_tileLayerPreview.Text = "Use DOE tile for layer preview"; + prefs_geoCore_table.Rows[prefs_geoCore_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_geoCore_tileLayerPreview }); + prefs_geoCore_table.Rows[prefs_geoCore_table.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + } + + void misc_settings_utilsUISetup(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; + + TableLayout tl = new TableLayout(); + p.Content = tl; + tl.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + tl.Rows[0].Cells.Add(tc0); + tl.Rows.Add(new TableRow()); // padding + + groupBox_misc = new GroupBox(); + tc0.Control = groupBox_misc; + TableLayout groupBox_misc_table = new TableLayout(); + groupBox_misc.Text = "Misc"; + groupBox_misc.Content = groupBox_misc_table; + + groupBox_misc_table.Rows.Add(new TableRow()); + TableCell row0 = new TableCell(); + groupBox_misc_table.Rows[groupBox_misc_table.Rows.Count - 1].Cells.Add(row0); + miscRow0(row0); + } + + void miscRow0(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; + + TableLayout tl = new TableLayout(); + tl.Rows.Add(new TableRow()); + p.Content = tl; + + tl.Rows.Add(new TableRow()); + + checkBox_friendlyNumbers = new CheckBox(); + checkBox_friendlyNumbers.Text = "Friendly Numbers"; + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_friendlyNumbers }); + + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + tl.Rows.Add(new TableRow()); // padding. + } + + void openGL_settings_utilsUISetup(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; + + TableLayout tl = new TableLayout(); + p.Content = tl; + tl.Rows.Add(new TableRow()); + TableCell tc0 = new TableCell(); + tl.Rows[0].Cells.Add(tc0); + tl.Rows.Add(new TableRow()); // padding + + groupBox_openGL = new GroupBox(); + tc0.Control = groupBox_openGL; + TableLayout groupBox_openGL_table = new TableLayout(); + groupBox_openGL.Text = "OpenGL"; + groupBox_openGL.Content = groupBox_openGL_table; + + groupBox_openGL_table.Rows.Add(new TableRow()); + TableCell row0 = new TableCell(); + groupBox_openGL_table.Rows[groupBox_openGL_table.Rows.Count - 1].Cells.Add(row0); + openGLRow0(row0); + + groupBox_openGL_table.Rows.Add(new TableRow()); + TableCell row1 = new TableCell(); + groupBox_openGL_table.Rows[groupBox_openGL_table.Rows.Count - 1].Cells.Add(row1); + openGLRow1(row1); + + groupBox_openGL_table.Rows.Add(new TableRow()); + TableCell row2 = new TableCell(); + groupBox_openGL_table.Rows[groupBox_openGL_table.Rows.Count - 1].Cells.Add(row2); + openGLRow2(row2); + } + + void openGLRow0(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; + + TableLayout tl = new TableLayout(); + tl.Rows.Add(new TableRow()); + p.Content = tl; + + Panel lRow0 = new Panel(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lRow0 }); + + Panel rRow0 = new Panel(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = rRow0 }); + + TableLayout lRow0tl = new TableLayout(); + lRow0.Content = lRow0tl; + lRow0tl.Rows.Add(new TableRow()); + + TableLayout rRow0tl = new TableLayout(); + rRow0.Content = rRow0tl; + rRow0tl.Rows.Add(new TableRow()); + + Panel zoomPnl = new Panel(); + TableLayout zoomTL = new TableLayout(); + zoomPnl.Content = zoomTL; + lRow0tl.Rows[lRow0tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = zoomPnl }); + + zoomTL.Rows.Add(new TableRow()); + + lbl_zoomSpeed = new Label(); + lbl_zoomSpeed.Text = "Zoom Increment"; + zoomTL.Rows[zoomTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_zoomSpeed }); + + num_zoomSpeed = new NumericStepper(); + num_zoomSpeed.MinValue = 1; + num_zoomSpeed.Increment = 1; + setSize(num_zoomSpeed, 50, num_Height); + zoomTL.Rows[zoomTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_zoomSpeed) }); + + zoomTL.Rows[zoomTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); // padding + + Panel fgOpPnl = new Panel(); + TableLayout fgOpTL = new TableLayout(); + fgOpPnl.Content = fgOpTL; + rRow0tl.Rows[rRow0tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = fgOpPnl }); + + fgOpTL.Rows.Add(new TableRow()); + + lbl_fgOpacity = new Label(); + lbl_fgOpacity.Text = "FG"; + fgOpTL.Rows[fgOpTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_fgOpacity }); + + num_fgOpacity = new NumericStepper(); + num_fgOpacity.MinValue = 0.01f; + num_fgOpacity.Increment = 0.1f; + num_fgOpacity.DecimalPlaces = 2; + setSize(num_fgOpacity, 50, num_Height); + fgOpTL.Rows[fgOpTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_fgOpacity) }); + + Panel bgOpPnl = new Panel(); + TableLayout bgOpTL = new TableLayout(); + bgOpPnl.Content = bgOpTL; + rRow0tl.Rows[rRow0tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = bgOpPnl }); + + bgOpTL.Rows.Add(new TableRow()); + + lbl_bgOpacity = new Label(); + lbl_bgOpacity.Text = "BG"; + bgOpTL.Rows[bgOpTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = lbl_bgOpacity }); + + num_bgOpacity = new NumericStepper(); + num_bgOpacity.MinValue = 0.01f; + num_bgOpacity.Increment = 0.1f; + num_bgOpacity.DecimalPlaces = 2; + setSize(num_bgOpacity, 50, num_Height); + bgOpTL.Rows[bgOpTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = TableLayout.AutoSized(num_bgOpacity) }); + + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = null }); + + tl.Rows.Add(new TableRow()); + + Panel lRow1 = new Panel(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = lRow1 }); + + Panel rRow1 = new Panel(); + tl.Rows[tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = rRow1 }); + + TableLayout lRow1tl = new TableLayout(); + lRow1.Content = lRow1tl; + lRow1tl.Rows.Add(new TableRow()); + + TableLayout rRow1tl = new TableLayout(); + rRow1.Content = rRow1tl; + rRow1tl.Rows.Add(new TableRow()); + + Panel dispOptsPnl = new Panel(); + TableLayout dispOptsTL = new TableLayout(); + dispOptsPnl.Content = dispOptsTL; + lRow1tl.Rows[lRow1tl.Rows.Count - 1].Cells.Add(new TableCell() { Control = dispOptsPnl }); + + dispOptsTL.Rows.Add(new TableRow()); + + checkBox_OGLAA = new CheckBox(); + checkBox_OGLAA.Text = "Antialiasing"; + dispOptsTL.Rows[dispOptsTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_OGLAA }); + + checkBox_OGLFill = new CheckBox(); + checkBox_OGLFill.Text = "Fill"; + dispOptsTL.Rows[dispOptsTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_OGLFill }); + + checkBox_OGLPoints = new CheckBox(); + checkBox_OGLPoints.Text = "Points"; + dispOptsTL.Rows[dispOptsTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = checkBox_OGLPoints }); + } + + void openGLRow1(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; + + TableLayout swatchesTL = new TableLayout(); + p.Content = swatchesTL; + + swatchesTL.Rows.Add(new TableRow()); + + TableRow row0 = new TableRow(); + swatchesTL.Rows.Add(row0); + + opengl_swatchrow0(row0); + + TableRow row1 = new TableRow(); + swatchesTL.Rows.Add(row1); + + opengl_swatchrow1(row1); + + TableRow row2 = new TableRow(); + swatchesTL.Rows.Add(row2); + + opengl_swatchrow2(row2); + + TableRow row3 = new TableRow(); + swatchesTL.Rows.Add(row3); + + opengl_swatchrow3(row3); + + TableRow row4 = new TableRow(); + swatchesTL.Rows.Add(row4); + + opengl_swatchrow4(row4); + + TableRow row5 = new TableRow(); + swatchesTL.Rows.Add(row5); + + opengl_swatchrow5(row5); + + TableRow row6 = new TableRow(); + swatchesTL.Rows.Add(row6); + + opengl_swatchrow6(row6); + + TableRow row7 = new TableRow(); + swatchesTL.Rows.Add(row7); + + opengl_swatchrow7(row7); + } + + void opengl_swatchrow0(TableRow tr) + { + Panel c0 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c0 }); + + TableLayout c0TL = new TableLayout(); + c0.Content = c0TL; + c0TL.Rows.Add(new TableRow()); + + lbl_minorGridColor = new Label(); + lbl_minorGridColor.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().minor_Color); + setSize(lbl_minorGridColor, label_Height, label_Height); + c0TL.Rows[0].Cells.Add(lbl_minorGridColor); + + lbl_minorGridColor_name = new Label(); + lbl_minorGridColor_name.Text = "Minor Grid"; + c0TL.Rows[0].Cells.Add(lbl_minorGridColor_name); + + Panel c1 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c1 }); + + TableLayout c1TL = new TableLayout(); + c1.Content = c1TL; + c1TL.Rows.Add(new TableRow()); + + lbl_majorGridColor = new Label(); + lbl_majorGridColor.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().major_Color); + setSize(lbl_majorGridColor, label_Height, label_Height); + c1TL.Rows[0].Cells.Add(lbl_majorGridColor); + + lbl_majorGridColor_name = new Label(); + lbl_majorGridColor_name.Text = "Major Grid"; + c1TL.Rows[0].Cells.Add(lbl_majorGridColor_name); + + Panel c2 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c2 }); + + Panel c3 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c3 }); + } + + void opengl_swatchrow1(TableRow tr) + { + Panel c0 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c0 }); + + TableLayout c0TL = new TableLayout(); + c0.Content = c0TL; + c0TL.Rows.Add(new TableRow()); + + lbl_Layer1Color = new Label(); + lbl_Layer1Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer1_Color); + setSize(lbl_Layer1Color, label_Height, label_Height); + c0TL.Rows[0].Cells.Add(lbl_Layer1Color); + + lbl_Layer1Color_name = new Label(); + lbl_Layer1Color_name.Text = "Layer 1"; + c0TL.Rows[0].Cells.Add(lbl_Layer1Color_name); + + Panel c1 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c1 }); + + TableLayout c1TL = new TableLayout(); + c1.Content = c1TL; + c1TL.Rows.Add(new TableRow()); + + lbl_Layer2Color = new Label(); + lbl_Layer2Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer2_Color); + setSize(lbl_Layer2Color, label_Height, label_Height); + c1TL.Rows[0].Cells.Add(lbl_Layer2Color); + + lbl_Layer2Color_name = new Label(); + lbl_Layer2Color_name.Text = "Layer 2"; + c1TL.Rows[0].Cells.Add(lbl_Layer2Color_name); + + Panel c2 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c2 }); + + TableLayout c2TL = new TableLayout(); + c2.Content = c2TL; + c2TL.Rows.Add(new TableRow()); + + lbl_Layer3Color = new Label(); + lbl_Layer3Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer3_Color); + setSize(lbl_Layer3Color, label_Height, label_Height); + c2TL.Rows[0].Cells.Add(lbl_Layer3Color); + + lbl_Layer3Color_name = new Label(); + lbl_Layer3Color_name.Text = "Layer 3"; + c2TL.Rows[0].Cells.Add(lbl_Layer3Color_name); + + Panel c3 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c3 }); + + TableLayout c3TL = new TableLayout(); + c3.Content = c3TL; + c3TL.Rows.Add(new TableRow()); + + lbl_Layer4Color = new Label(); + lbl_Layer4Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer4_Color); + setSize(lbl_Layer4Color, label_Height, label_Height); + c3TL.Rows[0].Cells.Add(lbl_Layer4Color); + + lbl_Layer4Color_name = new Label(); + lbl_Layer4Color_name.Text = "Layer 4"; + c3TL.Rows[0].Cells.Add(lbl_Layer4Color_name); + } + + void opengl_swatchrow2(TableRow tr) + { + Panel c0 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c0 }); + + TableLayout c0TL = new TableLayout(); + c0.Content = c0TL; + c0TL.Rows.Add(new TableRow()); + + lbl_Layer5Color = new Label(); + lbl_Layer5Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer5_Color); + setSize(lbl_Layer5Color, label_Height, label_Height); + c0TL.Rows[0].Cells.Add(lbl_Layer5Color); + + lbl_Layer5Color_name = new Label(); + lbl_Layer5Color_name.Text = "Layer 5"; + c0TL.Rows[0].Cells.Add(lbl_Layer5Color_name); + + Panel c1 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c1 }); + + TableLayout c1TL = new TableLayout(); + c1.Content = c1TL; + c1TL.Rows.Add(new TableRow()); + + lbl_Layer6Color = new Label(); + lbl_Layer6Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer6_Color); + setSize(lbl_Layer6Color, label_Height, label_Height); + c1TL.Rows[0].Cells.Add(lbl_Layer6Color); + + lbl_Layer6Color_name = new Label(); + lbl_Layer6Color_name.Text = "Layer 6"; + c1TL.Rows[0].Cells.Add(lbl_Layer6Color_name); + + Panel c2 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c2 }); + + TableLayout c2TL = new TableLayout(); + c2.Content = c2TL; + c2TL.Rows.Add(new TableRow()); + + lbl_Layer7Color = new Label(); + lbl_Layer7Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer7_Color); + setSize(lbl_Layer7Color, label_Height, label_Height); + c2TL.Rows[0].Cells.Add(lbl_Layer7Color); + + lbl_Layer7Color_name = new Label(); + lbl_Layer7Color_name.Text = "Layer 7"; + c2TL.Rows[0].Cells.Add(lbl_Layer7Color_name); + + Panel c3 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c3 }); + + TableLayout c3TL = new TableLayout(); + c3.Content = c3TL; + c3TL.Rows.Add(new TableRow()); + + lbl_Layer8Color = new Label(); + lbl_Layer8Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer8_Color); + setSize(lbl_Layer8Color, label_Height, label_Height); + c3TL.Rows[0].Cells.Add(lbl_Layer8Color); + + lbl_Layer8Color_name = new Label(); + lbl_Layer8Color_name.Text = "Layer 8"; + c3TL.Rows[0].Cells.Add(lbl_Layer8Color_name); + } + + void opengl_swatchrow3(TableRow tr) + { + Panel c0 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c0 }); + + TableLayout c0TL = new TableLayout(); + c0.Content = c0TL; + c0TL.Rows.Add(new TableRow()); + + lbl_Layer9Color = new Label(); + lbl_Layer9Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer9_Color); + setSize(lbl_Layer9Color, label_Height, label_Height); + c0TL.Rows[0].Cells.Add(lbl_Layer9Color); + + lbl_Layer9Color_name = new Label(); + lbl_Layer9Color_name.Text = "Layer 9"; + c0TL.Rows[0].Cells.Add(lbl_Layer9Color_name); + + Panel c1 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c1 }); + + TableLayout c1TL = new TableLayout(); + c1.Content = c1TL; + c1TL.Rows.Add(new TableRow()); + + lbl_Layer10Color = new Label(); + lbl_Layer10Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer10_Color); + setSize(lbl_Layer10Color, label_Height, label_Height); + c1TL.Rows[0].Cells.Add(lbl_Layer10Color); + + lbl_Layer10Color_name = new Label(); + lbl_Layer10Color_name.Text = "Layer 10"; + c1TL.Rows[0].Cells.Add(lbl_Layer10Color_name); + + Panel c2 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c2 }); + + TableLayout c2TL = new TableLayout(); + c2.Content = c2TL; + c2TL.Rows.Add(new TableRow()); + + lbl_Layer11Color = new Label(); + lbl_Layer11Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer11_Color); + setSize(lbl_Layer11Color, label_Height, label_Height); + c2TL.Rows[0].Cells.Add(lbl_Layer11Color); + + lbl_Layer11Color_name = new Label(); + lbl_Layer11Color_name.Text = "Layer 11"; + c2TL.Rows[0].Cells.Add(lbl_Layer11Color_name); + + Panel c3 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c3 }); + + TableLayout c3TL = new TableLayout(); + c3.Content = c3TL; + c3TL.Rows.Add(new TableRow()); + + lbl_Layer12Color = new Label(); + lbl_Layer12Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer12_Color); + setSize(lbl_Layer12Color, label_Height, label_Height); + c3TL.Rows[0].Cells.Add(lbl_Layer12Color); + + lbl_Layer12Color_name = new Label(); + lbl_Layer12Color_name.Text = "Layer 12"; + c3TL.Rows[0].Cells.Add(lbl_Layer12Color_name); + } + + void opengl_swatchrow4(TableRow tr) + { + Panel c0 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c0 }); + + TableLayout c0TL = new TableLayout(); + c0.Content = c0TL; + c0TL.Rows.Add(new TableRow()); + + lbl_Layer13Color = new Label(); + lbl_Layer13Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer13_Color); + setSize(lbl_Layer13Color, label_Height, label_Height); + c0TL.Rows[0].Cells.Add(lbl_Layer13Color); + + lbl_Layer13Color_name = new Label(); + lbl_Layer13Color_name.Text = "Layer 13"; + c0TL.Rows[0].Cells.Add(lbl_Layer13Color_name); + + Panel c1 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c1 }); + + TableLayout c1TL = new TableLayout(); + c1.Content = c1TL; + c1TL.Rows.Add(new TableRow()); + + lbl_Layer14Color = new Label(); + lbl_Layer14Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer14_Color); + setSize(lbl_Layer14Color, label_Height, label_Height); + c1TL.Rows[0].Cells.Add(lbl_Layer14Color); + + lbl_Layer14Color_name = new Label(); + lbl_Layer14Color_name.Text = "Layer 14"; + c1TL.Rows[0].Cells.Add(lbl_Layer14Color_name); + + Panel c2 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c2 }); + + TableLayout c2TL = new TableLayout(); + c2.Content = c2TL; + c2TL.Rows.Add(new TableRow()); + + lbl_Layer15Color = new Label(); + lbl_Layer15Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer15_Color); + setSize(lbl_Layer15Color, label_Height, label_Height); + c2TL.Rows[0].Cells.Add(lbl_Layer15Color); + + lbl_Layer15Color_name = new Label(); + lbl_Layer15Color_name.Text = "Layer 15"; + c2TL.Rows[0].Cells.Add(lbl_Layer15Color_name); + + Panel c3 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c3 }); + + TableLayout c3TL = new TableLayout(); + c3.Content = c3TL; + c3TL.Rows.Add(new TableRow()); + + lbl_Layer16Color = new Label(); + lbl_Layer16Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().layer16_Color); + setSize(lbl_Layer16Color, label_Height, label_Height); + c3TL.Rows[0].Cells.Add(lbl_Layer16Color); + + lbl_Layer16Color_name = new Label(); + lbl_Layer16Color_name.Text = "Layer 16"; + c3TL.Rows[0].Cells.Add(lbl_Layer16Color_name); + } + + void opengl_swatchrow5(TableRow tr) + { + Panel c0 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c0 }); + + TableLayout c0TL = new TableLayout(); + c0.Content = c0TL; + c0TL.Rows.Add(new TableRow()); + + lbl_Result1Color = new Label(); + lbl_Result1Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().result_Color); + setSize(lbl_Result1Color, label_Height, label_Height); + c0TL.Rows[0].Cells.Add(lbl_Result1Color); + + lbl_Result1Color_name = new Label(); + lbl_Result1Color_name.Text = "Result 1"; + c0TL.Rows[0].Cells.Add(lbl_Result1Color_name); + + Panel c1 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c1 }); + + TableLayout c1TL = new TableLayout(); + c1.Content = c1TL; + c1TL.Rows.Add(new TableRow()); + + lbl_Result2Color = new Label(); + lbl_Result2Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().result2_Color); + setSize(lbl_Result2Color, label_Height, label_Height); + c1TL.Rows[0].Cells.Add(lbl_Result2Color); + + lbl_Result2Color_name = new Label(); + lbl_Result2Color_name.Text = "Result 2"; + c1TL.Rows[0].Cells.Add(lbl_Result2Color_name); + + Panel c2 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c2 }); + + TableLayout c2TL = new TableLayout(); + c2.Content = c2TL; + c2TL.Rows.Add(new TableRow()); + + lbl_Result3Color = new Label(); + lbl_Result3Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().result3_Color); + setSize(lbl_Result3Color, label_Height, label_Height); + c2TL.Rows[0].Cells.Add(lbl_Result3Color); + + lbl_Result3Color_name = new Label(); + lbl_Result3Color_name.Text = "Result 3"; + lbl_Result3Color_name.Width = 80; + c2TL.Rows[0].Cells.Add(lbl_Result3Color_name); + + Panel c3 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c3 }); + + TableLayout c3TL = new TableLayout(); + c3.Content = c3TL; + c3TL.Rows.Add(new TableRow()); + + lbl_Result4Color = new Label(); + lbl_Result4Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().result4_Color); + setSize(lbl_Result4Color, label_Height, label_Height); + c3TL.Rows[0].Cells.Add(lbl_Result4Color); + + lbl_Result4Color_name = new Label(); + lbl_Result4Color_name.Text = "Result 4"; + c3TL.Rows[0].Cells.Add(lbl_Result4Color_name); + + } + + void opengl_swatchrow6(TableRow tr) + { + Panel c0 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c0 }); + + TableLayout c0TL = new TableLayout(); + c0.Content = c0TL; + c0TL.Rows.Add(new TableRow()); + + lbl_enabledColor = new Label(); + lbl_enabledColor.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().enabled_Color); + setSize(lbl_enabledColor, label_Height, label_Height); + c0TL.Rows[0].Cells.Add(lbl_enabledColor); + + lbl_enabledColor_name = new Label(); + lbl_enabledColor_name.Text = "Enabled"; + c0TL.Rows[0].Cells.Add(lbl_enabledColor_name); + + Panel c1 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c1 }); + + TableLayout c1TL = new TableLayout(); + c1.Content = c1TL; + c1TL.Rows.Add(new TableRow()); + + lbl_ss1Color = new Label(); + lbl_ss1Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().subshape1_Color); + setSize(lbl_ss1Color, label_Height, label_Height); + c1TL.Rows[0].Cells.Add(lbl_ss1Color); + + lbl_ss1Color_name = new Label(); + lbl_ss1Color_name.Text = "Subshape 1"; + c1TL.Rows[0].Cells.Add(lbl_ss1Color_name); + + Panel c2 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c2 }); + + TableLayout c2TL = new TableLayout(); + c2.Content = c2TL; + c2TL.Rows.Add(new TableRow()); + + lbl_ss2Color = new Label(); + lbl_ss2Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().subshape2_Color); + setSize(lbl_ss2Color, label_Height, label_Height); + c2TL.Rows[0].Cells.Add(lbl_ss2Color); + + lbl_ss2Color_name = new Label(); + lbl_ss2Color_name.Text = "Subshape 2"; + c2TL.Rows[0].Cells.Add(lbl_ss2Color_name); + + Panel c3 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c3 }); + + TableLayout c3TL = new TableLayout(); + c3.Content = c3TL; + c3TL.Rows.Add(new TableRow()); + + lbl_ss3Color = new Label(); + lbl_ss3Color.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().subshape3_Color); + setSize(lbl_ss3Color, label_Height, label_Height); + c3TL.Rows[0].Cells.Add(lbl_ss3Color); + + lbl_ss3Color_name = new Label(); + lbl_ss3Color_name.Text = "Subshape 3"; + c3TL.Rows[0].Cells.Add(lbl_ss3Color_name); + } + + void opengl_swatchrow7(TableRow tr) + { + Panel c0 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c0 }); + + TableLayout c0TL = new TableLayout(); + c0.Content = c0TL; + c0TL.Rows.Add(new TableRow()); + + lbl_implantMinColor = new Label(); + lbl_implantMinColor.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().implantMin_Color); + setSize(lbl_implantMinColor, label_Height, label_Height); + c0TL.Rows[0].Cells.Add(lbl_implantMinColor); + + lbl_implantMinColor_name = new Label(); + lbl_implantMinColor_name.Text = "Min Shadow"; + c0TL.Rows[0].Cells.Add(lbl_implantMinColor_name); + + Panel c1 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c1 }); + + TableLayout c1TL = new TableLayout(); + c1.Content = c1TL; + c1TL.Rows.Add(new TableRow()); + + lbl_implantMeanColor = new Label(); + lbl_implantMeanColor.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().implantMean_Color); + setSize(lbl_implantMeanColor, label_Height, label_Height); + c1TL.Rows[0].Cells.Add(lbl_implantMeanColor); + + lbl_implantMeanColor_name = new Label(); + lbl_implantMeanColor_name.Text = "Mean Shadow"; + c1TL.Rows[0].Cells.Add(lbl_implantMeanColor_name); + + Panel c2 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c2 }); + + TableLayout c2TL = new TableLayout(); + c2.Content = c2TL; + c2TL.Rows.Add(new TableRow()); + + lbl_implantMaxColor = new Label(); + lbl_implantMaxColor.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().implantMax_Color); + setSize(lbl_implantMaxColor, label_Height, label_Height); + c2TL.Rows[0].Cells.Add(lbl_implantMaxColor); + + lbl_implantMaxColor_name = new Label(); + lbl_implantMaxColor_name.Text = "Max Shadow"; + c2TL.Rows[0].Cells.Add(lbl_implantMaxColor_name); + + Panel c3 = new Panel(); + tr.Cells.Add(new TableCell() { Control = c3 }); + + TableLayout c3TL = new TableLayout(); + c3.Content = c3TL; + c3TL.Rows.Add(new TableRow()); + + lbl_implantResistColor = new Label(); + lbl_implantResistColor.BackgroundColor = UIHelper.myColorToColor(commonVars.getColors().implantResist_Color); + setSize(lbl_implantResistColor, label_Height, label_Height); + c3TL.Rows[0].Cells.Add(lbl_implantResistColor); + + lbl_implantResistColor_name = new Label(); + lbl_implantResistColor_name.Text = "Resist"; + c3TL.Rows[0].Cells.Add(lbl_implantResistColor_name); + } + + void openGLRow2(TableCell tc) + { + Panel p = new Panel(); + tc.Control = p; + + TableLayout tl = new TableLayout(); + tl.Rows.Add(new TableRow()); + p.Content = tl; + + + btn_resetColors = new Button(); + btn_resetColors.Text = "Reset"; + setSize(btn_resetColors, 60, 21); + tc.Control = TableLayout.AutoSized(btn_resetColors, centered: true); + } + + void addRNGMappingEqtn(object sender, EventArgs e) + { + string newString = text_rngMapping.Text; + if (newString == "") + { + return; + } + + // Only allow unique entries. + if (commonVars.rngCustomMapping.IndexOf(newString) == -1) + { + ExpressionParser parser = new ExpressionParser(); + double value = entropyRNG.RNG.nextdouble(); + while (value < 1E-15) + { + value = entropyRNG.RNG.nextdouble(); + } + parser.Values.Add("x", value); + value = entropyRNG.RNG.nextdouble(); + while (value < 1E-15) + { + value = entropyRNG.RNG.nextdouble(); + } + parser.Values.Add("y", value); + value = entropyRNG.RNG.nextdouble(); + while (value < 1E-15) + { + value = entropyRNG.RNG.nextdouble(); + } + parser.Values.Add("z", value); + try + { + string equation = newString; + // Substitute any Box-Muller queries with the full form. + equation = equation.Replace("_gxy", "(sqrt(-2 * ln(y)) * cos(2 * PI * x))"); + equation = equation.Replace("_gyz", "(sqrt(-2 * ln(z)) * cos(2 * PI * y))"); + equation = equation.Replace("_gxz", "(sqrt(-2 * ln(z)) * cos(2 * PI * x))"); + + double validation = parser.Parse(equation); + commonVars.rngCustomMapping.Add(newString); + } + catch (ParserException pe) + { + ErrorReporter.showMessage_OK(pe.ToString(), "Parser error"); + } + catch (Exception e2) + { + ErrorReporter.showMessage_OK(e2.ToString(), "Error"); + } + } + } + + void removeRNGMappingEqtn(object sender, EventArgs e) + { + int index = listBox_rngCustomMapping.SelectedIndex; + + // Forbid removal of default, Box-Muller, entry. + if ((index <= 0) || (commonVars.rngCustomMapping[index] == CommonVars.boxMuller)) + { + return; + } + + commonVars.rngCustomMapping.RemoveAt(index); + } + + void editRNGMappingEqtn(object sender, EventArgs e) + { + if (commonVars.rngCustomMapping[listBox_rngCustomMapping.SelectedIndex] != CommonVars.boxMuller) + { + text_rngMapping.Text = commonVars.rngCustomMapping[listBox_rngCustomMapping.SelectedIndex]; + } + } + + void rng_customMappingSetup(TableCell tc) + { + groupBox_rng = new GroupBox(); + tc.Control = groupBox_rng; + + TableLayout groupBox_rng_table = new TableLayout(); + groupBox_rng.Text = "RNG Mapping"; + groupBox_rng.Content = groupBox_rng_table; + + groupBox_rng_table.Rows.Add(new TableRow()); + listBox_rngCustomMapping = new ListBox(); + listBox_rngCustomMapping.BindDataContext(c => c.DataStore, (UIStringLists m) => m.rngMapping); + groupBox_rng_table.Rows[groupBox_rng_table.Rows.Count - 1].Cells.Add(listBox_rngCustomMapping); + + groupBox_rng_table.Rows.Add(new TableRow()); + + text_rngMapping = new TextBox(); + text_rngMapping.ToolTip = "Enter your custom mapping equation here. Three independent RNG variables are available: x, y and z.\r\nTo save the equation, use the Add button.\r\nValidation is performed before the equation is saved.\r\nPlease review any error output and correct it."; + groupBox_rng_table.Rows[groupBox_rng_table.Rows.Count - 1].Cells.Add(text_rngMapping); + + groupBox_rng_table.Rows.Add(new TableRow()); + + Panel btnRow = new Panel(); + + groupBox_rng_table.Rows[groupBox_rng_table.Rows.Count - 1].Cells.Add(btnRow); + + TableLayout btnTL = new TableLayout(); + btnRow.Content = btnTL; + btnTL.Rows.Add(new TableRow()); + + btn_rngMapping_Add = new Button(); + btn_rngMapping_Add.Text = "Add"; + btn_rngMapping_Add.ToolTip = "Add mapping equation to the list (duplicates will not be added)."; + btn_rngMapping_Add.Click += addRNGMappingEqtn; + btnTL.Rows[btnTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = btn_rngMapping_Add }); + + btn_rngMapping_Edit = new Button(); + btn_rngMapping_Edit.Text = "Edit"; + btn_rngMapping_Edit.ToolTip = "Load selected mapping equation for editing (Box-Muller cannot be edited)."; + btn_rngMapping_Edit.Click += editRNGMappingEqtn; + btnTL.Rows[btnTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = btn_rngMapping_Edit }); + + btn_rngMapping_Remove = new Button(); + btn_rngMapping_Remove.Text = "Remove"; + btn_rngMapping_Remove.ToolTip = "Remove selected mapping equation from list (Box-Muller cannot be removed)."; + btn_rngMapping_Remove.Click += removeRNGMappingEqtn; + btnTL.Rows[btnTL.Rows.Count - 1].Cells.Add(new TableCell() { Control = btn_rngMapping_Remove }); + } + } +} \ No newline at end of file diff --git a/Common/Variance/Variance.csproj b/Common/Variance/Variance.csproj new file mode 100644 index 0000000..02d6213 --- /dev/null +++ b/Common/Variance/Variance.csproj @@ -0,0 +1,61 @@ + + + + netcoreapp3.1 + Debug;Release;Release_obf + + + + TRACE;DISABLELICENSE + + + + TRACE; + + + + TRACE;DISABLELICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Common/Variance/chaos/chaosEngine.cs b/Common/Variance/chaos/chaosEngine.cs new file mode 100644 index 0000000..53a04b4 --- /dev/null +++ b/Common/Variance/chaos/chaosEngine.cs @@ -0,0 +1,775 @@ +using ClipperLib; +using geoWrangler; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Variance +{ + using Path = List; + using Paths = List>; + + class ChaosEngine + { + Paths listOfOutputPoints; + public Paths getPaths() + { + return pGetPaths(); + } + + Paths pGetPaths() + { + return listOfOutputPoints; + } + + string result; + public string getResult() + { + return pGetResult(); + } + + string pGetResult() + { + return result; + } + + bool outputValid; + public bool isValid() + { + return pIsValid(); + } + + bool pIsValid() + { + return outputValid; + } + + List simShapes; + Paths[] booleanPaths; + bool[] inputLayerEnabled; + + List preFlight(Paths aPath, Paths bPath) + { + // Put 0-index point at minX (see method for more notes) + int aCount = aPath.Count; + Parallel.For(0, aCount, (path) => + // for (Int32 path = 0; path < aCount; path++) + { + aPath[path] = reOrderPath("A", path); + }); + // Put 0-index point at minY (see method for more notes) + int bCount = bPath.Count; + Parallel.For(0, bCount, (path) => + // for (Int32 path = 0; path < bCount; path++) + { + bPath[path] = reOrderPath("B", path); + }); + List returnPaths = new List(); + returnPaths.Add(aPath.ToList()); + returnPaths.Add(bPath.ToList()); + + return returnPaths; + } + + Path reOrderPath(string shapeRef, Int32 pathIndex) + { + Path sourcePath = new Path(); + Path returnPath = new Path(); + if ((shapeRef.ToUpper() != "A") && (shapeRef.ToUpper() != "B")) + { + // Bad callsite. Throw exception. + throw (new Exception("reOrderPath: No shapeRef supplied!")); + } + else + { + if (shapeRef.ToUpper() == "A") + { + sourcePath = booleanPaths[0][pathIndex].ToList(); + } + else + { + sourcePath = booleanPaths[1][pathIndex].ToList(); + } + + returnPath = GeoWrangler.clockwiseAndReorder(sourcePath); + + } + return returnPath; + } + + public static Paths customBoolean(int firstLayerOperator, Paths firstLayer, int secondLayerOperator, Paths secondLayer, int booleanFlag) + { + return pCustomBoolean(firstLayerOperator, firstLayer, secondLayerOperator, secondLayer, booleanFlag); + } + + static Paths pCustomBoolean(int firstLayerOperator, Paths firstLayer, int secondLayerOperator, Paths secondLayer, int booleanFlag) + { + // In principle, 'rigorous' handling is only needed where the cutter is fully enclosed by the subject polygon. + // The challenge is to know whether this is the case or not. + // Possibility would be an intersection test and a vertex count and location comparison from before and after, to see whether anything changed. + bool rigorous = GeoWrangler.enclosed(firstLayer, secondLayer); // this is not a strict check because the enclosure can exist either way for this situation. + + // Need a secondary check because keyholed geometry could be problematic. + // Both paths will be reviewed; first one to have a keyhole will trigger the rigorous process. + if (!rigorous) + { + try + { + rigorous = GeoWrangler.enclosed(firstLayer, customSizing: 1, strict: true); // force a strict check. + + if (!rigorous) + { + // Need a further check because keyholed geometry in B could be problematic. + rigorous = GeoWrangler.enclosed(secondLayer, customSizing: 1, strict: true); // force a strict check. + } + } + catch (Exception) + { + // No big deal - carry on. + } + } + + Paths ret; + + ret = layerBoolean(firstLayerOperator, firstLayer, secondLayerOperator, secondLayer, booleanFlag, preserveColinear: true); + + ret = GeoWrangler.gapRemoval(ret).ToList(); + + bool holes = false; + bool gwHoles = false; + + for (int i = 0; i < ret.Count; i++) + { + holes = !Clipper.Orientation(ret[i]); + gwHoles = !GeoWrangler.isClockwise(ret[i]); + if (holes != gwHoles) + { + } + if (holes) + { + break; + } + } + + // Apply the keyholing and rationalize. + if (holes) + { + Paths merged = new Paths(); + merged = GeoWrangler.makeKeyHole(ret); + + int count = merged.Count; + Parallel.For(0, count, (i) => + //for (int i = 0; i < count; i++) + { + merged[i] = GeoWrangler.clockwise(merged[i]); + }); + + // Squash any accidental keyholes - not ideal, but best option found so far. + Clipper c1 = new Clipper(); + c1.PreserveCollinear = true; + c1.AddPaths(merged, PolyType.ptSubject, true); + c1.Execute(ClipType.ctUnion, ret); + } + + ret = GeoWrangler.sliverRemoval(ret); // experimental to try and remove any slivers. + + if (rigorous && !holes) + { + int count = ret.Count; + Parallel.For(0, count, (i) => + // for (int i = 0; i < count; i++) + { + ret[i] = GeoWrangler.clockwise(ret[i]); + ret[i] = GeoWrangler.close(ret[i]); + }); + // Return here because the attempt to rationalize the geometry below also screws things up, it seems. + return ret; + } + + IntRect bounds = Clipper.GetBounds(ret); + + Path bound = new Path(); + bound.Add(new IntPoint(bounds.left, bounds.bottom)); + bound.Add(new IntPoint(bounds.left, bounds.top)); + bound.Add(new IntPoint(bounds.right, bounds.top)); + bound.Add(new IntPoint(bounds.right, bounds.bottom)); + bound.Add(new IntPoint(bounds.left, bounds.bottom)); + + Clipper c = new Clipper(); + + c.AddPaths(ret, PolyType.ptSubject, true); + c.AddPath(bound, PolyType.ptClip, true); + + Paths simple = new Paths(); + c.Execute(ClipType.ctIntersection, simple); + + return GeoWrangler.clockwiseAndReorder(simple); + } + + Paths layerBoolean(EntropySettings simulationSettings, Int32 firstLayer, Int32 secondLayer, int booleanFlag, bool preserveColinear = true) + { + Paths firstLayerPaths = GeoWrangler.pathsFromPointFs(simShapes[firstLayer].getPoints(), CentralProperties.scaleFactorForOperation); + + Paths secondLayerPaths = GeoWrangler.pathsFromPointFs(simShapes[secondLayer].getPoints(), CentralProperties.scaleFactorForOperation); + + return layerBoolean(simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, firstLayer), firstLayerPaths, + simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, secondLayer), secondLayerPaths, booleanFlag, preserveColinear); + } + + static Paths layerBoolean(int firstLayerOperator, Paths firstLayerPaths, int secondLayerOperator, Paths secondLayerPaths, int booleanFlag, bool preserveColinear) + { + if (firstLayerOperator == 1) // NOT layer handling + { + try + { + firstLayerPaths = GeoWrangler.invertTone(firstLayerPaths, false).ToList(); + } + catch (Exception) + { + // Something blew up. + } + firstLayerPaths[0] = GeoWrangler.close(firstLayerPaths[0]); + } + + + if (secondLayerOperator == 1) // NOT layer handling + { + try + { + secondLayerPaths = GeoWrangler.invertTone(secondLayerPaths, false).ToList(); + } + catch (Exception) + { + // Something blew up. + } + secondLayerPaths[0] = GeoWrangler.close(secondLayerPaths[0]); + } + + if (firstLayerPaths[0].Count() <= 1) + { + return secondLayerPaths.ToList(); + } + if (secondLayerPaths[0].Count() <= 1) + { + return firstLayerPaths.ToList(); + } + + return layerBoolean(firstLayerPaths, secondLayerPaths, booleanFlag, preserveColinear: preserveColinear); + } + + static Paths layerBoolean(Paths firstPaths, Paths secondPaths, int booleanFlag, bool preserveColinear = true) + { + string booleanType = "AND"; + if (booleanFlag == 1) + { + booleanType = "OR"; + } + + Clipper c = new Clipper(); + c.PreserveCollinear = preserveColinear; // important - if we don't do this, we lose the fragmentation on straight edges. + + c.AddPaths(firstPaths, PolyType.ptSubject, true); + c.AddPaths(secondPaths, PolyType.ptClip, true); + + Paths outputPoints = new Paths(); + + if (booleanType == "AND") + { + c.Execute(ClipType.ctIntersection, outputPoints, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); + } + + if (booleanType == "OR") + { + c.Execute(ClipType.ctUnion, outputPoints, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); + } + return outputPoints; // Return our first list of points as the result of the boolean. + } + + Paths[] layerBoolean(CommonVars commonVars, bool preserveColinear = true) + { + // Boolean is structured as: + // Process two layers to get the interaction of two layers. + // Process each pair of results for the output of 4 layers + // Take each pair of results and get the combination of 8 layers. + + EntropySettings simulationSettings = commonVars.getSimulationSettings(); + + int limit2 = simulationSettings.getOperator(EntropySettings.properties_o.twoLayer).Length; + int limit4 = limit2 / 2; + int limit8 = limit4 / 2; + + Paths[] twoLayerResults = new Paths[limit2]; + Paths[] fourLayerResults = new Paths[limit4]; + Paths[] eightLayerResults = new Paths[limit8]; + + Path tPath = new Path(); + + Parallel.For(0, limit2, (i) => + // for (int i = 0; i < limit2; i++) + { + if (inputLayerEnabled[i * 2] && inputLayerEnabled[(i * 2) + 1]) + { + twoLayerResults[i] = layerBoolean(simulationSettings, i * 2, (i * 2) + 1, simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, i), preserveColinear: preserveColinear).ToList(); + } + else + { + if (inputLayerEnabled[i * 2] && !inputLayerEnabled[(i * 2) + 1]) + { + twoLayerResults[i] = layerBoolean(simulationSettings, i * 2, i * 2, 0, preserveColinear: preserveColinear); + } + else if (!inputLayerEnabled[i * 2] && inputLayerEnabled[(i * 2) + 1]) + { + twoLayerResults[i] = layerBoolean(simulationSettings, (i * 2) + 1, (i * 2) + 1, 0, preserveColinear: preserveColinear); + } + else + { + twoLayerResults[i] = new Paths(); + } + } + }); + + /* Direct the 4 layer boolean approach + -2 : no active layers. + -1 : only the left layer is enabled. + 0 : both layers are enabled. + 1 : only the right layer is enabled. + */ + int[] doLayer4Boolean = new int[limit4]; + + Parallel.For(0, limit4, (i) => + // for (int i = 0; i < limit4; i++) + { + if ( + (inputLayerEnabled[i * 4] || inputLayerEnabled[(i * 4) + 1]) && + (inputLayerEnabled[(i * 4) + 2] || inputLayerEnabled[(i * 4) + 3]) + ) + { + doLayer4Boolean[i] = 0; + } + else + { + if (inputLayerEnabled[i * 4] || inputLayerEnabled[(i * 4) + 1]) + { + doLayer4Boolean[i] = -1; + } + else if (inputLayerEnabled[(i * 4) + 2] || inputLayerEnabled[(i * 4) + 3]) + { + doLayer4Boolean[i] = 1; + } + else + { + doLayer4Boolean[i] = -2; + } + } + }); + + Parallel.For(0, limit4, (i) => + // for (int i = 0; i < limit4; i++) + { + if ((doLayer4Boolean[i] == 0) && ((twoLayerResults[(i * 2)].Count > 0) && (twoLayerResults[(i * 2) + 1].Count > 0))) + { + fourLayerResults[i] = layerBoolean( + firstPaths: twoLayerResults[(i * 2)], + secondPaths: twoLayerResults[(i * 2) + 1], + booleanFlag: simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, i), + preserveColinear: preserveColinear + ).ToList(); + } + else + { + switch (doLayer4Boolean[i]) + { + case -1: + fourLayerResults[i] = twoLayerResults[(i * 2)].ToList(); + break; + case 1: + fourLayerResults[i] = twoLayerResults[(i * 2) + 1].ToList(); + break; + case 0: + if (twoLayerResults[(i * 2)].Count > 0) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, i) == 0) + { + fourLayerResults[i] = new Paths(); + } + else + { + fourLayerResults[i] = twoLayerResults[i * 2].ToList(); + } + } + else if (twoLayerResults[(i * 2) + 1].Count > 0) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, i) == 0) + { + fourLayerResults[i] = new Paths(); + } + else + { + fourLayerResults[i] = twoLayerResults[(i * 2) + 1].ToList(); + } + } + else + { + fourLayerResults[i] = new Paths(); + } + break; + default: + fourLayerResults[i] = new Paths(); + break; + } + } + }); + + /* Direct the 8 layer boolean approach + -2 : no active layers. + -1 : only the left layer is enabled. + 0 : both layers are enabled. + 1 : only the right layer is enabled. + */ + int[] doLayer8Boolean = new int[limit8]; + + Parallel.For(0, limit8, (i) => + // for (int i = 0; i < limit8; i++) + { + // Are both sides active? + // 0th loop : 0 1 5 + // next : 8 9 + // next : 16 17 + if ( + ( + (inputLayerEnabled[i * 8] || inputLayerEnabled[(i * 8) + 1]) || + (inputLayerEnabled[(i * 8) + 2] || inputLayerEnabled[(i * 8) + 3]) + ) & + ( + (inputLayerEnabled[(i * 8) + 4] || inputLayerEnabled[(i * 8) + 5]) || + (inputLayerEnabled[(i * 8) + 6] || inputLayerEnabled[(i * 8) + 7]) + ) + ) + { + doLayer8Boolean[i] = 0; + } + else + { + if ( + (inputLayerEnabled[i * 8] || inputLayerEnabled[(i * 8) + 1]) || + (inputLayerEnabled[(i * 8) + 2] || inputLayerEnabled[(i * 8) + 3]) + ) + { + doLayer8Boolean[i] = -1; + } + else if ( + (inputLayerEnabled[(i * 8) + 4] || inputLayerEnabled[(i * 8) + 5]) || + (inputLayerEnabled[(i * 8) + 6] || inputLayerEnabled[(i * 8) + 7]) + ) + { + doLayer8Boolean[i] = 1; + } + else + { + doLayer8Boolean[i] = -2; + } + } + }); + + Parallel.For(0, limit8, (i) => + // for (int i = 0; i < limit8; i++) + { + if ((doLayer8Boolean[i] == 0) && ((fourLayerResults[(i * 2)].Count > 0) && (fourLayerResults[(i * 2) + 1].Count > 0))) + { + eightLayerResults[i] = layerBoolean( + firstPaths: fourLayerResults[(i * 2)], + secondPaths: fourLayerResults[(i * 2) + 1], + booleanFlag: simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, i), + preserveColinear: preserveColinear + ).ToList(); + } + else + { + switch (doLayer8Boolean[i]) + { + case -1: + eightLayerResults[i] = fourLayerResults[(i * 2)].ToList(); + break; + case 1: + eightLayerResults[i] = fourLayerResults[(i * 2) + 1].ToList(); + break; + case 0: + if (fourLayerResults[(i * 2)].Count > 0) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, i) == 0) + { + eightLayerResults[i] = new Paths(); + eightLayerResults[i].Add(tPath); + } + else + { + eightLayerResults[i] = fourLayerResults[i * 2].ToList(); + } + } + else if (fourLayerResults[(i * 2) + 1].Count > 0) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, i) == 0) + { + eightLayerResults[i] = new Paths(); + eightLayerResults[i].Add(tPath); + } + else + { + eightLayerResults[i] = fourLayerResults[(i * 2) + 1].ToList(); + } + } + else + { + eightLayerResults[i] = new Paths(); + eightLayerResults[i].Add(tPath); + } + break; + default: + eightLayerResults[i] = new Paths(); + eightLayerResults[i].Add(tPath); + break; + } + } + }); + + return eightLayerResults; + } + + // Preview mode is intended to allow multi-threaded evaluation for a single case - batch calculations run multiple separate single-threaded evaluations + public ChaosEngine(CommonVars commonVars, List simShapes, bool previewMode) + { + pChaosEngine(commonVars, simShapes, previewMode); + } + + void pChaosEngine(CommonVars commonVars, List simShapes, bool previewMode) + { + outputValid = false; + this.simShapes = simShapes; + + listOfOutputPoints = new Paths(); + + EntropySettings simulationSettings = commonVars.getSimulationSettings(); + + bool sgRemove_a = false; + bool sgRemove_b = false; + + inputLayerEnabled = new bool[CentralProperties.maxLayersForMC]; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + inputLayerEnabled[i] = commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1; + // Modify our state based on the omit flag (in case this layer is being used by an in-layer boolean elsewhere and the user requested to omit the input layer. + inputLayerEnabled[i] = inputLayerEnabled[i] && (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.omit) == 0); + if (!sgRemove_a) + { + if (i < CentralProperties.maxLayersForMC / 2) + { + sgRemove_a = (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.BOOLEAN); + } + } + if (!sgRemove_b) + { + if (i >= CentralProperties.maxLayersForMC / 2) + { + sgRemove_b = (commonVars.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.BOOLEAN); + } + } + } + + bool preserveColinear = (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (Int32)CommonVars.calcModes.enclosure_spacing_overlap); + + booleanPaths = layerBoolean(commonVars, preserveColinear); + + if (sgRemove_a) + { + booleanPaths[0] = GeoWrangler.sliverGapRemoval(booleanPaths[0]); + } + if (sgRemove_b) + { + booleanPaths[1] = GeoWrangler.sliverGapRemoval(booleanPaths[1]); + } + + Int32 layerAPathCount_orig = booleanPaths[0].Count(); + Int32 layerBPathCount_orig = booleanPaths[1].Count(); + + // Let's validate that we have something reasonable for the inputs before we do something with them. + bool inputsValid = true; + if ((layerAPathCount_orig == 0) || (layerBPathCount_orig == 0)) + { + // Assuming failSafe for each layer, we'd have one point per failed layer, so we fail for anything below or equal to 2. We also can't make a polygon from 2 points. + inputsValid = false; + } + + if (inputsValid) + { + switch (simulationSettings.getValue(EntropySettings.properties_i.oType)) + { + case (int)CommonVars.calcModes.area: // area + try + { + bool perPoly = false; + if (simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.areaCalcModes.perpoly) + { + perPoly = true; + } + AreaHandler aH = new AreaHandler(aPaths: booleanPaths[0], bPaths: booleanPaths[1], maySimplify: true, perPoly); + // Sum the areas by polygon returned. + result = (Convert.ToDouble(result) + aH.area).ToString(); + listOfOutputPoints.AddRange(aH.listOfOutputPoints); + outputValid = true; + } + catch (Exception) + { + // rejected case - don't care. + } + break; + + case (int)CommonVars.calcModes.enclosure_spacing_overlap: // spacing (or enclosure) + DistanceHandler dH = new DistanceHandler(aPaths: booleanPaths[0], bPaths: booleanPaths[1], simulationSettings, previewMode); // in preview mode, raycaster inside this engine will run threaded along the emit edge. + + // Store minimum case for the per polygon system. + if (result == null) + { + result = dH.distanceString; + listOfOutputPoints = dH.resultPaths.ToList(); + } + else + { + // Overlaps are reported as negative values, so this will handle both spacing and overlap cases. + if (Convert.ToDouble(dH.distanceString) < Convert.ToDouble(result)) + { + result = dH.distanceString; + listOfOutputPoints = dH.resultPaths.ToList(); + } + } + + // Viewport needs a polygon - lines aren't handled properly, so let's double up our line. + try + { + for (int poly = 0; poly < listOfOutputPoints.Count; poly++) + { + Int32 pt = listOfOutputPoints[poly].Count - 1; + while (pt > 0) + { + listOfOutputPoints[poly].Add(new IntPoint(listOfOutputPoints[poly][pt])); + pt--; + } + } + } + catch (Exception) + { + + } + outputValid = true; + + break; + + case (int)CommonVars.calcModes.chord: // chord + if (result == null) + { + result = "0.0,0.0,0.0,0.0"; + } + + double[] fraggedResult = new double[4]; + fraggedResult[0] = fraggedResult[1] = fraggedResult[2] = fraggedResult[3] = 0.0; + + Path tmpPath = new Path(); + tmpPath.Add(new IntPoint(0, 0)); + listOfOutputPoints.Add(tmpPath.ToList()); + listOfOutputPoints.Add(tmpPath.ToList()); + listOfOutputPoints.Add(tmpPath.ToList()); + listOfOutputPoints.Add(tmpPath.ToList()); + + try + { + Paths aPath = booleanPaths[0].ToList(); + Paths bPath = booleanPaths[1].ToList(); + List cleanedPaths = preFlight(aPath, bPath).ToList(); + aPath = cleanedPaths[0].ToList(); + bPath = cleanedPaths[1].ToList(); + ChordHandler cH = new ChordHandler(aPath, bPath, simulationSettings); + + // Fragment our result. + char[] resultSeparators = new char[] { ',' }; // CSV separator for splitting results for comparison. + string[] tmpfraggedResult = result.Split(resultSeparators); + Parallel.For(0, tmpfraggedResult.Length, (i) => + // for (Int32 i = 0; i < tmpfraggedResult.Length; i++) + { + fraggedResult[i] = Convert.ToDouble(tmpfraggedResult[i]); + }); + + fraggedResult[0] = cH.aChordLengths[0] / CentralProperties.scaleFactorForOperation; + listOfOutputPoints[0] = cH.a_chordPaths[0].ToList(); + fraggedResult[1] = cH.aChordLengths[1] / CentralProperties.scaleFactorForOperation; + listOfOutputPoints[1] = cH.a_chordPaths[1].ToList(); + fraggedResult[2] = cH.bChordLengths[0] / CentralProperties.scaleFactorForOperation; + listOfOutputPoints[2] = cH.b_chordPaths[0].ToList(); + fraggedResult[3] = cH.bChordLengths[1] / CentralProperties.scaleFactorForOperation; + listOfOutputPoints[3] = cH.b_chordPaths[1].ToList(); + + if (simulationSettings.getValue(EntropySettings.properties_i.subMode) != (int)CommonVars.chordCalcElements.b) + { + result = fraggedResult[0].ToString() + "," + fraggedResult[1].ToString(); + } + else + { + result = "N/A,N/A"; + } + + if (simulationSettings.getValue(EntropySettings.properties_i.subMode) >= (int)CommonVars.chordCalcElements.b) + { + result += "," + fraggedResult[2].ToString() + "," + fraggedResult[3].ToString(); + } + else + { + result += ",N/A,N/A"; + } + outputValid = true; + } + catch (Exception) + { + // We don't care about exceptions - these are probably rejected cases from coincident edges. + } + break; + + case (int)CommonVars.calcModes.angle: // angle + for (Int32 layerAPoly = 0; layerAPoly < layerAPathCount_orig; layerAPoly++) + { + for (Int32 layerBPoly = 0; layerBPoly < layerBPathCount_orig; layerBPoly++) + { + try + { + angleHandler agH = new angleHandler(layerAPath: booleanPaths[0], layerBPath: booleanPaths[1]); + if (result == null) + { + result = agH.minimumIntersectionAngle.ToString(); + listOfOutputPoints = agH.resultPaths.ToList(); + } + else + { + if (agH.minimumIntersectionAngle < Convert.ToDouble(result)) + { + result = agH.minimumIntersectionAngle.ToString(); + listOfOutputPoints.Clear(); + listOfOutputPoints = agH.resultPaths.ToList(); + } + } + outputValid = true; // mark that we're good for the callsite + } + catch (Exception) + { + // rejected case. + } + } + } + break; + } + } + else + { + outputValid = false; + // Need to return empty values. + } + } + } +} diff --git a/Common/Variance/chaos/chaosEngine_implant.cs b/Common/Variance/chaos/chaosEngine_implant.cs new file mode 100644 index 0000000..e8743ec --- /dev/null +++ b/Common/Variance/chaos/chaosEngine_implant.cs @@ -0,0 +1,410 @@ +using ClipperLib; +using geoLib; +using geoWrangler; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using utility; + +namespace Variance +{ + using Path = List; + using Paths = List>; + + class ChaosEngine_implant + { + string result, min, max; + public string getResult() + { + return pGetResult(); + } + + string pGetResult() + { + return result; + } + + public string getMin() + { + return pGetMin(); + } + + string pGetMin() + { + return min; + } + + public string getMax() + { + return pGetMax(); + } + + string pGetMax() + { + return max; + } + + bool outputValid; + public bool isValid() + { + return pIsValid(); + } + + bool pIsValid() + { + return outputValid; + } + + // Output geometry. + GeoLibPointF[] geom, bgGeom; + public GeoLibPointF[] getGeom() + { + return pGetGeom(); + } + + GeoLibPointF[] pGetGeom() + { + return geom; + } + + public GeoLibPointF[] getBGGeom() + { + return pGetBGGeom(); + } + + GeoLibPointF[] pGetBGGeom() + { + return bgGeom; + } + + GeoLibPointF[] shadow, minShadow, maxShadow; + public GeoLibPointF[] getShadow() + { + return pGetShadow(); + } + + GeoLibPointF[] pGetShadow() + { + return shadow; + } + + public GeoLibPointF[] getMinShadow() + { + return pGetMinShadow(); + } + + GeoLibPointF[] pGetMinShadow() + { + return minShadow; + } + + public GeoLibPointF[] getMaxShadow() + { + return pGetMaxShadow(); + } + + GeoLibPointF[] pGetMaxShadow() + { + return maxShadow; + } + + public ChaosEngine_implant(ChaosSettings_implant chaosSettings, EntropySettings entropySettings, EntropyImplantSettings implantCalcSettings) + { + pChaosEngine_implant(chaosSettings, entropySettings, implantCalcSettings); + } + + void pChaosEngine_implant(ChaosSettings_implant chaosSettings, EntropySettings entropySettings, EntropyImplantSettings implantCalcSettings) + { + outputValid = false; + + try + { + List implant_MLS = new List(); + EntropyLayerSettings mls = new EntropyLayerSettings(); + mls.setInt(EntropyLayerSettings.properties_i.edgeSlide, 0); // we don't want the edge slide in this situation. + mls.setInt(EntropyLayerSettings.properties_i.shapeIndex, (Int32)CommonVars.shapeNames.rect); + double resistWidth = implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.w) + (implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.wV) * chaosSettings.getValue(ChaosSettings_implant.properties.resistCDVar)); + mls.setDecimal(EntropyLayerSettings.properties_decimal.s0HorLength, Convert.ToDecimal(resistWidth)); + double resistHeight = implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.h) + (implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.hV) * chaosSettings.getValue(ChaosSettings_implant.properties.resistHeightVar)); + mls.setDecimal(EntropyLayerSettings.properties_decimal.s0VerLength, Convert.ToDecimal(resistHeight) * 2.0m); // double since we're making an ellipse and clipping later. + mls.setDecimal(EntropyLayerSettings.properties_decimal.oCR, Convert.ToDecimal(implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.cRR) + (implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.cV) * chaosSettings.getValue(ChaosSettings_implant.properties.resistTopCRRVar)))); + mls.setInt(EntropyLayerSettings.properties_i.posIndex, (Int32)CommonVars.subShapeLocations.C); + mls.setInt(EntropyLayerSettings.properties_i.enabled, 1); + implant_MLS.Add(mls); + + // To permit random variations at a later date. + // We take the existing simulation settings to make the shape engine, etc. more straightforward. + ChaosSettings implant_js = new ChaosSettings(true, implant_MLS, entropySettings); + + // Use our shape engine to create a nice ellipse. + EntropyShape ms = new EntropyShape(entropySettings, implant_MLS, settingsIndex: 0, doPASearch: false, previewMode: true, implant_js); + + // Set up our sourcePath for clipping, recentering it at 0,0 as well. + Path sourcePath = new Path(); + for (int pt = 0; pt < ms.getPoints().Length; pt++) + { + double x = ms.getPoints()[pt].X - (Convert.ToDouble(mls.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2.0f); + double y = ms.getPoints()[pt].Y - resistHeight; + sourcePath.Add(new IntPoint((Int64)(x * CentralProperties.scaleFactorForOperation), + (Int64)(y * CentralProperties.scaleFactorForOperation))); + } + Paths source = new Paths(); + source.Add(sourcePath); + + // Build our mask polygon from the bounds and 0,0 reference. Curiously, Clipper's top/bottom bounds are flipped from what might be expected. + IntRect bounds = Clipper.GetBounds(source); + Path maskPoly = new Path(); + maskPoly.Add(new IntPoint(0, 0)); + maskPoly.Add(new IntPoint(0, bounds.bottom)); + maskPoly.Add(new IntPoint(bounds.right, bounds.bottom)); + maskPoly.Add(new IntPoint(bounds.right, 0)); + maskPoly.Add(new IntPoint(0, 0)); + + // Get our region extracted using the mask. + Clipper c = new Clipper(); + c.PreserveCollinear = false; + c.AddPath(sourcePath, PolyType.ptSubject, true); + c.AddPath(maskPoly, PolyType.ptClip, true); + Paths solution = new Paths(); + c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); + + if (solution.Count == 0) + { + outputValid = false; + return; + } + // We only ever have one path in the solution. + // Re-order the points by finding our first (0,0) coordinate. + Int32 reIndexStart = 0; + for (int pt = 0; pt < solution[0].Count; pt++) + { + if ((solution[0][pt].X == 0) && (solution[0][pt].Y == 0)) + { + reIndexStart = pt; + break; + } + } + + // Build our point array, re-indexing if needed. + GeoLibPoint[] points = new GeoLibPoint[solution[0].Count + 1]; + if (reIndexStart != 0) + { + Int32 index = 0; // just to track our position in the points array. + for (Int32 pt = reIndexStart; pt < solution[0].Count; pt++) + { + points[index] = new GeoLibPoint(solution[0][pt].X, solution[0][pt].Y); + index++; + } + // Ensure we close the shape by hitting the reIndexStart point again, since we will possibly have pushed it to the beginning of the shape. + for (Int32 pt = 0; pt <= reIndexStart; pt++) + { + points[index] = new GeoLibPoint(solution[0][pt].X, solution[0][pt].Y); + index++; + } + } + else + { + Parallel.For(0, solution[0].Count, (pt) => + // for (int pt = 0; pt < solution[0].Count; pt++) + { + points[pt] = new GeoLibPoint(solution[0][pt].X, solution[0][pt].Y); + }); + } + points[points.Length - 1] = new GeoLibPoint(points[0].X, points[0].Y); // close it, for the sake of it. + + // Clockwise spin. + points = GeoWrangler.clockwise(points); + + // We can now get our tangent extraction sorted out. + Int32 nomPtIndex = -1; + double nomXIntercept = 0; + double nomYIntercept = 0; + + Int32 minPtIndex = -1; + double minXIntercept = 0; + double minYIntercept = 0; + + Int32 maxPtIndex = -1; + double maxXIntercept = 0; + double maxYIntercept = 0 + ; + // Reverse walk due to 0 angle shadowing occuring at the resist edge. + for (int pt = points.Length - 3; pt > 1; pt--) + { + double deltaY = points[pt + 1].Y - points[pt].Y; + double deltaX = points[pt + 1].X - points[pt].X; + + // A zero deltaX breaks the gradient calculation because it results in infinity. + // Instead, set an arbitrary small value. + // We also clamp for negative values as there is no prospect of negative shadowing. + if (deltaX <= 0) + { + deltaX = 1E-9; + } + + // Flip the sign - we're walking backwards, but want the positive change. Doing it this way made the code easier to understand. + deltaX *= -1; + deltaY *= -1; + + // retrieve our angle for the line segment. 0 is vertical; 90 would be parallel to surface. + // angle is negative as we're walking down the resist profile. + double angle = Utils.toDegrees(Math.Atan(deltaY / deltaX)); + + // Line parameters. + double m = deltaY / deltaX; + double c_ = points[pt].Y - (m * points[pt].X); + + if (chaosSettings.isPreview()) + { + // X intersect : y = mx + c and so we need to solve for y = 0, i.e. mx = -c + double twistAngle = implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.twist) + implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.twistV); + if (twistAngle > 90) + { + twistAngle = 90.0f; + } + double tiltAngle = implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.tilt) - implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.tiltV); + if (tiltAngle < 0) + { + tiltAngle = 0.0f; + } + if ((minPtIndex == -1) && (angle + 90.0f >= Convert.ToDouble(tiltAngle) * Math.Cos(Utils.toRadians(twistAngle)))) + { + minPtIndex = pt; + minXIntercept = -c_ / m; + minYIntercept = c_; + } + + if ((minPtIndex != -1) && (nomPtIndex == -1) && (angle + 90.0f >= Convert.ToDouble(implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.tilt)) * Math.Cos(Utils.toRadians(implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.twist))))) + { + nomPtIndex = pt; + nomXIntercept = -c_ / m; + nomYIntercept = c_; + } + + tiltAngle = implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.tilt) + implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.tiltV); + if (tiltAngle > 90) + { + tiltAngle = 90.0f; + } + if ((nomPtIndex != -1) && (maxPtIndex == -1) && (angle + 90.0f >= Convert.ToDouble(tiltAngle) * Math.Cos(Utils.toRadians(implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.twist))))) + { + maxPtIndex = pt; + maxXIntercept = -c_ / m; + maxYIntercept = c_; + } + } + else + { + double tiltAngle_3sigmaVar = implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.tilt) + (chaosSettings.getValue(ChaosSettings_implant.properties.tiltVar) * implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.tiltV)); + if (tiltAngle_3sigmaVar < 0) + { + tiltAngle_3sigmaVar = 0.0f; + } + if (tiltAngle_3sigmaVar > 90) + { + tiltAngle_3sigmaVar = 90.0f; + } + double twistAngle_3sigmaVar = implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.twist) + (chaosSettings.getValue(ChaosSettings_implant.properties.twistVar) * implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.twistV)); + if (twistAngle_3sigmaVar < 0) + { + twistAngle_3sigmaVar = 0.0f; + } + if (twistAngle_3sigmaVar > 90) + { + twistAngle_3sigmaVar = 90.0f; + } + + // X intersect : y = mx + c and so we need to solve for y = 0, i.e. mx = -c + if (angle + 90.0f >= Convert.ToDouble(tiltAngle_3sigmaVar) * Math.Cos(Utils.toRadians(twistAngle_3sigmaVar))) + { + nomPtIndex = pt; + nomXIntercept = -c_ / m; + nomYIntercept = c_; + break; + } + } + } + + // Get our shadow line (polys) sorted out. + shadow = new GeoLibPointF[4]; + shadow[0] = new GeoLibPointF(0.0f, (nomYIntercept / CentralProperties.scaleFactorForOperation)); + shadow[1] = new GeoLibPointF((nomXIntercept / CentralProperties.scaleFactorForOperation), 0.0f); + shadow[2] = new GeoLibPointF(shadow[1].X, shadow[1].Y); + shadow[3] = new GeoLibPointF(shadow[0].X, shadow[0].Y); + + // Calculate our shadow distance taking into account the resist width beyond the intercept point. + double actualResistWidth = implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.w) + (chaosSettings.getValue(ChaosSettings_implant.properties.resistCDVar) * implantCalcSettings.getDouble(EntropyImplantSettings.properties_d.wV)); + // Force a format here to avoid blanks in some cases. + result = (shadow[1].X - (actualResistWidth / 2.0f)).ToString("#.##"); + // Extra check in case of an escape above, but shoudn't be needed. + if (result == "") + { + result = "0.0"; + } + + minShadow = new GeoLibPointF[4]; + maxShadow = new GeoLibPointF[4]; + + if (chaosSettings.isPreview()) + { + minShadow[0] = new GeoLibPointF(0.0f, (minYIntercept / CentralProperties.scaleFactorForOperation)); + minShadow[1] = new GeoLibPointF((minXIntercept / CentralProperties.scaleFactorForOperation), 0.0f); + minShadow[2] = new GeoLibPointF(minShadow[1].X, minShadow[1].Y); + minShadow[3] = new GeoLibPointF(minShadow[0].X, minShadow[0].Y); + + maxShadow[0] = new GeoLibPointF(0.0f, (maxYIntercept / CentralProperties.scaleFactorForOperation)); + maxShadow[1] = new GeoLibPointF((maxXIntercept / CentralProperties.scaleFactorForOperation), 0.0f); + maxShadow[2] = new GeoLibPointF(maxShadow[1].X, maxShadow[1].Y); + maxShadow[3] = new GeoLibPointF(maxShadow[0].X, maxShadow[0].Y); + + min = (minShadow[1].X - (actualResistWidth / 2.0f)).ToString(); + // Seem to get periodic blanks for 0 cases so force the issue here. + if (min == "") + { + min = "0.0"; + } + max = (maxShadow[1].X - (actualResistWidth / 2.0f)).ToString(); + // Seem to get periodic blanks for 0 cases so force the issue here. + if (max == "") + { + max = "0.0"; + } + + // Preview mode result push. + } + else + { + min = "N/A"; + max = "N/A"; + + minShadow[0] = new GeoLibPointF(0, 0); + minShadow[1] = new GeoLibPointF(0, 0); + minShadow[2] = new GeoLibPointF(0, 0); + minShadow[3] = new GeoLibPointF(0, 0); + + maxShadow[0] = new GeoLibPointF(0, 0); + maxShadow[1] = new GeoLibPointF(0, 0); + maxShadow[2] = new GeoLibPointF(0, 0); + maxShadow[3] = new GeoLibPointF(0, 0); + } + + // Now need to scale our polygon back down again for display. + geom = new GeoLibPointF[points.Length]; // resist profile that has been evaluated for shadowing. + bgGeom = new GeoLibPointF[points.Length]; // display the other resist side, to avoid confusing user, but this isn't evaluated in shadowing. + Parallel.For(0, points.Length, (pt) => + // for (int pt = 0; pt < points.Length; pt++) + { + double x = (double)(points[pt].X) / CentralProperties.scaleFactorForOperation; + double y = (double)(points[pt].Y) / CentralProperties.scaleFactorForOperation; + geom[pt] = new GeoLibPointF(x, y); + bgGeom[pt] = new GeoLibPointF(-x, y); + }); + outputValid = true; + } + catch (Exception) + { + outputValid = false; + } + } + } +} diff --git a/Common/Variance/chaos/chaosSettings.cs b/Common/Variance/chaos/chaosSettings.cs new file mode 100644 index 0000000..b686443 --- /dev/null +++ b/Common/Variance/chaos/chaosSettings.cs @@ -0,0 +1,615 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Variance +{ + public class ChaosSettings + { + public enum properties { overlayX, overlayY, hTipBiasType, vTipBiasType, hTipBiasVar, vTipBiasVar, icVar, ocVar, LWRVar, LWR2Var, CDUTVar, CDUSVar, wobbleVar } + public enum ints { lwrSeed, lwr2Seed } + public enum bools { icPA, ocPA } + + static int dimensions = 15; // number of variations. + + public static int getDimensions() + { + return pGetDimensions(); + } + + static int pGetDimensions() + { + return dimensions; + } + + // This holds all of our run specific variations. It should be set up before EntropyShape is called. + double[] overlayX; + double[] overlayY; + double[] hTipBiasType; + double[] vTipBiasType; + double[] horTipBiasVar; + double[] verTipBiasVar; + double[] iCVar; + bool[] iC_PAsearch; + double[] oCVar; + bool[] oC_PAsearch; + double[] LWRVar; + double[] LWR2Var; + double[] CDUTVar; + double[] CDUSVar; + double[] wobbleVar; + int[] LWRSeed; + int[] LWR2Seed; + bool previewMode; + bool customRNGMapping; + + public bool getPreviewMode() + { + return pGetPreviewMode(); + } + + bool pGetPreviewMode() + { + return previewMode; + } + + public void setPreviewMode(bool p) + { + pSetPreviewMode(p); + } + + void pSetPreviewMode(bool p) + { + previewMode = p; + } + + public bool getCustomRNGMapping() + { + return pGetCustomRNGMapping(); + } + + bool pGetCustomRNGMapping() + { + return customRNGMapping; + } + + public void setCustomRNGMapping(bool p) + { + pSetCustomRNGMapping(p); + } + + void pSetCustomRNGMapping(bool p) + { + customRNGMapping = p; + } + + public void setValue(properties p, int index, double value) + { + pSetValue((int)p, index, value); + } + + void pSetValue(int p, int index, double value) + { + switch (p) + { + case (int)properties.overlayX: + overlayX[index] = value; + break; + case (int)properties.overlayY: + overlayY[index] = value; + break; + case (int)properties.hTipBiasType: + hTipBiasType[index] = value; + break; + case (int)properties.vTipBiasType: + vTipBiasType[index] = value; + break; + case (int)properties.hTipBiasVar: + horTipBiasVar[index] = value; + break; + case (int)properties.vTipBiasVar: + verTipBiasVar[index] = value; + break; + case (int)properties.icVar: + iCVar[index] = value; + break; + case (int)properties.ocVar: + oCVar[index] = value; + break; + case (int)properties.LWRVar: + LWRVar[index] = value; + break; + case (int)properties.LWR2Var: + LWR2Var[index] = value; + break; + case (int)properties.CDUTVar: + CDUTVar[index] = value; + break; + case (int)properties.CDUSVar: + CDUSVar[index] = value; + break; + case (int)properties.wobbleVar: + wobbleVar[index] = value; + break; + } + } + + public double getValue(properties p, int index) + { + return pGetValue((int)p, index); + } + + double pGetValue(int p, int index) + { + double retVal = 0; + switch (p) + { + case (int)properties.overlayX: + retVal = overlayX[index]; + break; + case (int)properties.overlayY: + retVal = overlayY[index]; + break; + case (int)properties.hTipBiasType: + retVal = hTipBiasType[index]; + break; + case (int)properties.vTipBiasType: + retVal = vTipBiasType[index]; + break; + case (int)properties.hTipBiasVar: + retVal = horTipBiasVar[index]; + break; + case (int)properties.vTipBiasVar: + retVal = verTipBiasVar[index]; + break; + case (int)properties.icVar: + retVal = iCVar[index]; + break; + case (int)properties.ocVar: + retVal = oCVar[index]; + break; + case (int)properties.LWRVar: + retVal = LWRVar[index]; + break; + case (int)properties.LWR2Var: + retVal = LWR2Var[index]; + break; + case (int)properties.CDUTVar: + retVal = CDUTVar[index]; + break; + case (int)properties.CDUSVar: + retVal = CDUSVar[index]; + break; + case (int)properties.wobbleVar: + retVal = wobbleVar[index]; + break; + } + + return retVal; + } + + public double[] getValues(properties p) + { + return pGetValues((int)p); + } + + double[] pGetValues(int p) + { + double[] retVal = new double[] { }; + switch (p) + { + case (int)properties.overlayX: + retVal = overlayX; + break; + case (int)properties.overlayY: + retVal = overlayY; + break; + case (int)properties.hTipBiasType: + retVal = hTipBiasType; + break; + case (int)properties.vTipBiasType: + retVal = vTipBiasType; + break; + case (int)properties.hTipBiasVar: + retVal = horTipBiasVar; + break; + case (int)properties.vTipBiasVar: + retVal = verTipBiasVar; + break; + case (int)properties.icVar: + retVal = iCVar; + break; + case (int)properties.ocVar: + retVal = oCVar; + break; + case (int)properties.LWRVar: + retVal = LWRVar; + break; + case (int)properties.LWR2Var: + retVal = LWR2Var; + break; + case (int)properties.CDUTVar: + retVal = CDUTVar; + break; + case (int)properties.CDUSVar: + retVal = CDUSVar; + break; + case (int)properties.wobbleVar: + retVal = wobbleVar; + break; + } + + return retVal; + } + + public void setValues(properties p, double[] values) + { + pSetValues((int)p, values); + } + + void pSetValues(int p, double[] values) + { + switch (p) + { + case (int)properties.overlayX: + overlayX = values; + break; + case (int)properties.overlayY: + overlayY = values; + break; + case (int)properties.hTipBiasType: + hTipBiasType = values; + break; + case (int)properties.vTipBiasType: + vTipBiasType = values; + break; + case (int)properties.hTipBiasVar: + horTipBiasVar = values; + break; + case (int)properties.vTipBiasVar: + verTipBiasVar = values; + break; + case (int)properties.icVar: + iCVar = values; + break; + case (int)properties.ocVar: + oCVar = values; + break; + case (int)properties.LWRVar: + LWRVar = values; + break; + case (int)properties.LWR2Var: + LWR2Var = values; + break; + case (int)properties.CDUTVar: + CDUTVar = values; + break; + case (int)properties.CDUSVar: + CDUSVar = values; + break; + case (int)properties.wobbleVar: + wobbleVar = values; + break; + } + } + + public void setInt(ints i, int index, int value) + { + pSetInt((int)i, index, value); + } + + void pSetInt(int i, int index, int value) + { + switch (i) + { + case (int)ints.lwrSeed: + LWRSeed[index] = value; + break; + case (int)ints.lwr2Seed: + LWR2Seed[index] = value; + break; + } + } + + public int getInt(ints i, int index) + { + return pGetInt((int)i, index); + } + + int pGetInt(int i, int index) + { + int retVal = 0; + switch (i) + { + case (int)ints.lwrSeed: + retVal = LWRSeed[index]; + break; + case (int)ints.lwr2Seed: + retVal = LWR2Seed[index]; + break; + } + return retVal; + } + + public int[] getInts(ints i) + { + return pGetInts((int)i); + } + + int[] pGetInts(int i) + { + int[] retVal = new int[] { }; + switch (i) + { + case (int)ints.lwrSeed: + retVal = LWRSeed; + break; + case (int)ints.lwr2Seed: + retVal = LWR2Seed; + break; + } + return retVal; + } + + public void setBool(bools b, int index, bool value) + { + pSetBool((int)b, index, value); + } + + void pSetBool(int b, int index, bool value) + { + switch (b) + { + case (int)bools.icPA: + iC_PAsearch[index] = value; + break; + case (int)bools.ocPA: + oC_PAsearch[index] = value; + break; + } + } + + public bool getBool(bools b, int index) + { + return pGetBool((int)b, index); + } + + bool pGetBool(int b, int index) + { + bool retVal = false; + switch (b) + { + case (int)bools.icPA: + retVal = iC_PAsearch[index]; + break; + case (int)bools.ocPA: + retVal = oC_PAsearch[index]; + break; + } + return retVal; + } + + public bool[] getBools(bools b) + { + return pGetBools((int)b); + } + + bool[] pGetBools(int b) + { + bool[] retVal = new bool[] { }; + switch (b) + { + case (int)bools.icPA: + retVal = iC_PAsearch; + break; + case (int)bools.ocPA: + retVal = oC_PAsearch; + break; + } + return retVal; + } + + public ChaosSettings(bool previewMode, List listOfSettings, EntropySettings simSettings) // set to true for preview; else we run with random inputs + { + pChaosSettings(previewMode, listOfSettings, simSettings); + } + + void pChaosSettings(bool previewMode, List listOfSettings, EntropySettings simSettings) // set to true for preview; else we run with random inputs + { + customRNGMapping = false; + this.previewMode = previewMode; + int count = listOfSettings.Count; + overlayX = new double[count]; + overlayY = new double[count]; + hTipBiasType = new double[count]; + vTipBiasType = new double[count]; + horTipBiasVar = new double[count]; + verTipBiasVar = new double[count]; + iCVar = new double[count]; + iC_PAsearch = new bool[count]; + oCVar = new double[count]; + oC_PAsearch = new bool[count]; + LWRVar = new double[count]; + LWR2Var = new double[count]; + CDUSVar = new double[count]; + CDUTVar = new double[count]; + wobbleVar = new double[count]; + LWRSeed = new int[count]; + LWR2Seed = new int[count]; + Parallel.For(0, count, (i) => + //for (Int32 i = 0; i < count; i++) + { + iC_PAsearch[i] = false; + oC_PAsearch[i] = false; + LWRSeed[i] = 1; + LWR2Seed[i] = 1; + if (previewMode) + { + overlayX[i] = 0; + overlayY[i] = 0; + hTipBiasType[i] = 0; + vTipBiasType[i] = 0; + horTipBiasVar[i] = 0; + verTipBiasVar[i] = 0; + iCVar[i] = 0; + oCVar[i] = 0; + LWRVar[i] = 0; + LWR2Var[i] = 0; + CDUSVar[i] = 0; + CDUTVar[i] = 0; + wobbleVar[i] = 0; + } + else + { + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.xOL_RNG))) + { + customRNGMapping = true; + overlayX[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.xOL_RNG), simSettings); + } + else + { + overlayX[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.yOL_RNG))) + { + customRNGMapping = true; + overlayY[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.yOL_RNG), simSettings); + } + else + { + overlayY[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + hTipBiasType[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + vTipBiasType[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + + horTipBiasVar[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + // Need to pay attention to sign here, to pull the right custom equation. + if ((hTipBiasType[i] < 0.5) && rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.hTipNVar_RNG))) + { + customRNGMapping = true; + horTipBiasVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.hTipNVar_RNG), simSettings); + } + if ((hTipBiasType[i] >= 0.5) && rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.hTipPVar_RNG))) + { + customRNGMapping = true; + horTipBiasVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.hTipPVar_RNG), simSettings); + } + + verTipBiasVar[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + // Need to pay attention to sign here, to pull the right custom equation. + if ((vTipBiasType[i] < 0.5) && rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.vTipNVar_RNG))) + { + customRNGMapping = true; + verTipBiasVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.vTipNVar_RNG), simSettings); + } + if ((vTipBiasType[i] >= 0.5) && ((listOfSettings[i].getString(EntropyLayerSettings.properties_s.vTipPVar_RNG) != "") && (listOfSettings[i].getString(EntropyLayerSettings.properties_s.vTipPVar_RNG) != CommonVars.boxMuller))) + { + verTipBiasVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.vTipPVar_RNG), simSettings); + } + + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.iCV_RNG))) + { + customRNGMapping = true; + iCVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.iCV_RNG), simSettings); + } + else + { + iCVar[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.oCV_RNG))) + { + customRNGMapping = true; + oCVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.oCV_RNG), simSettings); + } + else + { + oCVar[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.lwr_RNG))) + { + customRNGMapping = true; + LWRVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.lwr_RNG), simSettings); + } + else + { + LWRVar[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.lwr2_RNG))) + { + customRNGMapping = true; + LWR2Var[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.lwr2_RNG), simSettings); + } + else + { + LWR2Var[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.sCDU_RNG))) + { + customRNGMapping = true; + CDUSVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.sCDU_RNG), simSettings); + } + else + { + CDUSVar[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + + // Note that the TVar will be matched to SVar if the simulation settings call for these to be linked. + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.tCDU_RNG))) + { + customRNGMapping = true; + CDUTVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.tCDU_RNG), simSettings); + } + else + { + CDUTVar[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + + if (rngCheck(listOfSettings[i].getString(EntropyLayerSettings.properties_s.wobble_RNG))) + { + customRNGMapping = true; + wobbleVar[i] = UtilityFuncs.getCustomMappedRandomNumber(listOfSettings[i].getString(EntropyLayerSettings.properties_s.wobble_RNG), simSettings); + } + else + { + wobbleVar[i] = UtilityFuncs.getGaussianRandomNumber3(simSettings); + } + + LWRSeed[i] = UtilityFuncs.getRandomInt(simSettings); + LWR2Seed[i] = UtilityFuncs.getRandomInt(simSettings); + } + }); + // Rewalk to handle overlay and CDU correlation. We can't do this in the loop above since the correlated layer's settings + // are likely not available at that point in time. + Parallel.For(0, count, (i) => + // for (Int32 i = 0; i < count; i++) + { + if (listOfSettings[i].getInt(EntropyLayerSettings.properties_i.xOL_corr) == 1) + { + overlayX[i] = overlayX[listOfSettings[i].getInt(EntropyLayerSettings.properties_i.xOL_corr_ref)]; + } + if (listOfSettings[i].getInt(EntropyLayerSettings.properties_i.yOL_corr) == 1) + { + overlayY[i] = overlayY[listOfSettings[i].getInt(EntropyLayerSettings.properties_i.yOL_corr_ref)]; + } + if (listOfSettings[i].getInt(EntropyLayerSettings.properties_i.CDU_corr) == 1) + { + CDUSVar[i] = CDUSVar[listOfSettings[i].getInt(EntropyLayerSettings.properties_i.CDU_corr_ref)]; + } + if (listOfSettings[i].getInt(EntropyLayerSettings.properties_i.tCDU_corr) == 1) + { + // Note that the TVar will be matched to SVar if the simulation settings call for these to be linked. + CDUTVar[i] = CDUTVar[listOfSettings[i].getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref)]; + } + }); + } + + bool rngCheck(string rngString) + { + return ((rngString != "") && (rngString != CommonVars.boxMuller)); + } + } +} diff --git a/Common/Variance/chaos/chaosSettings_implant.cs b/Common/Variance/chaos/chaosSettings_implant.cs new file mode 100644 index 0000000..bf7315d --- /dev/null +++ b/Common/Variance/chaos/chaosSettings_implant.cs @@ -0,0 +1,113 @@ +using entropyRNG; + +namespace Variance +{ + class ChaosSettings_implant + { + public enum properties { resistCDVar, resistHeightVar, resistTopCRRVar, tiltVar, twistVar } + + static int dimensions = 5; // number of variations. + + public static int getDimensions() + { + return pGetDimensions(); + } + + static int pGetDimensions() + { + return dimensions; + } + + public double getValue(properties p) + { + return pGetValue((int)p); + } + + double pGetValue(int p) + { + double retVal = 0; + switch (p) + { + case (int)properties.resistCDVar: + retVal = implant_resistCDVar; + break; + case (int)properties.resistHeightVar: + retVal = implant_resistHeightVar; + break; + case (int)properties.resistTopCRRVar: + retVal = implant_resistTopCRRVar; + break; + case (int)properties.tiltVar: + retVal = implant_tiltVar; + break; + case (int)properties.twistVar: + retVal = implant_twistVar; + break; + } + + return retVal; + } + + double implant_resistCDVar; + double implant_resistHeightVar; + double implant_resistTopCRRVar; + double implant_tiltVar; + double implant_twistVar; + bool previewMode; + + public bool isPreview() + { + return pIsPreview(); + } + + bool pIsPreview() + { + return previewMode; + } + + public ChaosSettings_implant(bool previewMode, EntropySettings entropySettings) + { + pChaosSettings_implant(previewMode, entropySettings); + } + + void pChaosSettings_implant(bool previewMode, EntropySettings entropySettings) + { + this.previewMode = previewMode; + if (previewMode) + { + implant_resistCDVar = 0; + implant_resistHeightVar = 0; + implant_resistTopCRRVar = 0; + implant_tiltVar = 0; + implant_twistVar = 0; + } + else + { + switch (entropySettings.getValue(EntropySettings.properties_i.rngType)) + { + case ((int)commonRNG.rngIndex.mtwister): + implant_resistCDVar = MersenneTwister_RNG.random_gauss3()[0]; + implant_resistHeightVar = MersenneTwister_RNG.random_gauss3()[0]; + implant_resistTopCRRVar = MersenneTwister_RNG.random_gauss3()[0]; + implant_tiltVar = MersenneTwister_RNG.random_gauss3()[0]; + implant_twistVar = MersenneTwister_RNG.random_gauss3()[0]; + break; + case ((int)commonRNG.rngIndex.crypto): + implant_resistCDVar = Crypto_RNG.random_gauss3()[0]; + implant_resistHeightVar = Crypto_RNG.random_gauss3()[0]; + implant_resistTopCRRVar = Crypto_RNG.random_gauss3()[0]; + implant_tiltVar = Crypto_RNG.random_gauss3()[0]; + implant_twistVar = Crypto_RNG.random_gauss3()[0]; + break; + default: + implant_resistCDVar = RNG.random_gauss3()[0]; + implant_resistHeightVar = RNG.random_gauss3()[0]; + implant_resistTopCRRVar = RNG.random_gauss3()[0]; + implant_tiltVar = RNG.random_gauss3()[0]; + implant_twistVar = RNG.random_gauss3()[0]; + break; + } + } + } + } +} diff --git a/Common/Variance/engines/angleHandler.cs b/Common/Variance/engines/angleHandler.cs new file mode 100644 index 0000000..6bc41b6 --- /dev/null +++ b/Common/Variance/engines/angleHandler.cs @@ -0,0 +1,225 @@ +using ClipperLib; +using geoWrangler; +using System; +using System.Collections.Generic; +using System.Linq; +using utility; + +namespace Variance +{ + using Path = List; + using Paths = List>; + + class angleHandler + { + public double minimumIntersectionAngle { get; set; } + Paths listOfOutputPoints; + public Paths resultPaths { get; set; } // will only have one path, for minimum angle. + + void ZFillCallback(IntPoint bot1, IntPoint top1, IntPoint bot2, IntPoint top2, ref IntPoint pt) + { + pt.Z = -1; // Tag our intersection points. + } + + // Distance functions to drive scale-up of intersection marker if needed. + double minDistance = 10.0; + + public angleHandler(Paths layerAPath, Paths layerBPath) + { + angleHandlerLogic(layerAPath, layerBPath); + } + + void angleHandlerLogic(Paths layerAPath, Paths layerBPath) + { + listOfOutputPoints = new Paths(); + resultPaths = new Paths(); + Path resultPath = new Path(); + Clipper c = new Clipper(); + c.ZFillFunction = ZFillCallback; + List stringList = new List(); + c.AddPaths(layerAPath, PolyType.ptSubject, true); + c.AddPaths(layerBPath, PolyType.ptClip, true); + + // Boolean AND of the two levels for the area operation. + c.Execute(ClipType.ctIntersection, listOfOutputPoints); + + // Set initial output value for the case there are no intersections + minimumIntersectionAngle = 180.0; // no intersection angle. + + double tmpVal = 0.0; + for (Int32 i = 0; i < listOfOutputPoints.Count(); i++) + { + tmpVal += Clipper.Area(listOfOutputPoints[i]); + } + if (tmpVal == 0.0) + { + // No overlap + // Set output path and avoid heavy lifting + resultPath.Add(new IntPoint(0, 0)); + resultPaths.Add(resultPath); + } + else + { + double temporaryResult = 180.0; + Path temporaryPath = new Path(); + temporaryPath.Add(new IntPoint(0, 0)); + temporaryPath.Add(new IntPoint(0, 0)); + temporaryPath.Add(new IntPoint(0, 0)); + for (Int32 path = 0; path < listOfOutputPoints.Count(); path++) + { + Path overlapPath = GeoWrangler.clockwise(listOfOutputPoints[path]); + + int pt = 0; + while (pt < overlapPath.Count()) + { + if (overlapPath[pt].Z == -1) + { + // intersection point found - let's get our three points to find the angle. + // http://en.wikipedia.org/wiki/Law_of_cosines + IntPoint interSection_B; + IntPoint interSection_C; + IntPoint interSection_A; + if (pt == 0) + { + // Find preceding not-identical point. + int refPt = overlapPath.Count - 1; + while (Math.Abs(GeoWrangler.distanceBetweenPoints(overlapPath[refPt], overlapPath[pt])) == 0) + { + refPt--; + if (refPt == 0) + { + break; + } + } + interSection_B = overlapPath[refPt]; // map to last point + interSection_C = overlapPath[pt]; + // Find following not-identical point. + refPt = 0; + while (Math.Abs(GeoWrangler.distanceBetweenPoints(overlapPath[refPt], overlapPath[pt])) == 0) + { + refPt++; + if (refPt == overlapPath.Count - 1) + { + break; + } + } + interSection_A = overlapPath[refPt]; + } + else if (pt == overlapPath.Count() - 1) // last point in the list + { + // Find preceding not-identical point. + int refPt = pt; + while (Math.Abs(GeoWrangler.distanceBetweenPoints(overlapPath[refPt], overlapPath[pt])) == 0) + { + refPt--; + if (refPt == 0) + { + break; + } + } + interSection_B = overlapPath[refPt]; + interSection_C = overlapPath[pt]; + // Find following not-identical point. + refPt = 0; + while (Math.Abs(GeoWrangler.distanceBetweenPoints(overlapPath[refPt], overlapPath[pt])) == 0) + { + refPt++; + if (refPt == overlapPath.Count - 1) + { + break; + } + } + interSection_A = overlapPath[0]; // map to the first point + } + else + { + // Find preceding not-identical point. + int refPt = pt; + while (Math.Abs(GeoWrangler.distanceBetweenPoints(overlapPath[refPt], overlapPath[pt])) == 0) + { + refPt--; + if (refPt == 0) + { + break; + } + } + interSection_B = overlapPath[refPt]; + interSection_C = overlapPath[pt]; + // Find following not-identical point. + refPt = pt; + while (Math.Abs(GeoWrangler.distanceBetweenPoints(overlapPath[refPt], overlapPath[pt])) == 0) + { + refPt++; + if (refPt == overlapPath.Count - 1) + { + break; + } + } + interSection_A = overlapPath[refPt]; + } + + IntPoint cBVector = new IntPoint(interSection_B.X - interSection_C.X, interSection_B.Y - interSection_C.Y); + IntPoint cAVector = new IntPoint(interSection_A.X - interSection_C.X, interSection_A.Y - interSection_C.Y); + + Int64 xComponents = cBVector.X * cAVector.X; + Int64 yComponents = cBVector.Y * cAVector.Y; + + Int64 scalarProduct = xComponents + yComponents; + + double cBMagnitude = (Math.Sqrt(Utils.myPow(cBVector.X, 2) + Utils.myPow(cBVector.Y, 2))); + double cAMagnitude = (Math.Sqrt(Utils.myPow(cAVector.X, 2) + Utils.myPow(cAVector.Y, 2))); + + double theta = Math.Abs(Utils.toDegrees(Math.Acos((scalarProduct) / (cBMagnitude * cAMagnitude)))); // Avoid falling into a trap with negative angles. + + if (theta < temporaryResult) + { + temporaryResult = theta; + temporaryPath.Clear(); + temporaryPath.Add(new IntPoint(interSection_A.X, interSection_A.Y)); + temporaryPath.Add(new IntPoint(interSection_C.X, interSection_C.Y)); + temporaryPath.Add(new IntPoint(interSection_B.X, interSection_B.Y)); + } + } + pt++; + } + } + minimumIntersectionAngle = temporaryResult; + + // Check our temporary path to see if we need to scale it up. + double distance = GeoWrangler.distanceBetweenPoints(temporaryPath[0], temporaryPath[1]) / CentralProperties.scaleFactorForOperation; + IntPoint distanceIntPoint = GeoWrangler.intPoint_distanceBetweenPoints(temporaryPath[0], temporaryPath[1]); // A to C + if (distance < minDistance) + { + double X = temporaryPath[0].X; + double Y = temporaryPath[0].Y; + if (temporaryPath[1].X != temporaryPath[0].X) + { + X = temporaryPath[1].X + (distanceIntPoint.X * (minDistance / distance)); + } + if (temporaryPath[1].Y != temporaryPath[0].Y) + { + Y = temporaryPath[1].Y + (distanceIntPoint.Y * (minDistance / distance)); + } + temporaryPath[0] = new IntPoint((Int64)X, (Int64)Y); + } + distance = GeoWrangler.distanceBetweenPoints(temporaryPath[2], temporaryPath[1]) / CentralProperties.scaleFactorForOperation; + distanceIntPoint = GeoWrangler.intPoint_distanceBetweenPoints(temporaryPath[2], temporaryPath[1]); // B to C + if (distance < minDistance) + { + double X = temporaryPath[2].X; + double Y = temporaryPath[2].Y; + if (temporaryPath[1].Y != temporaryPath[2].Y) + { + Y = temporaryPath[1].Y + (distanceIntPoint.Y * (minDistance / distance)); + } + if (temporaryPath[1].X != temporaryPath[2].X) + { + X = temporaryPath[1].X + (distanceIntPoint.X * (minDistance / distance)); + } + temporaryPath[2] = new IntPoint((Int64)X, (Int64)Y); + } + resultPaths.Add(temporaryPath.ToList()); + } + } + } +} diff --git a/Common/Variance/engines/areaHandler.cs b/Common/Variance/engines/areaHandler.cs new file mode 100644 index 0000000..879bf50 --- /dev/null +++ b/Common/Variance/engines/areaHandler.cs @@ -0,0 +1,79 @@ + +using ClipperLib; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Variance +{ + using Paths = List>; + + class AreaHandler + { + public double area { get; set; } + public Paths listOfOutputPoints { get; set; } + + void ZFillCallback(IntPoint bot1, IntPoint top1, IntPoint bot2, IntPoint top2, ref IntPoint pt) + { + pt.Z = -1; // Tag our intersection points. + } + + public AreaHandler(Paths aPaths, Paths bPaths, bool maySimplify, bool perPoly, double scaleFactorForPointF = CentralProperties.scaleFactorForOperation) + { + areaHandlerLogic(aPaths, bPaths, scaleFactorForPointF, maySimplify, perPoly); + } + + void areaHandlerLogic(Paths aPaths, Paths bPaths, double scaleFactorForPointF, bool maySimplify, bool perPoly) + { + Paths tmpPaths = new Paths(); + listOfOutputPoints = new Paths(); + + Clipper c = new Clipper(); + c.PreserveCollinear = !maySimplify; // callsite may not want simplified geometry. + c.ZFillFunction = ZFillCallback; + + c.AddPaths(aPaths, PolyType.ptSubject, true); + + c.AddPaths(bPaths, PolyType.ptClip, true); + + // Boolean AND of the two levels for the area operation. + try + { + c.Execute(ClipType.ctIntersection, tmpPaths); //, firstLayerFillType, secondLayerFillType); + } + catch (Exception) + { + // Will handle downstream. + } + + double tmpVal = 0.0; + if (perPoly) + { + tmpVal = -1.0f; + } + + int polyCount = tmpPaths.Count(); + for (Int32 poly = 0; poly < polyCount; poly++) + { + if (perPoly) + { + double tmpVal2 = Clipper.Area(tmpPaths[poly]); + if ((tmpVal <= -0.0001f) || (tmpVal2 < tmpVal)) + { + tmpVal = tmpVal2; + listOfOutputPoints.Clear(); + listOfOutputPoints.Add(tmpPaths[poly].ToList()); + } + } + else + { + tmpVal += Clipper.Area(tmpPaths[poly]); + // Append the result output to the resultPoints list. + listOfOutputPoints.Add(tmpPaths[poly].ToList()); + } + } + // Sum the areas by polygon. + area = tmpVal / (scaleFactorForPointF * scaleFactorForPointF); + } + } +} diff --git a/Common/Variance/engines/chordHandler.cs b/Common/Variance/engines/chordHandler.cs new file mode 100644 index 0000000..9f29af0 --- /dev/null +++ b/Common/Variance/engines/chordHandler.cs @@ -0,0 +1,527 @@ +using ClipperLib; +using geoWrangler; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Variance +{ + using Path = List; + using Paths = List>; + + class ChordHandler + { + Path a; + Path b; + public Paths a_chordPaths { get; set; }// 0 is top, 1 is bottom + public Paths b_chordPaths { get; set; } // 0 is left, 1 is right + public double[] aChordLengths { get; set; } + public double[] bChordLengths { get; set; } + Int32 aPath_maxX_index; + Int32 bPath_maxY_index; + KDTree.KDTree aTree; + KDTree.KDTree bTree; + + void ZFillCallback(IntPoint bot1, IntPoint top1, IntPoint bot2, IntPoint top2, ref IntPoint pt) + { + pt.Z = -1; // Tag our intersection points. + } + + void doPathA() + { + aChordLengths[0] = 0.0; + aChordLengths[1] = 0.0; + + Int32 pt = 0; // will set based on start condition checks + + Path testPath = new Path(); + // Gather all of our points on the top edge for the nearest neighbor search + while (pt <= aPath_maxX_index) + { + testPath.Add(new IntPoint(a[pt])); + pt++; + } + + Clipper c = new Clipper(); + c.ZFillFunction = ZFillCallback; + c.PreserveCollinear = true; + c.AddPath(testPath, PolyType.ptSubject, false); + c.AddPath(b, PolyType.ptClip, true); + PolyTree polyTree_top = new PolyTree(); + c.Execute(ClipType.ctIntersection, polyTree_top); + Paths topChords = Clipper.OpenPathsFromPolyTree(polyTree_top); // potentially more than one chord. + + // Now we evaluate the lower edge + // We have to start from the max index because it could be shared between top and bottom chords. + pt = aPath_maxX_index; + testPath.Clear(); + c.Clear(); + + while (pt < a.Count) + { + testPath.Add(new IntPoint(a[pt])); + pt++; + } + + c.AddPath(testPath, PolyType.ptSubject, false); + c.AddPath(b, PolyType.ptClip, true); + PolyTree polyTree_bottom = new PolyTree(); + c.Execute(ClipType.ctIntersection, polyTree_bottom); + Paths bottomChords = Clipper.OpenPathsFromPolyTree(polyTree_bottom); // potentially more than one chord. + + // Now let's see what we have. + + double minTopChordLength = 0; + Path topChord = new Path(); + topChord.Add(new IntPoint(0, 0)); // safety in case we have no chords on the top. + for (int chord = 0; chord < topChords.Count; chord++) + { + // Does this chord segment actually belong to the 'B' geometry. + bool topEdgeIsFromA = true; + // First point and last point might not be matched to original geometry (imperfect intersection) + for (int tCPt = 1; tCPt < topChords[chord].Count - 1; tCPt++) + { + var pIter = aTree.NearestNeighbors(new double[] { topChords[chord][tCPt].X, topChords[chord][tCPt].Y }, 1); + while (pIter.MoveNext()) + { + if (pIter.CurrentDistance > 0) + { + topEdgeIsFromA = false; + break; + } + } + if (!topEdgeIsFromA) + { + break; + } + } + + if (!topEdgeIsFromA) + { + continue; + } + + // skip if false case + if ((topChords.Count == 1) || ((topChords.Count > 1) && ((topChords[chord][0].Z == -1) && (topChords[chord][topChords[chord].Count - 1].Z == -1)))) + { + double chordLength = 0; + // Assess length of each chord and only report the minimum length one. + for (int chordpt = 0; chordpt < topChords[chord].Count - 1; chordpt++) + { + chordLength += GeoWrangler.distanceBetweenPoints(topChords[chord][chordpt], topChords[chord][chordpt + 1]); + } + + if ((minTopChordLength == 0) || (chordLength < minTopChordLength)) + { + minTopChordLength = chordLength; + topChord = topChords[chord]; + } + } + } + + double minBottomChordLength = 0; + Path bottomChord = new Path(); + bottomChord.Add(new IntPoint(0, 0)); // safety in case we have no chords on the top. + for (int chord = 0; chord < bottomChords.Count; chord++) + { + // Does this chord segment actually belong to the 'B' geometry. + bool bottomEdgeIsFromA = true; + // First point and last point might not be matched to original geometry (imperfect intersection) + for (int bCPt = 1; bCPt < bottomChords[chord].Count - 1; bCPt++) + { + var pIter = aTree.NearestNeighbors(new double[] { bottomChords[chord][bCPt].X, bottomChords[chord][bCPt].Y }, 1); + while (pIter.MoveNext()) + { + if (pIter.CurrentDistance > 0) + { + bottomEdgeIsFromA = false; + break; + } + } + if (!bottomEdgeIsFromA) + { + break; + } + } + + if (!bottomEdgeIsFromA) + { + continue; + } + + // skip if false case + if ((bottomChords.Count == 1) || ((bottomChords.Count > 1) && ((bottomChords[chord][0].Z == -1) && (bottomChords[chord][bottomChords[chord].Count - 1].Z == -1)))) + { + double chordLength = 0; + // Assess length of each chord and only report the minimum length one. + for (int chordpt = 0; chordpt < bottomChords[chord].Count - 1; chordpt++) + { + chordLength += GeoWrangler.distanceBetweenPoints(bottomChords[chord][chordpt], bottomChords[chord][chordpt + 1]); + } + + if ((minBottomChordLength == 0) || (chordLength < minBottomChordLength)) + { + minBottomChordLength = chordLength; + bottomChord = bottomChords[chord]; + } + } + } + + aChordLengths[0] = minBottomChordLength; + a_chordPaths.Add(bottomChord.ToList()); + + aChordLengths[1] = minTopChordLength; + a_chordPaths.Add(topChord.ToList()); + } + + void doPathB() + { + bChordLengths[0] = 0.0; + bChordLengths[1] = 0.0; + + Int32 pt = 0; // will set based on start condition checks + + Path testPath = new Path(); + + // Gather all of our points on the left edge + while (pt <= bPath_maxY_index) + { + testPath.Add(new IntPoint(b[pt])); + pt++; + } + + Clipper c = new Clipper(); + c.PreserveCollinear = true; + c.ZFillFunction = ZFillCallback; + c.AddPath(testPath, PolyType.ptSubject, false); + c.AddPath(a, PolyType.ptClip, true); + PolyTree polyTree_left = new PolyTree(); + c.Execute(ClipType.ctIntersection, polyTree_left); + Paths leftChords = Clipper.OpenPathsFromPolyTree(polyTree_left); // potentially more than one chord. + + // Now we evaluate the right edge + // We have to start from the max index because it could be shared between top and bottom chords. + testPath.Clear(); + c.Clear(); + + while (pt < b.Count) + { + testPath.Add(new IntPoint(b[pt])); + pt++; + } + + c.ZFillFunction = ZFillCallback; + c.AddPath(testPath, PolyType.ptSubject, false); + c.AddPath(a, PolyType.ptClip, true); + PolyTree polyTree_right = new PolyTree(); + c.Execute(ClipType.ctIntersection, polyTree_right); + Paths rightChords = Clipper.OpenPathsFromPolyTree(polyTree_right); // potentially more than one chord. + + // Now let's see what we have. + + double minLeftChordLength = 0; + Path leftChord = new Path(); + leftChord.Add(new IntPoint(0, 0)); // safety in case we have no chords on the left. + + + for (int chord = 0; chord < leftChords.Count; chord++) + { + // Does this chord segment actually belong to the 'B' geometry. + bool leftEdgeIsFromB = true; + // First point and last point might not be matched to original geometry (imperfect intersection) + for (int lCPt = 1; lCPt < leftChords[chord].Count - 1; lCPt++) + { + var pIter = bTree.NearestNeighbors(new double[] { leftChords[chord][lCPt].X, leftChords[chord][lCPt].Y }, 1); + while (pIter.MoveNext()) + { + if (pIter.CurrentDistance > 0) + { + leftEdgeIsFromB = false; + break; + } + } + if (!leftEdgeIsFromB) + { + break; + } + } + + if (!leftEdgeIsFromB) + { + continue; + } + + // skip if false case + if ((leftChords.Count == 1) || ((leftChords.Count > 1) && ((leftChords[chord][0].Z == -1) && (leftChords[chord][leftChords[chord].Count - 1].Z == -1)))) + { + double chordLength = 0; + // Assess length of each chord and only report the minimum length one. + for (int chordpt = 0; chordpt < leftChords[chord].Count - 1; chordpt++) + { + chordLength += GeoWrangler.distanceBetweenPoints(leftChords[chord][chordpt], leftChords[chord][chordpt + 1]); + } + + if ((minLeftChordLength == 0) || (chordLength < minLeftChordLength)) + { + minLeftChordLength = chordLength; + leftChord = leftChords[chord]; + } + } + } + + double minRightChordLength = 0; + Path rightChord = new Path(); + rightChord.Add(new IntPoint(0, 0)); // safety in case we have no chords on the right. + for (int chord = 0; chord < rightChords.Count; chord++) + { + // Does this chord segment actually belong to the 'B' geometry. + bool rightEdgeIsFromB = true; + // First point and last point might not be matched to original geometry (imperfect intersection) + for (int rCPt = 1; rCPt < rightChords[chord].Count - 1; rCPt++) + { + var pIter = bTree.NearestNeighbors(new double[] { rightChords[chord][rCPt].X, rightChords[chord][rCPt].Y }, 1); + while (pIter.MoveNext()) + { + if (pIter.CurrentDistance > 0) + { + rightEdgeIsFromB = false; + break; + } + } + if (!rightEdgeIsFromB) + { + break; + } + } + + if (!rightEdgeIsFromB) + { + continue; + } + + // skip if false case + if ((rightChords.Count == 1) || (rightChords.Count > 1 && ((rightChords[chord][0].Z == -1) && (rightChords[chord][rightChords[chord].Count - 1].Z == -1)))) + { + double chordLength = 0; + // Assess length of each chord and only report the minimum length one. + for (int chordpt = 0; chordpt < rightChords[chord].Count - 1; chordpt++) + { + chordLength += GeoWrangler.distanceBetweenPoints(rightChords[chord][chordpt], rightChords[chord][chordpt + 1]); + } + + if ((minRightChordLength == 0) || (chordLength < minRightChordLength)) + { + minRightChordLength = chordLength; + rightChord = rightChords[chord]; + } + } + } + + bChordLengths[0] = minRightChordLength; + b_chordPaths.Add(rightChord.ToList()); + + bChordLengths[1] = minLeftChordLength; + b_chordPaths.Add(leftChord.ToList()); + + } + + public ChordHandler(Paths aSource, Paths bSource, EntropySettings simulationSettings) + { + chordHandlerLogic(aSource, bSource, simulationSettings); + } + + void chordHandlerLogic(Paths aSource, Paths bSource, EntropySettings simulationSettings) + { + a_chordPaths = new Paths(2); + Path tmpPath = new Path(); + tmpPath.Add(new IntPoint(0, 0)); + a_chordPaths.Add(tmpPath.ToList()); + a_chordPaths.Add(tmpPath.ToList()); + b_chordPaths = new Paths(2); + b_chordPaths.Add(tmpPath.ToList()); + b_chordPaths.Add(tmpPath.ToList()); + aChordLengths = new double[2]; + aChordLengths[0] = aChordLengths[1] = 0.0; + bChordLengths = new double[2]; + bChordLengths[0] = bChordLengths[1] = 0.0; + + List cHList = new List(); + for (Int32 aIndex = 0; aIndex < aSource.Count(); aIndex++) + { + for (Int32 bIndex = 0; bIndex < bSource.Count(); bIndex++) + { + try + { + cHList.Add(new ChordHandler(aIndex, aSource, bIndex, bSource, simulationSettings)); + } + catch (Exception) + { + // Don't care about raised exceptions. + } + } + } + + /* Review results to extract minimum cases. + + Some additional explanation is needed here. We can have cases where no chord is registered (i.e. zero is reported). However, if we only + ever checked for a value less than the reported chord length, we'd never have anything other than zero. + + So, in the checks below, the condition against zero is there to take any non-zero value that is reported; then we apply the minimum value from there. + */ + + for (Int32 result = 0; result < cHList.Count(); result++) + { + for (Int32 resultIndex = 0; resultIndex < 2; resultIndex++) + { + // Extract 'a' results only if non-zero + if (cHList[result].aChordLengths[resultIndex] != 0.0) + { + // We have either our first non-zero chord length or a chord length lower than previously recorded. + if ((aChordLengths[resultIndex] == 0.0) || (cHList[result].aChordLengths[resultIndex] < aChordLengths[resultIndex])) + { + aChordLengths[resultIndex] = cHList[result].aChordLengths[resultIndex]; + a_chordPaths[resultIndex] = cHList[result].a_chordPaths[resultIndex].ToList(); + } + } + + // Extract 'b' results only if non-zero + if (cHList[result].bChordLengths[resultIndex] != 0.0) + { + // We have either our first non-zero chord length or a chord length lower than previously recorded. + if ((bChordLengths[resultIndex] == 0.0) || (cHList[result].bChordLengths[resultIndex] < bChordLengths[resultIndex])) + { + bChordLengths[resultIndex] = cHList[result].bChordLengths[resultIndex]; + b_chordPaths[resultIndex] = cHList[result].b_chordPaths[resultIndex].ToList(); + } + } + } + } + } + + ChordHandler(Int32 aPathIndex, Paths aSource, Int32 bPathIndex, Paths bSource, EntropySettings simulationSettings) + { + pChordHandlerLogic(aPathIndex, aSource, bPathIndex, bSource, simulationSettings); + } + + void pChordHandlerLogic(Int32 aPathIndex, Paths aSource, Int32 bPathIndex, Paths bSource, EntropySettings simulationSettings) + { + a = aSource[aPathIndex].ToList(); + b = bSource[bPathIndex].ToList(); + + // Get our chord path storage sorted out. + a_chordPaths = new Paths(2); + b_chordPaths = new Paths(2); + + aChordLengths = new double[2] { 0, 0 }; + bChordLengths = new double[2] { 0, 0 }; + + // Max and min indices for each path. + // We'll use these for our chord within the edge checks. + aPath_maxX_index = GeoWrangler.MaxX(a); + bPath_maxY_index = GeoWrangler.MaxY(b); + + // Set up KDTrees for edge inspection. + aTree = new KDTree.KDTree(2, a.Count); + for (int aPt = 0; aPt < a.Count; aPt++) + { + aTree.AddPoint(new double[] { a[aPt].X, a[aPt].Y }, new IntPoint(a[aPt].X, a[aPt].Y)); + } + bTree = new KDTree.KDTree(2, b.Count); + for (int bPt = 0; bPt < b.Count; bPt++) + { + bTree.AddPoint(new double[] { b[bPt].X, b[bPt].Y }, new IntPoint(b[bPt].X, b[bPt].Y)); + } + + if (simulationSettings.getValue(EntropySettings.properties_i.subMode) != (int)CommonVars.chordCalcElements.b) + { + try + { + doPathA(); + } + catch (Exception) + { + } + } + + if (simulationSettings.getValue(EntropySettings.properties_i.subMode) >= (int)CommonVars.chordCalcElements.b) + { + try + { + doPathB(); + } + catch (Exception) + { + } + } + + double cutOffValue = simulationSettings.getResolution() * CentralProperties.scaleFactorForOperation; // arbitrary cut-off since rounding errors don't always mean 0 for a glancing contact. + + for (int r = 0; r < 2; r++) + { + if (aChordLengths[r] <= cutOffValue) + { + aChordLengths[r] = 0; + } + + if (bChordLengths[r] <= cutOffValue) + { + bChordLengths[r] = 0; + } + } + + // So this is where things get a little tricky. It can be the case that we have 'left/right' chords reported for only one of top/bottom, and vice versa. + // This is a natural consequence of the line clipping and we need to manage the output accordingly. + // Things otherwise break quite badly because we end up reporting invalid chords (see the chord_4 test case) + // As such, we need to perform some inspection and tag certain configurations as invalid. + // Note that this cross-setting can be confusing at first glance. + + bool aChordsValid = true; + bool bChordsValid = true; + + // We also need to be mindful of the user option for which chords to inspect. We should only need to wrangle this in case all chords are being requested. + if (simulationSettings.getValue(EntropySettings.properties_i.subMode) > (int)CommonVars.chordCalcElements.b) + { + /* + * If top > 0 and bottom == 0, can't have left or right chords - no bisection + * If top == 0 and bottom > 0, can't have left or right chords - no bisection. + * If top == 0 and bottom == 0, can have left or right chords. + * + */ + + if ( + ((aChordLengths[0] > 0) && (aChordLengths[1] == 0)) || + ((aChordLengths[1] > 0) && (aChordLengths[0] == 0)) + ) + + { + bChordsValid = false; + } + else + { + if ((aChordLengths[0] == 0) && (aChordLengths[1] == 0)) + { + aChordsValid = false; + } + } + } + + if (!aChordsValid) + { + a_chordPaths[0] = new Path(); + a_chordPaths[0].Add(new IntPoint(0, 0)); + a_chordPaths[1] = new Path(); + a_chordPaths[1].Add(new IntPoint(0, 0)); + aChordLengths = new double[2] { 0, 0 }; + } + + if (!bChordsValid) + { + b_chordPaths[0] = new Path(); + b_chordPaths[0].Add(new IntPoint(0, 0)); + b_chordPaths[1] = new Path(); + b_chordPaths[1].Add(new IntPoint(0, 0)); + bChordLengths = new double[2] { 0, 0 }; + } + } + } +} diff --git a/Common/Variance/engines/distanceHandler.cs b/Common/Variance/engines/distanceHandler.cs new file mode 100644 index 0000000..7cad264 --- /dev/null +++ b/Common/Variance/engines/distanceHandler.cs @@ -0,0 +1,752 @@ +using ClipperLib; +using Error; +using geoLib; +using geoWrangler; +using System; +using System.Collections.Generic; +using System.Linq; +using utility; + +namespace Variance +{ + using Path = List; + using Paths = List>; + + class DistanceHandler + { + bool debug = false; + public Paths resultPaths { get; set; } + double resultDistance; + public string distanceString { get; set; } + bool invert; + + void ZFillCallback(IntPoint bot1, IntPoint top1, IntPoint bot2, IntPoint top2, ref IntPoint pt) + { + pt.Z = -1; // Tag our intersection points. + } + + class spaceResult + { + public bool done { get; set; } // to flag early return. + public double distance { get; set; } + public Paths resultPaths { get; set; } + + public spaceResult() + { + resultPaths = new Paths(); + } + } + + public DistanceHandler(Paths aPaths, Paths bPaths, EntropySettings simulationSettings, bool runThreaded) + { + distanceHandlerLogic(aPaths, bPaths, simulationSettings, runThreaded); + } + + void distanceHandlerLogic(Paths aPaths, Paths bPaths, EntropySettings simulationSettings, bool runThreaded) + { + resultPaths = new Paths(); + // Safety check for no active layers. + if (((aPaths.Count() == 1) && (aPaths[0].Count() == 1)) || + ((bPaths.Count() == 1) && (bPaths[0].Count() == 1))) + { + Path tempPath = new Path(); + tempPath.Add(new IntPoint(0, 0)); + resultPaths.Add(tempPath.ToList()); + distanceString = "N/A"; + } + else + { + invert = true; + // Experimental check to see whether we can simplify this approach. + bool isEnclosed = GeoWrangler.enclosed(aPaths, bPaths); + + + if (!isEnclosed) + { + // Overlap method sets result fields. + overlap(aPaths, bPaths, simulationSettings, runThreaded); + } + else + { + spaceResult result = fastKDTree(aPaths, bPaths, simulationSettings); + + resultDistance = result.distance; + resultPaths = result.resultPaths; + } + + distanceString = (resultDistance).ToString(); + } + } + + spaceResult fastKDTree(Paths aPaths, Paths bPaths, EntropySettings simulationSettings) + { + Int32 numberOfPoints = 0; + double currentMinimum = 0; + double currentDistance = 0; + Path minimumDistancePath = new Path(); + bool resultNeedsInversion = false; + + double refArea = 0; + + for (Int32 shapeB = 0; shapeB < bPaths.Count(); shapeB++) + { + numberOfPoints += bPaths[shapeB].Count(); + refArea += Clipper.Area(bPaths[shapeB]); + } + // KDTree to store the points from our target shape(s) + KDTree.KDTree pTree = new KDTree.KDTree(2, numberOfPoints); + + for (Int32 shapeA = 0; shapeA < aPaths.Count(); shapeA++) + { + for (Int32 shapeB = 0; shapeB < bPaths.Count(); shapeB++) + { + for (Int32 pointB = 0; pointB < bPaths[shapeB].Count(); pointB++) + { + try + { + pTree.AddPoint(new double[] { bPaths[shapeB][pointB].X, bPaths[shapeB][pointB].Y }, new GeoLibPointF(bPaths[shapeB][pointB].X, bPaths[shapeB][pointB].Y)); + } + catch (Exception ex) + { + ErrorReporter.showMessage_OK("Oops", "jobEngine() KDTree error: " + ex.ToString()); + } + } + } + + // Do we need to invert the result? + Clipper c = new Clipper(); + c.PreserveCollinear = true; + Paths oCheck = new Paths(); + c.AddPaths(bPaths, PolyType.ptClip, true); + c.AddPath(aPaths[shapeA], PolyType.ptSubject, true); + c.Execute(ClipType.ctUnion, oCheck); + + double oCheckArea = 0; + for (int r = 0; r < oCheck.Count; r++) + { + oCheckArea += Clipper.Area(oCheck[r]); + } + + if ((simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosure) || (simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosureOld)) // negative value since we're fully inside a containing polygon. + { + if (Math.Abs(oCheckArea) != Math.Abs(refArea)) + { + resultNeedsInversion = true; + } + else + { + resultNeedsInversion = false; + } + } + if ((simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacing) || (simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacingOld)) // negative value since we're fully outside a containing polygon. + { + if (Math.Abs(oCheckArea) == Math.Abs(refArea)) + { + resultNeedsInversion = true; + } + else + { + resultNeedsInversion = false; + } + } + + // We can query here for the minimum distance for each shape combination. + for (Int32 pointA = 0; pointA < aPaths[shapeA].Count(); pointA++) + { + // '1' forces a single nearest neighbor to be returned. + var pIter = pTree.NearestNeighbors(new double[] { aPaths[shapeA][pointA].X, aPaths[shapeA][pointA].Y }, 1); + while (pIter.MoveNext()) + { + currentDistance = pIter.CurrentDistance; + + if (((shapeA == 0) && (pointA == 0)) || (currentDistance < currentMinimum)) + { + minimumDistancePath.Clear(); + minimumDistancePath.Add(new IntPoint(aPaths[shapeA][pointA])); + minimumDistancePath.Add(new IntPoint((pIter.Current.X + aPaths[shapeA][pointA].X) / 2.0f, (pIter.Current.Y + aPaths[shapeA][pointA].Y) / 2.0f)); + minimumDistancePath.Add(new IntPoint(pIter.Current.X, pIter.Current.Y)); + currentMinimum = currentDistance; + } + } + } + } + + spaceResult result = new spaceResult(); + result.resultPaths = new Paths(); + result.resultPaths.Add(minimumDistancePath); + // k-d tree distance is the squared distance. Need to scale and sqrt + result.distance = Math.Sqrt(currentMinimum / Utils.myPow(CentralProperties.scaleFactorForOperation, 2)); + + if (resultNeedsInversion) + { + result.distance *= -1; + } + + return result; + } + + void overlap(Paths aPaths, Paths bPaths, EntropySettings simulationSettings, bool runThreaded) + { + bool completeOverlap = false; + for (Int32 layerAPoly = 0; layerAPoly < aPaths.Count(); layerAPoly++) + { + Path layerAPath = new Path(); + layerAPath = aPaths[layerAPoly]; + for (Int32 layerBPoly = 0; layerBPoly < bPaths.Count(); layerBPoly++) + { + Path layerBPath = new Path(); + layerBPath = bPaths[layerBPoly]; + + Paths overlapShape = new Paths(); + + IntRect rectA = Clipper.GetBounds(new Paths() { layerAPath }); + IntRect rectB = Clipper.GetBounds(new Paths { layerBPath }); + + // Check for complete overlap + Clipper c = new Clipper(); + c.PreserveCollinear = true; + // Try a union and see whether the point count of the perimeter changes. This might break for re-entrant cases, but those are problematic anyway. + Paths fullOverlapCheck = new Paths(); + c.AddPath(layerAPath, PolyType.ptSubject, true); + c.AddPath(layerBPath, PolyType.ptClip, true); + c.Execute(ClipType.ctUnion, fullOverlapCheck); + double aArea = Math.Abs(Clipper.Area(layerAPath)); + double bArea = Math.Abs(Clipper.Area(layerBPath)); + double uArea = 0; + for (int r = 0; r < fullOverlapCheck.Count; r++) + { + uArea += Clipper.Area(fullOverlapCheck[r]); + } + uArea = Math.Abs(uArea); + + // If overlap area matches either of the input areas, we have a full overlap + if ((aArea == uArea) || (bArea == uArea)) + { + completeOverlap = true; + } + + if ((simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacing) || (simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacingOld)) // spacing + { + // Perform an area check in case of overlap. + // Overlap means X/Y negative space needs to be reported. + AreaHandler aH = new AreaHandler(new Paths() { layerAPath }, new Paths() { layerBPath }, maySimplify: false, perPoly: false, scaleFactorForPointF: 1.0); + overlapShape = aH.listOfOutputPoints;//.ToList(); + } + + if (!completeOverlap && ((simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosure) || ((simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosureOld)))) // enclosure + { + // Need to find the region outside our enclosure shape. We use the modifier to handle this. + c.Clear(); + c.ZFillFunction = ZFillCallback; + c.StrictlySimple = true; + c.PreserveCollinear = true; + // Try cutting layerB from layerA + c.AddPath(layerAPath, PolyType.ptSubject, true); + c.AddPath(layerBPath, PolyType.ptClip, true); + c.Execute(ClipType.ctDifference, overlapShape); + } + + if ((!completeOverlap) && (overlapShape.Count() > 0)) // call if there's an overlap, and it's incomplete. + { + spaceResult result = doPartialOverlap(overlapShape, layerAPath, layerBPath, simulationSettings, runThreaded); + if (result.done) + { + if ((resultPaths.Count() == 0) || (result.distance < resultDistance)) + { + resultPaths = result.resultPaths; + resultDistance = result.distance; + } + } + } + } + } + } + + spaceResult doPartialOverlap(Paths overlapShape, Path aPath, Path bPath, EntropySettings simulationSettings, bool runThreaded) + { + spaceResult result = new spaceResult(); + + // KDTree to store the points from our input shape(s) + int aPathCount = aPath.Count; + int bPathCount = bPath.Count; + KDTree.KDTree aTree = new KDTree.KDTree(2, aPathCount); + KDTree.KDTree bTree = new KDTree.KDTree(2, bPathCount); + for (int pt = 0; pt < aPathCount; pt++) + { + aTree.AddPoint(new double[] { aPath[pt].X, aPath[pt].Y }, new GeoLibPointF(aPath[pt].X, aPath[pt].Y)); + } + for (int pt = 0; pt < bPathCount; pt++) + { + bTree.AddPoint(new double[] { bPath[pt].X, bPath[pt].Y }, new GeoLibPointF(bPath[pt].X, bPath[pt].Y)); + } + + double minLength = 0; + + IntRect overlapRect = Clipper.GetBounds(overlapShape); + minLength = Math.Abs(overlapRect.right - overlapRect.left); + if (Math.Abs(overlapRect.top - overlapRect.bottom) > minLength) + { + minLength = Math.Abs(overlapRect.top - overlapRect.bottom); + } + + try + { + // Process the overlap shape polygon(s) to evaluate the overlap. + for (Int32 poly = 0; poly < overlapShape.Count(); poly++) + { + // Brute force decomposition of the overlap shape into A and B edge contributions. + // ClipperLib isn't robust for this, so we have to brute force it : line clipping fails and PointInPolygon is unreliable. + + int ptCount = overlapShape[poly].Count; + bool[] residesOnAEdge = new bool[ptCount]; + bool[] residesOnBEdge = new bool[ptCount]; + + for (int pt = 0; pt < ptCount; pt++) + { + residesOnAEdge[pt] = false; + residesOnBEdge[pt] = false; + if (overlapShape[poly][pt].Z == -1) + { + residesOnAEdge[pt] = true; + residesOnBEdge[pt] = true; + } + else + { + // Use the KDTree approach to find the nearest neighbor on each input shape to the point on the overlap geometry. + // Minimum distance wins ownership. + var aIter = aTree.NearestNeighbors(new double[] { overlapShape[poly][pt].X, overlapShape[poly][pt].Y }, 1); + aIter.MoveNext(); + double distanceToAEdge = Math.Sqrt(aIter.CurrentDistance); + var bIter = bTree.NearestNeighbors(new double[] { overlapShape[poly][pt].X, overlapShape[poly][pt].Y }, 1); + bIter.MoveNext(); + double distanceToBEdge = Math.Sqrt(bIter.CurrentDistance); + if (distanceToAEdge < distanceToBEdge) + { + // This overlap point is close to a point on A, so tag it and move to the next overlap point. + residesOnAEdge[pt] = true; + } + else + { + // This overlap point is close to a point on B, so tag it and move to the next overlap point. + residesOnBEdge[pt] = true; + } + } + } + + // Now we need to construct our Paths for the overlap edges, based on the true/false case for each array. + Paths aOverlapEdge = new Paths(); + Paths bOverlapEdge = new Paths(); + + Path tempPath = new Path(); + for (int i = 0; i < ptCount; i++) + { + if (residesOnAEdge[i]) + { + tempPath.Add(new IntPoint(overlapShape[poly][i])); + } + else // not found on A edge, probably resides on B edge, but we'll check that separately to keep code readable. + { + // If we have a tempPath with more than a single point in it, we have been creating a segment. + // Since we haven't found this point in the A edge, commit the segment and clear the temporary path. + if (tempPath.Count >= 1) + { + // We have some points, but now we're getting a new segment. + aOverlapEdge.Add(tempPath.ToList()); + tempPath.Clear(); + } + } + } + if (tempPath.Count > 1) + { + aOverlapEdge.Add(tempPath.ToList()); + } + + tempPath.Clear(); + for (int i = 0; i < ptCount; i++) + { + if (residesOnBEdge[i]) + { + tempPath.Add(new IntPoint(overlapShape[poly][i])); + } + else + { + if (tempPath.Count > 1) + { + // We have some points, but now we're getting a new segment. + bOverlapEdge.Add(tempPath.ToList()); + tempPath.Clear(); + } + } + } + if (tempPath.Count > 1) + { + bOverlapEdge.Add(tempPath.ToList()); + } + + // Walk our edges to figure out the overlap. + for (int aOL = 0; aOL < aOverlapEdge.Count; aOL++) + { + for (int bOL = 0; bOL < bOverlapEdge.Count; bOL++) + { + spaceResult tResult = overlapAssess(simulationSettings, overlapShape[poly], aOverlapEdge[aOL], bOverlapEdge[bOL], aPath, bPath, runThreaded); + if ((result.resultPaths.Count == 0) || (tResult.distance > result.distance)) + { + result.distance = tResult.distance; + result.resultPaths = tResult.resultPaths; + } + } + } + } + } + catch (Exception e) + { + ErrorReporter.showMessage_OK(e.ToString(), "Oops"); + } + result.done = true; + if (!simulationSettings.debugCalc) + { + result.distance = -result.distance / CentralProperties.scaleFactorForOperation; + } + return result; + } + + spaceResult overlapAssess(EntropySettings simulationSettings, Path overlapPoly, Path aOverlapEdge, Path bOverlapEdge, Path aPath, Path bPath, bool runThreaded) + { + spaceResult result = new spaceResult(); + double maxDistance_orthogonalFallback = 0; // fallback for the overlap case of orthogonal geometry, where self-intersections occur. + int maxDistance_fallbackIndex = 0; + double maxDistance = 0; // for the overlap cases. + + double lengthA = 0; + double lengthB = 0; + Path extractedPath = new Path(); + bool usingAEdge = false; + + /* Prior to 1.7, we used the edge from the layerB combination to raycast. This was not ideal. + We should have used the shortest edge. 1.7 adds an option to make this the behavior, and the old + approach is retained for now as well. + */ + + IntPoint shortestPathBeforeStartPoint = new IntPoint(0, 0); + IntPoint shortestPathAfterEndPoint = new IntPoint(0, 0); + + if ((simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacing)) + { + Path aSource = aOverlapEdge; + Path bSource = bOverlapEdge; + // Find the shortest edge length and use that for the projection reference + // Calculate lengths and check. + for (int pt = 0; pt < aSource.Count - 1; pt++) + { + lengthA += Math.Sqrt(Utils.myPow((aSource[pt + 1].X - aSource[pt].X), 2) + Utils.myPow((aSource[pt + 1].Y - aSource[pt].Y), 2)); + } + for (int pt = 0; pt < bSource.Count - 1; pt++) + { + lengthB += Math.Sqrt(Utils.myPow((bSource[pt + 1].X - bSource[pt].X), 2) + Utils.myPow((bSource[pt + 1].Y - bSource[pt].Y), 2)); + } + + extractedPath = bSource; // need a default in case of equivalent lengths + + if (extractedPath.Count == 0) + { + // No common overlap. + result.distance = 0; + return result; + } + + // Here we need to go back to our input polygons to derive the edge segment normal for the start/end of each edge. + if (lengthA < lengthB) + { + usingAEdge = true; + extractedPath = aSource; + int startIndex = aPath.FindIndex(p => p.Equals(extractedPath[0])); + if (startIndex == 0) + { + startIndex = aPath.Count - 1; + } + if (startIndex == -1) + { + // Failed to find it cheaply. Let's try a different approach. + double startDistanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[0], aPath[0]); + startIndex = 0; + for (int pt = 1; pt < aPath.Count; pt++) + { + double distanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[0], aPath[pt]); + if (distanceCheck < startDistanceCheck) + { + startDistanceCheck = distanceCheck; + startIndex = pt; + } + } + } + + int endIndex = aPath.FindIndex(p => p.Equals(extractedPath[extractedPath.Count - 1])); + if (endIndex == aPath.Count - 1) + { + endIndex = 0; + } + if (endIndex == -1) + { + // Failed to find it cheaply. Let's try a different approach. + double endDistanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[extractedPath.Count - 1], aPath[0]); + endIndex = 0; + for (int pt = 1; pt < aPath.Count; pt++) + { + double distanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[extractedPath.Count - 1], aPath[pt]); + if (distanceCheck < endDistanceCheck) + { + endDistanceCheck = distanceCheck; + endIndex = pt; + } + } + } + + shortestPathBeforeStartPoint = new IntPoint(aPath[startIndex]); + shortestPathAfterEndPoint = new IntPoint(aPath[endIndex]); + } + else + { + int startIndex = bPath.FindIndex(p => p.Equals(extractedPath[0])); + if (startIndex == 0) + { + startIndex = bPath.Count - 1; + } + if (startIndex == -1) + { + // Failed to find it cheaply. Let's try a different approach. + double startDistanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[0], bPath[0]); + startIndex = 0; + + for (int pt = 1; pt < bPath.Count; pt++) + { + double distanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[0], bPath[pt]); + if (distanceCheck < startDistanceCheck) + { + startDistanceCheck = distanceCheck; + startIndex = pt; + } + } + } + + int endIndex = bPath.FindIndex(p => p.Equals(extractedPath[extractedPath.Count - 1])); + if (endIndex == bPath.Count - 1) + { + endIndex = 0; + } + if (endIndex == -1) + { + // Failed to find it cheaply. Let's try a different approach. + double endDistanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[extractedPath.Count - 1], bPath[0]); + endIndex = 0; + for (int pt = 1; pt < bPath.Count; pt++) + { + double distanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[extractedPath.Count - 1], bPath[pt]); + if (distanceCheck < endDistanceCheck) + { + endDistanceCheck = distanceCheck; + endIndex = pt; + } + } + } + + shortestPathBeforeStartPoint = new IntPoint(bPath[startIndex]); + shortestPathAfterEndPoint = new IntPoint(bPath[endIndex]); + } + } + + if ((simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.spacingOld) || (simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosure) || (simulationSettings.getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.spacingCalcModes.enclosureOld)) + { + + extractedPath = bOverlapEdge; + + if (extractedPath.Count == 0) // No common edge. + { + result.distance = 0; + return result; + } + + int startIndex = -1; + startIndex = bPath.FindIndex(p => p.Equals(extractedPath[0])); + if (startIndex == 0) + { + startIndex = bPath.Count - 1; + } + if (startIndex == -1) + { + // Failed to find it cheaply. Let's try a different approach. + double startDistanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[0], bPath[0]); + startIndex = 0; + for (int pt = 1; pt < bPath.Count; pt++) + { + double distanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[0], bPath[pt]); + if (distanceCheck < startDistanceCheck) + { + startDistanceCheck = distanceCheck; + startIndex = pt; + } + } + } + + int endIndex = bPath.FindIndex(p => p.Equals(extractedPath[extractedPath.Count - 1])); + if (endIndex == bPath.Count - 1) + { + endIndex = 0; + } + if (endIndex == -1) + { + // Failed to find it cheaply. Let's try a different approach. + double endDistanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[extractedPath.Count - 1], bPath[0]); + for (int pt = 1; pt < bPath.Count; pt++) + { + double distanceCheck = GeoWrangler.distanceBetweenPoints(extractedPath[extractedPath.Count - 1], bPath[pt]); + endIndex = 0; + if (distanceCheck < endDistanceCheck) + { + endDistanceCheck = distanceCheck; + endIndex = pt; + } + } + } + + try + { + shortestPathBeforeStartPoint = new IntPoint(bPath[startIndex]); + } + catch (Exception) + { + ErrorReporter.showMessage_OK("distanceHandler: shortestPathBeforeStartPoint failed.", "Oops"); + } + try + { + shortestPathAfterEndPoint = new IntPoint(bPath[endIndex]); + } + catch (Exception) + { + ErrorReporter.showMessage_OK("distanceHandler: shortestPathAfterEndPoint failed.", "Oops"); + } + } + + // No blurry rays, so no point running the inner loop threaded. We thread the outer loop (the emission edge raycast), though. Testing showed small performance improvement for this approach. + RayCast rc = new RayCast(extractedPath, overlapPoly, CentralProperties.scaleFactorForOperation * CentralProperties.scaleFactorForOperation, runThreaded, invert, 0, true, false, shortestPathBeforeStartPoint, shortestPathAfterEndPoint); + + if (debug || simulationSettings.debugCalc) + { + result.done = true; + result.resultPaths = rc.getRays(); + result.distance = -1; + return result; + } + + Paths clippedLines = rc.getClippedRays(); + + bool validOverlapFound = false; + + // Need to scan for the maximum path length to record the overlap. + for (Int32 line = 0; line < clippedLines.Count(); line++) + { + double lineLength = rc.getRayLength(line); + // With the new LER implementation, normals can be fired in problematic directions. + // Valid overlaps don't have start and end points on the same polygon. + // Happily, we feed this polygon-wise, which makes the evaluation much easier. + bool validOverlap = true; + + double startPointCheck_A_dist = GeoWrangler.distanceBetweenPoints(clippedLines[line][0], aOverlapEdge[0]); + double endPointCheck_A_dist = GeoWrangler.distanceBetweenPoints(clippedLines[line][1], aOverlapEdge[0]); + for (int aPt = 0; aPt < aOverlapEdge.Count; aPt++) + { + double temp_startPointCheck_A_dist = GeoWrangler.distanceBetweenPoints(clippedLines[line][0], aOverlapEdge[aPt]); + double temp_endPointCheck_A_dist = GeoWrangler.distanceBetweenPoints(clippedLines[line][1], aOverlapEdge[aPt]); + if (temp_startPointCheck_A_dist < startPointCheck_A_dist) + { + startPointCheck_A_dist = temp_startPointCheck_A_dist; + } + if (temp_endPointCheck_A_dist < endPointCheck_A_dist) + { + endPointCheck_A_dist = temp_endPointCheck_A_dist; + } + } + + double startPointCheck_B_dist = GeoWrangler.distanceBetweenPoints(clippedLines[line][0], bOverlapEdge[0]); + double endPointCheck_B_dist = GeoWrangler.distanceBetweenPoints(clippedLines[line][1], bOverlapEdge[0]); + for (int bPt = 0; bPt < bOverlapEdge.Count; bPt++) + { + double temp_startPointCheck_B_dist = GeoWrangler.distanceBetweenPoints(clippedLines[line][0], bOverlapEdge[bPt]); + double temp_endPointCheck_B_dist = GeoWrangler.distanceBetweenPoints(clippedLines[line][1], bOverlapEdge[bPt]); + if (temp_startPointCheck_B_dist < startPointCheck_B_dist) + { + startPointCheck_B_dist = temp_startPointCheck_B_dist; + } + if (temp_endPointCheck_B_dist < endPointCheck_B_dist) + { + endPointCheck_B_dist = temp_endPointCheck_B_dist; + } + } + + bool ortho = false; + if ((clippedLines[line][0].X == clippedLines[line][1].X) || (clippedLines[line][0].Y == clippedLines[line][1].Y)) + { + ortho = true; + } + + double threshold = 1500; // arbitrary, dialed in by hand. + + if ((ortho) || ((usingAEdge && ((startPointCheck_A_dist < threshold) && (endPointCheck_A_dist < threshold))) || + (!usingAEdge && ((startPointCheck_B_dist < threshold) && (endPointCheck_B_dist < threshold)))) + ) + { + // This is a special situation, it turns out. + // There is one specific scenario where this overlap case (start and end on the same geometry) is valid - orthogonal shapes with a bisection. + // The orthogonal shapes cause the rays to hit the opposite side of the shape. We don't want to reject this. + validOverlap = false; + if (lineLength > maxDistance_orthogonalFallback) + { + maxDistance_fallbackIndex = line; + maxDistance_orthogonalFallback = lineLength; + } + } + else + { + if ((usingAEdge && ((startPointCheck_A_dist < threshold) && (endPointCheck_B_dist > threshold))) || + (!usingAEdge && ((startPointCheck_B_dist < threshold) && (endPointCheck_A_dist > threshold)))) + { + validOverlap = false; + } + + if (validOverlap && (lineLength > maxDistance)) + { + validOverlapFound = true; + maxDistance = lineLength; + Path tempPath = new Path(); + tempPath.Add(new IntPoint(clippedLines[line][0])); + tempPath.Add(new IntPoint(clippedLines[line][0])); + tempPath.Add(new IntPoint(clippedLines[line][clippedLines[line].Count() - 1])); + result.resultPaths.Clear(); + result.resultPaths.Add(tempPath); + } + } + } + + try + { + if (((clippedLines.Count() > 0) && (!validOverlapFound)) || (maxDistance_orthogonalFallback > maxDistance)) + { + // Couldn't find a valid overlap so assume the orthogonal fallback is needed. + maxDistance = maxDistance_orthogonalFallback; + Path tempPath = new Path(); + tempPath.Add(new IntPoint(clippedLines[maxDistance_fallbackIndex][0])); + tempPath.Add(new IntPoint(clippedLines[maxDistance_fallbackIndex][0])); + tempPath.Add(new IntPoint(clippedLines[maxDistance_fallbackIndex][clippedLines[maxDistance_fallbackIndex].Count() - 1])); + result.resultPaths.Clear(); + result.resultPaths.Add(tempPath); + } + } + catch (Exception) + { + // Harmless - we'll reject the case and move on. + } + + result.distance = maxDistance; + return result; + } + } +} diff --git a/Common/Variance/entropy/entropy.cs b/Common/Variance/entropy/entropy.cs new file mode 100644 index 0000000..e9fefa8 --- /dev/null +++ b/Common/Variance/entropy/entropy.cs @@ -0,0 +1,244 @@ +using System; +using System.Diagnostics; +using System.Threading; + +namespace Variance +{ + public partial class Entropy + { + public delegate void updateStatusUI(string statusLine); + public updateStatusUI updateStatus { get; set; } + + public delegate void configProgressUI(int value, int numberOfCases); + public configProgressUI configProgress { get; set; } + + public delegate void stepProgressUI(); + public stepProgressUI stepProgress { get; set; } + + public delegate void directProgressUI(int current, int done); + public directProgressUI directProgress { get; set; } + + public delegate bool abortCheck(); + public abortCheck abortCheckFunc { get; set; } + + public delegate void clearAbortFlag(); + public clearAbortFlag clearAbortFlagFunc { get; set; } + + public delegate void postSimUI(); + public postSimUI postSimUIFunc { get; set; } + + public delegate void postSimPASearchUI(SimResultPackage resultPackage); + public postSimPASearchUI postSimPASearchUIFunc { get; set; } + + public delegate void forceRepaint(); + public forceRepaint forceRepaintFunc { get; set; } + + public delegate bool abortAllRuns(); + public abortAllRuns abortAllRunsFunc { get; set; } + + public delegate void abortCSV(CancellationTokenSource cancelSource, CancellationToken cancellationToken); + public abortCSV abortCSVFunc { get; set; } + + public delegate void abortRun(); + public abortRun abortRunFunc { get; set; } + + public delegate void multithreadWarning(); + public multithreadWarning multithreadWarningFunc { get; set; } + + public delegate void abortRunMT(SimResultPackage resultPackage, CancellationTokenSource cancelSource, CancellationToken cancellationToken); + public abortRunMT abortRunFuncMT { get; set; } + + public delegate void simRunning(); + public simRunning simRunningFunc { get; set; } + + public delegate void simRunningUI(); + public simRunningUI simRunningUIFunc { get; set; } + + char[] csvSeparator = new char[] { ',' }; // to cleave the results apart. + public Stopwatch sw { get; set; } + public Stopwatch sw_Preview { get; set; } + public Int32 currentProgress; + public bool multiCaseSim { get; set; } + public double swTime { get; set; } + public bool simJustDone { get; set; } + public Int64 timeOfLastPreviewUpdate { get; set; } + CommonVars commonVars; + + string baseFileName; + + VarianceContext varianceContext; + + public string lastSimResultsOverview { get; set; } + string resultString; + + public Entropy(ref VarianceContext varianceContext, CommonVars commonVars) + { + this.varianceContext = varianceContext; + this.commonVars = commonVars; + } + + public void update(CommonVars commonVars) + { + this.commonVars = commonVars; + } + + void reset() + { + sw = null; + sw_Preview = null; + currentProgress = 0; + multiCaseSim = false; + swTime = 0.0; + simJustDone = false; + resultString = null; + resultPackage = null; + timeOfLastPreviewUpdate = 0; + commonVars.cancelling = false; + } + + bool entropyRunCore(Int32 numberOfCases, Int32 row, Int32 col, string fileName, bool useThreads, bool tileHandling, bool implantMode, bool doPASearch) + { + baseFileName = ""; + + if (fileName != null) + { + string[] tokens = fileName.Split(new char[] { '.' }); + + for (int i = 0; i < tokens.Length - 2; i++) + { + baseFileName += tokens[i] + "."; + } + baseFileName += tokens[tokens.Length - 2]; + } + + if (!implantMode) + { + preFlight(row, col, tileHandling); + + simRunningFunc?.Invoke(); + + bool previewMode = true; + if (numberOfCases > 1) + { + multiCaseSim = true; + previewMode = false; + if (!doPASearch) + { + configProgress?.Invoke(0, commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.nCases)); + } + else + { + configProgress?.Invoke(0, commonVars.getPASearch().numberofPassCases); + } + + simRunningUIFunc?.Invoke(); + } + + if (!useThreads) + { + entropyRunCore_singleThread(previewMode, numberOfCases, row, col, tileHandling, doPASearch); + } + else + { + sw_Preview.Start(); + entropyRunCore_multipleThread(previewMode, numberOfCases, row, col, tileHandling, doPASearch); + } + + if (doPASearch) + { + postSimPASearchUIFunc?.Invoke(resultPackage); + } + + // If user requested file save, let's add to the list for eventual writing. + if (!doPASearch && (baseFileName != null)) + { + clearAbortFlagFunc?.Invoke(); // reset our abort handler in case user also wants to abort save. + if (!previewMode) + { + try + { + saveResults(numberOfCases, tileHandling, col, row); + } + catch (Exception) + { + + } + } + + // Post-calc readout + + for (Int32 i = 0; i < resultPackage.getValues(SimResultPackage.properties.mean).Length; i++) + { + if (i > 0) + { + lastSimResultsOverview += ", "; + } + lastSimResultsOverview += "x: " + resultPackage.getValue(SimResultPackage.properties.mean, i).ToString("0.##") + " (" + (resultPackage.getValue(SimResultPackage.properties.mean, i) - resultPackage.getValue(SimResultPackage.properties.lastMean, i)).ToString("0.##") + ")"; + if (!resultPackage.nonGaussianInput) + { + lastSimResultsOverview += ", s: " + resultPackage.getValue(SimResultPackage.properties.stdDev, i).ToString("0.##") + " (" + (resultPackage.getValue(SimResultPackage.properties.stdDev, i) - resultPackage.getValue(SimResultPackage.properties.lastStdDev, i)).ToString("0.##") + ")"; + } + simJustDone = true; + } + } + + multiCaseSim = false; + return resultPackage.getState(); + } + else + { + bool previewMode = true; + preFlight(row: 0, col: 0, false); + + // implant mode. + simRunningFunc?.Invoke(); + + if (numberOfCases > 1) + { + previewMode = false; + multiCaseSim = true; + configProgress?.Invoke(0, commonVars.getImplantSimulationSettings().getValue(EntropySettings.properties_i.nCases)); + + implantSimRunningUIFunc?.Invoke(); + } + + + if (!useThreads) + { + entropyRunCore_implant_singleThread(previewMode, numberOfCases); + } + else + { + sw_Preview.Start(); + entropyRunCore_implant_multipleThread(previewMode, numberOfCases); + } + + // If user requested file save, let's add to the list for eventual writing. + if ((baseFileName != null) && (baseFileName != "")) + { + clearAbortFlagFunc?.Invoke(); // reset our abort handler in case user also wants to abort save. + if (!previewMode) + { + try + { + saveResults_implant(numberOfCases); + } + catch (Exception) + { + + } + } + } + + lastSimResultsOverview = "x: " + implantResultPackage.getValue(SimResultPackage.properties.mean, 0).ToString("0.##"); + if (!implantResultPackage.nonGaussianInput) + { + lastSimResultsOverview += ", s: " + implantResultPackage.getValue(SimResultPackage.properties.stdDev, 0).ToString("0.##"); + } + simJustDone = true; + multiCaseSim = false; + return implantResultPackage.getState(); + } + } + } +} diff --git a/Common/Variance/entropy/entropyLayerSettings.cs b/Common/Variance/entropy/entropyLayerSettings.cs new file mode 100644 index 0000000..f8f4e54 --- /dev/null +++ b/Common/Variance/entropy/entropyLayerSettings.cs @@ -0,0 +1,2058 @@ +using geoLib; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Variance +{ + [Serializable] + public class EntropyLayerSettings + { + static string default_comment = ""; + static Int32[] default_bgLayers = new Int32[CentralProperties.maxLayersForMC] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static Int32 default_enabled = 0; + static Int32 default_geoCoreShapeEngine = 0; + static Int32 default_showDrawn = 0; + static Int32 default_alignGeom = 0; + static string default_layerName = ""; + static Int32 default_shapeIndex = (Int32)CentralProperties.typeShapes.none; + + static decimal default_subShapeHorLength = 0; + static decimal default_subShapeHorOffset = 0; + static decimal default_subShapeVerLength = 0; + static decimal default_subShapeVerOffset = 0; + static Int32 default_subShapeTipLocIndex = 0; + static decimal default_subShape2HorLength = 0; + static decimal default_subShape2HorOffset = 0; + static decimal default_subShape2VerLength = 0; + static decimal default_subShape2VerOffset = 0; + static Int32 default_subShape2TipLocIndex = 0; + static decimal default_subShape3HorLength = 0; + static decimal default_subShape3HorOffset = 0; + static decimal default_subShape3VerLength = 0; + static decimal default_subShape3VerOffset = 0; + static Int32 default_subShape3TipLocIndex = 0; + static Int32 default_subShapeRefIndex = 0; + static Int32 default_posInSubShapeIndex = (int)CommonVars.subShapeLocations.BL; + + static decimal default_globalHorOffset = 0; + static decimal default_globalVerOffset = 0; + + static decimal default_sideBias = 0; + static decimal default_horTipBias = 0; + static string default_rngmapping = CommonVars.boxMuller; + static decimal default_horTipBiasNVar = 0; + static decimal default_horTipBiasPVar = 0; + static decimal default_verTipBias = 0; + static decimal default_verTipBiasNVar = 0; + static decimal default_verTipBiasPVar = 0; + static decimal default_rotation = 0; + static decimal default_proximityBias = 0; + static decimal default_proximityIsoDistance = 0; + static Int32 default_proximitySideRays = 2; + + static Int32 default_edgeSlide = 0; + static decimal default_edgeSlideTension = 0.35m; + + static decimal default_wobble = 0; + static decimal default_innerCRR = 0; + static decimal default_innerCV = 0; + static decimal default_outerCRR = 0; + static decimal default_outerCV = 0; + static decimal default_LWR = 0; + static Int32 default_LWRNoiseType = (Int32)CommonVars.noiseIndex.perlin; + static Int32 default_LWRNoisePreview = 0; + static decimal default_LWRNoiseFreq = 0.2m; + static decimal default_sideCDU = 0; + static decimal default_tipsCDU = 0; + static decimal default_horOverlay = 0; + static decimal default_verOverlay = 0; + + static Int32 default_correlatedTipCDU = 0; + static Int32 default_correlatedTipCDULayerIndex = -1; + static Int32 default_correlatedCDU = 0; + static Int32 default_correlatedCDULayerIndex = -1; + static Int32 default_correlatedXOverlay = 0; + static Int32 default_correlatedXOverlayLayerIndex = -1; + static Int32 default_correlatedYOverlay = 0; + static Int32 default_correlatedYOverlayLayerIndex = -1; + static Int32 default_overlayXReferenceLayer = -1; + static Int32 default_overlayYReferenceLayer = -1; + static Int32 default_averageOverlayX = 0; + static Int32 default_averageOverlayY = 0; + static Int32[] default_overlayXReferenceLayers = new Int32[CentralProperties.maxLayersForMC] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static Int32[] default_overlayYReferenceLayers = new Int32[CentralProperties.maxLayersForMC] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + static Int32 default_flipH = 0; + static Int32 default_flipV = 0; + + static Int32 default_fileType = 0; // layout (now exposed by geoCore - could be redundant) + static List default_fileData = new List { new GeoLibPointF[] { new GeoLibPointF(0, 0) } }; + static string default_fileToLoad = ""; + static string default_ldNameFromFile = ""; + static string default_structureNameFromFile = ""; + static Int32 default_ldFromFile = 0; + static Int32 default_polyFill = (Int32)CommonVars.PolyFill.pftNonZero; // non-zero + static Int32 default_structureFromFile = 0; + static Int32 default_perPoly = 0; + static Int32 default_referenceLayout = 0; + + static decimal default_lensDistortionCoeff1 = 0; + static decimal default_lensDistortionCoeff2 = 0; + + static Int32 default_booleanLayerA = -1; + static Int32 default_booleanLayerB = -1; + static Int32 default_booleanLayerOpA = 0; + static Int32 default_booleanLayerOpB = 0; + static Int32 default_booleanLayerOpAB = 0; + + static Int32 default_omitLayer = 0; + + [NonSerialized] + Int32[] bgLayers; + + Int32[] overlayXReferenceLayers; + Int32[] overlayYReferenceLayers; + + public enum properties_intarray + { + bglayers, xOLRefs, yOLRefs + } + + public bool isLayerActive() + { + return pIsLayerActive(); + } + + bool pIsLayerActive() + { + return ((enabled == 1) && (omitFromSim == 0)); + } + + public Int32[] getIntArray(properties_intarray p) + { + return pGetIntArray(p); + } + + Int32[] pGetIntArray(properties_intarray p) + { + Int32[] ret = new Int32[] { }; + switch (p) + { + case properties_intarray.bglayers: + ret = bgLayers; + break; + case properties_intarray.xOLRefs: + ret = overlayXReferenceLayers; + break; + case properties_intarray.yOLRefs: + ret = overlayYReferenceLayers; + break; + } + + return ret; + } + + public void setIntArray(properties_intarray p, Int32[] val) + { + pSetIntArray(p, val); + } + + void pSetIntArray(properties_intarray p, Int32[] val) + { + switch (p) + { + case properties_intarray.bglayers: + bgLayers = val; + break; + case properties_intarray.xOLRefs: + overlayXReferenceLayers = val; + break; + case properties_intarray.yOLRefs: + overlayYReferenceLayers = val; + break; + } + } + + public void defaultIntArray(properties_intarray p) + { + pDefaultIntArray(p); + } + + void pDefaultIntArray(properties_intarray p) + { + switch (p) + { + case properties_intarray.bglayers: + bgLayers = default_bgLayers.ToArray(); + break; + case properties_intarray.xOLRefs: + overlayXReferenceLayers = default_overlayXReferenceLayers.ToArray(); + break; + case properties_intarray.yOLRefs: + overlayYReferenceLayers = default_overlayYReferenceLayers.ToArray(); + break; + } + } + + public int getIntArrayValue(properties_intarray p, int index) + { + return pGetIntArrayValue(p, index); + } + + int pGetIntArrayValue(properties_intarray p, int index) + { + int ret = 0; + switch (p) + { + case properties_intarray.bglayers: + ret = bgLayers[index]; + break; + case properties_intarray.xOLRefs: + ret = overlayXReferenceLayers[index]; + break; + case properties_intarray.yOLRefs: + ret = overlayYReferenceLayers[index]; + break; + } + + return ret; + } + + public void setIntArrayValue(properties_intarray p, int index, int val) + { + pSetIntArrayValue(p, index, val); + } + + void pSetIntArrayValue(properties_intarray p, int index, int val) + { + switch (p) + { + case properties_intarray.bglayers: + bgLayers[index] = val; ; + break; + case properties_intarray.xOLRefs: + overlayXReferenceLayers[index] = val; + break; + case properties_intarray.yOLRefs: + overlayYReferenceLayers[index] = val; + break; + } + } + + Int32 enabled; + Int32 omitFromSim; // prevent layer being included in simulation. + Int32 geoCoreShapeEngine; + + [NonSerialized] + Int32 showDrawn; + + Int32 shapeIndex; + Int32 subShapeTipLocIndex; + Int32 subShape2TipLocIndex; + Int32 subShape3TipLocIndex; + Int32 subShapeRefIndex; + Int32 posInSubShapeIndex; + Int32 proximitySideRays; + Int32 edgeSlide; + Int32 LWRNoiseType; + Int32 LWR2NoiseType; + + [NonSerialized] + Int32 LWRNoisePreview; + + Int32 correlatedXOverlay; + Int32 correlatedXOverlayLayerIndex; + Int32 correlatedYOverlay; + Int32 correlatedYOverlayLayerIndex; + Int32 correlatedCDU; + Int32 correlatedCDULayerIndex; + Int32 correlatedTipCDU; + Int32 correlatedTipCDULayerIndex; + Int32 overlayXReferenceLayer; + Int32 overlayYReferenceLayer; + Int32 averageOverlayX; + Int32 averageOverlayY; + Int32 flipH; + Int32 flipV; + Int32 alignGeomX, alignGeomY; + Int32 structureFromFile; + Int32 ldFromFile; + Int32 polyFill; + Int32 fileType; // holds the value of the file type selected (0 == GDS, 1 == Oasis). Might be redundant with geoCore. + Int32 perPoly; + Int32 referenceLayout; + Int32 booleanLayerA; + Int32 booleanLayerB; + Int32 booleanLayerOpA; + Int32 booleanLayerOpB; + Int32 booleanLayerOpAB; + + public enum properties_i + { + enabled, omit, gCSEngine, showDrawn, shapeIndex, shape0Tip, shape1Tip, shape2Tip, subShapeIndex, posIndex, proxRays, edgeSlide, lwrType, lwr2Type, lwrPreview, + xOL_corr, xOL_corr_ref, yOL_corr, yOL_corr_ref, CDU_corr, CDU_corr_ref, tCDU_corr, tCDU_corr_ref, + xOL_ref, yOL_ref, xOL_av, yOL_av, + flipH, flipV, alignX, alignY, structure, lD, fill, fileType, perPoly, refLayout, + bLayerA, bLayerB, bLayerOpA, bLayerOpB, bLayerOpAB + } + + public Int32 getInt(properties_i p) + { + return pGetInt(p); + } + + Int32 pGetInt(properties_i p) + { + int ret = 0; + switch (p) + { + case properties_i.enabled: + ret = enabled; + break; + case properties_i.omit: + ret = omitFromSim; + break; + case properties_i.gCSEngine: + ret = geoCoreShapeEngine; + break; + case properties_i.showDrawn: + ret = showDrawn; + break; + case properties_i.shapeIndex: + ret = shapeIndex; + break; + case properties_i.shape0Tip: + ret = subShapeTipLocIndex; + break; + case properties_i.shape1Tip: + ret = subShape2TipLocIndex; + break; + case properties_i.shape2Tip: + ret = subShape3TipLocIndex; + break; + case properties_i.subShapeIndex: + ret = subShapeRefIndex; + break; + case properties_i.posIndex: + ret = posInSubShapeIndex; + break; + case properties_i.proxRays: + ret = proximitySideRays; + break; + case properties_i.edgeSlide: + ret = edgeSlide; + break; + case properties_i.lwrType: + ret = LWRNoiseType; + break; + case properties_i.lwr2Type: + ret = LWR2NoiseType; + break; + case properties_i.lwrPreview: + ret = LWRNoisePreview; + break; + case properties_i.xOL_ref: + ret = overlayXReferenceLayer; + break; + case properties_i.yOL_ref: + ret = overlayYReferenceLayer; + break; + case properties_i.xOL_av: + ret = averageOverlayX; + break; + case properties_i.yOL_av: + ret = averageOverlayY; + break; + case properties_i.xOL_corr: + ret = correlatedXOverlay; + break; + case properties_i.xOL_corr_ref: + ret = correlatedXOverlayLayerIndex; + break; + case properties_i.yOL_corr: + ret = correlatedYOverlay; + break; + case properties_i.yOL_corr_ref: + ret = correlatedYOverlayLayerIndex; + break; + case properties_i.CDU_corr: + ret = correlatedCDU; + break; + case properties_i.CDU_corr_ref: + ret = correlatedCDULayerIndex; + break; + case properties_i.tCDU_corr: + ret = correlatedTipCDU; + break; + case properties_i.tCDU_corr_ref: + ret = correlatedTipCDULayerIndex; + break; + case properties_i.alignX: + ret = alignGeomX; + break; + case properties_i.alignY: + ret = alignGeomY; + break; + case properties_i.flipH: + ret = flipH; + break; + case properties_i.flipV: + ret = flipV; + break; + case properties_i.structure: + ret = structureFromFile; + break; + case properties_i.lD: + ret = ldFromFile; + break; + case properties_i.fill: + ret = polyFill; + break; + case properties_i.fileType: + ret = fileType; + break; + case properties_i.perPoly: + ret = perPoly; + break; + case properties_i.refLayout: + ret = referenceLayout; + break; + case properties_i.bLayerA: + ret = booleanLayerA; + break; + case properties_i.bLayerB: + ret = booleanLayerB; + break; + case properties_i.bLayerOpA: + ret = booleanLayerOpA; + break; + case properties_i.bLayerOpB: + ret = booleanLayerOpB; + break; + case properties_i.bLayerOpAB: + ret = booleanLayerOpAB; + break; + } + + return ret; + } + + public void setInt(properties_i p, int val) + { + pSetInt(p, val); + } + + void pSetInt(properties_i p, int val) + { + switch (p) + { + case properties_i.enabled: + enabled = val; + break; + case properties_i.omit: + omitFromSim = val; + break; + case properties_i.gCSEngine: + geoCoreShapeEngine = val; + break; + case properties_i.showDrawn: + showDrawn = val; + break; + case properties_i.shapeIndex: + shapeIndex = val; + break; + case properties_i.shape0Tip: + subShapeTipLocIndex = val; + break; + case properties_i.shape1Tip: + subShape2TipLocIndex = val; + break; + case properties_i.shape2Tip: + subShape3TipLocIndex = val; + break; + case properties_i.subShapeIndex: + subShapeRefIndex = val; + break; + case properties_i.posIndex: + posInSubShapeIndex = val; + break; + case properties_i.proxRays: + proximitySideRays = val; + break; + case properties_i.edgeSlide: + edgeSlide = val; + break; + case properties_i.lwrType: + LWRNoiseType = val; + break; + case properties_i.lwr2Type: + LWR2NoiseType = val; + break; + case properties_i.lwrPreview: + LWRNoisePreview = val; + break; + case properties_i.xOL_ref: + overlayXReferenceLayer = val; + break; + case properties_i.yOL_ref: + overlayYReferenceLayer = val; + break; + case properties_i.xOL_av: + averageOverlayX = val; + break; + case properties_i.yOL_av: + averageOverlayY = val; + break; + case properties_i.xOL_corr: + correlatedXOverlay = val; + break; + case properties_i.xOL_corr_ref: + correlatedXOverlayLayerIndex = val; + break; + case properties_i.yOL_corr: + correlatedYOverlay = val; + break; + case properties_i.yOL_corr_ref: + correlatedYOverlayLayerIndex = val; + break; + case properties_i.CDU_corr: + correlatedCDU = val; + break; + case properties_i.CDU_corr_ref: + correlatedCDULayerIndex = val; + break; + case properties_i.tCDU_corr: + correlatedTipCDU = val; + break; + case properties_i.tCDU_corr_ref: + correlatedTipCDULayerIndex = val; + break; + case properties_i.alignX: + alignGeomX = val; + break; + case properties_i.alignY: + alignGeomY = val; + break; + case properties_i.flipH: + flipH = val; + break; + case properties_i.flipV: + flipV = val; + break; + case properties_i.structure: + structureFromFile = val; + break; + case properties_i.lD: + ldFromFile = val; + break; + case properties_i.fill: + polyFill = val; + break; + case properties_i.fileType: + fileType = val; + break; + case properties_i.perPoly: + perPoly = val; + break; + case properties_i.refLayout: + referenceLayout = val; + break; + case properties_i.bLayerA: + booleanLayerA = val; + break; + case properties_i.bLayerB: + booleanLayerB = val; + break; + case properties_i.bLayerOpA: + booleanLayerOpA = val; + break; + case properties_i.bLayerOpB: + booleanLayerOpB = val; + break; + case properties_i.bLayerOpAB: + booleanLayerOpAB = val; + break; + } + } + + public void defaultInt(properties_i p) + { + pDefaultInt(p); + } + + void pDefaultInt(properties_i p) + { + switch (p) + { + case properties_i.alignX: + case properties_i.alignY: + alignGeomY = default_alignGeom; + break; + case properties_i.CDU_corr: + correlatedCDU = default_correlatedCDU; + break; + case properties_i.CDU_corr_ref: + correlatedCDULayerIndex = default_correlatedCDULayerIndex; + break; + case properties_i.edgeSlide: + edgeSlide = default_edgeSlide; + break; + case properties_i.enabled: + enabled = default_enabled; + break; + case properties_i.omit: + omitFromSim = default_omitLayer; + break; + case properties_i.fileType: + fileType = default_fileType; + break; + case properties_i.fill: + polyFill = default_polyFill; + break; + case properties_i.flipH: + flipH = default_flipH; + break; + case properties_i.flipV: + flipV = default_flipV; + break; + case properties_i.gCSEngine: + geoCoreShapeEngine = default_geoCoreShapeEngine; + break; + case properties_i.lD: + ldFromFile = default_ldFromFile; + break; + case properties_i.lwrPreview: + LWRNoisePreview = default_LWRNoisePreview; + break; + case properties_i.lwrType: + LWRNoiseType = default_LWRNoiseType; + break; + case properties_i.lwr2Type: + LWR2NoiseType = default_LWRNoiseType; + break; + case properties_i.perPoly: + perPoly = default_perPoly; + break; + case properties_i.posIndex: + posInSubShapeIndex = default_posInSubShapeIndex; + break; + case properties_i.proxRays: + proximitySideRays = default_proximitySideRays; + break; + case properties_i.refLayout: + referenceLayout = default_referenceLayout; + break; + case properties_i.shape0Tip: + subShapeTipLocIndex = default_subShapeTipLocIndex; + break; + case properties_i.shape1Tip: + subShape2TipLocIndex = default_subShape2TipLocIndex; + break; + case properties_i.shape2Tip: + subShape3TipLocIndex = default_subShape3TipLocIndex; + break; + case properties_i.shapeIndex: + shapeIndex = default_shapeIndex; + break; + case properties_i.showDrawn: + showDrawn = default_showDrawn; + break; + case properties_i.structure: + structureFromFile = default_structureFromFile; + break; + case properties_i.subShapeIndex: + posInSubShapeIndex = default_posInSubShapeIndex; + break; + case properties_i.tCDU_corr: + correlatedTipCDU = default_correlatedTipCDU; + break; + case properties_i.tCDU_corr_ref: + correlatedTipCDULayerIndex = default_correlatedTipCDULayerIndex; + break; + case properties_i.xOL_av: + averageOverlayX = default_averageOverlayX; + break; + case properties_i.xOL_corr: + correlatedXOverlay = default_correlatedXOverlay; + break; + case properties_i.xOL_corr_ref: + correlatedXOverlayLayerIndex = default_correlatedXOverlayLayerIndex; + break; + case properties_i.xOL_ref: + overlayXReferenceLayer = default_overlayXReferenceLayer; + break; + case properties_i.yOL_av: + averageOverlayY = default_averageOverlayY; + break; + case properties_i.yOL_corr: + correlatedYOverlay = default_correlatedYOverlay; + break; + case properties_i.yOL_corr_ref: + correlatedYOverlayLayerIndex = default_correlatedYOverlayLayerIndex; + break; + case properties_i.yOL_ref: + overlayYReferenceLayer = default_overlayYReferenceLayer; + break; + case properties_i.bLayerA: + booleanLayerA = default_booleanLayerA; + break; + case properties_i.bLayerB: + booleanLayerB = default_booleanLayerA; + break; + case properties_i.bLayerOpA: + booleanLayerOpA = default_booleanLayerA; + break; + case properties_i.bLayerOpB: + booleanLayerOpB = default_booleanLayerA; + break; + case properties_i.bLayerOpAB: + booleanLayerOpAB = default_booleanLayerA; + break; + } + } + + public static Int32 getDefaultInt(properties_i p) + { + return pGetDefaultInt(p); + } + + static Int32 pGetDefaultInt(properties_i p) + { + int ret = 0; + switch (p) + { + case properties_i.enabled: + ret = default_enabled; + break; + case properties_i.omit: + ret = default_omitLayer; + break; + case properties_i.gCSEngine: + ret = default_geoCoreShapeEngine; + break; + case properties_i.showDrawn: + ret = default_showDrawn; + break; + case properties_i.shapeIndex: + ret = default_shapeIndex; + break; + case properties_i.shape0Tip: + ret = default_subShapeTipLocIndex; + break; + case properties_i.shape1Tip: + ret = default_subShape2TipLocIndex; + break; + case properties_i.shape2Tip: + ret = default_subShape3TipLocIndex; + break; + case properties_i.subShapeIndex: + ret = default_subShapeRefIndex; + break; + case properties_i.posIndex: + ret = default_posInSubShapeIndex; + break; + case properties_i.proxRays: + ret = default_proximitySideRays; + break; + case properties_i.edgeSlide: + ret = default_edgeSlide; + break; + case properties_i.lwrType: + case properties_i.lwr2Type: + ret = default_LWRNoiseType; + break; + case properties_i.lwrPreview: + ret = default_LWRNoisePreview; + break; + case properties_i.xOL_ref: + ret = default_overlayXReferenceLayer; + break; + case properties_i.yOL_ref: + ret = default_overlayYReferenceLayer; + break; + case properties_i.xOL_av: + ret = default_averageOverlayX; + break; + case properties_i.yOL_av: + ret = default_averageOverlayY; + break; + case properties_i.xOL_corr: + ret = default_correlatedXOverlay; + break; + case properties_i.xOL_corr_ref: + ret = default_correlatedXOverlayLayerIndex; + break; + case properties_i.yOL_corr: + ret = default_correlatedYOverlay; + break; + case properties_i.yOL_corr_ref: + ret = default_correlatedYOverlayLayerIndex; + break; + case properties_i.CDU_corr: + ret = default_correlatedCDU; + break; + case properties_i.CDU_corr_ref: + ret = default_correlatedCDULayerIndex; + break; + case properties_i.tCDU_corr: + ret = default_correlatedTipCDU; + break; + case properties_i.tCDU_corr_ref: + ret = default_correlatedTipCDULayerIndex; + break; + case properties_i.alignX: + case properties_i.alignY: + ret = default_alignGeom; + break; + case properties_i.flipH: + ret = default_flipH; + break; + case properties_i.flipV: + ret = default_flipV; + break; + case properties_i.structure: + ret = default_structureFromFile; + break; + case properties_i.lD: + ret = default_ldFromFile; + break; + case properties_i.fill: + ret = default_polyFill; + break; + case properties_i.fileType: + ret = default_fileType; + break; + case properties_i.perPoly: + ret = default_perPoly; + break; + case properties_i.refLayout: + ret = default_referenceLayout; + break; + case properties_i.bLayerA: + ret = default_booleanLayerA; + break; + case properties_i.bLayerB: + ret = default_booleanLayerB; + break; + case properties_i.bLayerOpA: + ret = default_booleanLayerOpA; + break; + case properties_i.bLayerOpB: + ret = default_booleanLayerOpB; + break; + case properties_i.bLayerOpAB: + ret = default_booleanLayerOpAB; + break; + } + + return ret; + } + + string comment; + string layerName; + string horTipBiasPVar_RNGMapping; + string horTipBiasNVar_RNGMapping; + string verTipBiasPVar_RNGMapping; + string verTipBiasNVar_RNGMapping; + string innerCV_RNGMapping; + string outerCV_RNGMapping; + string LWR_RNGMapping; + string LWR2_RNGMapping; + string sideCDU_RNGMapping; + string tipsCDU_RNGMapping; + string horOverlay_RNGMapping; + string verOverlay_RNGMapping; + string wobble_RNGMapping; + string fileToLoad; // file value to load. + string structureNameFromFile; + string ldNameFromFile; + + public enum properties_s + { + comment, name, hTipPVar_RNG, hTipNVar_RNG, vTipPVar_RNG, vTipNVar_RNG, iCV_RNG, oCV_RNG, lwr_RNG, lwr2_RNG, sCDU_RNG, tCDU_RNG, + xOL_RNG, yOL_RNG, wobble_RNG, + file, structure, lD + } + + public string getString(properties_s p) + { + return pGetString(p); + } + + string pGetString(properties_s p) + { + string ret = ""; + + switch (p) + { + case properties_s.comment: + ret = comment; + break; + case properties_s.name: + ret = layerName; + break; + case properties_s.hTipNVar_RNG: + ret = horTipBiasNVar_RNGMapping; + break; + case properties_s.hTipPVar_RNG: + ret = horTipBiasPVar_RNGMapping; + break; + case properties_s.vTipNVar_RNG: + ret = verTipBiasNVar_RNGMapping; + break; + case properties_s.vTipPVar_RNG: + ret = verTipBiasPVar_RNGMapping; + break; + case properties_s.iCV_RNG: + ret = innerCV_RNGMapping; + break; + case properties_s.oCV_RNG: + ret = outerCV_RNGMapping; + break; + case properties_s.lwr_RNG: + ret = LWR_RNGMapping; + break; + case properties_s.lwr2_RNG: + ret = LWR2_RNGMapping; + break; + case properties_s.sCDU_RNG: + ret = sideCDU_RNGMapping; + break; + case properties_s.tCDU_RNG: + ret = tipsCDU_RNGMapping; + break; + case properties_s.xOL_RNG: + ret = horOverlay_RNGMapping; + break; + case properties_s.yOL_RNG: + ret = verOverlay_RNGMapping; + break; + case properties_s.wobble_RNG: + ret = wobble_RNGMapping; + break; + case properties_s.file: + ret = fileToLoad; + break; + case properties_s.structure: + ret = structureNameFromFile; + break; + case properties_s.lD: + ret = ldNameFromFile; + break; + } + + return ret; + } + + public void setString(properties_s p, string val) + { + pSetString(p, val); + } + + void pSetString(properties_s p, string val) + { + switch (p) + { + case properties_s.comment: + comment = val; + break; + case properties_s.name: + layerName = val; + break; + case properties_s.hTipNVar_RNG: + horTipBiasNVar_RNGMapping = val; + break; + case properties_s.hTipPVar_RNG: + horTipBiasPVar_RNGMapping = val; + break; + case properties_s.vTipNVar_RNG: + verTipBiasNVar_RNGMapping = val; + break; + case properties_s.vTipPVar_RNG: + verTipBiasPVar_RNGMapping = val; + break; + case properties_s.iCV_RNG: + innerCV_RNGMapping = val; + break; + case properties_s.oCV_RNG: + outerCV_RNGMapping = val; + break; + case properties_s.lwr_RNG: + LWR_RNGMapping = val; + break; + case properties_s.lwr2_RNG: + LWR2_RNGMapping = val; + break; + case properties_s.sCDU_RNG: + sideCDU_RNGMapping = val; + break; + case properties_s.tCDU_RNG: + tipsCDU_RNGMapping = val; + break; + case properties_s.xOL_RNG: + horOverlay_RNGMapping = val; + break; + case properties_s.yOL_RNG: + verOverlay_RNGMapping = val; + break; + case properties_s.wobble_RNG: + wobble_RNGMapping = val; + break; + case properties_s.file: + fileToLoad = val; + break; + case properties_s.structure: + structureNameFromFile = val; + break; + case properties_s.lD: + ldNameFromFile = val; + break; + } + } + + public void defaultString(properties_s p) + { + pDefaultString(p); + } + + void pDefaultString(properties_s p) + { + switch (p) + { + case properties_s.comment: + comment = default_comment; + break; + case properties_s.file: + fileToLoad = default_fileToLoad; + break; + case properties_s.hTipNVar_RNG: + horTipBiasNVar_RNGMapping = default_rngmapping; + break; + case properties_s.hTipPVar_RNG: + horTipBiasPVar_RNGMapping = default_rngmapping; + break; + case properties_s.iCV_RNG: + innerCV_RNGMapping = default_rngmapping; + break; + case properties_s.lD: + ldNameFromFile = default_ldNameFromFile; + break; + case properties_s.lwr2_RNG: + LWR2_RNGMapping = default_rngmapping; + break; + case properties_s.lwr_RNG: + LWR_RNGMapping = default_rngmapping; + break; + case properties_s.name: + layerName = default_layerName; + break; + case properties_s.oCV_RNG: + outerCV_RNGMapping = default_rngmapping; + break; + case properties_s.sCDU_RNG: + sideCDU_RNGMapping = default_rngmapping; + break; + case properties_s.structure: + structureNameFromFile = default_structureNameFromFile; + break; + case properties_s.tCDU_RNG: + tipsCDU_RNGMapping = default_rngmapping; + break; + case properties_s.vTipNVar_RNG: + verTipBiasNVar_RNGMapping = default_rngmapping; + break; + case properties_s.vTipPVar_RNG: + verTipBiasPVar_RNGMapping = default_rngmapping; + break; + case properties_s.wobble_RNG: + wobble_RNGMapping = default_rngmapping; + break; + case properties_s.xOL_RNG: + horOverlay_RNGMapping = default_rngmapping; + break; + case properties_s.yOL_RNG: + verOverlay_RNGMapping = default_rngmapping; + break; + } + } + + public static string getDefaultString(properties_s p) + { + return pGetDefaultString(p); + } + + static string pGetDefaultString(properties_s p) + { + string ret = ""; + + switch (p) + { + case properties_s.comment: + ret = default_comment; + break; + case properties_s.name: + ret = default_layerName; + break; + case properties_s.hTipNVar_RNG: + case properties_s.hTipPVar_RNG: + case properties_s.vTipNVar_RNG: + case properties_s.vTipPVar_RNG: + case properties_s.iCV_RNG: + case properties_s.oCV_RNG: + case properties_s.lwr_RNG: + case properties_s.lwr2_RNG: + case properties_s.sCDU_RNG: + case properties_s.tCDU_RNG: + case properties_s.xOL_RNG: + case properties_s.yOL_RNG: + case properties_s.wobble_RNG: + ret = default_rngmapping; + break; + case properties_s.file: + ret = default_fileToLoad; + break; + case properties_s.structure: + ret = default_structureNameFromFile; + break; + case properties_s.lD: + ret = default_ldNameFromFile; + break; + } + + return ret; + } + + decimal subShapeHorLength; + decimal subShapeHorOffset; + decimal subShapeVerLength; + decimal subShapeVerOffset; + decimal subShape2HorLength; + decimal subShape2HorOffset; + decimal subShape2VerLength; + decimal subShape2VerOffset; + decimal subShape3HorLength; + decimal subShape3HorOffset; + decimal subShape3VerLength; + decimal subShape3VerOffset; + decimal globalHorOffset; + decimal globalVerOffset; + decimal rotation; + decimal wobble; + decimal sideBias; + decimal horTipBias; + decimal horTipBiasPVar; + decimal horTipBiasNVar; + decimal verTipBias; + decimal verTipBiasPVar; + decimal verTipBiasNVar; + decimal proximityBias; + decimal proximityIsoDistance; + decimal lensDistortionCoeff1; + decimal lensDistortionCoeff2; + decimal innerCRR; + decimal outerCRR; + decimal innerCV; + decimal outerCV; + decimal LWR; + decimal LWR2; + decimal edgeSlideTension; + decimal LWRNoiseFreq; + decimal LWR2NoiseFreq; + decimal sideCDU; + decimal tipsCDU; + decimal horOverlay; + decimal verOverlay; + + public enum properties_decimal + { + s0HorLength, s0VerLength, s0HorOffset, s0VerOffset, + s1HorLength, s1VerLength, s1HorOffset, s1VerOffset, + s2HorLength, s2VerLength, s2HorOffset, s2VerOffset, + gHorOffset, gVerOffset, + rot, wobble, + sBias, hTBias, hTNVar, hTPVar, vTBias, vTNVar, vTPVar, + pBias, pBiasDist, + lDC1, lDC2, + iCR, oCR, iCV, oCV, + lwr, lwrFreq, lwr2, lwr2Freq, + eTension, + sCDU, tCDU, + xOL, yOL + } + + public decimal getDecimal(properties_decimal p) + { + return pGetDecimal(p); + } + + decimal pGetDecimal(properties_decimal p) + { + decimal ret = 0m; + switch (p) + { + case properties_decimal.s0HorLength: + ret = subShapeHorLength; + break; + case properties_decimal.s0VerLength: + ret = subShapeVerLength; + break; + case properties_decimal.s0HorOffset: + ret = subShapeHorOffset; + break; + case properties_decimal.s0VerOffset: + ret = subShapeVerOffset; + break; + case properties_decimal.s1HorLength: + ret = subShape2HorLength; + break; + case properties_decimal.s1VerLength: + ret = subShape2VerLength; + break; + case properties_decimal.s1HorOffset: + ret = subShape2HorOffset; + break; + case properties_decimal.s1VerOffset: + ret = subShape2VerOffset; + break; + case properties_decimal.s2HorLength: + ret = subShape3HorLength; + break; + case properties_decimal.s2VerLength: + ret = subShape3VerLength; + break; + case properties_decimal.s2HorOffset: + ret = subShape3HorOffset; + break; + case properties_decimal.s2VerOffset: + ret = subShape3VerOffset; + break; + case properties_decimal.gHorOffset: + ret = globalHorOffset; + break; + case properties_decimal.gVerOffset: + ret = globalVerOffset; + break; + case properties_decimal.rot: + ret = rotation; + break; + case properties_decimal.wobble: + ret = wobble; + break; + case properties_decimal.sBias: + ret = sideBias; + break; + case properties_decimal.hTBias: + ret = horTipBias; + break; + case properties_decimal.hTNVar: + ret = horTipBiasNVar; + break; + case properties_decimal.hTPVar: + ret = horTipBiasPVar; + break; + case properties_decimal.vTBias: + ret = verTipBias; + break; + case properties_decimal.vTNVar: + ret = verTipBiasNVar; + break; + case properties_decimal.vTPVar: + ret = verTipBiasPVar; + break; + case properties_decimal.pBias: + ret = proximityBias; + break; + case properties_decimal.pBiasDist: + ret = proximityIsoDistance; + break; + case properties_decimal.lDC1: + ret = lensDistortionCoeff1; + break; + case properties_decimal.lDC2: + ret = lensDistortionCoeff2; + break; + case properties_decimal.iCR: + ret = innerCRR; + break; + case properties_decimal.iCV: + ret = innerCV; + break; + case properties_decimal.oCR: + ret = outerCRR; + break; + case properties_decimal.oCV: + ret = outerCV; + break; + case properties_decimal.lwr: + ret = LWR; + break; + case properties_decimal.lwrFreq: + ret = LWRNoiseFreq; + break; + case properties_decimal.lwr2: + ret = LWR2; + break; + case properties_decimal.lwr2Freq: + ret = LWR2NoiseFreq; + break; + case properties_decimal.eTension: + ret = edgeSlideTension; + break; + case properties_decimal.sCDU: + ret = sideCDU; + break; + case properties_decimal.tCDU: + ret = tipsCDU; + break; + case properties_decimal.xOL: + ret = horOverlay; + break; + case properties_decimal.yOL: + ret = verOverlay; + break; + } + + return ret; + } + + public static decimal getDefaultDecimal(properties_decimal p) + { + return pGetDefaultDecimal(p); + } + + static decimal pGetDefaultDecimal(properties_decimal p) + { + decimal ret = 0m; + switch (p) + { + case properties_decimal.s0HorLength: + ret = default_subShapeHorLength; + break; + case properties_decimal.s0VerLength: + ret = default_subShapeVerLength; + break; + case properties_decimal.s0HorOffset: + ret = default_subShapeHorOffset; + break; + case properties_decimal.s0VerOffset: + ret = default_subShapeVerOffset; + break; + case properties_decimal.s1HorLength: + ret = default_subShape2HorLength; + break; + case properties_decimal.s1VerLength: + ret = default_subShape2VerLength; + break; + case properties_decimal.s1HorOffset: + ret = default_subShape2HorOffset; + break; + case properties_decimal.s1VerOffset: + ret = default_subShape2VerOffset; + break; + case properties_decimal.s2HorLength: + ret = default_subShape3HorLength; + break; + case properties_decimal.s2VerLength: + ret = default_subShape3VerLength; + break; + case properties_decimal.s2HorOffset: + ret = default_subShape3HorOffset; + break; + case properties_decimal.s2VerOffset: + ret = default_subShape3VerOffset; + break; + case properties_decimal.gHorOffset: + ret = default_globalHorOffset; + break; + case properties_decimal.gVerOffset: + ret = default_globalVerOffset; + break; + case properties_decimal.rot: + ret = default_rotation; + break; + case properties_decimal.wobble: + ret = default_wobble; + break; + case properties_decimal.sBias: + ret = default_sideBias; + break; + case properties_decimal.hTBias: + ret = default_horTipBias; + break; + case properties_decimal.hTNVar: + ret = default_horTipBiasNVar; + break; + case properties_decimal.hTPVar: + ret = default_horTipBiasPVar; + break; + case properties_decimal.vTBias: + ret = default_verTipBias; + break; + case properties_decimal.vTNVar: + ret = default_verTipBiasNVar; + break; + case properties_decimal.vTPVar: + ret = default_verTipBiasPVar; + break; + case properties_decimal.pBias: + ret = default_proximityBias; + break; + case properties_decimal.pBiasDist: + ret = default_proximityIsoDistance; + break; + case properties_decimal.lDC1: + ret = default_lensDistortionCoeff1; + break; + case properties_decimal.lDC2: + ret = default_lensDistortionCoeff2; + break; + case properties_decimal.iCR: + ret = default_innerCRR; + break; + case properties_decimal.iCV: + ret = default_innerCV; + break; + case properties_decimal.oCR: + ret = default_outerCRR; + break; + case properties_decimal.oCV: + ret = default_outerCV; + break; + case properties_decimal.lwr: + case properties_decimal.lwr2: + ret = default_LWR; + break; + case properties_decimal.lwrFreq: + case properties_decimal.lwr2Freq: + ret = default_LWRNoiseFreq; + break; + case properties_decimal.eTension: + ret = default_edgeSlideTension; + break; + case properties_decimal.sCDU: + ret = default_sideCDU; + break; + case properties_decimal.tCDU: + ret = default_tipsCDU; + break; + case properties_decimal.xOL: + ret = default_horOverlay; + break; + case properties_decimal.yOL: + ret = default_verOverlay; + break; + } + + return ret; + } + + public void setDecimal(properties_decimal p, decimal val) + { + pSetDecimal(p, val); + } + + void pSetDecimal(properties_decimal p, decimal val) + { + switch (p) + { + case properties_decimal.s0HorLength: + subShapeHorLength = val; + break; + case properties_decimal.s0VerLength: + subShapeVerLength = val; + break; + case properties_decimal.s0HorOffset: + subShapeHorOffset = val; + break; + case properties_decimal.s0VerOffset: + subShapeVerOffset = val; + break; + case properties_decimal.s1HorLength: + subShape2HorLength = val; + break; + case properties_decimal.s1VerLength: + subShape2VerLength = val; + break; + case properties_decimal.s1HorOffset: + subShape2HorOffset = val; + break; + case properties_decimal.s1VerOffset: + subShape2VerOffset = val; + break; + case properties_decimal.s2HorLength: + subShape3HorLength = val; + break; + case properties_decimal.s2VerLength: + subShape3VerLength = val; + break; + case properties_decimal.s2HorOffset: + subShape3HorOffset = val; + break; + case properties_decimal.s2VerOffset: + subShape3VerOffset = val; + break; + case properties_decimal.gHorOffset: + globalHorOffset = val; + break; + case properties_decimal.gVerOffset: + globalVerOffset = val; + break; + case properties_decimal.rot: + rotation = val; + break; + case properties_decimal.wobble: + wobble = val; + break; + case properties_decimal.sBias: + sideBias = val; + break; + case properties_decimal.hTBias: + horTipBias = val; + break; + case properties_decimal.hTNVar: + horTipBiasNVar = val; + break; + case properties_decimal.hTPVar: + horTipBiasPVar = val; + break; + case properties_decimal.vTBias: + verTipBias = val; + break; + case properties_decimal.vTNVar: + verTipBiasNVar = val; + break; + case properties_decimal.vTPVar: + verTipBiasPVar = val; + break; + case properties_decimal.pBias: + proximityBias = val; + break; + case properties_decimal.pBiasDist: + proximityIsoDistance = val; + break; + case properties_decimal.lDC1: + lensDistortionCoeff1 = val; + break; + case properties_decimal.lDC2: + lensDistortionCoeff2 = val; + break; + case properties_decimal.iCR: + innerCRR = val; + break; + case properties_decimal.iCV: + innerCV = val; + break; + case properties_decimal.oCR: + outerCRR = val; + break; + case properties_decimal.oCV: + outerCV = val; + break; + case properties_decimal.lwr: + LWR = val; + break; + case properties_decimal.lwrFreq: + LWRNoiseFreq = val; + break; + case properties_decimal.lwr2: + LWR2 = val; + break; + case properties_decimal.lwr2Freq: + LWR2NoiseFreq = val; + break; + case properties_decimal.eTension: + edgeSlideTension = val; + break; + case properties_decimal.sCDU: + sideCDU = val; + break; + case properties_decimal.tCDU: + tipsCDU = val; + break; + case properties_decimal.xOL: + horOverlay = val; + break; + case properties_decimal.yOL: + verOverlay = val; + break; + } + } + + public void defaultDecimal(properties_decimal p) + { + pDefaultDecimal(p); + } + + void pDefaultDecimal(properties_decimal p) + { + switch (p) + { + case properties_decimal.eTension: + edgeSlideTension = default_edgeSlideTension; + break; + case properties_decimal.gHorOffset: + globalHorOffset = default_globalHorOffset; + break; + case properties_decimal.gVerOffset: + globalVerOffset = default_globalVerOffset; + break; + case properties_decimal.hTBias: + horTipBias = default_horTipBias; + break; + case properties_decimal.hTNVar: + horTipBiasNVar = default_horTipBiasNVar; + break; + case properties_decimal.hTPVar: + horTipBiasPVar = default_horTipBiasPVar; + break; + case properties_decimal.iCR: + innerCRR = default_innerCRR; + break; + case properties_decimal.iCV: + innerCV = default_innerCV; + break; + case properties_decimal.lDC1: + lensDistortionCoeff1 = default_lensDistortionCoeff1; + break; + case properties_decimal.lDC2: + lensDistortionCoeff2 = default_lensDistortionCoeff2; + break; + case properties_decimal.lwr: + LWR = default_LWR; + break; + case properties_decimal.lwr2: + LWR2 = default_LWR; + break; + case properties_decimal.lwrFreq: + LWRNoiseFreq = default_LWRNoiseFreq; + break; + case properties_decimal.lwr2Freq: + LWR2NoiseFreq = default_LWRNoiseFreq; + break; + case properties_decimal.oCR: + outerCRR = default_outerCRR; + break; + case properties_decimal.oCV: + outerCV = default_outerCV; + break; + case properties_decimal.pBias: + proximityBias = default_proximityBias; + break; + case properties_decimal.pBiasDist: + proximityIsoDistance = default_proximityIsoDistance; + break; + case properties_decimal.rot: + rotation = default_rotation; + break; + case properties_decimal.s0HorLength: + subShapeHorLength = default_subShapeHorLength; + break; + case properties_decimal.s0HorOffset: + subShapeHorOffset = default_subShapeHorOffset; + break; + case properties_decimal.s0VerLength: + subShapeVerLength = default_subShapeVerLength; + break; + case properties_decimal.s0VerOffset: + subShapeVerOffset = default_subShapeVerOffset; + break; + case properties_decimal.s1HorLength: + subShape2HorLength = default_subShape2HorLength; + break; + case properties_decimal.s1HorOffset: + subShape2HorOffset = default_subShape2HorOffset; + break; + case properties_decimal.s1VerLength: + subShape2VerLength = default_subShape2VerLength; + break; + case properties_decimal.s1VerOffset: + subShape2VerOffset = default_subShape2VerOffset; + break; + case properties_decimal.s2HorLength: + subShape3HorLength = default_subShape3HorLength; + break; + case properties_decimal.s2HorOffset: + subShape3HorOffset = default_subShape3HorOffset; + break; + case properties_decimal.s2VerLength: + subShape3VerLength = default_subShape3VerLength; + break; + case properties_decimal.s2VerOffset: + subShape3VerOffset = default_subShape3VerOffset; + break; + case properties_decimal.sBias: + sideBias = default_sideBias; + break; + case properties_decimal.sCDU: + sideCDU = default_sideCDU; + break; + case properties_decimal.tCDU: + tipsCDU = default_tipsCDU; + break; + case properties_decimal.vTBias: + verTipBias = default_verTipBias; + break; + case properties_decimal.vTNVar: + verTipBiasNVar = default_verTipBiasNVar; + break; + case properties_decimal.vTPVar: + verTipBiasPVar = default_verTipBiasPVar; + break; + case properties_decimal.wobble: + wobble = default_wobble; + break; + case properties_decimal.xOL: + horOverlay = default_horOverlay; + break; + case properties_decimal.yOL: + verOverlay = default_verOverlay; + break; + } + } + + bool reloadedFileData; // if true, we pulled in point data from a reloaded XML file and shouldn't obliterate it. + public bool isReloaded() + { + return pIsReloaded(); + } + + bool pIsReloaded() + { + return reloadedFileData; + } + + public void setReloaded(bool val) + { + pSetReloaded(val); + } + + void pSetReloaded(bool val) + { + reloadedFileData = val; + } + + List fileData; // holds the parsed point data of our level, for file-based content. Allows for multiple polys in layer + + public List getFileData() + { + return pGetFileData(); + } + + List pGetFileData() + { + return fileData; + } + + public void setFileData(List newdata) + { + pSetFileData(newdata); + } + + void pSetFileData(List newdata) + { + fileData = newdata.ToList(); + } + + public void defaultFileData() + { + pDefaultFileData(); + } + + void pDefaultFileData() + { + fileData = default_fileData.ToList(); + } + + public EntropyLayerSettings() + { + pEntropyLayerSettings(); + } + + void pEntropyLayerSettings() + { + comment = default_comment; + bgLayers = default_bgLayers.ToArray(); + enabled = default_enabled; + geoCoreShapeEngine = default_geoCoreShapeEngine; + shapeIndex = default_shapeIndex; + layerName = default_layerName; + + subShapeHorLength = default_subShapeHorLength; + subShapeVerLength = default_subShapeVerLength; + subShapeHorOffset = default_subShapeHorOffset; + subShapeVerOffset = default_subShapeVerOffset; + subShapeTipLocIndex = default_subShapeTipLocIndex; + subShape2HorLength = default_subShape2HorLength; + subShape2VerLength = default_subShape2VerLength; + subShape2HorOffset = default_subShape2HorOffset; + subShape2VerOffset = default_subShape2VerOffset; + subShape2TipLocIndex = default_subShape2TipLocIndex; + subShape3HorLength = default_subShape3HorLength; + subShape3VerLength = default_subShape3VerLength; + subShape3HorOffset = default_subShape3HorOffset; + subShape3VerOffset = default_subShape3VerOffset; + subShape3TipLocIndex = default_subShape3TipLocIndex; + subShapeRefIndex = default_subShapeRefIndex; + posInSubShapeIndex = default_posInSubShapeIndex; + + rotation = default_rotation; + wobble = default_wobble; + wobble_RNGMapping = default_rngmapping; + sideBias = default_sideBias; + horTipBias = default_horTipBias; + horTipBiasNVar = default_horTipBiasNVar; + horTipBiasNVar_RNGMapping = default_rngmapping; + horTipBiasPVar = default_horTipBiasPVar; + horTipBiasPVar_RNGMapping = default_rngmapping; + verTipBias = default_verTipBias; + verTipBiasNVar = default_verTipBiasNVar; + verTipBiasNVar_RNGMapping = default_rngmapping; + verTipBiasPVar = default_verTipBiasPVar; + verTipBiasPVar_RNGMapping = default_rngmapping; + proximityBias = default_proximityBias; + proximityIsoDistance = default_proximityIsoDistance; + proximitySideRays = default_proximitySideRays; + + innerCRR = default_innerCRR; + innerCV = default_innerCV; + innerCV_RNGMapping = default_rngmapping; + outerCRR = default_outerCRR; + outerCV = default_outerCV; + outerCV_RNGMapping = default_rngmapping; + edgeSlide = default_edgeSlide; + edgeSlideTension = default_edgeSlideTension; + + LWR = default_LWR; + LWR_RNGMapping = default_rngmapping; + LWRNoiseType = default_LWRNoiseType; + LWRNoisePreview = default_LWRNoisePreview; + LWRNoiseFreq = default_LWRNoiseFreq; + LWR2 = default_LWR; + LWR2_RNGMapping = default_rngmapping; + LWR2NoiseType = default_LWRNoiseType; + LWR2NoiseFreq = default_LWRNoiseFreq; + + horOverlay = default_horOverlay; + horOverlay_RNGMapping = default_rngmapping; + verOverlay = default_verOverlay; + verOverlay_RNGMapping = default_rngmapping; + + sideCDU = default_sideCDU; + sideCDU_RNGMapping = default_rngmapping; + tipsCDU = default_tipsCDU; + tipsCDU_RNGMapping = default_rngmapping; + + fileType = default_fileType; + fileData = default_fileData; + fileToLoad = default_fileToLoad; + ldFromFile = default_ldFromFile; + polyFill = default_polyFill; + ldNameFromFile = default_ldNameFromFile; + reloadedFileData = false; + structureFromFile = default_structureFromFile; + structureNameFromFile = default_structureNameFromFile; + perPoly = default_perPoly; + referenceLayout = default_referenceLayout; + + correlatedTipCDU = default_correlatedTipCDU; + correlatedTipCDULayerIndex = default_correlatedTipCDULayerIndex; + correlatedCDU = default_correlatedCDU; + correlatedCDULayerIndex = default_correlatedCDULayerIndex; + correlatedXOverlay = default_correlatedXOverlay; + correlatedXOverlayLayerIndex = default_correlatedXOverlayLayerIndex; + correlatedYOverlay = default_correlatedYOverlay; + correlatedYOverlayLayerIndex = default_correlatedYOverlayLayerIndex; + overlayXReferenceLayer = default_overlayXReferenceLayer; + overlayYReferenceLayer = default_overlayYReferenceLayer; + averageOverlayX = default_averageOverlayX; + averageOverlayY = default_averageOverlayY; + overlayXReferenceLayers = default_overlayXReferenceLayers.ToArray(); + overlayYReferenceLayers = default_overlayYReferenceLayers.ToArray(); + flipH = default_flipH; + flipV = default_flipV; + alignGeomX = default_alignGeom; + alignGeomY = default_alignGeom; + showDrawn = default_showDrawn; + + lensDistortionCoeff1 = default_lensDistortionCoeff1; + lensDistortionCoeff2 = default_lensDistortionCoeff2; + + booleanLayerA = default_booleanLayerA; + booleanLayerB = default_booleanLayerB; + booleanLayerOpA = default_booleanLayerOpA; + booleanLayerOpB = default_booleanLayerOpB; + booleanLayerOpAB = default_booleanLayerOpAB; + + omitFromSim = default_omitLayer; + } + + public void adjustSettings(EntropyLayerSettings source, bool gdsOnly) + { + pAdjustSettings(source, gdsOnly); + } + + void pAdjustSettings(EntropyLayerSettings source, bool gdsOnly) + { + comment = source.comment; + bgLayers = source.bgLayers.ToArray(); + enabled = source.enabled; + geoCoreShapeEngine = source.geoCoreShapeEngine; + showDrawn = source.showDrawn; + layerName = source.layerName; + shapeIndex = source.shapeIndex; + + if (!gdsOnly) + { + subShapeHorLength = source.subShapeHorLength; + subShapeHorOffset = source.subShapeHorOffset; + subShapeVerLength = source.subShapeVerLength; + subShapeVerOffset = source.subShapeVerOffset; + subShapeTipLocIndex = source.subShapeTipLocIndex; + + subShape2HorLength = source.subShape2HorLength; + subShape2HorOffset = source.subShape2HorOffset; + subShape2VerLength = source.subShape2VerLength; + subShape2VerOffset = source.subShape2VerOffset; + subShape2TipLocIndex = source.subShape2TipLocIndex; + + subShape3HorLength = source.subShape3HorLength; + subShape3HorOffset = source.subShape3HorOffset; + subShape3VerLength = source.subShape3VerLength; + subShape3VerOffset = source.subShape3VerOffset; + subShape3TipLocIndex = source.subShape3TipLocIndex; + + subShapeRefIndex = source.subShapeRefIndex; + posInSubShapeIndex = source.posInSubShapeIndex; + + globalHorOffset = source.globalHorOffset; + globalVerOffset = source.globalVerOffset; + + rotation = source.rotation; + wobble = source.wobble; + wobble_RNGMapping = source.wobble_RNGMapping; + sideBias = source.sideBias; + + horTipBias = source.horTipBias; + horTipBiasNVar = source.horTipBiasNVar; + horTipBiasNVar_RNGMapping = source.horTipBiasNVar_RNGMapping; + horTipBiasPVar = source.horTipBiasPVar; + horTipBiasPVar_RNGMapping = source.horTipBiasPVar_RNGMapping; + verTipBias = source.verTipBias; + verTipBiasNVar = source.verTipBiasNVar; + verTipBiasNVar_RNGMapping = source.verTipBiasNVar_RNGMapping; + verTipBiasPVar = source.verTipBiasPVar; + verTipBiasPVar_RNGMapping = source.verTipBiasPVar_RNGMapping; + proximityBias = source.proximityBias; + proximityIsoDistance = source.proximityIsoDistance; + proximitySideRays = source.proximitySideRays; + + innerCRR = source.innerCRR; + innerCV = source.innerCV; + innerCV_RNGMapping = source.innerCV_RNGMapping; + outerCRR = source.outerCRR; + outerCV = source.outerCV; + outerCV_RNGMapping = source.outerCV_RNGMapping; + edgeSlide = source.edgeSlide; + edgeSlideTension = source.edgeSlideTension; + + LWR = source.LWR; + LWRNoiseType = source.LWRNoiseType; + LWRNoisePreview = source.LWRNoisePreview; + LWRNoiseFreq = source.LWRNoiseFreq; + LWR2 = source.LWR2; + LWR2NoiseType = source.LWR2NoiseType; + LWR2NoiseFreq = source.LWR2NoiseFreq; + + sideCDU = source.sideCDU; + sideCDU_RNGMapping = source.sideCDU_RNGMapping; + tipsCDU = source.tipsCDU; + tipsCDU_RNGMapping = source.tipsCDU_RNGMapping; + + horOverlay = source.horOverlay; + horOverlay_RNGMapping = source.horOverlay_RNGMapping; + verOverlay = source.verOverlay; + verOverlay_RNGMapping = source.verOverlay_RNGMapping; + + correlatedTipCDU = source.correlatedTipCDU; + correlatedTipCDULayerIndex = source.correlatedTipCDULayerIndex; + + correlatedCDU = source.correlatedCDU; + correlatedCDULayerIndex = source.correlatedCDULayerIndex; + + correlatedXOverlay = source.correlatedXOverlay; + correlatedXOverlayLayerIndex = source.correlatedXOverlayLayerIndex; + + correlatedYOverlay = source.correlatedYOverlay; + correlatedYOverlayLayerIndex = source.correlatedYOverlayLayerIndex; + + overlayXReferenceLayer = source.overlayXReferenceLayer; + overlayYReferenceLayer = source.overlayYReferenceLayer; + + averageOverlayX = source.averageOverlayX; + averageOverlayY = source.averageOverlayY; + overlayXReferenceLayers = source.overlayXReferenceLayers.ToArray(); + overlayYReferenceLayers = source.overlayYReferenceLayers.ToArray(); + + flipH = source.flipH; + flipV = source.flipV; + alignGeomX = source.alignGeomX; + alignGeomY = source.alignGeomY; + + lensDistortionCoeff1 = source.lensDistortionCoeff1; + lensDistortionCoeff2 = source.lensDistortionCoeff2; + + booleanLayerA = source.booleanLayerA; + booleanLayerB = source.booleanLayerB; + booleanLayerOpA = source.booleanLayerOpA; + booleanLayerOpB = source.booleanLayerOpB; + booleanLayerOpAB = source.booleanLayerOpAB; + + omitFromSim = source.omitFromSim; + } + + // layout stuff + + fileToLoad = source.fileToLoad; + structureFromFile = source.structureFromFile; + structureNameFromFile = source.structureNameFromFile; + ldFromFile = source.ldFromFile; + ldNameFromFile = source.ldNameFromFile; + polyFill = source.polyFill; + fileData = source.fileData.ToList(); + referenceLayout = source.referenceLayout; + fileType = source.fileType; + + reloadedFileData = source.reloadedFileData; + + perPoly = source.perPoly; + } + + public EntropyLayerSettings(EntropyLayerSettings source, bool gdsOnly) + { + adjustSettings(source, gdsOnly); + } + + public bool nonGaussianValues() + { + return pNonGaussianValues(); + } + + bool pNonGaussianValues() + { + bool gaussianvalues = horOverlay_RNGMapping == CommonVars.boxMuller; + gaussianvalues = gaussianvalues && (verOverlay_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (innerCV_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (outerCV_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (sideCDU_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (tipsCDU_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (horTipBiasNVar_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (horTipBiasPVar_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (verTipBiasNVar_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (verTipBiasPVar_RNGMapping == CommonVars.boxMuller); + gaussianvalues = gaussianvalues && (wobble_RNGMapping == CommonVars.boxMuller); + + return !gaussianvalues; + } + } +} diff --git a/Common/Variance/entropy/entropySettings.cs b/Common/Variance/entropy/entropySettings.cs new file mode 100644 index 0000000..65df964 --- /dev/null +++ b/Common/Variance/entropy/entropySettings.cs @@ -0,0 +1,481 @@ +using Error; +using System; +using System.Linq; + +namespace Variance +{ + [Serializable] + public class EntropySettings + { + public bool debugCalc { get; set; } // job engine specific debug flag from user. + + DOESettings DOESettings; + public DOESettings getDOESettings() + { + return pGetDOESettings(); + } + + DOESettings pGetDOESettings() + { + return DOESettings; + } + + public enum properties_i { nCases, linkCDU, subMode, cSeg, optC, oType, rngType, ler } + + Int32 numberOfCases; + Int32 linkTipandSideCDU; + Int32 subMode; // allows adjustment of calculation mode to subtypes. + Int32 cornerSegments; // CR step count + Int32 optimizeCorners; // overrides the CR stepping with a linear check against edge resolution (see EntropyShape) + + Int32 lerFromLWR_by_sqrt2; + + Int32 outputType; + + // RNG type for run. + Int32 rngType; + + public Int32 getValue(properties_i p) + { + return pGetValue(p); + } + + Int32 pGetValue(properties_i p) + { + Int32 ret = 0; + switch (p) + { + case properties_i.cSeg: + ret = cornerSegments; + break; + case properties_i.linkCDU: + ret = linkTipandSideCDU; + break; + case properties_i.nCases: + ret = numberOfCases; + break; + case properties_i.optC: + ret = optimizeCorners; + break; + case properties_i.oType: + ret = outputType; + break; + case properties_i.rngType: + ret = rngType; + break; + case properties_i.subMode: + ret = subMode; + break; + case properties_i.ler: + ret = lerFromLWR_by_sqrt2; + break; + } + + return ret; + } + + public void setValue(properties_i p, int val) + { + pSetValue(p, val); + } + + void pSetValue(properties_i p, int val) + { + switch (p) + { + case properties_i.cSeg: + cornerSegments = val; + break; + case properties_i.linkCDU: + linkTipandSideCDU = val; + break; + case properties_i.nCases: + numberOfCases = val; + break; + case properties_i.optC: + optimizeCorners = val; + break; + case properties_i.oType: + outputType = val; + break; + case properties_i.rngType: + rngType = val; + break; + case properties_i.subMode: + subMode = val; + break; + case properties_i.ler: + lerFromLWR_by_sqrt2 = val; + break; + } + } + + public void defaultValue(properties_i p) + { + pDefaultValue(p); + } + + void pDefaultValue(properties_i p) + { + switch (p) + { + case properties_i.cSeg: + cornerSegments = default_cornerSegments; + break; + case properties_i.ler: + lerFromLWR_by_sqrt2 = default_lerFromLWR_by_sqrt2; + break; + case properties_i.linkCDU: + linkTipandSideCDU = default_linkTipandSideCDU; + break; + case properties_i.nCases: + numberOfCases = default_numberOfCases; + break; + case properties_i.optC: + optimizeCorners = default_optimizeCorners; + break; + case properties_i.oType: + outputType = default_outputType; + break; + case properties_i.rngType: + rngType = default_rngType; + break; + case properties_i.subMode: + subMode = default_subMode; + break; + } + } + + public Int32 getDefaultValue(properties_i p) + { + return pGetDefaultValue(p); + } + + Int32 pGetDefaultValue(properties_i p) + { + Int32 ret = 0; + switch (p) + { + case properties_i.cSeg: + ret = default_cornerSegments; + break; + case properties_i.linkCDU: + ret = default_linkTipandSideCDU; + break; + case properties_i.nCases: + ret = default_numberOfCases; + break; + case properties_i.optC: + ret = default_optimizeCorners; + break; + case properties_i.oType: + ret = default_outputType; + break; + case properties_i.rngType: + ret = default_rngType; + break; + case properties_i.subMode: + ret = default_subMode; + break; + case properties_i.ler: + ret = default_lerFromLWR_by_sqrt2; + break; + } + + return ret; + } + + double resolution; + + public double getResolution() + { + return pGetResolution(); + } + + double pGetResolution() + { + return resolution; + } + + public void setResolution(double val) + { + pSetResolution(val); + } + + void pSetResolution(double val) + { + resolution = val; + } + + public void defaultResolution() + { + pDefaultResolution(); + } + + void pDefaultResolution() + { + resolution = default_resolution; + } + + // Index in respective drop-down + public enum properties_o { layer, twoLayer, fourLayer, eightLayer } + Int32[] layerOperator; + Int32[] twoLayerOperator; + Int32[] fourLayerOperator; + Int32[] eightLayerOperator; + + public Int32[] getOperator(properties_o p) + { + return pGetOperator(p); + } + + Int32[] pGetOperator(properties_o p) + { + Int32[] ret = new Int32[] { }; + switch (p) + { + case properties_o.layer: + ret = layerOperator; + break; + case properties_o.twoLayer: + ret = twoLayerOperator; + break; + case properties_o.fourLayer: + ret = fourLayerOperator; + break; + case properties_o.eightLayer: + ret = eightLayerOperator; + break; + } + + return ret; + } + + public Int32 getOperatorValue(properties_o p, int index) + { + return pGetOperatorValue(p, index); + } + + Int32 pGetOperatorValue(properties_o p, int index) + { + return pGetOperator(p)[index]; + } + + public void setOperatorValue(properties_o p, int index, int val) + { + pSetOperatorValue(p, index, val); + } + + void pSetOperatorValue(properties_o p, int index, int val) + { + switch (p) + { + case properties_o.layer: + layerOperator[index] = val; + break; + case properties_o.twoLayer: + twoLayerOperator[index] = val; + break; + case properties_o.fourLayer: + fourLayerOperator[index] = val; + break; + case properties_o.eightLayer: + eightLayerOperator[index] = val; + break; + } + } + + public void defaultOperator(properties_o p, int index) + { + pDefaultOperator(p, index); + } + + void pDefaultOperator(properties_o p, int index) + { + switch (p) + { + case properties_o.layer: + layerOperator[index] = default_layerOperator; + break; + case properties_o.twoLayer: + twoLayerOperator[index] = default_layerBoolOperator; + break; + case properties_o.fourLayer: + fourLayerOperator[index] = default_layerBoolOperator; + break; + case properties_o.eightLayer: + eightLayerOperator[index] = default_layerBoolOperator; + break; + } + } + + static Int32 default_outputType = (Int32)CommonVars.calcModes.area; + static Int32 default_numberOfCases = 25000; + static double default_resolution = 1.0; + static Int32 default_cornerSegments = 90; + static Int32 default_layerOperator = 0; + static Int32 default_layerBoolOperator = 0; + static Int32 default_linkTipandSideCDU = 1; + static Int32 default_optimizeCorners = 1; + static Int32 default_lerFromLWR_by_sqrt2 = 1; + static Int32 default_rngType = 0; + static Int32 default_subMode = 0; + + public EntropySettings() + { + pMCSettings(); + } + + void pMCSettings() + { + DOESettings = new DOESettings(); // Handle iDRM DOE where tiles need to be broken out. + debugCalc = false; + outputType = default_outputType; + numberOfCases = default_numberOfCases; + resolution = default_resolution; + layerOperator = new int[CentralProperties.maxLayersForMC]; + for (int i = 0; i < layerOperator.Length; i++) + { + layerOperator[i] = default_layerOperator; + } + twoLayerOperator = new int[CentralProperties.maxLayersForMC / 2]; + for (int i = 0; i < twoLayerOperator.Length; i++) + { + twoLayerOperator[i] = default_layerBoolOperator; + } + fourLayerOperator = new int[twoLayerOperator.Length / 2]; + for (int i = 0; i < fourLayerOperator.Length; i++) + { + fourLayerOperator[i] = default_layerBoolOperator; + } + eightLayerOperator = new int[fourLayerOperator.Length / 2]; + for (int i = 0; i < eightLayerOperator.Length; i++) + { + eightLayerOperator[i] = default_layerBoolOperator; + } + + optimizeCorners = default_optimizeCorners; + linkTipandSideCDU = default_linkTipandSideCDU; + cornerSegments = default_cornerSegments; + lerFromLWR_by_sqrt2 = default_lerFromLWR_by_sqrt2; + rngType = default_rngType; // default + subMode = default_subMode; + } + + public string tileListToString(bool zeroIndex = false) + { + return pTileListToString(zeroIndex); + } + + string pTileListToString(bool zeroIndex) + { + int offset = 1; + if (zeroIndex) + { + offset = 0; + } + string returnString = ""; + if (DOESettings.getTileList_ColRow().Count() > 0) + { + int entry = 0; + returnString += (DOESettings.getTileList_Value(entry, 0) + offset).ToString() + "," + (DOESettings.getTileList_Value(entry, 1) + offset).ToString(); + entry++; + while (entry < DOESettings.getTileList_ColRow().Count()) + { + returnString += ";" + (DOESettings.getTileList_Value(entry, 0) + offset).ToString() + "," + (DOESettings.getTileList_Value(entry, 1) + offset).ToString(); + entry++; + } + } + return returnString; + } + + public bool setTileList(string tmpString, bool zeroIndex) + { + return pSetTileList(tmpString, zeroIndex); + } + + bool pSetTileList(string tmpString, bool zeroIndex) + { + int offset = -1; + if (zeroIndex) + { + offset = 0; + } + + // We need to parse our tile list + bool entryOK = false; + int colValue = 0; + int rowValue = 0; + char[] tileSep = new char[] { ';' }; + char[] coordSep = new char[] { ',' }; + + if (tmpString.Length > 0) + { + // We have some user entries. Perform some more validation + string[] tmpStringArray = tmpString.Split(coordSep); + switch (tmpStringArray.Count()) + { + case 0: + // No entries - abort out + break; + case 1: + // Only one value provided - abort out. + break; + case 2: + // We have one entry. Need to generate valid ints for array. + try + { + colValue = Convert.ToInt32(tmpStringArray[0]); + rowValue = Convert.ToInt32(tmpStringArray[1]); + DOESettings.resetTileList_ColRow(); + DOESettings.addTileList_Value(new Int32[] { colValue + offset, rowValue + offset }); + entryOK = true; + } + catch (Exception) + { + // invalid input. We ignore it. + } + break; + default: + // All other cases. + string[] tmpCoordPairArray = tmpString.Split(tileSep); + if (tmpCoordPairArray.Count() == 0) + { + // User used incorrect syntax. Failsafe. + ErrorReporter.showMessage_OK("Couldn't find a coordinate pair", "Invalid input"); + break; + } + // We have some initial entries that appear to be valid. + DOESettings.resetTileList_ColRow(); + for (Int32 entry = 0; entry < tmpCoordPairArray.Count(); entry++) + { + tmpStringArray = tmpCoordPairArray[entry].Split(coordSep); + if (tmpStringArray.Count() == 2) + { + try + { + colValue = Convert.ToInt32(tmpStringArray[0]); + rowValue = Convert.ToInt32(tmpStringArray[1]); + DOESettings.addTileList_Value(new Int32[] { colValue + offset, rowValue + offset }); + } + catch (Exception) + { + // Invalid input; ignore it. + } + } + } + if (DOESettings.getTileList_ColRow().Count() == 0) + { + entryOK = false; + } + else + { + entryOK = true; + } + break; + } + } + return entryOK; + } + } +} diff --git a/Common/Variance/entropy/entropySettings_nonSim.cs b/Common/Variance/entropy/entropySettings_nonSim.cs new file mode 100644 index 0000000..9487777 --- /dev/null +++ b/Common/Variance/entropy/entropySettings_nonSim.cs @@ -0,0 +1,232 @@ +using System; + +namespace Variance +{ + public class EntropySettings_nonSim + { + Int32 externalType { get; set; } + Int32 generateExternal { get; set; } + Int32 generateCSV { get; set; } + + static Int32 default_externalType = (Int32)CommonVars.external_Type.svg; + static Int32 default_generateExternal = 0; + static Int32 default_generateCSV = 0; + + Int32 greedyMode { get; set; } + string comment { get; set; } + string paSearchComment { get; set; } + + static string default_comment = ""; + static Int32 default_greedyMode = 1; + + Int32 displayResults { get; set; } + Int32 displayShape { get; set; } + + static Int32 default_displayResults = 1; + static Int32 default_displayShape = 1; + + public enum properties_i { external, externalType, csv, greedy, results, shape } + + public Int32 getValue(properties_i p) + { + return pGetValue(p); + } + + Int32 pGetValue(properties_i p) + { + Int32 ret = 0; + switch (p) + { + case properties_i.csv: + ret = generateCSV; + break; + case properties_i.external: + ret = generateExternal; + break; + case properties_i.externalType: + ret = externalType; + break; + case properties_i.greedy: + ret = greedyMode; + break; + case properties_i.results: + ret = displayResults; + break; + case properties_i.shape: + ret = displayShape; + break; + } + + return ret; + } + + public void setValue(properties_i p, int val) + { + pSetValue(p, val); + } + + void pSetValue(properties_i p, int val) + { + switch (p) + { + case properties_i.csv: + generateCSV = val; + break; + case properties_i.external: + generateExternal = val; + break; + case properties_i.externalType: + externalType = val; + break; + case properties_i.greedy: + greedyMode = val; + break; + case properties_i.results: + displayResults = val; + break; + case properties_i.shape: + displayShape = val; + break; + } + } + + public void defaultValue(properties_i p) + { + pDefaultValue(p); + } + + void pDefaultValue(properties_i p) + { + switch (p) + { + case properties_i.csv: + generateCSV = default_generateCSV; + break; + case properties_i.greedy: + greedyMode = default_greedyMode; + break; + case properties_i.results: + displayResults = default_displayResults; + break; + case properties_i.shape: + displayShape = default_displayShape; + break; + case properties_i.external: + generateExternal = default_generateExternal; + break; + case properties_i.externalType: + externalType = default_externalType; + break; + } + } + + public Int32 getDefaultValue(properties_i p) + { + return pGetDefaultValue(p); + } + + Int32 pGetDefaultValue(properties_i p) + { + Int32 ret = 0; + switch (p) + { + case properties_i.csv: + ret = default_generateCSV; + break; + case properties_i.external: + ret = default_generateExternal; + break; + case properties_i.externalType: + ret = default_externalType; + break; + case properties_i.greedy: + ret = default_greedyMode; + break; + case properties_i.results: + ret = default_displayResults; + break; + case properties_i.shape: + ret = default_displayShape; + break; + } + + return ret; + } + + public enum properties_s { comment, paComment } + + public string getString(properties_s p) + { + return pGetString(p); + } + + string pGetString(properties_s p) + { + string ret = ""; + switch (p) + { + case properties_s.comment: + ret = comment; + break; + case properties_s.paComment: + ret = paSearchComment; + break; + } + return ret; + } + + public void setString(properties_s p, string val) + { + pSetString(p, val); + } + + void pSetString(properties_s p, string val) + { + switch (p) + { + case properties_s.comment: + comment = val; + break; + case properties_s.paComment: + paSearchComment = val; + break; + } + } + + public void defaultString(properties_s p) + { + pDefaultString(p); + } + + void pDefaultString(properties_s p) + { + switch (p) + { + case properties_s.comment: + comment = default_comment; + break; + case properties_s.paComment: + paSearchComment = default_comment; + break; + } + } + + public EntropySettings_nonSim() + { + pEntropySettings_nonSim(); + } + + void pEntropySettings_nonSim() + { + displayResults = default_displayResults; + displayShape = default_displayShape; + + comment = default_comment; + paSearchComment = default_comment; + greedyMode = default_greedyMode; + generateExternal = default_generateExternal; + externalType = default_externalType; + generateCSV = default_generateCSV; + } + } +} \ No newline at end of file diff --git a/Common/Variance/entropy/entropyShape.cs b/Common/Variance/entropy/entropyShape.cs new file mode 100644 index 0000000..c181a22 --- /dev/null +++ b/Common/Variance/entropy/entropyShape.cs @@ -0,0 +1,1209 @@ +using Error; +using geoLib; +using geoWrangler; +using System; +using System.Collections.Generic; +using System.Linq; +using utility; + +namespace Variance +{ + public class EntropyShape + { + Fragmenter fragment; + + GeoLibPointF[] points; + + public GeoLibPointF[] getPoints() + { + return pGetPoints(); + } + + GeoLibPointF[] pGetPoints() + { + return points; + } + + GeoLibPointF pivot; + + double globalBias_Sides, globalBias_Tips; + + MyVertex[] Vertex; // container for our extended point properties information. + MyRound[] round1; // container for the rounding data. + Boolean[] tips; // large array to hold tip information. + + class BoundingBox + { + List points; + public List getPoints() + { + return pGetPoints(); + } + + List pGetPoints() + { + return points; + } + + GeoLibPointF midPoint; + public GeoLibPointF getMidPoint() + { + return pGetMidPoint(); + } + + GeoLibPointF pGetMidPoint() + { + return midPoint; + } + + public BoundingBox(List incomingPoints) + { + pBoundingBox(incomingPoints); + } + + void pBoundingBox(List incomingPoints) + { + points = new List(); + if (incomingPoints == null) + { + points.Add(new GeoLibPointF(0.0f, 0.0f)); + midPoint = new GeoLibPointF(0.0f, 0.0f); + } + else + { + var minX = incomingPoints.Min(p => p.X); + var minY = incomingPoints.Min(p => p.Y); + var maxX = incomingPoints.Max(p => p.X); + var maxY = incomingPoints.Max(p => p.Y); + points.Add(new GeoLibPointF(minX, minY)); + points.Add(new GeoLibPointF(minX, maxY)); + points.Add(new GeoLibPointF(maxX, maxY)); + points.Add(new GeoLibPointF(maxX, minY)); + midPoint = new GeoLibPointF(minX + ((maxX - minX) / 2.0f), minY + ((maxY - minY) / 2.0f)); + } + } + + void pBoundingBox(GeoLibPointF[] incomingPoints) + { + points = new List(); + if (incomingPoints == null) + { + points.Add(new GeoLibPointF(0.0f, 0.0f)); + midPoint = new GeoLibPointF(0.0f, 0.0f); + } + else + { + // Compile a list of our points. + List iPoints = new List(); + for (int i = 0; i < incomingPoints.Count(); i++) + { + iPoints.Add(incomingPoints[i]); + } + var minX = iPoints.Min(p => p.X); + var minY = iPoints.Min(p => p.Y); + var maxX = iPoints.Max(p => p.X); + var maxY = iPoints.Max(p => p.Y); + points.Add(new GeoLibPointF(minX, minY)); + points.Add(new GeoLibPointF(minX, maxY)); + points.Add(new GeoLibPointF(maxX, maxY)); + points.Add(new GeoLibPointF(maxX, minY)); + midPoint = new GeoLibPointF(minX + ((maxX - minX) / 2.0f), minY + ((maxY - minY) / 2.0f)); + } + } + + void pBoundingBox(MyVertex[] incomingPoints) + { + points = new List(); + if (incomingPoints == null) + { + points.Add(new GeoLibPointF(0.0f, 0.0f)); + midPoint = new GeoLibPointF(0.0f, 0.0f); + } + else + { + // Compile a list of our points. + List iPoints = new List(); + for (int i = 0; i < incomingPoints.Count(); i++) + { + iPoints.Add(new GeoLibPointF(incomingPoints[i].X, incomingPoints[i].Y)); + } + var minX = iPoints.Min(p => p.X); + var minY = iPoints.Min(p => p.Y); + var maxX = iPoints.Max(p => p.X); + var maxY = iPoints.Max(p => p.Y); + points.Add(new GeoLibPointF(minX, minY)); + points.Add(new GeoLibPointF(minX, maxY)); + points.Add(new GeoLibPointF(maxX, maxY)); + points.Add(new GeoLibPointF(maxX, minY)); + midPoint = new GeoLibPointF(minX + ((maxX - minX) / 2.0f), minY + ((maxY - minY) / 2.0f)); + } + } + } + + List preFlight(List mcPoints, EntropyLayerSettings entropyLayerSettings, EntropySettings entropySettings) + { + // Fragment by resolution + List newMCPoints = fragment.fragmentPath(mcPoints); + + bool H = entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.flipH) == 1; + bool V = entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.flipV) == 1; + bool alignX = entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.alignX) == 1; + bool alignY = entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.alignY) == 1; + + newMCPoints = GeoWrangler.flip(H, V, alignX, alignY, pivot, newMCPoints); + + List tempList = new List(); + // Now to start the re-indexing. + bool addPoint = true; + for (Int32 pt = 0; pt < newMCPoints.Count; pt++) + { + if (pt == 0) + { + addPoint = true; + } + else + { + addPoint = !((tempList[tempList.Count - 1].X == newMCPoints[pt].X) && (tempList[tempList.Count - 1].Y == newMCPoints[pt].Y)); + } + + // Avoid adding duplicate vertices + if (addPoint) + { + tempList.Add(new GeoLibPointF(newMCPoints[pt].X, newMCPoints[pt].Y)); + } + } + + return tempList; + } + + public EntropyShape(EntropySettings entropySettings, List entropyLayerSettingsList, Int32 settingsIndex, bool doPASearch, bool previewMode, ChaosSettings chaosSettings, ShapeLibrary shape = null, GeoLibPointF pivot = null) + { + makeEntropyShape(entropySettings, entropyLayerSettingsList, settingsIndex, doPASearch, previewMode, chaosSettings, shape, pivot); + } + + List makeShape(bool returnEarly, bool cornerCheck, EntropySettings entropySettings, List entropyLayerSettingsList, int settingsIndex, bool doPASearch, bool previewMode, ChaosSettings chaosSettings, ShapeLibrary shape) + { + List mcPoints = new List(); // overall points container. We'll use this to populate and send back our Point array later. Ints only... + + Vertex = shape.Vertex; + tips = shape.tips; + round1 = shape.round1; + // Wrangle the tips. + for (Int32 cp = 0; cp < (Vertex.Count() - 1); cp++) // We don't drive the last point directly - we'll close our shape. + { + if (tips[cp]) + { + // Note that these are reversed due to top-left origin of drawing! + // A positive bias shrinks the shape in this code..... + // Values below are correlated in the MCControl system for simulations. In preview mode, these are all zero. + double vTipBiasNegVar = chaosSettings.getValue(ChaosSettings.properties.vTipBiasVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.vTNVar)); + double vTipBiasPosVar = chaosSettings.getValue(ChaosSettings.properties.vTipBiasVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.vTPVar)); + double hTipBiasNegVar = chaosSettings.getValue(ChaosSettings.properties.hTipBiasVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.hTNVar)); + double hTipBiasPosVar = chaosSettings.getValue(ChaosSettings.properties.hTipBiasVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.hTPVar)); + if ((Vertex[cp].direction == typeDirection.down1) && (Vertex[cp].yBiasApplied == false)) + { + Vertex[cp].Y -= Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.vTBias)); + Vertex[cp].Y -= Convert.ToDouble(globalBias_Tips); + if (chaosSettings.getValue(ChaosSettings.properties.vTipBiasType, settingsIndex) < 0.5) // Need to use our negative variation value + { + Vertex[cp].Y -= vTipBiasNegVar; + } + else + { + Vertex[cp].Y -= vTipBiasPosVar; + } + Vertex[cp].yBiasApplied = true; + } + if ((Vertex[cp].direction == typeDirection.up1) && (Vertex[cp].yBiasApplied == false)) + { + Vertex[cp].Y += Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.vTBias)); + Vertex[cp].Y += globalBias_Tips; + if (chaosSettings.getValue(ChaosSettings.properties.vTipBiasType, settingsIndex) < 0.5) // Need to use our negative variation value + { + Vertex[cp].Y += vTipBiasNegVar; + } + else + { + Vertex[cp].Y += vTipBiasPosVar; + } + Vertex[cp].yBiasApplied = true; + } + if ((Vertex[cp].direction == typeDirection.left1) && (Vertex[cp].xBiasApplied == false)) + { + Vertex[cp].X -= Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.hTBias)); + Vertex[cp].X -= globalBias_Tips; + if (chaosSettings.getValue(ChaosSettings.properties.hTipBiasType, settingsIndex) < 0.5) // Need to use our negative variation value + { + Vertex[cp].X -= hTipBiasNegVar; + } + else + { + Vertex[cp].X -= hTipBiasPosVar; + } + Vertex[cp].xBiasApplied = true; + } + if ((Vertex[cp].direction == typeDirection.right1) && (Vertex[cp].xBiasApplied == false)) + { + Vertex[cp].X += Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.hTBias)); + Vertex[cp].X += globalBias_Tips; + if (chaosSettings.getValue(ChaosSettings.properties.hTipBiasType, settingsIndex) < 0.5) // Need to use our negative variation value + { + Vertex[cp].X += hTipBiasNegVar; + } + else + { + Vertex[cp].X += hTipBiasPosVar; + } + Vertex[cp].xBiasApplied = true; + } + } + } + + // Global bias for anything that isn't a tip. + for (Int32 cp = 0; cp < (Vertex.Count() - 1); cp++) // We don't drive the last point directly - we'll close our shape. + { + if ((!Vertex[cp].xBiasApplied) && (!tips[cp])) + { + switch (Vertex[cp].direction) + { + case typeDirection.left1: + Vertex[cp].X -= globalBias_Sides; + break; + case typeDirection.right1: + Vertex[cp].X += globalBias_Sides; + break; + } + } + if ((!Vertex[cp].yBiasApplied) && (!tips[cp])) + { + switch (Vertex[cp].direction) + { + case typeDirection.up1: + Vertex[cp].Y += globalBias_Sides; + break; + case typeDirection.down1: + Vertex[cp].Y -= globalBias_Sides; + break; + } + } + } + + // Iterate the corners to apply the bias from the edges. + for (Int32 corner = 0; corner < round1.Count(); corner++) + { + Vertex[round1[corner].index].X = Vertex[round1[corner].verFace].X; + Vertex[round1[corner].index].Y = Vertex[round1[corner].horFace].Y; + } + + Vertex[Vertex.Count() - 1] = Vertex[0]; // close the shape. + round1[round1.Count() - 1] = round1[0]; + + // Set the midpoints of the edges to the average between the two corners + for (Int32 corner = 0; corner < round1.Count(); corner++) + { + double previousEdgeLength = 0.0f; + double nextEdgeLength = 0.0f; + double currentEdgeLength = 0.0f; + + if (corner == 0) + { + previousEdgeLength = Math.Abs( + GeoWrangler.distanceBetweenPoints(new GeoLibPointF(Vertex[round1[corner].index].X, Vertex[round1[corner].index].Y), + new GeoLibPointF(Vertex[round1[round1.Count() - 1].index].X, Vertex[round1[round1.Count() - 1].index].Y)) + ); + } + else + { + previousEdgeLength = Math.Abs( + GeoWrangler.distanceBetweenPoints(new GeoLibPointF(Vertex[round1[corner].index].X, Vertex[round1[corner].index].Y), + new GeoLibPointF(Vertex[round1[corner - 1].index].X, Vertex[round1[corner - 1].index].Y)) + ); + } + + // Wrap around if we exceed the length + nextEdgeLength = Math.Abs( + GeoWrangler.distanceBetweenPoints(new GeoLibPointF(Vertex[round1[(corner + 1) % (round1.Count() - 1)].index].X, Vertex[round1[(corner + 1) % (round1.Count() - 1)].index].Y), + new GeoLibPointF(Vertex[round1[(corner + 2) % (round1.Count() - 1)].index].X, Vertex[round1[(corner + 2) % (round1.Count() - 1)].index].Y)) + ); + + currentEdgeLength = Math.Abs( + GeoWrangler.distanceBetweenPoints(new GeoLibPointF(Vertex[round1[corner].index].X, Vertex[round1[corner].index].Y), + new GeoLibPointF(Vertex[round1[(corner + 1) % (round1.Count() - 1)].index].X, Vertex[round1[(corner + 1) % (round1.Count() - 1)].index].Y)) + ); + + double offset = 0.5f * currentEdgeLength; + bool reverseSlide = true; // used in the linear mode to handle reversed case (where ratio is > 1), and the no-slide case.) + + if ((entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.edgeSlide) == 1) && (previousEdgeLength > 0) && (nextEdgeLength > 0)) + { + // Now we need to figure out the weighting. + double ratio = Math.Abs(nextEdgeLength / previousEdgeLength); + bool doLinearSlide = false; + + if (ratio < 1) + { + reverseSlide = false; + if (ratio < 1E-2) + { + ratio = 1E-2; // clamp + } + ratio = (1 / ratio); // normalize into our expected range + } + + if (doLinearSlide) + { + // Linear + offset = Math.Pow(currentEdgeLength / 2.0f, 1.0f / ratio); // ratio * currentEdgeLength / 2.0f; + } + else + { + // Sigmoid function to try and provide some upper and lower resistance to the slide. + // center is to force 0.5 value of the scaling factor for a ratio of 1 + // tension controls the shape of the curve, and thus the sensitivity of the response.. + double center = 1.0f; + //float tension = 0.35f; + double tension = Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.eTension)); + offset = currentEdgeLength * (1 / (1 + Math.Exp(-tension * (center - ratio)))); + } + } + + if (corner % 2 == 0) + { + // Get our associated vertical edge Y position + double yPoint1 = 0.0; + double yPoint2 = Vertex[round1[(corner + 1) % (round1.Count() - 1)].horFace].Y; + if (corner == 0) + { + // Need to wrap around for bias look-up + yPoint1 = Vertex[round1[round1.Count() - 1].horFace].Y; + } + else + { + yPoint1 = Vertex[round1[corner].horFace].Y; + } + + if (yPoint1 < yPoint2) + { + if (reverseSlide) + { + Vertex[round1[corner].verFace].Y = yPoint2 - offset; + } + else + { + Vertex[round1[corner].verFace].Y = yPoint1 + offset; + } + } + else + { + if (reverseSlide) + { + Vertex[round1[corner].verFace].Y = yPoint2 + offset; + } + else + { + Vertex[round1[corner].verFace].Y = yPoint1 - offset; + } + } + } + else + { + // Tweak horizontal edge + double xPoint1 = Vertex[round1[corner].verFace].X; + double xPoint2 = 0.0; + xPoint2 = Vertex[round1[(corner + 1) % (round1.Count() - 1)].verFace].X; + + if (xPoint1 < xPoint2) + { + if (reverseSlide) + { + Vertex[round1[corner].horFace].X = xPoint2 - offset; + } + else + { + Vertex[round1[corner].horFace].X = xPoint1 + offset; + } + } + else + { + if (reverseSlide) + { + Vertex[round1[corner].horFace].X = xPoint2 + offset; + } + else + { + Vertex[round1[corner].horFace].X = xPoint1 - offset; + } + } + } + } + + if (returnEarly) + { + mcPoints.Clear(); + for (Int32 i = 0; i < Vertex.Count(); i++) + { + mcPoints.Add(new GeoLibPointF(Vertex[i].X, Vertex[i].Y)); + } + return mcPoints; + } + + List mcHorEdgePoints = new List(); // corner coordinates list, used as a temporary container for each iteration + List mcVerEdgePoints = new List(); // edge coordinates list, used as a temporary container for each iteration + List> mcHorEdgePointsList = new List>(); // Hold our lists of doubles for each corner in the shape, in order. We cast these to Ints in the mcPoints list. + List> mcVerEdgePointsList = new List>(); // Hold our lists of doubles for each edge in the shape, in order. We cast these to Ints in the mcPoints list. + + // OK. We need to walk the corner and associated edge for each case. + double increment = entropySettings.getResolution(); + + for (Int32 round = 0; round < round1.Count() - 1; round++) + { + // Derive our basic coordinates for the three vertices on the edge. + double start_x = Vertex[round1[round].index].X; + double start_y = Vertex[round1[round].index].Y; + double currentHorEdge_mid_x = Vertex[round1[round].horFace].X; + double currentVerEdge_mid_y = Vertex[round1[round].verFace].Y; + double end_x = Vertex[round1[round + 1].index].X; + double end_y = Vertex[round1[round + 1].index].Y; + double nextVerEdge_mid_y = Vertex[round1[round + 1].verFace].Y; + + // Test whether we have a vertical edge or not. We only process horizontal edges to avoid doubling up + if (start_y == end_y) + { + double mcPX = 0.0f; + double mcPY = 0.0f; + // Establish corner rounding sign at start and end points of edge. Default is to move outwards (inner CRR) + bool startInnerRounding = true; + bool endInnerRounding = true; + if (round1[round].direction == typeRound.exter) + { + startInnerRounding = false; + } + if (round1[round + 1].direction == typeRound.exter) + { + endInnerRounding = false; + } + + // Now sort out the shift based on face orientation. + bool horFaceUp = true; + switch (Vertex[round1[round].horFace].direction) + { + case typeDirection.up1: + break; + case typeDirection.down1: + horFaceUp = false; + break; + } + bool verFaceLeft = true; + switch (Vertex[round1[round].verFace].direction) + { + case typeDirection.left1: + break; + case typeDirection.right1: + verFaceLeft = false; + break; + } + + // Segment 1 + + // Clamp radius in each direction, if needed, to available distance + double hRadius = round1[round].MaxRadius; + double x_Distance = Math.Sqrt(Utils.myPow(currentHorEdge_mid_x - start_x, 2)); + double vRadius = round1[round].MaxRadius; + double y_Distance = Math.Sqrt(Utils.myPow(currentVerEdge_mid_y - start_y, 2)); + + // Add our random variation based on rounding type : + + bool paSearchAffectsCornerRounding = false; + + if (doPASearch) + { + if (startInnerRounding) + { + paSearchAffectsCornerRounding = chaosSettings.getBool(ChaosSettings.bools.icPA, settingsIndex); + } + else + { + paSearchAffectsCornerRounding = chaosSettings.getBool(ChaosSettings.bools.ocPA, settingsIndex); + } + } + + if (paSearchAffectsCornerRounding) + { + if (startInnerRounding) + { + hRadius = chaosSettings.getValue(ChaosSettings.properties.icVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.iCR)); + vRadius = chaosSettings.getValue(ChaosSettings.properties.icVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.iCR)); + } + else + { + hRadius = chaosSettings.getValue(ChaosSettings.properties.ocVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.oCR)); + vRadius = chaosSettings.getValue(ChaosSettings.properties.ocVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.oCR)); + } + } + else + { + if (!previewMode) + { + if (startInnerRounding) + { + hRadius += chaosSettings.getValue(ChaosSettings.properties.icVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.iCV)); + vRadius += chaosSettings.getValue(ChaosSettings.properties.icVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.iCV)); + } + else + { + hRadius += chaosSettings.getValue(ChaosSettings.properties.ocVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.oCV)); + vRadius += chaosSettings.getValue(ChaosSettings.properties.ocVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.oCV)); + } + } + } + + if (hRadius > x_Distance) + { + hRadius = x_Distance; + } + if (vRadius > y_Distance) + { + vRadius = y_Distance; + } + + // Clamp for negative radius values that would make no sense + if (hRadius < 0) + { + hRadius = 0; + } + if (vRadius < 0) + { + vRadius = 0; + } + + double angleIncrement = 90.0f / entropySettings.getValue(EntropySettings.properties_i.cSeg); + + // Sweep our corner. + double angle = 0.0f; + while (angle <= 90.0f) + { + // Set start condition + mcPX = start_x; // X position for new point. + mcPY = start_y; // this will hold our Y position for the new point. + + // Remove full contribution from rounding. + if (verFaceLeft) + { + if (startInnerRounding) + { + mcPX -= hRadius; + } + else + { + mcPX += hRadius; + } + } + else + { + if (startInnerRounding) + { + mcPX += hRadius; + } + else + { + mcPX -= hRadius; + } + } + if (horFaceUp) + { + if (startInnerRounding) + { + mcPY += vRadius; + } + else + { + mcPY -= vRadius; + } + } + else + { + if (startInnerRounding) + { + mcPY -= vRadius; + } + else + { + mcPY += vRadius; + } + } + + // Now process corner, adding back contribution from rounding + if (verFaceLeft) + { + if (startInnerRounding) + { + mcPX += hRadius * Math.Cos(Utils.toRadians(angle)); + } + else + { + mcPX -= hRadius * Math.Cos(Utils.toRadians(angle)); + } + } + else + { + if (startInnerRounding) + { + mcPX -= hRadius * Math.Cos(Utils.toRadians(angle)); + } + else + { + mcPX += hRadius * Math.Cos(Utils.toRadians(angle)); + } + } + if (horFaceUp) + { + if (startInnerRounding) + { + mcPY -= vRadius * Math.Sin(Utils.toRadians(angle)); + } + else + { + mcPY += vRadius * Math.Sin(Utils.toRadians(angle)); + } + } + else + { + if (startInnerRounding) + { + mcPY += vRadius * Math.Sin(Utils.toRadians(angle)); + } + else + { + mcPY -= vRadius * Math.Sin(Utils.toRadians(angle)); + } + } + + GeoLibPointF cPt = new GeoLibPointF(mcPX, mcPY); + if ((angle == 0) || (angle == 90) || (entropySettings.getValue(EntropySettings.properties_i.optC) == 0) || + ((entropySettings.getValue(EntropySettings.properties_i.optC) == 1) && + (Math.Abs( + GeoWrangler.distanceBetweenPoints(mcHorEdgePoints[mcHorEdgePoints.Count() - 1], cPt) + ) + > entropySettings.getResolution() + ) + ) + ) + { + mcHorEdgePoints.Add(cPt); + } + angle += angleIncrement; + } + + // OK. We now need to add points along the edge based on the simulation settings resolution. + // We need to add points from here to just before the midpoint + + double bridgeX = mcHorEdgePoints[mcHorEdgePoints.Count() - 1].X; + + // Fragmenter returns first and last points in the point array. + GeoLibPointF[] fragments = fragment.fragmentPath(new GeoLibPointF[] { new GeoLibPointF(bridgeX, mcPY), new GeoLibPointF(currentHorEdge_mid_x, mcPY) }); + + for (int i = 1; i < fragments.Length - 1; i++) + { + mcHorEdgePoints.Add(fragments[i]); + } + + // Add our midpoint. + mcHorEdgePoints.Add(new GeoLibPointF(currentHorEdge_mid_x, mcPY)); + + // Segment 2, plus bridging on first pass through. + + bool firstPass = true; // With this set, we bridge from midpoint to our first point in the first pass through + // segment 2 of the edge. + verFaceLeft = true; + switch (Vertex[round1[round + 1].verFace].direction) + { + case typeDirection.left1: + break; + case typeDirection.right1: + verFaceLeft = false; + break; + } + + // Clamp radius to available distance, if needed. + hRadius = round1[round + 1].MaxRadius; + x_Distance = Math.Sqrt(Utils.myPow(currentHorEdge_mid_x - end_x, 2)); + vRadius = round1[round + 1].MaxRadius; + y_Distance = Math.Sqrt(Utils.myPow(nextVerEdge_mid_y - end_y, 2)); + + // Add our random variation based on rounding type : + + paSearchAffectsCornerRounding = false; + if (doPASearch) + { + if (startInnerRounding) + { + paSearchAffectsCornerRounding = chaosSettings.getBool(ChaosSettings.bools.icPA, settingsIndex); + } + else + { + paSearchAffectsCornerRounding = chaosSettings.getBool(ChaosSettings.bools.ocPA, settingsIndex); + } + } + + if (paSearchAffectsCornerRounding) + { + if (startInnerRounding) + { + hRadius = chaosSettings.getValue(ChaosSettings.properties.icVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.iCR)); + vRadius = chaosSettings.getValue(ChaosSettings.properties.icVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.iCR)); + } + else + { + hRadius = chaosSettings.getValue(ChaosSettings.properties.ocVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.oCR)); + vRadius = chaosSettings.getValue(ChaosSettings.properties.ocVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.oCR)); + } + } + else + { + // Add our random variation based on rounding type : + if (!previewMode) + { + if (endInnerRounding) + { + hRadius += chaosSettings.getValue(ChaosSettings.properties.icVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.iCV)); + vRadius += chaosSettings.getValue(ChaosSettings.properties.icVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.iCV)); + } + else + { + hRadius += chaosSettings.getValue(ChaosSettings.properties.ocVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.oCV)); + vRadius += chaosSettings.getValue(ChaosSettings.properties.ocVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.oCV)); + } + } + } + + if (hRadius > x_Distance) + { + hRadius = x_Distance; + } + if (vRadius > y_Distance) + { + vRadius = y_Distance; + } + + // Clamp for negative radius values that would make no sense + if (hRadius < 0) + { + hRadius = 0; + } + if (vRadius < 0) + { + vRadius = 0; + } + + // Sweep our end corner. We need to run the sweep in the opposite direction. + angle = 90.0f; + while (angle >= 0.0f) + { + // Set start conditions + mcPX = end_x; + mcPY = end_y; + + // Remove full extent of rounding in each direction, based on face orientation + if (verFaceLeft) + { + if (endInnerRounding) + { + mcPX -= hRadius; + } + else + { + mcPX += hRadius; + } + } + else + { + if (endInnerRounding) + { + mcPX += hRadius; + } + else + { + mcPX -= hRadius; + } + } + if (horFaceUp) + { + if (endInnerRounding) + { + mcPY += vRadius; + } + else + { + mcPY -= vRadius; + } + } + else + { + if (endInnerRounding) + { + mcPY -= vRadius; + } + else + { + mcPY += vRadius; + } + } + + // Process corners, adding back the contribution from the rounding based on the angle + if (verFaceLeft) + { + if (endInnerRounding) + { + mcPX += hRadius * Math.Cos(Utils.toRadians(angle)); + } + else + { + mcPX -= hRadius * Math.Cos(Utils.toRadians(angle)); + } + } + else + { + if (endInnerRounding) + { + mcPX -= hRadius * Math.Cos(Utils.toRadians(angle)); + } + else + { + mcPX += hRadius * Math.Cos(Utils.toRadians(angle)); + } + } + if (horFaceUp) + { + if (endInnerRounding) + { + mcPY -= vRadius * Math.Sin(Utils.toRadians(angle)); + } + else + { + mcPY += vRadius * Math.Sin(Utils.toRadians(angle)); + } + } + else + { + if (endInnerRounding) + { + mcPY += vRadius * Math.Sin(Utils.toRadians(angle)); + } + else + { + mcPY -= vRadius * Math.Sin(Utils.toRadians(angle)); + } + } + + // If this is the first pass, we need to add points to the start of the rounding, from the midpoint. + if (firstPass == true) + { + bridgeX = currentHorEdge_mid_x; + + // Fragmenter returns first and last points in the point array. + fragments = fragment.fragmentPath(new GeoLibPointF[] { new GeoLibPointF(bridgeX, mcPY), new GeoLibPointF(mcPX, mcPY) }); + + for (int i = 1; i < fragments.Length - 1; i++) + { + mcHorEdgePoints.Add(fragments[i]); + } + + firstPass = false; + } + + GeoLibPointF cPt = new GeoLibPointF(mcPX, mcPY); + if ((angle == 0) || (angle == 90) || (entropySettings.getValue(EntropySettings.properties_i.optC) == 0) || + ((entropySettings.getValue(EntropySettings.properties_i.optC) == 1) && + (Math.Abs( + GeoWrangler.distanceBetweenPoints(mcHorEdgePoints[mcHorEdgePoints.Count() - 1], cPt) + ) + > entropySettings.getResolution() + ) + ) + ) + { + mcHorEdgePoints.Add(cPt); + } + angle -= angleIncrement; + } + + mcHorEdgePointsList.Add(mcHorEdgePoints.ToList()); // make a deep copy of the points. + mcHorEdgePoints.Clear(); // clear our list of points to use on the next pass. + } + } + + if (cornerCheck) + { + mcPoints.Clear(); + for (Int32 i = 0; i < mcHorEdgePointsList.Count(); i++) + { + for (Int32 j = 0; j < mcHorEdgePointsList[i].Count(); j++) + { + mcPoints.Add(new GeoLibPointF(mcHorEdgePointsList[i][j].X, mcHorEdgePointsList[i][j].Y)); + } + } + mcPoints.Add(new GeoLibPointF(mcPoints[0].X, mcPoints[0].Y)); + return mcPoints; + } + + // Now we have our corners, let's process the vertical edges. We need the corners in order to get our start/end on each vertical edge. + for (int edge = 0; edge < mcHorEdgePointsList.Count(); edge++) + { + // Get our start and end Y positions for our vertical edge. + List startHorEdgePointList = mcHorEdgePointsList[edge]; + List endHorEdgePointList; + Int32 endHorEdgePointListIndex; + if (edge == 0) + { + endHorEdgePointListIndex = mcHorEdgePointsList.Count() - 1; // need to wrap around. + } + else + { + endHorEdgePointListIndex = edge - 1; + } + + endHorEdgePointList = mcHorEdgePointsList[endHorEdgePointListIndex]; + Double vert_x = endHorEdgePointList[endHorEdgePointList.Count() - 1].X; + Double startPoint_y = endHorEdgePointList[endHorEdgePointList.Count() - 1].Y; + Double endPoint_y = startHorEdgePointList[0].Y; + + // We get the start and end points here. + GeoLibPointF[] fragments = fragment.fragmentPath(new GeoLibPointF[] { new GeoLibPointF(vert_x, startPoint_y), new GeoLibPointF(vert_x, endPoint_y) }); + + mcVerEdgePointsList.Add(fragments.ToList()); // make a deep copy of the points. + mcVerEdgePoints.Clear(); + } + + // OK. We have our corners and edges. We need to walk them now. We'll apply the subshape 1 offset at the same time. + for (Int32 section = 0; section < mcVerEdgePointsList.Count(); section++) + { + for (Int32 point = 0; point < mcVerEdgePointsList[section].Count(); point++) + { + double x = mcVerEdgePointsList[section][point].X + Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset)); + double y = mcVerEdgePointsList[section][point].Y + Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset)); + mcPoints.Add(new GeoLibPointF(x, y)); + } + + // Corner next. + // Start and end points match those in the vertical edges, so we avoid them to eliminate duplicates. + for (Int32 point = 1; point < mcHorEdgePointsList[section].Count() - 1; point++) + { + double x = mcHorEdgePointsList[section][point].X + Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset)); + double y = mcHorEdgePointsList[section][point].Y + Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset)); + mcPoints.Add(new GeoLibPointF(x, y)); + } + } + + return mcPoints; + } + + void makeEntropyShape(EntropySettings entropySettings, List entropyLayerSettingsList, Int32 settingsIndex, bool doPASearch, bool previewMode, ChaosSettings chaosSettings, ShapeLibrary shape = null, GeoLibPointF pivot = null) + { + bool geoCoreShapeDefined = (shape != null); + bool cornerCheck = false; + bool returnEarly = false; + + double xOverlayVal = 0.0f; + double yOverlayVal = 0.0f; + + if (pivot != null) + { + this.pivot = new GeoLibPointF(pivot.X, pivot.Y); + } + + fragment = new Fragmenter(entropySettings.getResolution(), CentralProperties.scaleFactorForOperation); + + // Define our biases. We will use these later. + globalBias_Sides = Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.sBias)); + globalBias_Sides += (chaosSettings.getValue(ChaosSettings.properties.CDUSVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.sCDU)) / 2); + globalBias_Tips = (chaosSettings.getValue(ChaosSettings.properties.CDUTVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.tCDU)) / 2); + + bool failSafe = false; // setting to true will cause a single point to be created at 0,0 and returned. + + if (shape == null) + { + shape = new ShapeLibrary(entropyLayerSettingsList[settingsIndex]); + shape.setShape(entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.shapeIndex)); + } + + // Tip wrangling and shape closure will happen next + failSafe = !shape.shapeValid; // Set failsafe if shape is invalid. + + if (entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.enabled) == 0) + { + failSafe = true; + } + + List mcPoints = new List(); // overall points container. We'll use this to populate and send back our Point array later. Ints only... + + // Handle non-orthogonal case. + + if (!failSafe) + { + if ((!geoCoreShapeDefined) || (geoCoreShapeDefined && shape.geoCoreShapeOrthogonal)) + { + mcPoints = makeShape(returnEarly, cornerCheck, entropySettings, entropyLayerSettingsList, settingsIndex, doPASearch, previewMode, chaosSettings, shape); + } + else + { + // We have a non-orthogonal geoCore shape, so we take the defined vertices and use them directly. No rounding or tips (tips might be doable at a later date). + for (int pt = 0; pt < shape.Vertex.Length; pt++) + { + mcPoints.Add(new GeoLibPointF(shape.Vertex[pt].X, shape.Vertex[pt].Y)); + } + } + if (returnEarly || cornerCheck) + { + points = mcPoints.ToArray(); + return; + } + } + + // Sort out our overlay values. + if (!previewMode) + { + xOverlayVal = chaosSettings.getValue(ChaosSettings.properties.overlayX, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.xOL)); + + if (entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.xOL_av) == 1) // overlay average + { + List overlayValues = new List(); + for (int avgolref_x = 0; avgolref_x < entropyLayerSettingsList[settingsIndex].getIntArray(EntropyLayerSettings.properties_intarray.xOLRefs).Length; avgolref_x++) + { + if (entropyLayerSettingsList[settingsIndex].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, avgolref_x) == 1) + { + overlayValues.Add(chaosSettings.getValue(ChaosSettings.properties.overlayX, avgolref_x) * Convert.ToDouble(entropyLayerSettingsList[avgolref_x].getDecimal(EntropyLayerSettings.properties_decimal.xOL))); // Overlay shift + } + } + + try + { + xOverlayVal += overlayValues.Average(); + } + catch (Exception) + { + } + } + else // vanilla overlay reference mode + { + if (entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.xOL_ref) != -1) + { + xOverlayVal += chaosSettings.getValue(ChaosSettings.properties.overlayX, entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.xOL_ref)) * Convert.ToDouble(entropyLayerSettingsList[entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.xOL_ref)].getDecimal(EntropyLayerSettings.properties_decimal.xOL)); // Overlay shift + } + } + + yOverlayVal = chaosSettings.getValue(ChaosSettings.properties.overlayY, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.yOL)); // Overlay shift + + if (entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.yOL_av) == 1) // overlay average + { + List overlayValues = new List(); + for (int avgolref_y = 0; avgolref_y < entropyLayerSettingsList[settingsIndex].getIntArray(EntropyLayerSettings.properties_intarray.yOLRefs).Length; avgolref_y++) + { + if (entropyLayerSettingsList[settingsIndex].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, avgolref_y) == 1) + { + overlayValues.Add(chaosSettings.getValue(ChaosSettings.properties.overlayY, avgolref_y) * Convert.ToDouble(entropyLayerSettingsList[avgolref_y].getDecimal(EntropyLayerSettings.properties_decimal.yOL))); // Overlay shift + } + } + + try + { + yOverlayVal += overlayValues.Average(); + } + catch (Exception) + { + + } + } + else // vanilla overlay reference mode + { + if (entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.yOL_ref) != -1) + { + yOverlayVal += chaosSettings.getValue(ChaosSettings.properties.overlayY, entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.yOL_ref)) * Convert.ToDouble(entropyLayerSettingsList[entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.yOL_ref)].getDecimal(EntropyLayerSettings.properties_decimal.yOL)); // Overlay shift + } + } + } + + for (int pt = 0; pt < mcPoints.Count; pt++) + { + mcPoints[pt].X += xOverlayVal; + mcPoints[pt].Y += yOverlayVal; + } + + double threshold = 1E-5; // threshold for proximity, to avoid normal extraction issues. + if (mcPoints.Count > 1) + { + // Need to clean up any duplicate points at this point, to avoid causing /0 issues below. + List newPoints = new List(); + for (int pt = 1; pt < mcPoints.Count; pt++) + { + if (Math.Abs(Math.Sqrt(Utils.myPow(mcPoints[pt].X - mcPoints[pt - 1].X, 2) + Utils.myPow(mcPoints[pt].Y - mcPoints[pt - 1].Y, 2))) > threshold) + { + newPoints.Add(new GeoLibPointF(mcPoints[pt - 1])); + } + } + if (newPoints.Count != 0) + { + // Close shape. + mcPoints = newPoints.ToList(); + mcPoints.Add(new GeoLibPointF(mcPoints[0])); + } + } + + double rotationAngle = Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.rot)); + double rotationVar = chaosSettings.getValue(ChaosSettings.properties.wobbleVar, settingsIndex) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.wobble)); + // Per-poly rotation for layout case (only scenario where we have polygon sheets at this level) + // Note that we don't have CSV tracking for this case - there's no practical way to record the random values here. + if ((entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.perPoly) == 1) && (entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE)) + { + rotationVar = UtilityFuncs.getGaussianRandomNumber3(entropySettings) * Convert.ToDouble(entropyLayerSettingsList[settingsIndex].getDecimal(EntropyLayerSettings.properties_decimal.wobble)); + } + double rotationDirection = UtilityFuncs.getGaussianRandomNumber3(entropySettings); + if (rotationDirection <= 0.5) + { + rotationAngle -= rotationVar; + } + else + { + rotationAngle += rotationVar; + } + + if ((rotationAngle != 0) || (((entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.flipH) == 1) || (entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.flipV) == 1)) && ((entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.alignX) == 1) || (entropyLayerSettingsList[settingsIndex].getInt(EntropyLayerSettings.properties_i.alignY) == 1)))) + { + // Get our bounding box. + BoundingBox bb = new BoundingBox(mcPoints); + + if (this.pivot == null) + { + this.pivot = new GeoLibPointF(bb.getMidPoint()); + } + + // OK. Let's try some rotation and wobble. + // Temporary separate container for our rotated points, just for now. + List rotatedPoints = new List(); + + rotatedPoints = GeoWrangler.Rotate(this.pivot, mcPoints, rotationAngle); + mcPoints.Clear(); + mcPoints = rotatedPoints.ToList(); + } + + // Error handling (failSafe) for no points or no subshape - safety measure. + if (mcPoints.Count() == 0) + { + mcPoints.Add(new GeoLibPointF(0.0f, 0.0f)); + } + + // Path direction, point order and re-fragmentation (as needed) + mcPoints = preFlight(mcPoints, entropyLayerSettingsList[settingsIndex], entropySettings); + + points = new GeoLibPointF[mcPoints.Count()]; + for (Int32 i = 0; i < mcPoints.Count(); i++) + { + points[i] = mcPoints[i]; + } + + if ((points[0].X != points[points.Count() - 1].X) || (points[0].Y != points[points.Count() - 1].Y)) + { + ErrorReporter.showMessage_OK("Start and end not the same - entropyShape", "Oops"); + } + } + } +} diff --git a/Common/Variance/entropy/entropy_geo.cs b/Common/Variance/entropy/entropy_geo.cs new file mode 100644 index 0000000..a805782 --- /dev/null +++ b/Common/Variance/entropy/entropy_geo.cs @@ -0,0 +1,1412 @@ +using ClipperLib; // for tile extraction +using Error; +using geoCoreLib; +using geoLib; +using geoWrangler; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using utility; + +namespace Variance +{ + using Path = List; + using Paths = List>; + + public partial class Entropy + { + public delegate void updateSimUI(bool doPASearch, SimResultPackage resultPackage, string resultString); + public updateSimUI updateSimUIFunc { get; set; } + + public delegate void updateSimUIMT(); + public updateSimUIMT updateSimUIMTFunc { get; set; } + + public delegate void updateProgressBar(double val); + public updateProgressBar updateProgressBarFunc { get; set; } + + public delegate bool tooManyPolysWarning(); + public tooManyPolysWarning tooManyPolysWarningFunc { get; set; } + + SimResultPackage resultPackage; + + public SimResultPackage getResultPackage() + { + return pGetResultPackage(); + } + + SimResultPackage pGetResultPackage() + { + return resultPackage; + } + + bool useLoadedSettings; + bool nonGaussianInput; + ChaosSettings loadedJobSettings_; // used in replay mode to store job settings. + int replayRow, replayCol; + + Sampler_Geo sampler; + + void preFlight(Int32 row, Int32 col, bool tileHandling) + { + // Do tile extraction here - it's a problem to do it later since we cause major runtime impact. + if (tileHandling) + { + doTileExtraction(col, row); + } + lastSimResultsOverview = ""; + simJustDone = false; + currentProgress = 0; + multiCaseSim = false; + swTime = 0.0; // reset time for the batch + timeOfLastPreviewUpdate = 0; + sw = new Stopwatch(); + sw.Stop(); + sw.Reset(); + sw_Preview = new Stopwatch(); + sw_Preview.Stop(); + sw_Preview.Reset(); + } + + void uiProgressBarWrapper(double val) + { + updateProgressBarFunc?.Invoke(val); + } + + void setSampler(int numberOfCases, bool previewMode, bool doPASearch) + { + sampler = new Sampler_Geo(numberOfCases, previewMode, doPASearch, ref commonVars); + string tmp; + if (commonVars.getFriendly()) + { + tmp = Utils.friendlyNumber(sampler.getDimensions() * CentralProperties.maxLayersForMC * numberOfCases); + } + else + { + tmp = (sampler.getDimensions() * CentralProperties.maxLayersForMC * numberOfCases).ToString(); + } + updateStatus?.Invoke("Computing " + tmp + " samples."); + sampler.updateProgressBarFunc = uiProgressBarWrapper; + } + + void entropyRunCore_singleThread(bool previewMode, Int32 numberOfCases, Int32 row, Int32 col, bool tileHandling, bool doPASearch) + { + if (!doPASearch) + { + setSampler(numberOfCases, previewMode, doPASearch); + } + else + { + setSampler(1, previewMode, doPASearch); + } + sampler.sample(false); + + sw.Start(); + + // Let's sample this for non PA search and non-preview mode runs. + Int32 sampleRate = 100; + + // Set up our cleavedResults based on the max number of results we expect: + Int32 numberOfResultsFields = 1; + switch (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType)) + { + case (int)CommonVars.calcModes.chord: // chord + numberOfResultsFields = 4; + break; + default: // area, angle, spacing + numberOfResultsFields = 1; + break; + } + + if (doPASearch) + { + resultPackage = new SimResultPackage(ref varianceContext.previewLock, commonVars.getPASearch().numberofPassCases, numberOfResultsFields); + } + else + { + resultPackage = new SimResultPackage(ref varianceContext.previewLock, numberOfCases, numberOfResultsFields); + } + + // Set our input state in case of custom RNG mapping. + resultPackage.nonGaussianInput = nonGaussianInput; + sw.Reset(); + + int generateExternal = commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.external); + if (doPASearch) + { + generateExternal = 0; // no SVG storage in PA search mode. + } + + for (Int32 i = 0; i < numberOfCases; i++) + { + sw.Start(); + if (!doPASearch) + { + currentProgress++; + } + try + { + // Get the results from the MC engine. + Results currentResult = EntropyEval(previewMode, doPASearch, row, col, sampler.getSample(i)); + + bool addResultToPackage = true; + if (doPASearch) + { + // Review results and check against any limits from the PA search. + string[] tempString = currentResult.getResult().Split(csvSeparator); + for (int r = 0; r < tempString.Length; r++) + { + if (commonVars.getPASearch().useFilter[r]) + { + if (tempString[r] != "N/A") + { + double compareValue = Convert.ToDouble(tempString[r]); + // Now we need to review the value against the limit values. + // We have to pay attention to the min/max limit type + if (commonVars.getPASearch().filterIsMaxValue[r]) + { + if (compareValue > commonVars.getPASearch().filterValues[r]) + { + addResultToPackage = false; + } + } + else + { + if (compareValue < commonVars.getPASearch().filterValues[r]) + { + addResultToPackage = false; + } + } + } + } + } + } + + if (addResultToPackage) + { + if (doPASearch) + { + currentProgress++; + stepProgress?.Invoke(); + } + resultPackage.Add(currentResult, generateExternal); + if (doPASearch && (resultPackage.getListOfResults().Count == commonVars.getPASearch().numberofPassCases)) + { + break; + } + } + else + { + continue; + } + + // PASearch - update with every match, at least for now. + if (doPASearch || (previewMode || (currentProgress % sampleRate == 0))) + { + int index = i; + if (doPASearch) + { + index = resultPackage.getListOfResults().Count - 1; + } + // Update the preview configuration. + if (resultPackage.getResult(index).isValid()) + { + if (numberOfCases > 1) + { + try + { + resultString = resultPackage.getMeanAndStdDev(); + } + catch (Exception) + { + // Non-critical if an exception is raised. Ignore and carry on. + } + } + else + { + resultString = ""; + string[] tempString = resultPackage.getResult(index).getResult().Split(csvSeparator); + for (Int32 j = 0; j < tempString.Length; j++) + { + if (j > 0) + { + resultString += ","; + } + if (tempString[j] == "N/A") + { + resultString += "N/A"; + } + else + { + resultString += Convert.ToDouble(tempString[j]).ToString("0.##"); + } + } + } + updateSimUIFunc?.Invoke(doPASearch, resultPackage, resultString); + } + // Force redraw. We could use the progress bar to repaint, though. + // Note that this is an ugly hack to also ensure we collect stop button presses. + + forceRepaintFunc?.Invoke(); + } + } + catch (Exception) + { + // Reject the case - something happened. + } + + if (numberOfCases > 1) + { + timeOfFlight(sw.Elapsed.TotalSeconds, doPASearch); + // Nudge progress bar for non PA search mode. + if (!doPASearch) + { + stepProgress?.Invoke(); + } + } + + // Check if user cancelled. + if (abortRunFunc != null) + { + abortRunFunc(); + if (commonVars.runAbort) + { + sw.Stop(); + resultPackage.setState(false); + commonVars.runAbort = false; // reset state to allow user to abort save of results. + break; + } + } + } + + resultPackage.setRunTime(sw.Elapsed.TotalSeconds); + sw.Stop(); + } + + void entropyRunCore_multipleThread(bool previewMode, Int32 numberOfCases, Int32 row, Int32 col, bool tileHandling, bool doPASearch) + { + if (!doPASearch) + { + setSampler(numberOfCases, previewMode, doPASearch); + } + else + { + setSampler(1, previewMode, doPASearch); + } + sampler.sample(true); + + sw.Start(); + + // Set up our cleavedResults based on the max number of results we expect: + Int32 numberOfResultsFields = 1; + switch (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType)) + { + case (int)CommonVars.calcModes.chord: // chord + numberOfResultsFields = 4; + break; + default: // area, angle, spacing + numberOfResultsFields = 1; + break; + } + + if (doPASearch) + { + resultPackage = new SimResultPackage(ref varianceContext.previewLock, commonVars.getPASearch().numberofPassCases, numberOfResultsFields); + } + else + { + resultPackage = new SimResultPackage(ref varianceContext.previewLock, numberOfCases, numberOfResultsFields); + multithreadWarningFunc?.Invoke(); + } + + // Set our input state in case of custom RNG mapping. + resultPackage.nonGaussianInput = nonGaussianInput; + + commonVars.m_timer = new System.Timers.Timer(); + // Set up timers for the UI refresh + commonVars.m_timer.AutoReset = true; + commonVars.m_timer.Interval = CentralProperties.timer_interval; + updateSimUIMTFunc?.Invoke(); + commonVars.m_timer.Start(); + + // Set our parallel task options based on user settings. + ParallelOptions po = new ParallelOptions(); + // Attempt at parallelism. + CancellationTokenSource cancelSource = new CancellationTokenSource(); + CancellationToken cancellationToken = cancelSource.Token; + + if (varianceContext.numberOfThreads == -1) + { + po.MaxDegreeOfParallelism = commonVars.HTCount; + } + else + { + po.MaxDegreeOfParallelism = varianceContext.numberOfThreads; + } + + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.greedy) == 0) + { + if (po.MaxDegreeOfParallelism > 1) // avoid setting to 0 + { + po.MaxDegreeOfParallelism -= 1; + } + } + + int generateExternal = commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.external); + if (doPASearch) + { + generateExternal = 0; // no SVG for the PA search mode. + } + + try + { + Parallel.For(0, numberOfCases, po, (i, loopState) => + { + Results currentResult = new Results(); + try + { + currentResult = EntropyEval(previewMode, doPASearch, row, col, sampler.getSample(i)); + + bool addResultToPackage = true; + if (doPASearch) + { + // Review results and check against any limits from the PA search. + string[] tempString = currentResult.getResult().Split(csvSeparator); + for (int r = 0; r < tempString.Length; r++) + { + if (tempString[r] != "N/A") + { + double compareValue = Convert.ToDouble(tempString[r]); + // Now we need to review the value against the limit values. + if (commonVars.getPASearch().useFilter[r]) + { + // We have to pay attention to the min/max limit type + if (commonVars.getPASearch().filterIsMaxValue[r]) + { + if (compareValue > commonVars.getPASearch().filterValues[r]) + { + addResultToPackage = false; + } + } + else + { + if (compareValue < commonVars.getPASearch().filterValues[r]) + { + addResultToPackage = false; + } + } + } + } + } + } + + if (addResultToPackage && currentResult.isValid()) // only update if result is valid. + { + try + { + if (!doPASearch) + { + if ((commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.external) == 1) && (baseFileName != "")) + { + switch (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType)) + { + case (Int32)CommonVars.external_Type.svg: + writeSVG(currentResult, i, numberOfCases, tileHandling, col, row); + break; + default: + writeLayout(currentResult, i, numberOfCases, commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType), tileHandling, col, row); + break; + } + } + } + // resultPackage has its own locking. + resultPackage.Add(currentResult, 0); // disable retention of geometry given new write-during-run methodology. + } + catch (Exception ex) + { + string oops = ex.Message; + } + + } + + if ((!doPASearch) || (doPASearch && addResultToPackage)) + { + Interlocked.Increment(ref currentProgress); + if (doPASearch && Equals(resultPackage.getListOfResults().Count, commonVars.getPASearch().numberofPassCases)) + { + loopState.Stop(); + } + } + + forceRepaintFunc?.Invoke(); + + abortRunFuncMT?.Invoke(resultPackage, cancelSource, cancellationToken); + } + catch (OperationCanceledException) + { + resultPackage.setState(false); + commonVars.m_timer.Stop(); + commonVars.runAbort = false; // reset state to allow user to abort save of results. + sw.Stop(); + loopState.Stop(); + } + } + ); + } + catch (OperationCanceledException) + { + resultPackage.setState(false); + commonVars.runAbort = false; // reset state to allow user to abort save of results. + commonVars.m_timer.Stop(); + sw.Stop(); + } + catch (AggregateException) + { + commonVars.m_timer.Stop(); + sw.Stop(); + } + catch (Exception) + { + } + //t.Dispose(); // might be irrelevant now - commented out for testing. + commonVars.m_timer.Stop(); + commonVars.m_timer.Dispose(); + resultPackage.setRunTime(swTime); + sw.Stop(); + sw.Reset(); + } + + void doTileExtraction(Int32 col, Int32 row) + { + double tileXOffset = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colOffset); + double tileXSize = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colPitch); + double tileYOffset = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowOffset); + double tileYSize = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowPitch); + Path tileCutter = new Path(); + Int64 tileLeftX = (Int64)(tileXOffset + (col * tileXSize)) * CentralProperties.scaleFactorForOperation; + Int64 tileRightX = (Int64)(tileLeftX + (tileXSize * CentralProperties.scaleFactorForOperation)); + Int64 tileBottomY = (Int64)(tileYOffset + (row * tileYSize)) * CentralProperties.scaleFactorForOperation; + Int64 tileTopY = (Int64)(tileBottomY + (tileYSize * CentralProperties.scaleFactorForOperation)); + tileCutter.Add(new IntPoint(tileLeftX, tileBottomY)); + tileCutter.Add(new IntPoint(tileLeftX, tileTopY)); + tileCutter.Add(new IntPoint(tileRightX, tileTopY)); + tileCutter.Add(new IntPoint(tileRightX, tileBottomY)); + tileCutter.Add(new IntPoint(tileLeftX, tileBottomY)); + + for (Int32 layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + List polyHashCodes = new List(); + if (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(layer) == 1) + { + Paths result = new Paths(); + List extractedPolys = new List(); + // Get our layout for clipping. + Paths layout = new Paths(); // Use Paths since we have polygon islands to wrangle. + // fileData contains all of our polygons + for (Int32 poly = 0; poly < commonVars.getLayerSettings(layer).getFileData().Count(); poly++) + { + Path polyPath = GeoWrangler.pathFromPointF(commonVars.getLayerSettings(layer).getFileData()[poly], CentralProperties.scaleFactorForOperation); + string polyHash = Utils.GetMD5Hash(polyPath); + if (polyHashCodes.IndexOf(polyHash) == -1) + { + // Hash not found - assuming unique polygon. This is done to avoid impact of copy/paste fails in layout where + // totally coincident duplicate polygons cause the extracted tile to be empty. + // This avoids full overlaps causing complications in the Union used below to resolve partial overlaps. + layout.Add(polyPath.ToList()); + polyHashCodes.Add(polyHash); + } + } + + // We now use a Union() to merge any partially overlapping polys. + Clipper c = new Clipper(); + if (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.gCSEngine) == 0) + { + c.PreserveCollinear = true; // important - if we don't do this, we lose the fragmentation on straight edges. + } + else + { + c.PreserveCollinear = false; // since we'll be using the contour engine, we can simplify our geometry. + } + c.AddPaths(layout, PolyType.ptSubject, true); + c.Execute(ClipType.ctUnion, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero); + layout = result.ToList(); + result.Clear(); + + // Carve out our tile + c = new Clipper(); + if (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.gCSEngine) == 0) + { + c.PreserveCollinear = true; // important - if we don't do this, we lose the fragmentation on straight edges. + } + else + { + c.PreserveCollinear = false; // since we'll be using the contour engine, we can simplify our geometry. + } + c.AddPath(tileCutter, PolyType.ptClip, true); + c.AddPaths(layout, PolyType.ptSubject, true); + c.Execute(ClipType.ctIntersection, result); + + // Need to map output and downscale to floating points again. + // We might have more than one polygon in the result, so be careful. + double xCompensation = (double)tileLeftX / CentralProperties.scaleFactorForOperation; + double yCompensation = (double)tileBottomY / CentralProperties.scaleFactorForOperation; + + for (Int32 poly = 0; poly < result.Count(); poly++) + { + GeoLibPointF[] tempPoly = GeoWrangler.pointFFromPath(result[poly], CentralProperties.scaleFactorForOperation); + // move back to origin from tile location + Parallel.For(0, tempPoly.Length, (pt) => + // for (int pt = 0; pt < tempPoly.Length; pt++) + { + tempPoly[pt].X -= xCompensation; + tempPoly[pt].Y -= yCompensation; + }); + extractedPolys.Add(tempPoly); + } + + commonVars.getNonSimulationSettings().extractedTile[layer] = extractedPolys.ToList(); + } + } + } + + public void timeOfFlight(double swTime, bool doPASearch) + { + pTimeOfFlight(swTime, doPASearch); + } + + void pTimeOfFlight(double swTime, bool doPASearch) + { + // Update status bar with elapsed and predicted time. + try + { + if (swTime != 0.0) + { + Int32 numberOfCases = commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.nCases); + if (doPASearch) + { + numberOfCases = commonVars.getPASearch().numberofPassCases; + } + TimeSpan eT = TimeSpan.FromSeconds(swTime); + string statusLineString = eT.Seconds.ToString() + " s elapsed"; + if (eT.Minutes >= 1) + { + // We have minutes + statusLineString = eT.Minutes.ToString() + " m, " + statusLineString; + } + if (eT.Hours >= 1) + { + // We have hours. + statusLineString = eT.Hours.ToString() + " h, " + statusLineString; + } + + if (currentProgress != numberOfCases) + { + double completionTime = ((swTime / currentProgress) * (numberOfCases - currentProgress)); + TimeSpan cT = TimeSpan.FromSeconds(completionTime); + statusLineString += "; "; + + if (cT.Hours >= 1) + { + // We have hours. + statusLineString += cT.Hours.ToString() + " h"; + } + if (cT.Minutes >= 1) + { + if (cT.Hours >= 1) + { + statusLineString += ", "; + } + // We have minutes + statusLineString += cT.Minutes.ToString() + " m"; + } + if (!((cT.Minutes < 1) && (cT.Hours < 1))) + { + statusLineString += ", "; + } + statusLineString += cT.Seconds.ToString() + " s remaining"; + } + + string tmp; + if (commonVars.getFriendly()) + { + tmp = Utils.friendlyNumber(currentProgress) + "/" + Utils.friendlyNumber(numberOfCases); + } + else + { + tmp = currentProgress.ToString() + "/" + numberOfCases.ToString(); + } + + statusLineString += " => (" + tmp + ") complete"; + updateStatus?.Invoke(statusLineString); + } + } + catch (Exception) + { + // We don't care - this is a UI update call; non-critical. + } + } + + bool saveResults(Int32 numberOfCases, bool tileHandling, Int32 col, Int32 row) + { + string csvFileName = baseFileName; + if (tileHandling) + { + csvFileName += "_col" + col.ToString() + "_row" + row.ToString(); + } + + csvFileName += ".csv"; + + bool returnValue = false; + Int32 doneCases = resultPackage.getListOfResults().Count(); + int rows = doneCases + 4; + string[] stringList = new string[rows]; + + configProgress?.Invoke(0, doneCases); + // Create header for CSV output, if applicable + string headerString = "Run,"; + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.area) // area output + { + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.areaCalcModes.all) + { + headerString += "Total Area"; + } + else + { + headerString += "Minimum Area"; + } + } + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.enclosure_spacing_overlap) // spacing output + { + switch (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.subMode)) + { + case (int)CommonVars.spacingCalcModes.spacing: + case (int)CommonVars.spacingCalcModes.spacingOld: + headerString += "Spacing"; + break; + case (int)CommonVars.spacingCalcModes.enclosure: + case (int)CommonVars.spacingCalcModes.enclosureOld: + headerString += "Enclosure"; + break; + } + } + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.chord) // chord output + { + headerString += "AMinTopChord,AMinBottomChord,BMinLeftChord,BMinRightChord"; + } + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.angle) // angle output + { + headerString += "MinIntersectionAngle"; + } + for (Int32 layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + if (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.enabled) == 1) + { + headerString += ","; + for (int i = 0; i < CommonVars.csvHeader.Length; i++) + { + headerString += CommonVars.csvHeader[i] + layer.ToString(); + if (i != CommonVars.csvHeader.Length - 1) + { + headerString += ","; + } + } + } + } + stringList[0] = headerString; + commonVars.runAbort = false; + + + try + { + summaryFile(tileHandling, col, row); + } + catch (Exception) + { + // MessageBox.Show(ex.Message); + } + + string statusLine = "No CSV or external files written per job settings. All done."; + + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1) + { + // Set our parallel task options based on user settings. + ParallelOptions po = new ParallelOptions(); + // Attempt at parallelism. + CancellationTokenSource cancelSource = new CancellationTokenSource(); + CancellationToken cancellationToken = cancelSource.Token; + + string statusString = "Compiling CSV file for results"; + updateStatus?.Invoke(statusString); + int counter = 0; + Parallel.For(0, doneCases, (resultEntry, loopState) => + { + try + { + if (resultPackage.getResult(resultEntry).isValid()) + { + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1) + { + // result can be a CSV string for multiple values - header is aligned above + string csvString = resultEntry.ToString() + "," + resultPackage.getResult(resultEntry).getResult(); + for (Int32 layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + if (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.enabled) == 1) + { + csvString += ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.svar, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.tvar, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.lwr, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getSeed(Results.fields_i.lwrs, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.lwr2, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getSeed(Results.fields_i.lwr2s, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.htip, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.vtip, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.icv, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.ocv, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.olx, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.oly, layer).ToString() + ","; + csvString += resultPackage.getResult(resultEntry).getField(Results.fields_d.wob, layer).ToString(); + } + } + stringList[resultEntry + 1] = csvString; + } + } + Interlocked.Increment(ref counter); + abortCSVFunc?.Invoke(cancelSource, cancellationToken); + } + catch (OperationCanceledException) + { + commonVars.runAbort = false; + commonVars.cancelling = false; + loopState.Stop(); + } + catch (Exception) + { + } + + // stepProgress?.Invoke(); + // directProgress?.Invoke(resultEntry, doneCases); + }); + // We need to warn here if the project shows a changed state, because replay will be affected. + if (commonVars.isChanged()) + { + ErrorReporter.showMessage_OK("Project should be saved to ensure replay can be used with this CSV file.", "Warning"); + } + + // Append hashes to the stringList to allow replay to warn against mismatch. + // Ensure the hashes are current. + string[] oldHashes = commonVars.getHashes(); + commonVars.setHashes(); + stringList[doneCases + 1] = "lHash," + commonVars.getHash(CommonVars.hashes.settings); + stringList[doneCases + 2] = "eHash," + commonVars.getHash(CommonVars.hashes.entropy); + stringList[doneCases + 3] = "gHash," + commonVars.getHash(CommonVars.hashes.gc); + commonVars.setHashes(oldHashes); + + File.WriteAllLines(csvFileName, stringList); + + string tmp; + if (commonVars.getFriendly()) + { + tmp = Utils.friendlyNumber(counter); + } + else + { + tmp = counter.ToString(); + } + statusLine = tmp + " results saved to CSV file"; + } + + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.external) == 1) + { + if (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1) + { + statusLine += " and shapes "; + } + else + { + statusLine = "Shapes "; + } + + statusLine += "saved to " + commonVars.getExternalTypes()[commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType)] + " files"; + } + + updateStatus?.Invoke(statusLine); + forceRepaintFunc?.Invoke(); + return returnValue; + } + + void writeSVG(Results currentResult, int resultEntry, int numberOfCases, bool tileHandling, int col, int row) + { + string svgFileName = baseFileName; + if (tileHandling) + { + svgFileName += "_col" + col.ToString() + "_row" + row.ToString(); + } + + string paddingString = "D" + numberOfCases.ToString().Length.ToString(); // count chars in the number of cases as a string, use that to define padding. + svgFileName += "_run" + resultEntry.ToString(paddingString) + ".svg"; + + SVGBuilder svg = new SVGBuilder(); + + // Inputs + for (Int32 previewShapeIndex = 0; previewShapeIndex < currentResult.getPreviewShapes().Count(); previewShapeIndex++) + { + svg.style.brushClr = commonVars.getColors().simPreviewColors[previewShapeIndex]; // Color.FromArgb(0x10, 0, 0, 0x9c); + svg.style.penClr = commonVars.getColors().simPreviewColors[previewShapeIndex]; //Color.FromArgb(0xd3, 0xd3, 0xda); + // Overloaded operator can handle List + svg.AddPolygons(currentResult.getPreviewShapes()[previewShapeIndex]); + } + + // Result + for (Int32 poly = 0; poly < currentResult.getPoints().Count(); poly++) + { + svg.style.brushClr = commonVars.getColors().resultColors[poly]; // Color.FromArgb(0x10, 0x9c, 0, 0); + svg.style.penClr = commonVars.getColors().resultColors[poly]; // Color.FromArgb(0xff, 0xa0, 0x7a); + svg.AddPolygons(currentResult.getPoints()[poly]); // results from MC evaluation + } + + svg.SaveToFile(svgFileName); + } + + void writeLayout(Results currentResult, int resultEntry, int numberOfCases, int type, bool tileHandling, int col, int row) + { + string layoutFileName = baseFileName; + + if (tileHandling) + { + layoutFileName += "_col" + col.ToString() + "_row" + row.ToString(); + } + + string paddingString = "D" + numberOfCases.ToString().Length.ToString(); // count chars in the number of cases as a string, use that to define padding. + layoutFileName += "_run" + resultEntry.ToString(paddingString); + + int scale = 100; // for 0.01 nm resolution + GeoCore g = new GeoCore(); + g.reset(); + GCDrawingfield drawing_ = new GCDrawingfield(""); + drawing_.accyear = (short)DateTime.Now.Year; + drawing_.accmonth = (short)DateTime.Now.Month; + drawing_.accday = (short)DateTime.Now.Day; + drawing_.acchour = (short)DateTime.Now.Hour; + drawing_.accmin = (short)DateTime.Now.Minute; + drawing_.accsec = (short)DateTime.Now.Second; + drawing_.modyear = (short)DateTime.Now.Year; + drawing_.modmonth = (short)DateTime.Now.Month; + drawing_.modday = (short)DateTime.Now.Day; + drawing_.modhour = (short)DateTime.Now.Hour; + drawing_.modmin = (short)DateTime.Now.Minute; + drawing_.modsec = (short)DateTime.Now.Second; + drawing_.databaseunits = 1000 * scale; + drawing_.userunits = 0.001 / scale; + drawing_.libname = "variance"; + + GCCell gcell_root = drawing_.addCell(); + gcell_root.accyear = (short)DateTime.Now.Year; + gcell_root.accmonth = (short)DateTime.Now.Month; + gcell_root.accday = (short)DateTime.Now.Day; + gcell_root.acchour = (short)DateTime.Now.Hour; + gcell_root.accmin = (short)DateTime.Now.Minute; + gcell_root.accsec = (short)DateTime.Now.Second; + gcell_root.modyear = (short)DateTime.Now.Year; + gcell_root.modmonth = (short)DateTime.Now.Month; + gcell_root.modday = (short)DateTime.Now.Day; + gcell_root.modhour = (short)DateTime.Now.Hour; + gcell_root.modmin = (short)DateTime.Now.Minute; + gcell_root.modsec = (short)DateTime.Now.Second; + gcell_root.cellName = "result" + resultEntry.ToString(); + + List layers = new List(); + // Input shapes. + for (Int32 previewShapeIndex = 0; previewShapeIndex < currentResult.getPreviewShapes().Count(); previewShapeIndex++) + { + // Get the geometry for the shape + List polys = currentResult.getPreviewShapes()[previewShapeIndex]; + + // Find our source layer value that we need to write the geometry into the correct geoCore layer. + int layerIndex = currentResult.getLayerIndex(previewShapeIndex); + if (layers.IndexOf(layerIndex) == -1) + { + layers.Add(layerIndex); + // Register layer names with geoCore. Need to compensate the 1-index for the layer registration. + g.addLayerName("L" + (layerIndex + 1).ToString() + "D0", commonVars.getLayerSettings(layerIndex).getString(EntropyLayerSettings.properties_s.name)); + } + + for (int poly = 0; poly < polys.Count; poly++) + { + int polyLength = polys[poly].Length; + if (polyLength > 2) + { + GeoLibPoint[] ePoly = new GeoLibPoint[polyLength]; + Parallel.For(0, polyLength, (pt) => + // for (int pt = 0; pt < polyLength; pt++) + { + ePoly[pt] = new GeoLibPoint((int)(polys[poly][pt].X * scale), (int)(polys[poly][pt].Y * scale)); + }); + + gcell_root.addPolygon(ePoly.ToArray(), layerIndex + 1, 0); // layer is 1-index based for output, so need to offset value accordingly. + } + } + } + + // Get the geometry for the result + List rpolys = currentResult.getPoints(); + + for (int poly = 0; poly < rpolys.Count; poly++) + { + int layerNum = CentralProperties.maxLayersForMC + poly + 1; + g.addLayerName("L" + layerNum.ToString() + "D0", "result" + poly.ToString()); + int polyLength = rpolys[poly].Length; + if (polyLength > 2) + { + GeoLibPoint[] ePoly = new GeoLibPoint[polyLength]; + Parallel.For(0, polyLength, (pt) => + // for (int pt = 0; pt < polyLength; pt++) + { + ePoly[pt] = new GeoLibPoint((int)(rpolys[poly][pt].X * scale), (int)(rpolys[poly][pt].Y * scale)); + }); + + gcell_root.addPolygon(ePoly.ToArray(), layerNum, 0); // layer is 1-index based for output, so need to offset value accordingly. + } + } + + g.setDrawing(drawing_); + g.setValid(true); + + switch (type) + { + case (int)CommonVars.external_Type.gds: + gds.gdsWriter gw = new gds.gdsWriter(g, layoutFileName + ".gds"); + gw.save(); + break; + case (int)CommonVars.external_Type.oas: + oasis.oasWriter ow = new oasis.oasWriter(g, layoutFileName + ".oas"); + ow.save(); + break; + + } + } + + void summaryFile(bool tileHandling, int col, int row) + { + string internalFileName = baseFileName; // (remove the .csv from the string) + if (tileHandling) + { + internalFileName += "_col" + col.ToString() + "_row" + row.ToString(); + } + + // Force an evaluation. + resultPackage.getMeanAndStdDev(); + // Create our summaryFile string, assuming it is needed. + // This was simplier before, but now user can avoid CSV creation and will instead select the summary output filename (txt) + string summaryFile_ = internalFileName + "_summary.txt"; + string csvFileName = internalFileName + ".csv"; + List linesToWrite = new List(); + + // Results first + // Write the results first. + linesToWrite.Add(commonVars.titleText); + linesToWrite.Add("Results summary for job: " + csvFileName + " run on : " + System.DateTime.Today.ToLocalTime().ToLongDateString() + ". Runtime: " + resultPackage.runTime.ToString("0.##") + " seconds"); + if (Debugger.IsAttached == true) + { + linesToWrite.Add("Run under debugger : performance was lower"); + } + + linesToWrite.Add(""); + commonVars.getBooleanEquation(linesToWrite); + + linesToWrite.Add(""); + for (int resultGroup = 0; resultGroup < resultPackage.getValues(SimResultPackage.properties.mean).Length; resultGroup++) + { + string tempString = "result " + resultGroup.ToString() + " mean"; + if (!resultPackage.nonGaussianInput) + { + tempString += " and standard deviation"; + } + tempString += " for " + resultPackage.getListOfResults().Count().ToString() + " cases:"; + tempString += " x: " + resultPackage.getValue(SimResultPackage.properties.mean, resultGroup).ToString("0.##"); + if (!resultPackage.nonGaussianInput) + { + tempString += ", s: " + resultPackage.getValue(SimResultPackage.properties.stdDev, resultGroup).ToString("0.##"); + } + else + { + tempString += ". Non-Gaussian inputs require offline analysis of CSV file."; + } + linesToWrite.Add(tempString); + } + + linesToWrite.Add(""); + + linesToWrite.AddRange(resultPackage.getHistograms()); + + // Simulation Settings + linesToWrite.Add(""); + linesToWrite.Add("Layer settings for job"); + linesToWrite.Add(""); + for (int layer = 0; layer < commonVars.getListOfSettings().Count(); layer++) + { + commonVars.getLayerSettings(layer, ref linesToWrite, onlyActive: true); + } + + commonVars.getSimulationSettings(linesToWrite); + commonVars.getDOESettings(linesToWrite); + + try + { + File.WriteAllLines(summaryFile_, linesToWrite); + } + catch (Exception ex) + { + ErrorReporter.showMessage_OK(ex.ToString(), "Exception"); + } + } + + public void EntropyRun(Int32 numberOfCases, string csvFile, bool useThreads, bool doPASearch, bool setJobSettings = false, ChaosSettings loadedJobSettings = null, int replayRow = 0, int replayCol = 0) // event handler will call this with 1 and null as the csvFile + { + this.replayCol = replayCol; + this.replayRow = replayRow; + + useLoadedSettings = setJobSettings; + + // Replay mode + if (useLoadedSettings) + { + loadedJobSettings_ = loadedJobSettings; + numberOfCases = 1; + csvFile = null; + } + pEntropyRun(numberOfCases, csvFile, useThreads, doPASearch); + } + + void pEntropyRun(Int32 numberOfCases, string csvFile, bool useThreads, bool doPASearch) + { + reset(); + // Apply PA search values to settings. + // This mode doesn't support replay, so checksum is not important. + if (doPASearch) + { + commonVars.getPASearch().applySearchValues(ref commonVars); + numberOfCases = Int32.MaxValue; // we're going to run until we find the number of pass cases the user requested. + } + + // Check for non-Gaussian inputs and set the flag. + nonGaussianInput = commonVars.nonGaussianInputs(); + + // Warn user if the setup could be problematic. + if ((numberOfCases > 1) && !doPASearch && nonGaussianInput && (commonVars.getSimulationSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 0)) + { + ErrorReporter.showMessage_OK("Non-Gaussian inputs with no CSV requested!\r\nNon-Gaussian inputs require offline analysis of simulation results, through CSV", "Warning"); + } + + string emailString = ""; + clearAbortFlagFunc?.Invoke(); + bool simState = true; + bool tileHandling = false; + bool listOfTiles = false; + Int32 listOfTilesCount = 0; + Int32 startRow = 0; + Int32 endRow = 1; + Int32 startCol = 0; + Int32 endCol = 1; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(i) == 1) + { + tileHandling = true; + break; + } + } + if (tileHandling) + { + // We have some tiles to run. + if (commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.uTileList) == 1) + { + listOfTiles = true; + if (numberOfCases == 1) + { + // preview mode + listOfTilesCount = 1; + } + else + { + listOfTilesCount = commonVars.getSimulationSettings().getDOESettings().getTileList_ColRow().Count(); + } + } + else + { + if (commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.sTile) == 0) + { + if (csvFile != null) // avoid doing something stupid for a preview call. + { + // We have more than one tile to run. + endCol = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.cols); + endRow = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.rows); + } + } + else + { + // Convert from UI 1-based to 0-based indexing. + startCol = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.sTileCol) - 1; + startRow = commonVars.getSimulationSettings().getDOESettings().getInt(DOESettings.properties_i.sTileRow) - 1; + endCol = startCol + 1; + endRow = startRow + 1; + } + } + } + + Int32 row = 0; + Int32 col = 0; + + if (useLoadedSettings) + { + row = replayRow; + col = replayCol; + } + + if (!tileHandling) + { + try + { + simState = entropyRunCore(numberOfCases, row, col, csvFile, useThreads, tileHandling, implantMode: false, doPASearch); + if (!simState) + { + emailString = "Variance run aborted : " + commonVars.projectFileName; + } + else + { + emailString = "Variance run completed : " + commonVars.projectFileName; + } + } + catch (Exception) + { + // Don't care about exceptions - we handle them internally. + } + // Assume user error if perJob is set and not onCompletion. + if ((commonVars.getNonSimulationSettings().emailOnCompletion || commonVars.getNonSimulationSettings().emailPerJob) && (numberOfCases > 1)) + { + Email.Send(commonVars.getNonSimulationSettings().host, commonVars.getNonSimulationSettings().port, commonVars.getNonSimulationSettings().ssl, emailString, lastSimResultsOverview, commonVars.getNonSimulationSettings().emailAddress, commonVars.getNonSimulationSettings().emailPwd); + } + } + else + { + if (listOfTiles) + { + for (Int32 tile = 0; tile < listOfTilesCount; tile++) + { + try + { + int tileRow = commonVars.getSimulationSettings().getDOESettings().getTileList_Value(tile, 1); + int tileCol = commonVars.getSimulationSettings().getDOESettings().getTileList_Value(tile, 0); + simState = entropyRunCore(numberOfCases, tileRow, tileCol, csvFile, useThreads, tileHandling, implantMode: false, doPASearch); + if (!simState) + { + if (abortAllRunsFunc != null) + { + bool really = true; + // Only ask to abort all runs if we have multiple runs and more runs pending. + if ((listOfTilesCount > 1) && (tile != listOfTilesCount - 1)) + { + really = abortAllRunsFunc(); + } + if (really) + { + listOfTilesCount = tile; + // Email notification + if (commonVars.getNonSimulationSettings().emailPerJob) + { + emailString = "Variance run aborted for tile " + tileCol.ToString() + "," + tileRow.ToString(); + } + } + } + } + else + { + emailString = "Variance run completed for tile " + tileCol.ToString() + "," + tileRow.ToString(); + } + } + catch (Exception) + { + // Don't care about exceptions - we handle them internally. + } + if (commonVars.getNonSimulationSettings().emailPerJob) + { + Email.Send(commonVars.getNonSimulationSettings().host, commonVars.getNonSimulationSettings().port, commonVars.getNonSimulationSettings().ssl, emailString, lastSimResultsOverview, commonVars.getNonSimulationSettings().emailAddress, commonVars.getNonSimulationSettings().emailPwd); + } + } + } + else + { + row = startRow; + col = startCol; + bool ending = false; + while (row < endRow) + { + while (col < endCol) + { + try + { + simState = entropyRunCore(numberOfCases, row, col, csvFile, useThreads, tileHandling, implantMode: false, doPASearch); + if (!simState) + { + if (abortAllRunsFunc != null) + { + bool really = true; + // Only ask to abort all runs if we have more runs pending. + if ((row != endRow - 1) && (col != endCol - 1)) + { + really = abortAllRunsFunc(); + } + if (really) + { + ending = true; + col = endCol; + row = endRow; + if (commonVars.getNonSimulationSettings().emailPerJob) + { + emailString = "Variance run aborted for tile " + col.ToString() + "," + row.ToString(); + } + } + } + } + else + { + emailString = "Variance run completed for tile " + col.ToString() + "," + row.ToString(); + } + } + catch (Exception) + { + // Don't care about exceptions - we handle them internally. + } + if (commonVars.getNonSimulationSettings().emailPerJob) + { + Email.Send(commonVars.getNonSimulationSettings().host, commonVars.getNonSimulationSettings().port, commonVars.getNonSimulationSettings().ssl, emailString, lastSimResultsOverview, commonVars.getNonSimulationSettings().emailAddress, commonVars.getNonSimulationSettings().emailPwd); + } + col++; + } + row++; + if (!ending) + { + col = startCol; // reset column + } + } + } + if (tileHandling && (commonVars.getNonSimulationSettings().emailOnCompletion)) + { + Email.Send(commonVars.getNonSimulationSettings().host, commonVars.getNonSimulationSettings().port, commonVars.getNonSimulationSettings().ssl, "Variance batch complete: " + commonVars.projectFileName, lastSimResultsOverview, commonVars.getNonSimulationSettings().emailAddress, commonVars.getNonSimulationSettings().emailPwd); + } + } + + // Restore original values to settings. + if (doPASearch) + { + commonVars.getPASearch().removeSearchValues(ref commonVars); + } + + postSimUIFunc?.Invoke(); + } + + Results EntropyEval(bool previewMode, bool doPASearch, Int32 currentRow, Int32 currentCol, ChaosSettings currentJobSettings) + { + string value = "N/A"; + List listOfPoints; + GeoLibPointF[] points; + + // Replay mode + if (useLoadedSettings) + { + currentJobSettings = loadedJobSettings_; + } + + // Number crunching goes here. + List simShapes = new List(); + for (Int32 layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + // Show our variations - set preview to false + // We share our jobSettings in case of correlated settings between levels. + // currentRow/Col ignored in previewShape for non-tiled layout cases. + // For omitted layers, we just set a blank entry. Slightly ugly, but it works. + if (commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.omit) == 1) + { + simShapes.Add(new PreviewShape()); + } + else + { + simShapes.Add(new PreviewShape( + commonVars:commonVars, + jobSettings_: currentJobSettings, + settingsIndex: layer, + subShapeIndex: commonVars.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.subShapeIndex), + mode: 1, + doPASearch: doPASearch, + previewMode: false, + currentRow: currentRow, + currentCol: currentCol) + ); + } + } + + ChaosEngine currentJobEngine = new ChaosEngine(commonVars, simShapes, previewMode); + + listOfPoints = new List(); + if (currentJobEngine.isValid()) + { + value = currentJobEngine.getResult(); + for (Int32 listMember = 0; listMember < currentJobEngine.getPaths().Count(); listMember++) + { + // Check whether we need to manually close our shape or not, also only for the area case. + int length = currentJobEngine.getPaths()[listMember].Count(); + int arraySize = length; + if ((commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.area) && (currentJobEngine.getPaths()[listMember][currentJobEngine.getPaths()[listMember].Count() - 1] != currentJobEngine.getPaths()[listMember][0])) + { + arraySize++; + } + points = new GeoLibPointF[arraySize]; + + Parallel.For(0, length, (i) => + // for (Int32 i = 0; i < length; i++) + { + // The cast below is important - if this is missing or screwed up, we get clamped to integers and the viewport representation is fouled up. + points[i] = new GeoLibPointF(((float)currentJobEngine.getPaths()[listMember][i].X / CentralProperties.scaleFactorForOperation), + ((float)currentJobEngine.getPaths()[listMember][i].Y / CentralProperties.scaleFactorForOperation)); + }); + // Close the shape only if we have an area calculation; for other cases we expect lines. + if ((commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.oType) == (int)CommonVars.calcModes.area) && (points[points.Count() - 1] != points[0])) + { + points[points.Count() - 1] = points[0]; + } + listOfPoints.Add(points); + } + } + else + { + points = new GeoLibPointF[1]; + points[0] = new GeoLibPointF(0.0f, 0.0f); + listOfPoints.Add(points); + } + + Results evalResults = new Results(); + evalResults.setSimShapes(simShapes); + evalResults.setResult(value); + evalResults.setPoints(listOfPoints); + evalResults.setFields(Results.fields_d.svar, currentJobSettings.getValues(ChaosSettings.properties.CDUSVar)); + evalResults.setFields(Results.fields_d.tvar, currentJobSettings.getValues(ChaosSettings.properties.CDUTVar)); + evalResults.setFields(Results.fields_d.lwr, currentJobSettings.getValues(ChaosSettings.properties.LWRVar)); + evalResults.setFields(Results.fields_d.lwr2, currentJobSettings.getValues(ChaosSettings.properties.LWR2Var)); + evalResults.setFields(Results.fields_d.htip, currentJobSettings.getValues(ChaosSettings.properties.hTipBiasVar)); + evalResults.setFields(Results.fields_d.vtip, currentJobSettings.getValues(ChaosSettings.properties.vTipBiasVar)); + evalResults.setFields(Results.fields_d.icv, currentJobSettings.getValues(ChaosSettings.properties.icVar)); + evalResults.setFields(Results.fields_d.ocv, currentJobSettings.getValues(ChaosSettings.properties.ocVar)); + evalResults.setFields(Results.fields_d.olx, currentJobSettings.getValues(ChaosSettings.properties.overlayX)); + evalResults.setFields(Results.fields_d.oly, currentJobSettings.getValues(ChaosSettings.properties.overlayY)); + evalResults.setFields(Results.fields_d.wob, currentJobSettings.getValues(ChaosSettings.properties.wobbleVar)); + evalResults.setSeeds(Results.fields_i.lwrs, currentJobSettings.getInts(ChaosSettings.ints.lwrSeed)); + evalResults.setSeeds(Results.fields_i.lwr2s, currentJobSettings.getInts(ChaosSettings.ints.lwr2Seed)); + evalResults.setValid(currentJobEngine.isValid()); + evalResults.genPreviewShapes(); + return evalResults; + } + } +} \ No newline at end of file diff --git a/Common/Variance/entropy/entropy_implant.cs b/Common/Variance/entropy/entropy_implant.cs new file mode 100644 index 0000000..8f2fbed --- /dev/null +++ b/Common/Variance/entropy/entropy_implant.cs @@ -0,0 +1,696 @@ +using Error; +using geoCoreLib; +using geoLib; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using utility; + +namespace Variance +{ + public partial class Entropy + { + public delegate void forceImplantRepaint(); + public forceImplantRepaint forceImplantRepaintFunc { get; set; } + + public delegate void updateImplantSimUIMT(); + public updateSimUIMT updateImplantSimUIMTFunc { get; set; } + + public delegate void updateImplantSimUI(SimResultPackage implantResultPackage, string resultString); + public updateSimUI updateImplantSimUIFunc { get; set; } + + public delegate void implantSimRunningUI(); + public simRunningUI implantSimRunningUIFunc { get; set; } + + SimResultPackage implantResultPackage; + + public SimResultPackage getImplantResultPackage() + { + return pGetImplantResultPackage(); + } + + SimResultPackage pGetImplantResultPackage() + { + return implantResultPackage; + } + + Sampler_Implant sampler_implant; + + void setSampler_implant(int numberOfCases, bool previewMode) + { + sampler_implant = new Sampler_Implant(numberOfCases, previewMode, commonVars.getImplantSimulationSettings()); + string tmp; + if (commonVars.getFriendly()) + { + tmp = Utils.friendlyNumber(sampler_implant.getDimensions() * numberOfCases); + } + else + { + tmp = (sampler_implant.getDimensions() * numberOfCases).ToString(); + } + updateStatus?.Invoke("Computing " + tmp + " samples."); + sampler_implant.updateProgressBarFunc = uiProgressBarWrapper; + } + + void entropyRunCore_implant_singleThread(bool previewMode, Int32 numberOfCases) + { + Int32 numberOfResultsFields = 1; + // Let's sample this + Int32 sampleRate = 100; + + setSampler_implant(numberOfCases, previewMode); + sampler_implant.sample(false); + sw.Start(); + + implantResultPackage = new SimResultPackage(ref varianceContext.implantPreviewLock, numberOfCases, numberOfResultsFields); + sw.Reset(); + for (Int32 i = 0; i < numberOfCases; i++) + { + sw.Start(); + currentProgress = i + 1; + try + { + // Get the results from the implant calc engine. + implantResultPackage.Add(entropyEval_implant(previewMode, sampler_implant.getSample(i))); + + if ((numberOfCases == 1) || (currentProgress % sampleRate == 0)) + { + // Update the preview configuration. + if (implantResultPackage.getImplantResult(i).isValid()) + { + if (numberOfCases > 1) + { + try + { + resultString = implantResultPackage.getMeanAndStdDev(); + } + catch (Exception) + { + // Non-critical if an exception is raised. Ignore and carry on. + } + } + else + { + // Need to workaround some oddness here. The .ToString() calls below seemed to turn "0.0" into blanks. + string tmp = Convert.ToDouble(implantResultPackage.getImplantResult(i).getResult()).ToString("0.##"); + resultString += tmp + ","; + + tmp = Convert.ToDouble(implantResultPackage.getImplantResult(i).getMin()).ToString("0.##"); + resultString += tmp + ","; + + tmp = Convert.ToDouble(implantResultPackage.getImplantResult(i).getMax()).ToString("0.##"); + resultString += tmp; + } + updateImplantSimUIFunc?.Invoke(false, implantResultPackage, resultString); + } + // Force redraw. We could use the progress bar to repaint, though. + // Note that this is an ugly hack to also ensure we collect stop button presses. + forceImplantRepaintFunc?.Invoke(); + } + } + catch (Exception) + { + // MessageBox.Show("MCRun() had an issue, aborting and saving results so far: " + MCRE.ToString(), "Oops", MessageBoxButtons.OK); + // Reject the case - something happened. + } + // Nudge progress bar. + if (numberOfCases > 1) + { + timeOfFlight_implant(sw.Elapsed.TotalSeconds); + stepProgress?.Invoke(); + } + + // Check if user cancelled. + if (abortRunFunc != null) + { + abortRunFunc(); + if (commonVars.runAbort) + { + sw.Stop(); + implantResultPackage.setState(false); + commonVars.runAbort = false; // reset state to allow user to abort save of results. + break; + } + } + } + + implantResultPackage.setRunTime(sw.Elapsed.TotalSeconds); + sw.Stop(); + } + + void entropyRunCore_implant_multipleThread(bool previewMode, Int32 numberOfCases) + { + setSampler_implant(numberOfCases, previewMode); + sampler.sample(true); + + Int32 numberOfResultsFields = 1; + + implantResultPackage = new SimResultPackage(ref varianceContext.implantPreviewLock, numberOfCases, numberOfResultsFields); + + multithreadWarningFunc?.Invoke(); + + commonVars.m_timer = new System.Timers.Timer(); + // Set up timers for the UI refresh + commonVars.m_timer.AutoReset = true; + commonVars.m_timer.Interval = CentralProperties.timer_interval; + updateImplantSimUIMTFunc?.Invoke(); + commonVars.m_timer.Start(); + + // Set our parallel task options based on user settings. + ParallelOptions po = new ParallelOptions(); + // Attempt at parallelism. + CancellationTokenSource cancelSource = new CancellationTokenSource(); + CancellationToken cancellationToken = cancelSource.Token; + if (varianceContext.numberOfThreads == -1) + { + po.MaxDegreeOfParallelism = commonVars.HTCount; + } + else + { + po.MaxDegreeOfParallelism = varianceContext.numberOfThreads; + } + + if (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.greedy) == 0) + { + if (po.MaxDegreeOfParallelism > 1) // avoid setting to 0 + { + po.MaxDegreeOfParallelism -= 1; + } + } + + /* // Removing as seems to not be necessary, but leaving code in place in case we need to restore this for some reason. + // Run a task to enable cancelling from another thread. + Task.Factory.StartNew(() => + { + if (abortRunFunc != null) + { + abortRunFunc(); + if (commonVars.runAbort) + { + cancelSource.Cancel(); + } + } + }); + */ + + try + { + Parallel.For(0, numberOfCases, po, (i, loopState) => + { + Results_implant currentResult = new Results_implant(); + try + { + currentResult = entropyEval_implant(previewMode, sampler_implant.getSample(i)); + + if (currentResult.isValid()) // only update if result is valid. + { + try + { + { + if ((commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.external) == 1) && (baseFileName != "")) + { + switch (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType)) + { + case (Int32)CommonVars.external_Type.svg: + writeSVG(currentResult, i, numberOfCases); + break; + default: + writeLayout_implant(currentResult, i, numberOfCases, commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType)); + break; + } + } + implantResultPackage.Add(currentResult); + } + } + catch (Exception ex) + { + string oops = ex.Message; + } + + } + Interlocked.Increment(ref currentProgress); + + forceImplantRepaintFunc?.Invoke(); + + abortRunFuncMT?.Invoke(implantResultPackage, cancelSource, cancellationToken); + } + catch (OperationCanceledException) + { + implantResultPackage.setState(false); + commonVars.m_timer.Stop(); + commonVars.runAbort = false; // reset state to allow user to abort save of results. + sw.Stop(); + loopState.Stop(); + } + } + ); + } + catch (OperationCanceledException) + { + implantResultPackage.setState(false); + commonVars.runAbort = false; // reset state to allow user to abort save of results. + commonVars.m_timer.Stop(); + sw.Stop(); + } + catch (AggregateException) + { + commonVars.m_timer.Stop(); + sw.Stop(); + } + catch (Exception) + { + } + //t.Dispose(); // might be irrelevant now - commented out for testing. + commonVars.m_timer.Stop(); + commonVars.m_timer.Dispose(); + implantResultPackage.setRunTime(swTime); + sw.Stop(); + sw.Reset(); + } + + Results_implant entropyEval_implant(bool previewMode, ChaosSettings_implant currentJobSettings) + { + // UI handler has already applied 'accuracy' to the resolution and angular resolution values. + + ChaosEngine_implant currentJobEngine = new ChaosEngine_implant(currentJobSettings, commonVars.getImplantSimulationSettings(), commonVars.getImplantSettings()); + + Results_implant evalResults = new Results_implant(); + + if (currentJobEngine.isValid()) + { + evalResults.setResult(currentJobEngine.getResult()); + evalResults.setMin(currentJobEngine.getMin()); + evalResults.setMax(currentJobEngine.getMax()); + evalResults.resistWidthVar = currentJobSettings.getValue(ChaosSettings_implant.properties.resistCDVar); + evalResults.resistHeightVar = currentJobSettings.getValue(ChaosSettings_implant.properties.resistHeightVar); + evalResults.resistCRRVar = currentJobSettings.getValue(ChaosSettings_implant.properties.resistTopCRRVar); + evalResults.tiltVar = currentJobSettings.getValue(ChaosSettings_implant.properties.tiltVar); + evalResults.twistVar = currentJobSettings.getValue(ChaosSettings_implant.properties.twistVar); + evalResults.setResistShapes(commonVars.getColors(), currentJobEngine.getGeom(), currentJobEngine.getBGGeom(), currentJobEngine.getShadow(), currentJobEngine.getMinShadow(), currentJobEngine.getMaxShadow()); + evalResults.setValid(currentJobEngine.isValid()); + } + return evalResults; + } + + public void entropyRun_implant(Int32 numberOfCases, string csvFile, bool useThreads) + { + pEntropyRun_implant(numberOfCases, csvFile, useThreads); + } + + void pEntropyRun_implant(Int32 numberOfCases, string csvFile, bool useThreads) + { + reset(); + clearAbortFlagFunc?.Invoke(); + bool simState = true; + string emailString = ""; + + simState = entropyRunCore(numberOfCases, row: 0, col: 0, csvFile, useThreads, tileHandling: false, implantMode: true, doPASearch: false); + if (!simState) + { + emailString = "Implant run aborted"; + } + else + { + emailString = "Implant run completed"; + } + // Assume user error if perJob is set and not onCompletion. + // We'll use simulationSettings here just because legacy put the settings there and it's the easiest option. + if (commonVars.getNonSimulationSettings().emailOnCompletion && (numberOfCases > 1)) + { + Email.Send(commonVars.getNonSimulationSettings().host, commonVars.getNonSimulationSettings().port, commonVars.getNonSimulationSettings().ssl, emailString, lastSimResultsOverview, commonVars.getNonSimulationSettings().emailAddress, commonVars.getNonSimulationSettings().emailPwd); + } + + if (numberOfCases > 1) + { + implantResultPackage.getMeanAndStdDev(); + updateStatus?.Invoke(lastSimResultsOverview); + } + + postSimUIFunc?.Invoke(); + } + + public void timeOfFlight_implant(double swTime) + { + pTimeOfFlight_implant(swTime); + } + + void pTimeOfFlight_implant(double swTime) + { + // Update status bar with elapsed and predicted time. + try + { + if (swTime != 0.0) + { + int numberOfCases = commonVars.getImplantSimulationSettings().getValue(EntropySettings.properties_i.nCases); + + TimeSpan eT = TimeSpan.FromSeconds(swTime); + string statusLineString = eT.Seconds.ToString() + " s elapsed"; + if (eT.Minutes >= 1) + { + // We have minutes + statusLineString = eT.Minutes.ToString() + " m, " + statusLineString; + } + if (eT.Hours >= 1) + { + // We have hours. + statusLineString = eT.Hours.ToString() + " h, " + statusLineString; + } + + if (currentProgress != numberOfCases) + { + double completionTime = ((swTime / currentProgress) * numberOfCases - currentProgress); + TimeSpan cT = TimeSpan.FromSeconds(completionTime); + statusLineString += "; "; + + if (cT.Hours >= 1) + { + // We have hours. + statusLineString += cT.Hours.ToString() + " h"; + } + if (cT.Minutes >= 1) + { + if (cT.Hours >= 1) + { + statusLineString += ", "; + } + // We have minutes + statusLineString += cT.Minutes.ToString() + " m"; + } + if (!((cT.Minutes < 1) && (cT.Hours < 1))) + { + statusLineString += ", "; + } + statusLineString += cT.Seconds.ToString() + " s remaining"; + } + + string tmp; + if (commonVars.getFriendly()) + { + tmp = Utils.friendlyNumber(currentProgress) + "/" + Utils.friendlyNumber(numberOfCases); + } + else + { + tmp = currentProgress.ToString() + "/" + numberOfCases.ToString(); + } + + statusLineString += " => (" + tmp + ") complete"; + updateStatus?.Invoke(statusLineString); + } + } + catch (Exception) + { + // We don't care - this is a UI update call; non-critical. + } + } + + bool saveResults_implant(Int32 numberOfCases) + { + string csvFileName = baseFileName; + csvFileName += ".csv"; + + bool returnValue = false; + + Int32 doneCases = implantResultPackage.getListOfResults_implant().Count(); + + int rows = doneCases + 1; + string[] stringList = new string[rows]; + + configProgress?.Invoke(0, doneCases); + string headerString = "Run,Implant Shadowing"; + headerString += ","; + headerString += "CDUVar" + ","; + headerString += "HeightVar" + ","; + headerString += "CRRVar" + ","; + headerString += "tiltAngleVar" + ","; + headerString += "twistAngleVar"; + stringList[0] = headerString; + commonVars.runAbort = false; + + try + { + summaryFile_implant(csvFileName); + } + catch (Exception) + { + // MessageBox.Show(ex.Message); + } + + string statusLine = "No CSV or external files written per job settings.All done."; + + if (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1) + { + // Set our parallel task options based on user settings. + ParallelOptions po = new ParallelOptions(); + // Attempt at parallelism. + CancellationTokenSource cancelSource = new CancellationTokenSource(); + CancellationToken cancellationToken = cancelSource.Token; + + string statusString = "Compiling CSV file for results"; + updateStatus?.Invoke(statusString); + int counter = 0; + Parallel.For(0, doneCases, (resultEntry, loopState) => + { + try + { + if (implantResultPackage.getImplantResult(resultEntry).isValid()) + { + if (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1) + { + // result can be a CSV string for multiple values - header is aligned above + string csvString = resultEntry.ToString() + "," + implantResultPackage.getImplantResult(resultEntry).getResult(); + csvString += ","; + csvString += implantResultPackage.getImplantResult(resultEntry).resistWidthVar.ToString() + ","; + csvString += implantResultPackage.getImplantResult(resultEntry).resistHeightVar.ToString() + ","; + csvString += implantResultPackage.getImplantResult(resultEntry).resistCRRVar.ToString() + ","; + csvString += implantResultPackage.getImplantResult(resultEntry).tiltVar.ToString() + ","; + csvString += implantResultPackage.getImplantResult(resultEntry).twistVar.ToString(); + stringList[resultEntry + 1] = csvString; + } + } + + Interlocked.Increment(ref counter); + abortCSVFunc?.Invoke(cancelSource, cancellationToken); + } + catch (OperationCanceledException) + { + commonVars.runAbort = false; + commonVars.cancelling = false; + loopState.Stop(); + } + catch (Exception) + { + } + + //stepProgress?.Invoke(); + //directProgress?.Invoke(resultEntry, doneCases); + }); + + File.WriteAllLines(csvFileName, stringList); + statusLine = counter.ToString() + " results saved to CSV file"; + } + + if (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.external) == 1) + { + if (commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.csv) == 1) + { + statusLine += " and"; + } + statusLine += " shapes saved to "; + + statusLine += commonVars.getExternalTypes()[commonVars.getImplantSettings_nonSim().getValue(EntropySettings_nonSim.properties_i.externalType)] + " files"; + } + + updateStatus?.Invoke(statusLine); + forceRepaintFunc?.Invoke(); + return returnValue; + } + + void writeSVG(Results_implant currentResult, int resultEntry, int numberOfCases) + { + string svgFileName = baseFileName; + + string paddingString = "D" + numberOfCases.ToString().Length.ToString(); // count chars in the number of cases as a string, use that to define padding. + svgFileName += "_run" + resultEntry.ToString(paddingString) + ".svg"; + + SVGBuilder svg = new SVGBuilder(); + + // Active resist contour + svg.style.brushClr = currentResult.getResistShapes()[0].getColor(); + svg.style.penClr = currentResult.getResistShapes()[0].getColor(); + svg.AddPolygons(currentResult.getResistShapes()[0].getPoints()); + + // Background resist contour + svg.style.brushClr = currentResult.getResistShapes()[1].getColor(); + svg.style.penClr = currentResult.getResistShapes()[1].getColor(); + svg.AddPolygons(currentResult.getResistShapes()[1].getPoints()); + + // Shadow + svg.style.brushClr = currentResult.getLine(Results_implant.lines.shadow).getColor(); + svg.style.penClr = currentResult.getLine(Results_implant.lines.shadow).getColor(); + svg.AddPolygons(currentResult.getLine(Results_implant.lines.shadow).getPoints()); + + svg.SaveToFile(svgFileName); + } + + void writeLayout_implant(Results_implant currentResult, int resultEntry, int numberOfCases, int type) + { + string layoutFileName = baseFileName; + + string paddingString = "D" + numberOfCases.ToString().Length.ToString(); // count chars in the number of cases as a string, use that to define padding. + layoutFileName += "_run" + resultEntry.ToString(paddingString); + + int scale = 100; // for 0.01 nm resolution + GeoCore g = new GeoCore(); + g.reset(); + GCDrawingfield drawing_ = new GCDrawingfield(""); + drawing_.accyear = (short)DateTime.Now.Year; + drawing_.accmonth = (short)DateTime.Now.Month; + drawing_.accday = (short)DateTime.Now.Day; + drawing_.acchour = (short)DateTime.Now.Hour; + drawing_.accmin = (short)DateTime.Now.Minute; + drawing_.accsec = (short)DateTime.Now.Second; + drawing_.modyear = (short)DateTime.Now.Year; + drawing_.modmonth = (short)DateTime.Now.Month; + drawing_.modday = (short)DateTime.Now.Day; + drawing_.modhour = (short)DateTime.Now.Hour; + drawing_.modmin = (short)DateTime.Now.Minute; + drawing_.modsec = (short)DateTime.Now.Second; + drawing_.databaseunits = 1000 * scale; + drawing_.userunits = 0.001 / scale; + drawing_.libname = "variance"; + + GCCell gcell_root = drawing_.addCell(); + gcell_root.accyear = (short)DateTime.Now.Year; + gcell_root.accmonth = (short)DateTime.Now.Month; + gcell_root.accday = (short)DateTime.Now.Day; + gcell_root.acchour = (short)DateTime.Now.Hour; + gcell_root.accmin = (short)DateTime.Now.Minute; + gcell_root.accsec = (short)DateTime.Now.Second; + gcell_root.modyear = (short)DateTime.Now.Year; + gcell_root.modmonth = (short)DateTime.Now.Month; + gcell_root.modday = (short)DateTime.Now.Day; + gcell_root.modhour = (short)DateTime.Now.Hour; + gcell_root.modmin = (short)DateTime.Now.Minute; + gcell_root.modsec = (short)DateTime.Now.Second; + gcell_root.cellName = "implantCase" + resultEntry.ToString(); + + // Resist + for (int i = 0; i < 2; i++) + { + List resistPolys = currentResult.getResistShapes()[i].getPoints(); + g.addLayerName("L" + (i + 1).ToString() + "D0", "resistPolys" + i.ToString()); + + for (int poly = 0; poly < resistPolys.Count; poly++) + { + int length = resistPolys[poly].Length; + GeoLibPoint[] ePoly = new GeoLibPoint[length]; + Parallel.For(0, length, (pt) => + // for (int pt = 0; pt < length; pt++) + { + ePoly[pt] = new GeoLibPoint((int)(resistPolys[poly][pt].X * scale), (int)(resistPolys[poly][pt].Y * scale)); + }); + + gcell_root.addPolygon(ePoly.ToArray(), i + 1, 0); + } + } + + // Shadowing line + List shadowLine = currentResult.getLine(Results_implant.lines.shadow).getPoints(); + g.addLayerName("L2D0", "shadowLine"); + for (int poly = 0; poly < shadowLine.Count; poly++) + { + int length = shadowLine[poly].Length; + GeoLibPoint[] ePoly = new GeoLibPoint[length]; + Parallel.For(0, length, (pt) => + // for (int pt = 0; pt < length; pt++) + { + ePoly[pt] = new GeoLibPoint((int)(shadowLine[poly][pt].X * scale), (int)(shadowLine[poly][pt].Y * scale)); + }); + + gcell_root.addPolygon(ePoly.ToArray(), 2, 0); + } + + g.setDrawing(drawing_); + g.setValid(true); + + switch (type) + { + case (int)CommonVars.external_Type.gds: + gds.gdsWriter gw = new gds.gdsWriter(g, layoutFileName + ".gds"); + gw.save(); + break; + case (int)CommonVars.external_Type.oas: + oasis.oasWriter ow = new oasis.oasWriter(g, layoutFileName + ".oas"); + ow.save(); + break; + + } + } + + void summaryFile_implant(string csvFileName) + { + // Force the evaluation. + implantResultPackage.getMeanAndStdDev(); + // Create our summaryFile string, assuming it is needed. + // This was simplier before, but now user can avoid CSV creation and will instead select the summary output filename (txt) + string summaryFile_ = csvFileName; + if (!summaryFile_.EndsWith("_summary.txt", StringComparison.CurrentCulture)) + { + summaryFile_ = csvFileName.Substring(0, csvFileName.Length - 4); + summaryFile_ += "_summary.txt"; + } + List linesToWrite = new List(); + + // Results first + // Write the results first. + linesToWrite.Add("Results summary for job: " + csvFileName + " run on : " + System.DateTime.Today.ToLocalTime().ToLongDateString() + ". Runtime: " + implantResultPackage.runTime.ToString("0.##") + " seconds"); + if (Debugger.IsAttached == true) + { + linesToWrite.Add("Run under debugger : performance was lower"); + } + + linesToWrite.Add(""); + for (int resultGroup = 0; resultGroup < implantResultPackage.getValues(SimResultPackage.properties.mean).Length; resultGroup++) + { + linesToWrite.Add("result " + resultGroup.ToString() + " mean and standard deviation for " + implantResultPackage.getListOfResults_implant().Count().ToString() + " cases: x: " + implantResultPackage.getValue(SimResultPackage.properties.mean, resultGroup).ToString("0.##") + ", s: " + implantResultPackage.getValue(SimResultPackage.properties.stdDev, resultGroup).ToString("0.##")); + } + + linesToWrite.Add(""); + + linesToWrite.AddRange(implantResultPackage.getHistograms()); + + // Simulation Settings + linesToWrite.Add(""); + linesToWrite.Add("Implant settings for job"); + linesToWrite.Add(""); + linesToWrite.Add("Resist Width: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.w).ToString()); + linesToWrite.Add("Resist CDU: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.wV).ToString()); + linesToWrite.Add("Resist Height: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.h).ToString()); + linesToWrite.Add("Resist Height Var: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.hV).ToString()); + linesToWrite.Add("Resist Top CRR: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.cRR).ToString()); + linesToWrite.Add("Resist Top CRR Var: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.cV).ToString()); + linesToWrite.Add(""); + linesToWrite.Add("Implant Tilt Angle: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.tilt).ToString()); + linesToWrite.Add("Implant Tilt Angle Var: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.tiltV).ToString()); + linesToWrite.Add("Implant Twist Angle: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.twist).ToString()); + linesToWrite.Add("Implant Twist Angle Var: " + commonVars.getImplantSettings().getDouble(EntropyImplantSettings.properties_d.twistV).ToString()); + + // Simulation Settings + linesToWrite.Add(""); + commonVars.getSimulationSettings_implant(linesToWrite); + + try + { + File.WriteAllLines(summaryFile_, linesToWrite); + } + catch (Exception ex) + { + ErrorReporter.showMessage_OK(ex.ToString(), "Exception"); + } + } + } +} \ No newline at end of file diff --git a/Common/Variance/entropy/implantSettings.cs b/Common/Variance/entropy/implantSettings.cs new file mode 100644 index 0000000..5e9bddd --- /dev/null +++ b/Common/Variance/entropy/implantSettings.cs @@ -0,0 +1,245 @@ +using System; + +namespace Variance +{ + [Serializable] + public class EntropyImplantSettings + { + public enum properties_d { w, wV, h, hV, cRR, cV, tilt, tiltV, twist, twistV } + + string comment; + double resistWidth; + double resistWidthVar; + double resistHeight_postDevelop; + double resistHeight_postDevelopVar; + double resistCRR; + double resistCRRVar; + double tiltAngle; + double tiltAngleVar; + double twistAngle; + double twistAngleVar; + + static double default_resistWidth = 0.0; + static double default_resistWidthVar = 0.0; + static double default_resistHeight_postDevelop = 0.0; + static double default_resistHeight_postDevelopVar = 0.0; + static double default_resistCRR = 0.0; + static double default_resistCRRVar = 0.0; + static double default_tilt = 0.0; + static double default_tiltVar = 0.0; + static double default_twist = 0.0; + static double default_twistVar = 0.0; + + public EntropyImplantSettings() + { + pEntropyImplantSettings(); + } + + void pEntropyImplantSettings() + { + comment = ""; + resistWidth = default_resistWidth; + resistHeight_postDevelop = default_resistHeight_postDevelop; + resistCRR = default_resistCRR; + tiltAngle = default_tilt; + twistAngle = default_twist; + resistWidthVar = default_resistWidthVar; + resistHeight_postDevelopVar = default_resistHeight_postDevelopVar; + resistCRRVar = default_resistCRRVar; + tiltAngleVar = default_tiltVar; + twistAngleVar = default_twistVar; + } + + public void setComment(string text) + { + pSetComment(text); + } + + void pSetComment(string text) + { + comment = text; + } + + public string getComment() + { + return pGetComment(); + } + + string pGetComment() + { + return comment; + } + + public void setDouble(properties_d p, double val) + { + pSetDouble(p, val); + } + + void pSetDouble(properties_d p, double val) + { + switch (p) + { + case properties_d.w: + resistWidth = val; + break; + case properties_d.wV: + resistWidthVar = val; + break; + case properties_d.h: + resistHeight_postDevelop = val; + break; + case properties_d.hV: + resistHeight_postDevelopVar = val; + break; + case properties_d.cRR: + resistCRR = val; + break; + case properties_d.cV: + resistCRRVar = val; + break; + case properties_d.tilt: + tiltAngle = val; + break; + case properties_d.tiltV: + tiltAngleVar = val; + break; + case properties_d.twist: + twistAngle = val; + break; + case properties_d.twistV: + twistAngleVar = val; + break; + } + } + + public void defaultDouble(properties_d p) + { + pDefaultDouble(p); + } + + void pDefaultDouble(properties_d p) + { + switch (p) + { + case properties_d.w: + resistWidth = default_resistWidth; + break; + case properties_d.wV: + resistWidthVar = default_resistWidthVar; + break; + case properties_d.h: + resistHeight_postDevelop = default_resistHeight_postDevelop; + break; + case properties_d.hV: + resistHeight_postDevelopVar = default_resistHeight_postDevelopVar; + break; + case properties_d.cRR: + resistCRR = default_resistCRR; + break; + case properties_d.cV: + resistCRRVar = default_resistCRRVar; + break; + case properties_d.tilt: + tiltAngle = default_tilt; + break; + case properties_d.tiltV: + tiltAngleVar = default_tiltVar; + break; + case properties_d.twist: + twistAngle = default_twist; + break; + case properties_d.twistV: + twistAngleVar = default_twistVar; + break; + } + } + + public double getDouble(properties_d p) + { + return pGetDouble(p); + } + + double pGetDouble(properties_d p) + { + double ret = 0; + switch (p) + { + case properties_d.w: + ret = resistWidth; + break; + case properties_d.wV: + ret = resistWidthVar; + break; + case properties_d.h: + ret = resistHeight_postDevelop; + break; + case properties_d.hV: + ret = resistHeight_postDevelopVar; + break; + case properties_d.cRR: + ret = resistCRR; + break; + case properties_d.cV: + ret = resistCRRVar; + break; + case properties_d.tilt: + ret = tiltAngle; + break; + case properties_d.tiltV: + ret = tiltAngleVar; + break; + case properties_d.twist: + ret = twistAngle; + break; + case properties_d.twistV: + ret = twistAngleVar; + break; + } + return ret; + } + + public double getDefaultDouble(properties_d p) + { + return pGetDefaultDouble(p); + } + + double pGetDefaultDouble(properties_d p) + { + double ret = 0; + switch (p) + { + case properties_d.w: + ret = default_resistWidth; + break; + case properties_d.wV: + ret = default_resistWidthVar; + break; + case properties_d.h: + ret = default_resistHeight_postDevelop; + break; + case properties_d.hV: + ret = default_resistHeight_postDevelopVar; + break; + case properties_d.cRR: + ret = default_resistCRR; + break; + case properties_d.cV: + ret = default_resistCRRVar; + break; + case properties_d.tilt: + ret = default_tilt; + break; + case properties_d.tiltV: + ret = default_tiltVar; + break; + case properties_d.twist: + ret = default_twist; + break; + case properties_d.twistV: + ret = default_twistVar; + break; + } + return ret; + } + } +} diff --git a/Common/Variance/entropy/paSearchSettings.cs b/Common/Variance/entropy/paSearchSettings.cs new file mode 100644 index 0000000..6634c38 --- /dev/null +++ b/Common/Variance/entropy/paSearchSettings.cs @@ -0,0 +1,624 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Variance +{ + public class PASearch + { + /* + // Disabled entries pending review for suitability and practical implementation. + Wobble : needs to support per-polygon variation at point-of-use. + sideBias : deep shape engine support, to propagate the PA search awareness + tipBias : need support for positive/negative limits and variation. + proxBias : deep shape engine support, like others. + */ + public static string[] paNames = new string[] { "xOL", "yOL", "SCDU", "TCDU", "LWR", "LWR2", "hTipNVar", "hTipPVar", "vTipNVar", "vTipPVar", "ICR", "OCR", "Wobble" }; + public enum paEnum { XOL, YOL, SCDU, TCDU, LWR, LWR2, HTIPNVAR, HTIPPVAR, VTIPNVAR, VTIPPVAR, ICR, OCR, WOB } + + bool[,] searchablePAs; + decimal[,] upperLimit; + decimal[,] originalValues; // to allow restoration later. + string[,] meanValues; + + public string getMeanValue(int x, int y) + { + return pGetMeanValue(x, y); + } + + string pGetMeanValue(int x, int y) + { + return meanValues[x, y]; + } + + string[,] stdDevValues; + + public string getSDValue(int x, int y) + { + return pGetSDValue(x, y); + } + + string pGetSDValue(int x, int y) + { + return stdDevValues[x, y]; + } + + // Expose these as they are less complicated than the layer case. + public int numberofPassCases { get; set; } + public double[] filterValues { get; set; } + public bool[] useFilter { get; set; } + public bool[] filterIsMaxValue { get; set; } + + public PASearch() + { + pPASearch(); + } + + void pPASearch() + { + originalValues = new decimal[CentralProperties.maxLayersForMC, paNames.Length]; + searchablePAs = new bool[CentralProperties.maxLayersForMC, paNames.Length]; + upperLimit = new decimal[CentralProperties.maxLayersForMC, paNames.Length]; + meanValues = new string[CentralProperties.maxLayersForMC, paNames.Length]; + stdDevValues = new string[CentralProperties.maxLayersForMC, paNames.Length]; + // 4 fields based on chord case. + filterValues = new double[4]; + useFilter = new bool[4]; + filterIsMaxValue = new bool[4]; + pReset(); + } + + public void reset() + { + pReset(); + } + + void pReset() + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + pResetLayer(i); + } + } + + public void resetLayer(int layer) + { + pResetLayer(layer); + } + + void pResetLayer(int layer) + { + if ((layer < 0) || (layer > CentralProperties.maxLayersForMC)) + { + return; + } + Parallel.For(0, paNames.Length, (j) => + // for (int j = 0; j < paNames.Length; j++) + { + searchablePAs[layer, j] = false; + upperLimit[layer, j] = 0; + meanValues[layer, j] = ""; + stdDevValues[layer, j] = ""; + }); + } + + public bool isPASearchable(int layer, int index) + { + return pIsPASearchable(layer, index); + } + + bool pIsPASearchable(int layer, int index) + { + return searchablePAs[layer, index]; + } + + public void setPASearchable(int layer, int index, bool searchable) + { + pSetPASearchable(layer, index, searchable); + } + + void pSetPASearchable(int layer, int index, bool searchable) + { + searchablePAs[layer, index] = searchable; + } + + // Note that the set methods below return a value to the caller, which allows for transposition and lower limit violations to be handled. + + // Upper limit + public decimal setUpperLimit(int layer, int index, decimal upperVal) + { + return pSetUpperLimit(layer, index, upperVal); + } + + decimal pSetUpperLimit(int layer, int index, decimal upperVal) + { + upperLimit[layer, index] = upperVal; + return upperLimit[layer, index]; + } + + public double getUpperLimit(int layer, int index) + { + return pGetUpperLimit(layer, index); + } + + double pGetUpperLimit(int layer, int index) + { + return Convert.ToDouble(upperLimit[layer, index]); + } + + public bool paAllowsNegativeValues(int index) + { + return pPAAllowsNegativeValues(index); + } + + bool pPAAllowsNegativeValues(int index) + { + + if (paNames[index].Contains("Bias")) + { + return true; + } + else + { + return false; + } + } + + public bool[] getEnabledState(EntropyLayerSettings layerSettings) + { + return pGetEnabledState(layerSettings); + } + + bool[] pGetEnabledState(EntropyLayerSettings layerSettings) + { + int length = paNames.Length; + bool[] enabled = new bool[length]; + Parallel.For(0, length, (i) => + // for (int i = 0; i < length; i++) + { + bool enable = layerSettings.getInt(EntropyLayerSettings.properties_i.enabled) == 1; + if (enable) + { + if (layerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.GEOCORE) + { + // Disable for geoCore case, as appropriate. + if (layerSettings.getInt(EntropyLayerSettings.properties_i.gCSEngine) == 0) + { + switch (i) + { + case (int)paEnum.XOL: + case (int)paEnum.YOL: + // case (int)paEnum.LWR: + // case (int)paEnum.SBIAS: + // case (int)paEnum.PBIAS: + enable = true; + break; + default: + enable = false; + break; + } + } + } + } + enabled[i] = enable; + }); + + return enabled; + } + + public void applySearchValues(ref CommonVars commonVars) + { + pBackupOriginalValues(commonVars); + pSetValues(ref commonVars); + } + + void pBackupOriginalValues(CommonVars commonVars) + { + Parallel.For(0, CentralProperties.maxLayersForMC, (i) => + // for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (searchablePAs[i, (int)paEnum.XOL]) + { + originalValues[i, (int)paEnum.XOL] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.xOL); + } + if (searchablePAs[i, (int)paEnum.YOL]) + { + originalValues[i, (int)paEnum.YOL] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.yOL); + } + if (searchablePAs[i, (int)paEnum.SCDU]) + { + originalValues[i, (int)paEnum.SCDU] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.sCDU); + } + if (searchablePAs[i, (int)paEnum.TCDU]) + { + originalValues[i, (int)paEnum.TCDU] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.tCDU); + } + if (searchablePAs[i, (int)paEnum.LWR]) + { + originalValues[i, (int)paEnum.LWR] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.lwr); + } + if (searchablePAs[i, (int)paEnum.LWR2]) + { + originalValues[i, (int)paEnum.LWR2] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.lwr2); + } + if (searchablePAs[i, (int)paEnum.HTIPNVAR]) + { + originalValues[i, (int)paEnum.HTIPNVAR] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.hTNVar); + } + if (searchablePAs[i, (int)paEnum.HTIPPVAR]) + { + originalValues[i, (int)paEnum.HTIPPVAR] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.hTPVar); + } + if (searchablePAs[i, (int)paEnum.VTIPNVAR]) + { + originalValues[i, (int)paEnum.VTIPNVAR] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.vTNVar); + } + if (searchablePAs[i, (int)paEnum.VTIPPVAR]) + { + originalValues[i, (int)paEnum.VTIPPVAR] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.vTPVar); + } + if (searchablePAs[i, (int)paEnum.ICR]) + { + originalValues[i, (int)paEnum.ICR] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.iCR); + } + if (searchablePAs[i, (int)paEnum.OCR]) + { + originalValues[i, (int)paEnum.OCR] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.oCR); + } + if (searchablePAs[i, (int)paEnum.WOB]) + { + originalValues[i, (int)paEnum.WOB] = commonVars.getLayerSettings(i).getDecimal(EntropyLayerSettings.properties_decimal.wobble); + } + }); + } + + void pSetValues(ref CommonVars commonVars) + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (searchablePAs[i, (int)paEnum.XOL]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.xOL, upperLimit[i, (int)paEnum.XOL]); + } + if (searchablePAs[i, (int)paEnum.YOL]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.yOL, upperLimit[i, (int)paEnum.YOL]); + } + if (searchablePAs[i, (int)paEnum.SCDU]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.sCDU, upperLimit[i, (int)paEnum.SCDU]); + } + if (searchablePAs[i, (int)paEnum.TCDU]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.tCDU, upperLimit[i, (int)paEnum.TCDU]); + } + if (searchablePAs[i, (int)paEnum.LWR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.lwr, upperLimit[i, (int)paEnum.LWR]); + } + if (searchablePAs[i, (int)paEnum.LWR2]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.lwr2, upperLimit[i, (int)paEnum.LWR2]); + } + if (searchablePAs[i, (int)paEnum.HTIPNVAR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.hTNVar, upperLimit[i, (int)paEnum.HTIPNVAR]); + } + if (searchablePAs[i, (int)paEnum.HTIPPVAR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.hTPVar, upperLimit[i, (int)paEnum.HTIPPVAR]); + } + if (searchablePAs[i, (int)paEnum.VTIPNVAR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.vTNVar, upperLimit[i, (int)paEnum.VTIPNVAR]); + } + if (searchablePAs[i, (int)paEnum.VTIPPVAR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.vTPVar, upperLimit[i, (int)paEnum.VTIPPVAR]); + } + if (searchablePAs[i, (int)paEnum.ICR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.iCR, upperLimit[i, (int)paEnum.ICR]); + } + if (searchablePAs[i, (int)paEnum.OCR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.oCR, upperLimit[i, (int)paEnum.OCR]); + } + if (searchablePAs[i, (int)paEnum.WOB]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.wobble, upperLimit[i, (int)paEnum.WOB]); + } + } + } + + public void removeSearchValues(ref CommonVars commonVars) + { + pRestoreOriginalValues(ref commonVars); + } + + void pRestoreOriginalValues(ref CommonVars commonVars) + { + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (searchablePAs[i, (int)paEnum.XOL]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.xOL, originalValues[i, (int)paEnum.XOL]); + } + if (searchablePAs[i, (int)paEnum.YOL]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.yOL, originalValues[i, (int)paEnum.YOL]); + } + if (searchablePAs[i, (int)paEnum.SCDU]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.sCDU, originalValues[i, (int)paEnum.SCDU]); + } + if (searchablePAs[i, (int)paEnum.TCDU]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.tCDU, originalValues[i, (int)paEnum.TCDU]); + } + if (searchablePAs[i, (int)paEnum.LWR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.lwr, originalValues[i, (int)paEnum.LWR]); + } + if (searchablePAs[i, (int)paEnum.LWR2]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.lwr2, originalValues[i, (int)paEnum.LWR2]); + } + if (searchablePAs[i, (int)paEnum.HTIPNVAR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.hTNVar, originalValues[i, (int)paEnum.HTIPNVAR]); + } + if (searchablePAs[i, (int)paEnum.HTIPPVAR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.hTPVar, originalValues[i, (int)paEnum.HTIPPVAR]); + } + if (searchablePAs[i, (int)paEnum.VTIPNVAR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.vTNVar, originalValues[i, (int)paEnum.VTIPNVAR]); + } + if (searchablePAs[i, (int)paEnum.VTIPPVAR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.vTPVar, originalValues[i, (int)paEnum.VTIPPVAR]); + } + if (searchablePAs[i, (int)paEnum.ICR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.iCR, originalValues[i, (int)paEnum.ICR]); + } + if (searchablePAs[i, (int)paEnum.OCR]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.oCR, originalValues[i, (int)paEnum.OCR]); + } + if (searchablePAs[i, (int)paEnum.WOB]) + { + commonVars.getLayerSettings(i).setDecimal(EntropyLayerSettings.properties_decimal.wobble, originalValues[i, (int)paEnum.WOB]); + } + } + } + + public void calculateMeanAndStdDev(SimResultPackage resultPackage) + { + pCalculateMeanAndStdDev(resultPackage); + } + + void pCalculateMeanAndStdDev(SimResultPackage resultPackage) + { + // Find out whether we are actually interested in a given PA for a layer + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + layer_meanStdDev(resultPackage, layer); + } + } + + void layer_meanStdDev(SimResultPackage resultPackage, int layer) + { + for (int pa = 0; pa < paNames.Length; pa++) + { + pa_layer_meanStdDev(resultPackage, layer, pa); + } + } + + void pa_layer_meanStdDev(SimResultPackage resultPackage, int layer, int pa) + { + // We're interested in this PA, so we need to pull out the values and calculate the mean and standard deviation for this input to the simulation. + if (searchablePAs[layer, pa]) + { + List rawValues = new List(); + for (int resultField = 0; resultField < resultPackage.getListOfResults().Count; resultField++) + { + double factor = 0; + switch (pa) + { + case (int)paEnum.XOL: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.olx, layer); + break; + case (int)paEnum.YOL: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.oly, layer); + break; + case (int)paEnum.SCDU: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.svar, layer); + break; + case (int)paEnum.TCDU: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.tvar, layer); + break; + case (int)paEnum.LWR: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.lwr, layer); + break; + case (int)paEnum.LWR2: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.lwr2, layer); + break; + case (int)paEnum.HTIPNVAR: + case (int)paEnum.HTIPPVAR: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.htip, layer); + break; + case (int)paEnum.VTIPNVAR: + case (int)paEnum.VTIPPVAR: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.vtip, layer); + break; + case (int)paEnum.ICR: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.icv, layer); + break; + case (int)paEnum.OCR: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.ocv, layer); + break; + case (int)paEnum.WOB: + factor = resultPackage.getResult(resultField).getField(Results.fields_d.wob, layer); + break; + } + // Since we're talking variations, we need absolute values - can't have a negative CDU value, for example. + // RNG expects 3-sigma PA, so we need to convert back to 3-sigma for reporting. + rawValues.Add(Math.Abs(factor) * Convert.ToDouble(upperLimit[layer, pa])); + } + double meanVal = mean(rawValues); + if (meanVal != -1) + { + meanValues[layer, pa] = meanVal.ToString("0.##"); + if (!resultPackage.nonGaussianInput) + { + stdDevValues[layer, pa] = stdDev(rawValues).ToString("0.##"); + } + else + { + stdDevValues[layer, pa] = "N/A"; + } + } + else + { + meanValues[layer, pa] = "N/A"; + stdDevValues[layer, pa] = "N/A"; + } + } + else + { + meanValues[layer, pa] = ""; + stdDevValues[layer, pa] = ""; + } + } + + double mean(List rawValues) + { + if (rawValues.Count == 0) + { + return -1; + } + else + { + return rawValues.Average(); + } + } + + double stdDev(List rawValues) + { + // Welford's approach + double m = 0.0; + double s = 0.0; + int k = 1; + + for (int value = 0; value < rawValues.Count; value++) + { + double tmpM = m; + + double _value = rawValues[value]; + m += (_value - tmpM) / k; + s += (_value - tmpM) * (_value - m); + k++; + } + + return Math.Sqrt(s / (k - 2)); + } + + public void modifyJobSettings(ref ChaosSettings jobSettings) + { + pModifyJobSettings(ref jobSettings); + } + + // In Gaussian mode, variations are scaled from 3-sigma to 1-sigma, but in PA search, we need to reverse this, so upscale the RNG value accordingly. + void pModifyJobSettings(ref ChaosSettings jobSettings) + { + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + for (int pa = 0; pa < paNames.Length; pa++) + { + if (isPASearchable(layer, pa)) + { + switch (pa) + { + case (int)paEnum.XOL: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.overlayX, layer, jobSettings.getValue(ChaosSettings.properties.overlayX, layer) * 3); + } + break; + case (int)paEnum.YOL: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.overlayY, layer, jobSettings.getValue(ChaosSettings.properties.overlayY, layer) * 3); + } + break; + case (int)paEnum.SCDU: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.CDUSVar, layer, jobSettings.getValue(ChaosSettings.properties.CDUSVar, layer) * 3); + } + break; + case (int)paEnum.TCDU: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.CDUTVar, layer, jobSettings.getValue(ChaosSettings.properties.CDUTVar, layer) * 3); + } + break; + case (int)paEnum.LWR: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.LWRVar, layer, jobSettings.getValue(ChaosSettings.properties.LWRVar, layer) * 3); + } + break; + case (int)paEnum.LWR2: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.LWR2Var, layer, jobSettings.getValue(ChaosSettings.properties.LWR2Var, layer) * 3); + } + break; + case (int)paEnum.HTIPNVAR: + case (int)paEnum.HTIPPVAR: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.hTipBiasVar, layer, jobSettings.getValue(ChaosSettings.properties.hTipBiasVar, layer) * 3); + } + break; + case (int)paEnum.VTIPPVAR: + case (int)paEnum.VTIPNVAR: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.vTipBiasVar, layer, jobSettings.getValue(ChaosSettings.properties.vTipBiasVar, layer) * 3); + } + break; + case (int)paEnum.ICR: + jobSettings.setBool(ChaosSettings.bools.icPA, layer, true); + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.icVar, layer, jobSettings.getValue(ChaosSettings.properties.icVar, layer) * 3); + } + break; + case (int)paEnum.OCR: + jobSettings.setBool(ChaosSettings.bools.ocPA, layer, true); + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.ocVar, layer, jobSettings.getValue(ChaosSettings.properties.ocVar, layer) * 3); + } + break; + case (int)paEnum.WOB: + if (!jobSettings.getCustomRNGMapping()) + { + jobSettings.setValue(ChaosSettings.properties.wobbleVar, layer, jobSettings.getValue(ChaosSettings.properties.wobbleVar, layer) * 3); + } + break; + default: + break; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Common/Variance/entropy/sampler_geo.cs b/Common/Variance/entropy/sampler_geo.cs new file mode 100644 index 0000000..dbcb3f3 --- /dev/null +++ b/Common/Variance/entropy/sampler_geo.cs @@ -0,0 +1,146 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Variance +{ + class Sampler_Geo + { + public delegate void updateProgressBar(double val); + public updateProgressBar updateProgressBarFunc { get; set; } + + int dimensions; + int sampleCount, samples_par; + bool pMode, paSearch; + double progress; + + ChaosSettings[] samples; + CommonVars _commonVars; + public Sampler_Geo(int number, bool previewMode, bool doPASearch, ref CommonVars commonVars) + { + init(number, previewMode, doPASearch, ref commonVars); + } + + void init(int number, bool previewMode, bool doPASearch, ref CommonVars commonVars) + { + dimensions = ChaosSettings.getDimensions(); + _commonVars = commonVars; + if (_commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.linkCDU) == 1) + { + dimensions -= 3; + } + sampleCount = number; + pMode = previewMode; + paSearch = doPASearch; + } + + public int getDimensions() + { + return pGetDimensions(); + } + + int pGetDimensions() + { + return dimensions; + } + + public void sample(bool useThreads) + { + samples = new ChaosSettings[sampleCount]; + progress = 0; + if (useThreads) + { + threaded(); + } + else + { + unthreaded(); + } + } + + void unthreaded() + { + int increment = sampleCount / 100; + if (increment < 1) + { + increment = 1; + } + updateProgressBarFunc?.Invoke(progress); + + for (int i = 0; i < sampleCount; i++) + { + samples[i] = generateSample(); + if (i % increment == 0) + { + updateProgressBarFunc?.Invoke(progress); + progress += 0.01; + } + } + } + + void updateHost(object sender, EventArgs e) + { + progress = (double)samples_par / sampleCount; + updateProgressBarFunc?.Invoke(progress); + } + + void threaded() + { + samples_par = 0; + System.Timers.Timer m_timer = new System.Timers.Timer(); + // Set up timers for the UI refresh + m_timer.AutoReset = true; + m_timer.Interval = CentralProperties.timer_interval; + m_timer.Start(); + m_timer.Elapsed += updateHost; + + ParallelOptions po = new ParallelOptions(); + + Parallel.For(0, sampleCount, po, (i, loopState) => + { + samples[i] = generateSample(); + Interlocked.Increment(ref samples_par); + } + ); + + m_timer.Stop(); + m_timer.Dispose(); + } + + ChaosSettings generateSample() + { + ChaosSettings currentJobSettings = new ChaosSettings(pMode, _commonVars.getListOfSettings(), _commonVars.getSimulationSettings()); + if (paSearch) + { + _commonVars.getPASearch().modifyJobSettings(ref currentJobSettings); + } + + // Massage our CDUTVar if the simulation settings call for the variation to be linked (default) + // Tie up the tip variation values as well. + if (_commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.linkCDU) == 1) + { + currentJobSettings.setValues(ChaosSettings.properties.CDUTVar, currentJobSettings.getValues(ChaosSettings.properties.CDUSVar)); + currentJobSettings.setValues(ChaosSettings.properties.hTipBiasVar, currentJobSettings.getValues(ChaosSettings.properties.vTipBiasVar)); + currentJobSettings.setValues(ChaosSettings.properties.hTipBiasType, currentJobSettings.getValues(ChaosSettings.properties.vTipBiasType)); + } + + return currentJobSettings; + + } + + public ChaosSettings getSample(int i) + { + // PA search doesn't presample, so we have to generate a live sample and return it back. + if (paSearch) + { + return generateSample(); + } + return pGetSample(i); + } + + ChaosSettings pGetSample(int i) + { + return samples[i]; + } + } +} diff --git a/Common/Variance/entropy/sampler_implant.cs b/Common/Variance/entropy/sampler_implant.cs new file mode 100644 index 0000000..026621e --- /dev/null +++ b/Common/Variance/entropy/sampler_implant.cs @@ -0,0 +1,120 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Variance +{ + class Sampler_Implant + { + public delegate void updateProgressBar(double val); + public updateProgressBar updateProgressBarFunc { get; set; } + + ChaosSettings_implant[] samples; + + int dimensions; + int sampleCount, samples_par; + bool pMode; + double progress; + + EntropySettings entropySettings_implant; + + public Sampler_Implant(int number, bool previewMode, EntropySettings entropySettings) + { + init(number, previewMode, entropySettings); + } + + void init(int number, bool previewMode, EntropySettings entropySettings) + { + dimensions = ChaosSettings_implant.getDimensions(); + sampleCount = number; + pMode = previewMode; + entropySettings_implant = entropySettings; + } + + public int getDimensions() + { + return pGetDimensions(); + } + + int pGetDimensions() + { + return dimensions; + } + public void sample(bool useThreads) + { + progress = 0; + samples = new ChaosSettings_implant[sampleCount]; + + if (useThreads) + { + threaded(); + } + else + { + unthreaded(); + } + } + + void unthreaded() + { + int increment = sampleCount / 100; + if (increment < 1) + { + increment = 1; + } + updateProgressBarFunc?.Invoke(progress); + + for (int i = 0; i < sampleCount; i++) + { + ChaosSettings_implant currentJobSettings = new ChaosSettings_implant(pMode, entropySettings_implant); + samples[i] = currentJobSettings; + + if (i % increment == 0) + { + updateProgressBarFunc?.Invoke(progress); + progress += 0.01; + } + } + } + + void updateHost(object sender, EventArgs e) + { + progress = (double)samples_par / sampleCount; + updateProgressBarFunc?.Invoke(progress); + } + + void threaded() + { + samples_par = 0; + System.Timers.Timer m_timer = new System.Timers.Timer(); + // Set up timers for the UI refresh + m_timer.AutoReset = true; + m_timer.Interval = CentralProperties.timer_interval; + m_timer.Start(); + m_timer.Elapsed += updateHost; + + ParallelOptions po = new ParallelOptions(); + + Parallel.For(0, sampleCount, po, (i, loopState) => + { + ChaosSettings_implant currentJobSettings = new ChaosSettings_implant(pMode, entropySettings_implant); + samples[i] = currentJobSettings; + Interlocked.Increment(ref samples_par); + } + ); + + m_timer.Stop(); + m_timer.Dispose(); + } + + public ChaosSettings_implant getSample(int i) + { + return pGetSample(i); + } + + ChaosSettings_implant pGetSample(int i) + { + return samples[i]; + } + } +} diff --git a/Common/Variance/results/results.cs b/Common/Variance/results/results.cs new file mode 100644 index 0000000..be55cb9 --- /dev/null +++ b/Common/Variance/results/results.cs @@ -0,0 +1,371 @@ +using geoLib; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Variance +{ + public class Results + { + List> previewShapes; + List simShapes; + + public Int32 getLayerIndex(int shapeIndex) + { + return pGetLayerIndex(shapeIndex); + } + + Int32 pGetLayerIndex(int shapeIndex) + { + return simShapes[shapeIndex].getIndex(); + } + public List> getPreviewShapes() + { + return pGetPreviewShapes(); + } + + List> pGetPreviewShapes() + { + return previewShapes; + } + + public void clearPreviewShapes() + { + pClearPreviewShapes(); + } + + void pClearPreviewShapes() + { + previewShapes.Clear(); + } + + public void setPreviewShapes(List> newPreviewShapes) + { + pSetPreviewShapes(newPreviewShapes); + } + + void pSetPreviewShapes(List> newPreviewShapes) + { + previewShapes = newPreviewShapes.ToList(); + } + + public List getSimShapes() + { + return pGetSimShapes(); + } + + List pGetSimShapes() + { + return simShapes; + } + + public void setSimShapes(List newSimShapes) + { + pSetSimShapes(newSimShapes); + } + + void pSetSimShapes(List newSimShapes) + { + simShapes = newSimShapes.ToList(); + } + + public void clearSimShapes() + { + pClearSimShapes(); + } + + void pClearSimShapes() + { + simShapes.Clear(); + } + + string result; + + public string getResult() + { + return pGetResult(); + } + + string pGetResult() + { + return result; + } + + public void setResult(string val) + { + pSetResult(val); + } + + void pSetResult(string val) + { + result = val; + } + + List points; // result points. + + public List getPoints() + { + return pGetPoints(); + } + + List pGetPoints() + { + return points; + } + + public void setPoints(List newPoints) + { + pSetPoints(newPoints); + } + + void pSetPoints(List newPoints) + { + points = newPoints.ToList(); + } + + public void clearPoints() + { + pClearPoints(); + } + + void pClearPoints() + { + points.Clear(); + } + + public enum fields_d { svar, tvar, lwr, lwr2, htip, vtip, icv, ocv, olx, oly, wob } + + double[] CDUSVar; + double[] CDUTVar; + double[] LWRVar; + double[] LWR2Var; + double[] horTipBiasVar; + double[] verTipBiasVar; + double[] iCVar; + double[] oCVar; + double[] overlayX; + double[] overlayY; + double[] wobbleVar; + + public double[] getFields(fields_d f) + { + return pGetFields(f); + } + + double[] pGetFields(fields_d f) + { + double[] ret = new double[] { }; + switch (f) + { + case fields_d.svar: + ret = CDUSVar; + break; + case fields_d.tvar: + ret = CDUTVar; + break; + case fields_d.lwr: + ret = LWRVar; + break; + case fields_d.lwr2: + ret = LWR2Var; + break; + case fields_d.htip: + ret = horTipBiasVar; + break; + case fields_d.vtip: + ret = verTipBiasVar; + break; + case fields_d.icv: + ret = iCVar; + break; + case fields_d.ocv: + ret = oCVar; + break; + case fields_d.olx: + ret = overlayX; + break; + case fields_d.oly: + ret = overlayY; + break; + case fields_d.wob: + ret = wobbleVar; + break; + } + + return ret; + } + + public double getField(fields_d f, int index) + { + return pGetField(f, index); + } + + double pGetField(fields_d f, int index) + { + double[] t = pGetFields(f); + return t[index]; + } + + public void setFields(fields_d f, double[] val) + { + pSetFields(f, val); + } + + void pSetFields(fields_d f, double[] val) + { + switch (f) + { + case fields_d.svar: + CDUSVar = val; + break; + case fields_d.tvar: + CDUTVar = val; + break; + case fields_d.lwr: + LWRVar = val; + break; + case fields_d.lwr2: + LWR2Var = val; + break; + case fields_d.htip: + horTipBiasVar = val; + break; + case fields_d.vtip: + verTipBiasVar = val; + break; + case fields_d.icv: + iCVar = val; + break; + case fields_d.ocv: + oCVar = val; + break; + case fields_d.olx: + overlayX = val; + break; + case fields_d.oly: + overlayY = val; + break; + case fields_d.wob: + wobbleVar = val; + break; + } + } + + public void setField(fields_d f, int index, double val) + { + pSetField(f, index, val); + } + + void pSetField(fields_d f, int index, double val) + { + double[] t = pGetFields(f); + t[index] = val; + } + + public enum fields_i { lwrs, lwr2s } + + int[] LWRSeed; + int[] LWR2Seed; + + public int[] getSeeds(fields_i f) + { + return pGetSeeds(f); + } + + int[] pGetSeeds(fields_i f) + { + int[] ret = new int[] { }; + switch (f) + { + case fields_i.lwrs: + ret = LWRSeed; + break; + case fields_i.lwr2s: + ret = LWR2Seed; + break; + } + + return ret; + } + + public int getSeed(fields_i f, int index) + { + return pGetSeed(f, index); + } + + int pGetSeed(fields_i f, int index) + { + int[] t = pGetSeeds(f); + return t[index]; + } + + public void setSeeds(fields_i f, int[] val) + { + pSetSeeds(f, val); + } + + void pSetSeeds(fields_i f, int[] val) + { + switch (f) + { + case fields_i.lwrs: + LWRSeed = val; + break; + case fields_i.lwr2s: + LWR2Seed = val; + break; + } + } + + + bool valid; + + public void setValid(bool val) + { + pSetValid(val); + } + + void pSetValid(bool val) + { + valid = val; + } + + public bool isValid() + { + return pIsValid(); + } + + bool pIsValid() + { + return valid; + } + + public Results() + { + init(); + } + + void init() + { + LWRSeed = new int[] { }; + LWR2Seed = new int[] { }; + + previewShapes = new List>(); + valid = false; + } + + public void genPreviewShapes() + { + pGenPreviewShapes(); + } + + void pGenPreviewShapes() + { + previewShapes.Clear(); + for (Int32 layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + previewShapes.Add(simShapes[layer].getPoints().ToList()); + } + } + } +} diff --git a/Common/Variance/results/results_implant.cs b/Common/Variance/results/results_implant.cs new file mode 100644 index 0000000..74314a5 --- /dev/null +++ b/Common/Variance/results/results_implant.cs @@ -0,0 +1,220 @@ +using color; +using geoLib; +using System.Collections.Generic; +using System.Linq; + +namespace Variance +{ + public class Results_implant + { + List resistShapes; // poly at 0 is the resist contour being evaluated. poly at 1 is the bg poly to complete the shape. + + public List getResistShapes() + { + return pGetResistShapes(); + } + + List pGetResistShapes() + { + return resistShapes; + } + + public void setResistShapes(Colors colors, GeoLibPointF[] geom, GeoLibPointF[] bgGeom, GeoLibPointF[] shadow, GeoLibPointF[] min, GeoLibPointF[] max) + { + pSetResistShapes(colors, geom, bgGeom, shadow, min, max); + } + + void pSetResistShapes(Colors colors, GeoLibPointF[] geom, GeoLibPointF[] bgGeom, GeoLibPointF[] shadow, GeoLibPointF[] min, GeoLibPointF[] max) + { + resistShapes.Clear(); + + resistShapes.Add(new PreviewShape()); + resistShapes[0].addPoints(geom); + resistShapes[0].setColor(colors.implantResist_Color); + + resistShapes.Add(new PreviewShape()); + resistShapes[1].addPoints(bgGeom); + resistShapes[1].setColor(colors.implantResist_Color); + + shadowLine = new PreviewShape(); + shadowLine.addPoints(shadow); + shadowLine.setColor(colors.implantMean_Color); + + minShadowLine = new PreviewShape(); + minShadowLine.addPoints(min); + minShadowLine.setColor(colors.implantMin_Color); + + maxShadowLine = new PreviewShape(); + maxShadowLine.addPoints(max); + maxShadowLine.setColor(colors.implantMax_Color); + + } + + public void setResistShapes(List newShapes) + { + pSetResistShapes(newShapes); + } + + void pSetResistShapes(List newShapes) + { + resistShapes = newShapes.ToList(); + } + + public void clear() + { + pClear(); + } + + void pClear() + { + resistShapes.Clear(); + shadowLine.clearPoints(); + minShadowLine.clearPoints(); + maxShadowLine.clearPoints(); + } + + public void set(Results_implant newResult) + { + pSet(newResult); + } + + void pSet(Results_implant newResult) + { + resistShapes = newResult.resistShapes.ToList(); + shadowLine.setPoints(newResult.shadowLine.getPoints()); + shadowLine.setColor(newResult.shadowLine.getColor()); + minShadowLine.setPoints(newResult.minShadowLine.getPoints()); + minShadowLine.setColor(newResult.minShadowLine.getColor()); + maxShadowLine.setPoints(newResult.maxShadowLine.getPoints()); + maxShadowLine.setColor(newResult.maxShadowLine.getColor()); + valid = newResult.valid; + } + + public enum lines { shadow, min, max } + PreviewShape shadowLine, minShadowLine, maxShadowLine; + + public PreviewShape getLine(lines l) + { + return pGetLine(l); + } + + PreviewShape pGetLine(lines l) + { + PreviewShape ret = new PreviewShape(); ; + switch (l) + { + case lines.shadow: + ret = shadowLine; + break; + case lines.min: + ret = minShadowLine; + break; + case lines.max: + ret = maxShadowLine; + break; + } + + return ret; + } + + string result, min, max; + + public string getResult() + { + return pGetResult(); + } + + string pGetResult() + { + return result; + } + + public void setResult(string val) + { + pSetResult(val); + } + + void pSetResult(string val) + { + result = val; + } + + public string getMin() + { + return pGetMin(); + } + + string pGetMin() + { + return min; + } + + public void setMin(string val) + { + pSetMin(val); + } + + void pSetMin(string val) + { + min = val; + } + + public string getMax() + { + return pGetMax(); + } + + string pGetMax() + { + return max; + } + + public void setMax(string val) + { + pSetMax(val); + } + + void pSetMax(string val) + { + max = val; + } + + bool valid; + + public void setValid(bool val) + { + pSetValid(val); + } + + void pSetValid(bool val) + { + valid = val; + } + + public bool isValid() + { + return pIsValid(); + } + + bool pIsValid() + { + return valid; + } + + public double resistHeightVar, resistWidthVar, resistCRRVar, tiltVar, twistVar; + + public Results_implant() + { + init(); + } + + void init() + { + resistShapes = new List(); + shadowLine = new PreviewShape(); + minShadowLine = new PreviewShape(); + maxShadowLine = new PreviewShape(); + valid = false; + } + } +} diff --git a/Common/Variance/results/simResultPackage.cs b/Common/Variance/results/simResultPackage.cs new file mode 100644 index 0000000..1132665 --- /dev/null +++ b/Common/Variance/results/simResultPackage.cs @@ -0,0 +1,553 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using utility; + +namespace Variance +{ + public class SimResultPackage + { + object previewLock; + string lastMeanStdDev; + object resultLock; + object cleavedResultLock; + object meanStdLock; + bool state; + + public bool getState() + { + return pGetState(); + } + + bool pGetState() + { + return state; + } + + public void setState(bool val) + { + pSetState(val); + } + + void pSetState(bool val) + { + state = val; + } + + Results previewResult; + + public Results getPreviewResult() + { + return pGetPreviewResult(); + } + + Results pGetPreviewResult() + { + return previewResult; + } + + Results_implant previewResult_implant; + + public Results_implant getImplantPreviewResult() + { + return pGetImplantPreviewResult(); + } + + Results_implant pGetImplantPreviewResult() + { + return previewResult_implant; + } + + List listOfResults; + + public List getListOfResults() + { + return pGetListOfResults(); + } + + List pGetListOfResults() + { + return listOfResults; + } + + public Results getResult(int index) + { + return pGetResult(index); + } + + Results pGetResult(int index) + { + return listOfResults[index]; + } + + List listOfResults_implant; + + public List getListOfResults_implant() + { + return pGetListOfResults_implant(); + } + + List pGetListOfResults_implant() + { + return listOfResults_implant; + } + + public Results_implant getImplantResult(int index) + { + return pGetImplantResult(index); + } + + Results_implant pGetImplantResult(int index) + { + return listOfResults_implant[index]; + } + + List pGetImplantResultStrings() + { + List resultStrings = new List(); + char[] s = { ',' }; + for (int i = 0; i < listOfResults_implant.Count; i++) + { + resultStrings.Add(listOfResults_implant[i].getResult().Split(s)); + } + + return resultStrings; + } + + List pGetResultStrings() + { + List resultStrings = new List(); + char[] s = { ',' }; + for (int i = 0; i < listOfResults.Count; i++) + { + resultStrings.Add(listOfResults[i].getResult().Split(s)); + } + + return resultStrings; + } + + public List getHistograms(int buckets = 100) + { + return pGetHistograms(buckets); + } + + List pGetHistograms(int buckets) + { + // Figure out which result package we should use. + if (listOfResults.Count > 0) + { + return pGetHistograms(pGetResultStrings(), buckets); + } + else if (listOfResults_implant.Count > 0) + { + return pGetHistograms(pGetImplantResultStrings(), buckets); + } + else + { + return new List() { "No results" }; + } + } + + List pGetHistograms(List results, int buckets) + { + int numberOfResultsFields = results[0].Length; + + List[] res = new List[numberOfResultsFields]; + + Parallel.For(0, numberOfResultsFields, (i) => + // for (int i = 0; i < numberOfResultsFields; i++) + { + res[i] = new List(); + }); + + for (int r = 0; r < results.Count; r++) + { + Parallel.For(0, numberOfResultsFields, (i) => + // for (int i = 0; i < numberOfResultsFields; i++) + { + // Could have "N/A" and need to skip the result in that case. + if (results[r][i] != "N/A") + { + res[i].Add(Convert.ToDouble(results[r][i])); + } + }); + } + + return pGetHistograms(res, buckets); + } + + List pGetHistograms(List[] values, int buckets) + { + List histograms = new List(); + // Generate histograms for each set, unless there are no results in that set. + for (int i = 0; i < values.Length; i++) + { + if (values[i].Count == 0) + { + histograms.Add("No data for result " + i.ToString() + "\r\n"); + } + else + { + histograms.Add("Histogram for result " + i.ToString() + ":\r\n"); + Histo h = new Histo(10, values[i].ToArray()); + histograms.Add(h.StemLeaf(true, buckets)); + } + } + + return histograms; + } + + List> cleavedResults; + double[] summedValues; + double[] summedSquarevalues; + Int32[] numberOfValues; + + public enum properties { mean, lastMean, stdDev, lastStdDev } + + double[] meanValues; + double[] lastMeanValues; + double[] stdDevValues; + double[] lastStdDevValues; + + public double[] getValues(properties p) + { + return pGetValues(p); + } + + double[] pGetValues(properties p) + { + double[] ret = new double[] { }; + + switch (p) + { + case properties.mean: + ret = meanValues; + break; + case properties.lastMean: + ret = lastMeanValues; + break; + case properties.stdDev: + ret = stdDevValues; + break; + case properties.lastStdDev: + ret = lastStdDevValues; + break; + } + + return ret; + } + + public double getValue(properties p, int index) + { + return pGetValue(p, index); + } + + double pGetValue(properties p, int index) + { + double ret = 0; + + switch (p) + { + case properties.mean: + ret = meanValues[index]; + break; + case properties.lastMean: + ret = lastMeanValues[index]; + break; + case properties.stdDev: + ret = stdDevValues[index]; + break; + case properties.lastStdDev: + ret = lastStdDevValues[index]; + break; + } + + return ret; + } + + public string resultString { get; set; } + char[] csvSeparator = new char[] { ',' }; // to cleave the results apart. + Results lastResult; + Results_implant lastResult_implant; + public double runTime { get; set; } + public bool nonGaussianInput { get; set; } + + public void setRunTime(double swTime) + { + runTime = swTime; + } + + public SimResultPackage(ref object previewLock, Int32 numberOfCases, Int32 numberOfResultsFields, bool state = true) + { + pSimResultPackage(ref previewLock, numberOfCases, numberOfResultsFields, state); + } + + void pSimResultPackage(ref object previewLock, Int32 numberOfCases, Int32 numberOfResultsFields, bool state = true) + { + nonGaussianInput = false; + this.previewLock = previewLock; + resultLock = new object(); + cleavedResultLock = new object(); + meanStdLock = new object(); + resultString = ""; + lastMeanStdDev = ""; + runTime = 0.0; + previewResult = new Results(); + previewResult_implant = new Results_implant(); + this.state = state; + listOfResults = new List(numberOfCases); + listOfResults_implant = new List(numberOfCases); + createCleavedResults(numberOfCases, numberOfResultsFields); + } + + public void Add(Results_implant newResult) + { + pAdd(newResult); + } + + void pAdd(Results_implant newResult) + { + if (Monitor.TryEnter(previewLock)) + { + try + { + previewResult_implant.set(newResult); + } + finally + { + Monitor.Exit(previewLock); + } + } + newResult.clear(); + + Monitor.Enter(resultLock); + try + { + listOfResults_implant.Add(newResult); + } + finally + { + Monitor.Exit(resultLock); + } + + lastResult_implant = newResult; + + updateCleavedResults(new string[] { newResult.getResult() }); + } + + public void Add(Results newResult, Int32 retainGeometry) + { + pAdd(newResult, retainGeometry); + } + + void pAdd(Results newResult, Int32 retainGeometry) + { + if (Monitor.TryEnter(previewLock)) + { + try + { + previewResult.setSimShapes(newResult.getSimShapes()); + previewResult.setPreviewShapes(newResult.getPreviewShapes()); + previewResult.setPoints(newResult.getPoints()); + previewResult.setValid(newResult.isValid()); + } + finally + { + Monitor.Exit(previewLock); + } + } + if (retainGeometry == 0) + { + newResult.clearPreviewShapes(); + newResult.clearSimShapes(); + newResult.clearPoints(); + } + + Monitor.Enter(resultLock); + try + { + listOfResults.Add(newResult); + } + finally + { + Monitor.Exit(resultLock); + } + + lastResult = newResult; + if ((lastResult.getResult() == "N/A") && (listOfResults.Count() == 1)) + { + // We just have one result so far and it's a fail - purge and move on. + resultString = "N/A"; + } + else + { + // Split the result string : + string[] tempStr = newResult.getResult().Split(csvSeparator); + updateCleavedResults(tempStr); + // update(); + } + } + + void createCleavedResults(Int32 numberOfCases, Int32 numberOfResultsFields) + { + cleavedResults = new List>(numberOfResultsFields); + numberOfValues = new Int32[numberOfResultsFields]; + meanValues = new double[numberOfResultsFields]; + stdDevValues = new double[numberOfResultsFields]; + summedValues = new double[numberOfResultsFields]; + summedSquarevalues = new double[numberOfResultsFields]; + for (Int32 i = 0; i < numberOfResultsFields; i++) + { + cleavedResults.Add(new List(numberOfCases)); + numberOfValues[i] = 0; + summedValues[i] = 0.0; + summedSquarevalues[i] = 0.0; + meanValues[i] = 0.0; + stdDevValues[i] = 0.0; + } + } + + public void updateCleavedResults(string[] newResults) + { + pUpdateCleavedResults(newResults); + } + + void pUpdateCleavedResults(string[] newResults) + { + Monitor.Enter(cleavedResultLock); + try + { + for (int i = 0; i < newResults.Length; i++) + { + if (newResults[i] == "N/A") + { + } + else + { + double newValue = Convert.ToDouble(newResults[i]); + cleavedResults[i].Add(newValue); + summedValues[i] += newValue; + summedSquarevalues[i] += newValue * newValue; + numberOfValues[i]++; + } + } + } + finally + { + Monitor.Exit(cleavedResultLock); + } + } + + void mean() + { + lastMeanValues = meanValues.ToArray(); + for (int i = 0; i < meanValues.Length; i++) + { + if (numberOfValues[i] == 0) + { + meanValues[i] = summedValues[i]; + } + else + { + meanValues[i] = summedValues[i] / numberOfValues[i]; // cleavedResults[i].Average(); + } + } + } + + void stdDev() + { + if (nonGaussianInput) + { + return; + } + lastStdDevValues = stdDevValues.ToArray(); + // Welford's approach + for (int i = 0; i < meanValues.Length; i++) + { + double m = 0.0; + double s = 0.0; + int k = 1; + + for (int value = 0; value < numberOfValues[i]; value++) + { + double tmpM = m; + + double _value = cleavedResults[i][value]; + m += (_value - tmpM) / k; + s += (_value - m) * (_value - tmpM); + k++; + } + + stdDevValues[i] = Math.Sqrt(s / (k - 2)); + } + } + + void setMeanAndStdDev() + { + // This is called with cleavedResult under a lock. + mean(); + stdDev(); + } + + public string getMeanAndStdDev() + { + return pGetMeanAndStdDev(); + } + + string pGetMeanAndStdDev() + { + string returnString = lastMeanStdDev; + Monitor.Enter(meanStdLock); + try + { + returnString = ""; + string[] tempString = new string[] { "" }; + + if (lastResult != null) + { + tempString = lastResult.getResult().Split(csvSeparator); + } + if (lastResult_implant != null) + { + tempString = lastResult_implant.getResult().Split(csvSeparator); + } + for (Int32 k = 0; k < meanValues.Length; k++) + { + setMeanAndStdDev(); + if (k > 0) + { + returnString += ","; + } + // Need to handle N/A cases. + if (tempString[k] == "N/A") + { + returnString += "N/A"; + } + else + { + try + { + returnString += "x: " + meanValues[k].ToString("0.##") + " (" + (meanValues[k] - lastMeanValues[k]).ToString("0.##") + ")"; + if (!nonGaussianInput) + { + returnString += ", s: " + stdDevValues[k].ToString("0.##") + " (" + (stdDevValues[k] - lastStdDevValues[k]).ToString("0.##") + ")"; + } + } + catch (Exception) + { + // Non-critical if an exception is raised, so we'll ignore it and carry on. + } + } + } + lastMeanStdDev = returnString; + } + finally + { + Monitor.Exit(meanStdLock); + } + return returnString; + } + } +} diff --git a/Common/Variance/support/Email.cs b/Common/Variance/support/Email.cs new file mode 100644 index 0000000..e36e854 --- /dev/null +++ b/Common/Variance/support/Email.cs @@ -0,0 +1,36 @@ +using Error; +using System; +using MailKit.Net.Smtp; +using MailKit; +using MimeKit; + +namespace Variance +{ + public static class Email + { + public static void Send(string host, string port, bool ssl, string subject, string messageContent, string address, string password) + { + if ((host != "") && (port != "") && (address != "") && (password != "")) + { + try + { + SmtpClient client = new SmtpClient(); + client.ServerCertificateValidationCallback = (s, c, h, e) => true; + client.Connect(host, Convert.ToInt32(port), ssl); + MimeMessage message = new MimeMessage(); + message.From.Add(new MailboxAddress(address)); + message.To.Add(new MailboxAddress(address)); + message.Subject = subject; + message.Body = new TextPart("plain") { Text = messageContent }; + client.Authenticate(address, password); + client.Send(message); + client.Disconnect(true); + } + catch (Exception ex) + { + ErrorReporter.showMessage_OK(ex.Message, "Email problem"); + } + } + } + } +} diff --git a/Common/Variance/support/SVGBuilder.cs b/Common/Variance/support/SVGBuilder.cs new file mode 100644 index 0000000..987f2df --- /dev/null +++ b/Common/Variance/support/SVGBuilder.cs @@ -0,0 +1,228 @@ +using color; +using geoLib; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace Variance +{ + using Polygon = List; + using Polygons = List>; + //a very simple class that builds an SVG file with any number of + //polygons of the specified formats ... + public class SVGBuilder + { + public class StyleInfo + { + public Int32 pft { get; set; } + public MyColor brushClr { get; set; } + public MyColor penClr { get; set; } + public double penWidth { get; set; } + public Int32[] dashArray { get; set; } + public Boolean showCoords { get; set; } + public StyleInfo Clone() + { + StyleInfo si = new StyleInfo(); + si.pft = pft; + si.brushClr = brushClr; + si.dashArray = dashArray; + si.penClr = penClr; + si.penWidth = penWidth; + si.showCoords = showCoords; + return si; + } + public StyleInfo() + { + pft = 0; // PolyFillType.pftNonZero; + brushClr = MyColor.AntiqueWhite; + dashArray = null; + penClr = MyColor.Black; + penWidth = 0.8; + showCoords = false; + } + } + + public class PolyInfo + { + public Polygons polygons { get; set; } + public StyleInfo si { get; set; } + //public Color pi_color; + } + + public class BoundingRect + { + public double bottom { get; set; } + public double top { get; set; } + public double left { get; set; } + public double right { get; set; } + } + + public StyleInfo style; + private List PolyInfoList; + const string svg_header = "\n" + + "\n\n" + + "\n\n"; + const string svg_path_format = "\"\n style=\"fill:{0};" + + " fill-opacity:0; fill-rule:{2}; stroke:{3};" + + " stroke-opacity:{4:f2}; stroke-width:{5:f2};\"/>\n\n"; + + public SVGBuilder() + { + PolyInfoList = new List(); + style = new StyleInfo(); + } + + public void AddPolygons(List pointArrayList) + { + Polygons tempPolygonsList = new Polygons(); + for (int listMember = 0; listMember < pointArrayList.Count(); listMember++) + { + Polygon tempPolygon = new Polygon(); + for (int pt = 0; pt < pointArrayList[listMember].Count(); pt++) + { + tempPolygon.Add(pointArrayList[listMember][pt]); + } + tempPolygonsList.Add(tempPolygon.ToList()); + } + AddPolygons(tempPolygonsList.ToList()); + } + + public void AddPolygons(GeoLibPointF[] pointArray) + { + Polygons tempPolygonsList = new Polygons(); + Polygon tempPolygon = new Polygon(); + for (int pt = 0; pt < pointArray.Count(); pt++) + { + tempPolygon.Add(pointArray[pt]); + } + tempPolygonsList.Add(tempPolygon.ToList()); + AddPolygons(tempPolygonsList.ToList()); + } + + public void AddPolygons(Polygons poly) + { + if (poly.Count == 0) return; + PolyInfo pi = new PolyInfo(); + pi.polygons = poly; + pi.si = style.Clone(); + PolyInfoList.Add(pi); + } + + public Boolean SaveToFile(string filename, double scale = 10.0, Int32 margin = 10) + { + // if (scale == 0) scale = 1.0; + // if (margin < 0) margin = 0; + + //calculate the bounding rect ... + Int32 i = 0, j = 0; + while (i < PolyInfoList.Count) + { + j = 0; + while (j < PolyInfoList[i].polygons.Count && + PolyInfoList[i].polygons[j].Count == 0) j++; + if (j < PolyInfoList[i].polygons.Count) break; + i++; + } + if (i == PolyInfoList.Count) return false; + BoundingRect rec = new BoundingRect(); + rec.left = PolyInfoList[i].polygons[j][0].X; + rec.right = rec.left; + rec.top = PolyInfoList[0].polygons[j][0].Y; + rec.bottom = rec.top; + + for (; i < PolyInfoList.Count; i++) + { + foreach (Polygon pg in PolyInfoList[i].polygons) + foreach (GeoLibPointF pt in pg) + { + if (pt.X < rec.left) rec.left = pt.X; + else if (pt.X > rec.right) rec.right = pt.X; + if (pt.Y < rec.top) rec.top = pt.Y; + else if (pt.Y > rec.bottom) rec.bottom = pt.Y; + } + } + + rec.left = rec.left * scale; + rec.top = rec.top * scale; + rec.right = rec.right * scale; + rec.bottom = rec.bottom * scale; + double offsetX = -rec.left + margin; + double offsetY = -rec.top + margin; + + using (StreamWriter writer = new StreamWriter(filename)) + { + writer.Write(svg_header, + (rec.right - rec.left) + margin * 2, + (rec.bottom - rec.top) + margin * 2, + (rec.right - rec.left) + margin * 2, + (rec.bottom - rec.top) + margin * 2); + + foreach (PolyInfo pi in PolyInfoList) + { + writer.Write(" \n\n"); + foreach (Polygon p in pi.polygons) + { + foreach (GeoLibPointF pt in p) + { + double x = pt.X; + double y = pt.Y; + writer.Write(String.Format( + "{2},{3}\n", + (x * scale + offsetX), (y * scale + offsetY), x, y)); + + } + writer.Write("\n"); + } + writer.Write("\n"); + } + } + writer.Write("\n"); + } + return true; + } + + static private GeoLibPointF[] PolygonToPointFArray(Polygon pg, float scale) + { + int l = pg.Count; + GeoLibPointF[] result = new GeoLibPointF[l]; + Parallel.For(0, l, (i) => + // for (Int32 i = 0; i < pg.Count; ++i) + { + result[i].X = (float)pg[i].X / scale; + result[i].Y = (float)pg[i].Y / scale; + }); + return result; + } + } +} diff --git a/Common/Variance/support/Storage.cs b/Common/Variance/support/Storage.cs new file mode 100644 index 0000000..4a05cd8 --- /dev/null +++ b/Common/Variance/support/Storage.cs @@ -0,0 +1,2428 @@ +using Error; +using geoLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; + +namespace Variance +{ + public class Storage + { + public delegate void PrepUI(); + public PrepUI prepUI { get; set; } + public delegate void StorageSetSettingsCallback(EntropyLayerSettings readSettings, int layer, bool gdsOnly, bool resumeUI, bool updateGeoCoreGeometryFromFile = false); + public StorageSetSettingsCallback setLayerSettings { get; set; } + public delegate void StorageSuspendSettingsUICallback(); + public StorageSuspendSettingsUICallback suspendSettingsUI { get; set; } + public delegate void StorageSuspendImplantUICallback(); + public StorageSuspendImplantUICallback suspendImplantUI { get; set; } + public delegate void StorageSuspendGDSSettingsUICallback(); + public StorageSuspendGDSSettingsUICallback suspendDOESettingsUI { get; set; } + public delegate void StorageUpdateSettingsUICallback(); + public StorageUpdateSettingsUICallback updateSettingsUIFromSettings { get; set; } + public delegate void StorageUpdateImplantUICallback(); + public StorageUpdateImplantUICallback updateImplantUIFromSettings { get; set; } + public delegate void StorageUpdateDOESettingsUICallback(); + public StorageUpdateDOESettingsUICallback updateDOESettingsUIFromSettings { get; set; } + public delegate bool StorageUpdateLoadLayoutCallback(int layer, string filename); + public StorageUpdateLoadLayoutCallback loadLayout { get; set; } + public delegate void ResumeUICallback(); + public ResumeUICallback resumeUI { get; set; } + + // Callbacks for viewport values. + public delegate void viewportLoadCallback(int index, double[] camInfo); + public viewportLoadCallback viewportLoad { get; set; } + public delegate double[] viewportSaveCallback(int index); // 2 fields : X and Y, zoom + public viewportSaveCallback viewportSave { get; set; } + + public delegate void implantViewportLoadCallback(double[] camInfo); + public implantViewportLoadCallback implantViewportLoad { get; set; } + public delegate double[] implantViewportSaveCallback(); // 3 fields : X and Y, zoom + public implantViewportSaveCallback implantViewportSave { get; set; } + + bool[] loadedLayers; + + public Storage() + { + pStorage(); + } + + void pStorage() + { + setLayerSettings = null; + suspendSettingsUI = null; + suspendDOESettingsUI = null; + updateSettingsUIFromSettings = null; + updateDOESettingsUIFromSettings = null; + } + + // compatibility shim for old projects pre-3.0 + void modifyLayerRefs_forLayerChange(ref EntropyLayerSettings readSettings, Int32 compatibilityLayerOffset) + { + if (compatibilityLayerOffset == 6) // v1.x-2.1 file + { + if ((readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == 2) || (readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == 3)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == 2) || (readSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == 3)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, readSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == 2) || (readSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == 3)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, readSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == 2) || (readSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == 3)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, readSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) == 2) || (readSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) == 3)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.xOL_ref, readSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) == 2) || (readSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) == 3)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.yOL_ref, readSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) + compatibilityLayerOffset); + } + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 2 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 2)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 3 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 3)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 2, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 3, 0); + + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 2 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 2)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 3 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 3)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 2, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 3, 0); + } + if (compatibilityLayerOffset == 4) // v2.2 file + { + if ((readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == 4) || (readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == 5) || + (readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == 6) || (readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == 7)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == 4) || (readSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == 5) || + (readSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == 6) || (readSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == 7)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, readSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == 4) || (readSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == 5) || + (readSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == 6) || (readSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == 7)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, readSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == 4) || (readSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == 5) || + (readSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == 6) || (readSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == 7)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, readSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) == 4) || (readSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) == 5) || + (readSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) == 6) || (readSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) == 7)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.xOL_ref, readSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) + compatibilityLayerOffset); + } + if ((readSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) == 4) || (readSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) == 5) || + (readSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) == 6) || (readSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) == 7)) + { + readSettings.setInt(EntropyLayerSettings.properties_i.yOL_ref, readSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) + compatibilityLayerOffset); + } + + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 4 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 4)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 5 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 5)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 6 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 6)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 7 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 7)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 4, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 5, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 6, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 7, 0); + + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 4 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 4)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 5 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 5)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 6 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 6)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 7 + compatibilityLayerOffset, readSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 7)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 4, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 5, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 6, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 7, 0); + } + } + + List fileDataFromString(string fileDataString) + { + List returnList = new List(); + + char[] polySep = new char[] { ';' }; + char[] coordSep = new char[] { ',' }; + + if (fileDataString.Length > 0) + { + List hashList = new List(); + + string[] polyStringArray = fileDataString.Split(polySep); + for (int poly = 0; poly < polyStringArray.Count(); poly++) + { + string[] pointStringArray = polyStringArray[poly].Split(coordSep); + GeoLibPointF[] polyData = new GeoLibPointF[pointStringArray.Count() / 2]; // since we have two coord values per point (X,Y) + int pt = 0; + while (pt < pointStringArray.Count()) + { + polyData[pt / 2] = new GeoLibPointF((float)Convert.ToDouble(pointStringArray[pt]), (float)Convert.ToDouble(pointStringArray[pt + 1])); + pt += 2; + } + + // Avoid duplicated geometry - this is insurance against older projects files that may have doubled-up polygons included. + string p_Hash = utility.Utils.GetMD5Hash(polyData); + if (hashList.IndexOf(p_Hash) == -1) + { + hashList.Add(p_Hash); + returnList.Add(polyData); + } + } + } + else + { + returnList.Add(new GeoLibPointF[] { new GeoLibPointF(0, 0) }); + returnList.Add(new GeoLibPointF[] { new GeoLibPointF(0, 0) }); + returnList.Add(new GeoLibPointF[] { new GeoLibPointF(0, 0) }); + } + return returnList; + } + + string stringFromFileData(List fileData) + { + string returnString = ""; + if (fileData != null) + { + int poly = 0; + int pt = 0; + returnString += fileData[poly][pt].X.ToString() + "," + fileData[poly][pt].Y.ToString(); + pt++; + while (pt < fileData[poly].Count()) + { + returnString += "," + fileData[poly][pt].X.ToString() + "," + fileData[poly][pt].Y.ToString(); + pt++; + } + poly++; + while (poly < fileData.Count()) + { + returnString += ";"; + pt = 0; + returnString += fileData[poly][0].X.ToString() + "," + fileData[poly][0].Y.ToString(); + pt++; + while (pt < fileData[poly].Count()) + { + returnString += "," + fileData[poly][pt].X.ToString() + "," + fileData[poly][pt].Y.ToString(); + pt++; + } + poly++; + } + } + else + { + } + return returnString; + } + + public bool storeSimulationSettings(string filename, EntropySettings simulationSettings, EntropySettings_nonSim simulationSettings_nonSim, List listOfSettings, EntropySettings implantSimSettings, EntropySettings_nonSim implantSettings_nonSim, EntropyImplantSettings implantSettings_, NonSimulationSettings nonSimulationSettings_) + { + return pStoreSimulationSettings(filename, simulationSettings, simulationSettings_nonSim, listOfSettings, implantSimSettings, implantSettings_nonSim, implantSettings_, nonSimulationSettings_); + } + + bool pStoreSimulationSettings(string filename, EntropySettings simulationSettings, EntropySettings_nonSim simulationSettings_nonSim, List listOfSettings, EntropySettings implantSimSettings, EntropySettings_nonSim implantSettings_nonSim, EntropyImplantSettings implantSettings_, NonSimulationSettings nonSimulationSettings_) + { + double[] camParameters; + XDocument doc = new XDocument(new XElement("Variance")); + doc.Root.Add(new XElement("version", nonSimulationSettings_.version)); + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + camParameters = viewportSave?.Invoke(i); + XElement xelement = new XElement("layer" + (i + 1).ToString(), + new XElement("name", listOfSettings[i].getString(EntropyLayerSettings.properties_s.name)), + new XElement("comment", listOfSettings[i].getString(EntropyLayerSettings.properties_s.comment)), + new XElement("enabled", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.enabled)), + new XElement("omitLayer", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.omit)), + new XElement("layer1BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 0)), + new XElement("layer2BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 1)), + new XElement("layer3BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 2)), + new XElement("layer4BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 3)), + new XElement("layer5BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 4)), + new XElement("layer6BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 5)), + new XElement("layer7BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 6)), + new XElement("layer8BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 7)), + new XElement("layer9BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 8)), + new XElement("layer10BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 9)), + new XElement("layer11BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 10)), + new XElement("layer12BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 11)), + new XElement("layer13BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 12)), + new XElement("layer14BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 13)), + new XElement("layer15BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 14)), + new XElement("layer16BG", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 15)), + new XElement("showDrawn", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.showDrawn)), + new XElement("flipH", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.flipH)), + new XElement("flipV", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.flipV)), + new XElement("alignGeomX", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.alignX)), + new XElement("alignGeomY", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.alignY)), + new XElement("shapeIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.shapeIndex)), + new XElement("geoCoreShapeEngine", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.gCSEngine)), + new XElement("subShapeHorLength", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)), + new XElement("subShapeHorOffset", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset)), + new XElement("subShapeVerLength", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)), + new XElement("subShapeVerOffset", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset)), + new XElement("subShapeTipLocIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.shape0Tip)), + new XElement("subShape2HorLength", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)), + new XElement("subShape2HorOffset", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)), + new XElement("subShape2VerLength", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)), + new XElement("subShape2VerOffset", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)), + new XElement("subShape2TipLocIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.shape1Tip)), + new XElement("subShape3HorLength", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength)), + new XElement("subShape3HorOffset", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset)), + new XElement("subShape3VerLength", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength)), + new XElement("subShape3VerOffset", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset)), + new XElement("subShape3TipLocIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.shape2Tip)), + new XElement("subShapeRefIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.subShapeIndex)), + new XElement("posInSubShapeIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.posIndex)), + new XElement("globalHorOffset", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.gHorOffset)), + new XElement("globalVerOffset", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.gVerOffset)), + new XElement("rotation", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.rot)), + new XElement("wobble", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.wobble)), + new XElement("wobbleRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.wobble_RNG)), + new XElement("sideBias", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.sBias)), + new XElement("horTipBias", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.hTBias)), + new XElement("horTipBiasPVar", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.hTPVar)), + new XElement("horTipBiasPVarRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.hTipPVar_RNG)), + new XElement("horTipBiasNVar", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.hTNVar)), + new XElement("horTipBiasNVarRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.hTipNVar_RNG)), + new XElement("verTipBias", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.vTBias)), + new XElement("verTipBiasPVar", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.vTPVar)), + new XElement("verTipBiasPVarRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.vTipPVar_RNG)), + new XElement("verTipBiasNVar", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.vTNVar)), + new XElement("verTipBiasNVarRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.vTipNVar_RNG)), + new XElement("proximityBias", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.pBias)), + new XElement("proximityIsoDistance", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.pBiasDist)), + new XElement("proximitySideRays", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.proxRays)), + new XElement("innerCRR", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.iCR)), + new XElement("outerCRR", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.oCR)), + new XElement("innerCV", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.iCV)), + new XElement("innerCVRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.iCV_RNG)), + new XElement("outerCV", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.oCV)), + new XElement("outerCVRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.oCV_RNG)), + new XElement("edgeSlide", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.edgeSlide)), + new XElement("edgeSlideTension", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.eTension)), + new XElement("LWR", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.lwr)), + new XElement("LWRRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.lwr_RNG)), + new XElement("LWRNoiseFreq", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.lwrFreq)), + new XElement("LWRNoiseType", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.lwrType)), + new XElement("LWR2", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.lwr2)), + new XElement("LWR2RNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.lwr2_RNG)), + new XElement("LWR2NoiseFreq", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.lwr2Freq)), + new XElement("LWR2NoiseType", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.lwr2Type)), + new XElement("LWRNoisePreview", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.lwrPreview)), + new XElement("sideCDU", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.sCDU)), + new XElement("sideCDURNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.sCDU_RNG)), + new XElement("tipsCDU", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.tCDU)), + new XElement("tipsCDURNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.tCDU_RNG)), + new XElement("horOverlay", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.xOL)), + new XElement("horOverlayRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.xOL_RNG)), + new XElement("verOverlay", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.yOL)), + new XElement("verOverlayRNGMapping", listOfSettings[i].getString(EntropyLayerSettings.properties_s.yOL_RNG)), + new XElement("correlatedXOverlay", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.xOL_corr)), + new XElement("correlatedXOverlayLayerIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.xOL_corr_ref)), + new XElement("correlatedYOverlay", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.yOL_corr)), + new XElement("correlatedYOverlayLayerIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.yOL_corr_ref)), + new XElement("correlatedTipCDU", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.tCDU_corr)), + new XElement("correlatedTipCDULayerIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref)), + new XElement("correlatedCDU", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.CDU_corr)), + new XElement("correlatedCDULayerIndex", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.CDU_corr_ref)), + new XElement("overlayXReferenceLayer", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.xOL_ref)), + new XElement("overlayYReferenceLayer", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.yOL_ref)), + + new XElement("averageOverlayX", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.xOL_av)), + new XElement("overlayXReferenceLayer_1", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 0)), + new XElement("overlayXReferenceLayer_2", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 1)), + new XElement("overlayXReferenceLayer_3", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 2)), + new XElement("overlayXReferenceLayer_4", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 3)), + new XElement("overlayXReferenceLayer_5", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 4)), + new XElement("overlayXReferenceLayer_6", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 5)), + new XElement("overlayXReferenceLayer_7", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 6)), + new XElement("overlayXReferenceLayer_8", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 7)), + new XElement("overlayXReferenceLayer_9", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 8)), + new XElement("overlayXReferenceLayer_10", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 9)), + new XElement("overlayXReferenceLayer_11", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 10)), + new XElement("overlayXReferenceLayer_12", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 11)), + new XElement("overlayXReferenceLayer_13", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 12)), + new XElement("overlayXReferenceLayer_14", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 13)), + new XElement("overlayXReferenceLayer_15", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 14)), + new XElement("overlayXReferenceLayer_16", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 15)), + + new XElement("averageOverlayY", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.yOL_av)), + new XElement("overlayYReferenceLayer_1", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 0)), + new XElement("overlayYReferenceLayer_2", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 1)), + new XElement("overlayYReferenceLayer_3", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 2)), + new XElement("overlayYReferenceLayer_4", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 3)), + new XElement("overlayYReferenceLayer_5", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 4)), + new XElement("overlayYReferenceLayer_6", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 5)), + new XElement("overlayYReferenceLayer_7", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 6)), + new XElement("overlayYReferenceLayer_8", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 7)), + new XElement("overlayYReferenceLayer_9", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 8)), + new XElement("overlayYReferenceLayer_10", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 9)), + new XElement("overlayYReferenceLayer_11", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 10)), + new XElement("overlayYReferenceLayer_12", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 11)), + new XElement("overlayYReferenceLayer_13", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 12)), + new XElement("overlayYReferenceLayer_14", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 13)), + new XElement("overlayYReferenceLayer_15", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 14)), + new XElement("overlayYReferenceLayer_16", listOfSettings[i].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 15)), + + new XElement("lensDistortionCoeff1", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.lDC1)), + new XElement("lensDistortionCoeff2", listOfSettings[i].getDecimal(EntropyLayerSettings.properties_decimal.lDC2)), + + new XElement("booleanLayerA", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.bLayerA)), + new XElement("booleanLayerB", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.bLayerB)), + new XElement("booleanLayerOpA", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.bLayerOpA)), + new XElement("booleanLayerOpB", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.bLayerOpB)), + new XElement("booleanLayerOpAB", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.bLayerOpAB)), + + new XElement("displayZoomFactor", (camParameters != null) ? camParameters[2] : 1), + new XElement("viewportX", (camParameters != null) ? camParameters[0] : 0), + new XElement("viewportY", (camParameters != null) ? camParameters[1] : 0), + new XElement("fileToLoad", listOfSettings[i].getString(EntropyLayerSettings.properties_s.file)), + new XElement("structureFromFile", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.structure)), + new XElement("structureNameFromFile", listOfSettings[i].getString(EntropyLayerSettings.properties_s.structure)), + new XElement("ldFromFile", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.lD)), + new XElement("ldNameFromFile", listOfSettings[i].getString(EntropyLayerSettings.properties_s.lD)), + new XElement("fileType", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.fileType)), + new XElement("polyFill", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.fill)), + new XElement("geoCoreShapeEngine", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.gCSEngine)), + new XElement("geoCoreShapeEnginePerPoly", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.perPoly)), + new XElement("geoCoreReferenceLayout", listOfSettings[i].getInt(EntropyLayerSettings.properties_i.refLayout)), + // fileData is List where each list entry is a polygon. + new XElement("fileData", stringFromFileData(listOfSettings[i].getFileData())) + ); + doc.Root.Add(xelement); + } + + camParameters = viewportSave?.Invoke(CentralProperties.maxLayersForMC); + doc.Root.Add(new XElement("settings", + new XElement("comment", simulationSettings_nonSim.getString(EntropySettings_nonSim.properties_s.comment)), + new XElement("paSearchComment", simulationSettings_nonSim.getString(EntropySettings_nonSim.properties_s.paComment)), + new XElement("numberOfCases", simulationSettings.getValue(EntropySettings.properties_i.nCases)), + new XElement("resolution", simulationSettings.getResolution()), + new XElement("displayResults", simulationSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.results)), + new XElement("displayZoomFactor", (camParameters != null) ? camParameters[2] : 1), + new XElement("viewportX", (camParameters != null) ? camParameters[0] : 0), + new XElement("viewportY", (camParameters != null) ? camParameters[1] : 0), + new XElement("displayShape", simulationSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.shape)), + new XElement("generateExternal", simulationSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.external)), + new XElement("externalType", simulationSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.externalType)), + new XElement("generateCSV", simulationSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.csv)), + new XElement("linkTipandSideCDU", simulationSettings.getValue(EntropySettings.properties_i.linkCDU)), + new XElement("lerFromLWR_by_sqrt2", simulationSettings.getValue(EntropySettings.properties_i.ler)), + new XElement("subMode", simulationSettings.getValue(EntropySettings.properties_i.subMode)), + new XElement("cornerSegments", simulationSettings.getValue(EntropySettings.properties_i.cSeg)), + new XElement("optimizeCorners", simulationSettings.getValue(EntropySettings.properties_i.optC)), + new XElement("greedyMode", simulationSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.greedy)), + new XElement("rng", simulationSettings.getValue(EntropySettings.properties_i.rngType)), + new XElement("outputType", simulationSettings.getValue(EntropySettings.properties_i.oType)), + new XElement("layer1Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 0)), + new XElement("layer2Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 1)), + new XElement("layer3Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 2)), + new XElement("layer4Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 3)), + new XElement("layer5Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 4)), + new XElement("layer6Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 5)), + new XElement("layer7Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 6)), + new XElement("layer8Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 7)), + new XElement("layer9Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 8)), + new XElement("layer10Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 9)), + new XElement("layer11Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 10)), + new XElement("layer12Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 11)), + new XElement("layer13Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 12)), + new XElement("layer14Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 13)), + new XElement("layer15Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 14)), + new XElement("layer16Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 15)), + new XElement("layer1_2Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 0)), + new XElement("layer3_4Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 1)), + new XElement("layer5_6Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 2)), + new XElement("layer7_8Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 3)), + new XElement("layer9_10Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 4)), + new XElement("layer11_12Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 5)), + new XElement("layer13_14Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 6)), + new XElement("layer15_16Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 7)), + new XElement("layer12_34Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 0)), + new XElement("layer56_78Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 1)), + new XElement("layer910_1112Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 2)), + new XElement("layer1314_1516Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 3)), + new XElement("layer1234_5678Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, 0)), + new XElement("layer9101112_13141516Operator", simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, 1)) + )); + + camParameters = viewportSave?.Invoke(CentralProperties.maxLayersForMC + 1); + doc.Root.Add(new XElement("DOESettings", + new XElement("displayZoomFactor", (camParameters != null) ? camParameters[2] : 1), + new XElement("viewportX", (camParameters != null) ? camParameters[0] : 0), + new XElement("viewportY", (camParameters != null) ? camParameters[1] : 0), + new XElement("comment", simulationSettings.getDOESettings().getString(DOESettings.properties_s.comment)), + new XElement("layer1Affected", simulationSettings.getDOESettings().getLayerAffected(0)), + new XElement("layer2Affected", simulationSettings.getDOESettings().getLayerAffected(1)), + new XElement("layer3Affected", simulationSettings.getDOESettings().getLayerAffected(2)), + new XElement("layer4Affected", simulationSettings.getDOESettings().getLayerAffected(3)), + new XElement("layer5Affected", simulationSettings.getDOESettings().getLayerAffected(4)), + new XElement("layer6Affected", simulationSettings.getDOESettings().getLayerAffected(5)), + new XElement("layer7Affected", simulationSettings.getDOESettings().getLayerAffected(6)), + new XElement("layer8Affected", simulationSettings.getDOESettings().getLayerAffected(7)), + new XElement("layer9Affected", simulationSettings.getDOESettings().getLayerAffected(8)), + new XElement("layer10Affected", simulationSettings.getDOESettings().getLayerAffected(9)), + new XElement("layer11Affected", simulationSettings.getDOESettings().getLayerAffected(10)), + new XElement("layer12Affected", simulationSettings.getDOESettings().getLayerAffected(11)), + new XElement("layer13Affected", simulationSettings.getDOESettings().getLayerAffected(12)), + new XElement("layer14Affected", simulationSettings.getDOESettings().getLayerAffected(13)), + new XElement("layer15Affected", simulationSettings.getDOESettings().getLayerAffected(14)), + new XElement("layer16Affected", simulationSettings.getDOESettings().getLayerAffected(15)), + new XElement("rowPitch", simulationSettings.getDOESettings().getDouble(DOESettings.properties_d.rowPitch)), + new XElement("colPitch", simulationSettings.getDOESettings().getDouble(DOESettings.properties_d.colPitch)), + new XElement("rows", simulationSettings.getDOESettings().getInt(DOESettings.properties_i.rows)), + new XElement("cols", simulationSettings.getDOESettings().getInt(DOESettings.properties_i.cols)), + new XElement("specificTile", simulationSettings.getDOESettings().getInt(DOESettings.properties_i.sTile)), + new XElement("specificTile_Row", simulationSettings.getDOESettings().getInt(DOESettings.properties_i.sTileRow)), + new XElement("specificTile_Col", simulationSettings.getDOESettings().getInt(DOESettings.properties_i.sTileCol)), + new XElement("colOffset", simulationSettings.getDOESettings().getDouble(DOESettings.properties_d.colOffset)), + new XElement("rowOffset", simulationSettings.getDOESettings().getDouble(DOESettings.properties_d.rowOffset)), + new XElement("listOfTiles", simulationSettings.getDOESettings().getInt(DOESettings.properties_i.uTileList)), + new XElement("tileList_ColRow", simulationSettings.tileListToString(true)), + new XElement("iDRMConfigured", simulationSettings.getDOESettings().getBool(DOESettings.properties_b.iDRM) ? 1 : 0) + )); + + camParameters = implantViewportSave?.Invoke(); + doc.Root.Add(new XElement("implant", + new XElement("displayZoomFactor", (camParameters != null) ? camParameters[2] : 1), + new XElement("viewportX", (camParameters != null) ? camParameters[0] : 0), + new XElement("viewportY", (camParameters != null) ? camParameters[1] : 0), + new XElement("comment", implantSettings_.getComment()), + new XElement("resistCRR", implantSettings_.getDouble(EntropyImplantSettings.properties_d.cRR)), + new XElement("resistCRRVar", implantSettings_.getDouble(EntropyImplantSettings.properties_d.cV)), + new XElement("resistHeight_postDevelop", implantSettings_.getDouble(EntropyImplantSettings.properties_d.h)), + new XElement("resistHeight_postDevelopVar", implantSettings_.getDouble(EntropyImplantSettings.properties_d.hV)), + new XElement("resistWidth", implantSettings_.getDouble(EntropyImplantSettings.properties_d.w)), + new XElement("resistWidthVar", implantSettings_.getDouble(EntropyImplantSettings.properties_d.wV)), + new XElement("tiltAngle", implantSettings_.getDouble(EntropyImplantSettings.properties_d.tilt)), + new XElement("tiltAngleVar", implantSettings_.getDouble(EntropyImplantSettings.properties_d.tiltV)), + new XElement("twistAngle", implantSettings_.getDouble(EntropyImplantSettings.properties_d.twist)), + new XElement("twistAngleVar", implantSettings_.getDouble(EntropyImplantSettings.properties_d.twistV)), + new XElement("numberOfCases", implantSimSettings.getValue(EntropySettings.properties_i.nCases)), + new XElement("cornerSegments", implantSimSettings.getValue(EntropySettings.properties_i.cSeg)), + new XElement("rngType", implantSimSettings.getValue(EntropySettings.properties_i.rngType)), + new XElement("generateCSV", implantSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.csv)), + new XElement("generateExternal", implantSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.external)), + new XElement("externalType", implantSettings_nonSim.getValue(EntropySettings_nonSim.properties_i.externalType)) + )); + + bool savedOK = true; + try + { + doc.Save(filename); + } + catch (Exception) + { + savedOK = false; + } + return savedOK; + } + + public string loadSimulationSettings(string currentVersion, string filename, EntropySettings simulationSettings, EntropySettings_nonSim simulationSettings_nonSim, List listOfSettings, EntropySettings implantSimSettings, EntropySettings_nonSim implantSettings_nonSim, EntropyImplantSettings implantSettings_, NonSimulationSettings nonSimulationSettings_) + { + return pLoadSimulationSettings(currentVersion, filename, simulationSettings, simulationSettings_nonSim, listOfSettings, implantSimSettings, implantSettings_nonSim, implantSettings_, nonSimulationSettings_); + } + + string pLoadSimulationSettings(string currentVersion, string filename, EntropySettings simulationSettings, EntropySettings_nonSim simulationSettings_nonSim, List listOfSettings, EntropySettings implantSimSettings, EntropySettings_nonSim implantSettings_nonSim, EntropyImplantSettings implantSettings_, NonSimulationSettings nonSimulationSettings_) + { + loadedLayers = new bool[CentralProperties.maxLayersForMC]; + string returnString = ""; + bool error = false; + XElement simulationFromFile; + try + { + simulationFromFile = XElement.Load(filename); + } + catch (Exception ex) + { + return ex.Message.ToString(); + } + + // root is required for legacy projects. + if ((simulationFromFile.Name != "Variance") && (simulationFromFile.Name != "root")) + { + error = true; + return "This is not a " + CentralProperties.productName + " project file."; + } + + EntropyLayerSettings readSettings = new EntropyLayerSettings(); + + string version = simulationFromFile.Descendants("version").First().Value; + string[] tokenVersion = version.Split(new char[] { '.' }); + + if (version != currentVersion) + { + ErrorReporter.showMessage_OK("Settings file for version " + version, "Legacy import"); + } + + prepUI?.Invoke(); + + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + // Tracking our loaded layers to avoid stomping over them. + if (loadedLayers[layer]) + { + continue; + } + + string layerref = "layer" + (layer + 1).ToString(); + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.enabled, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("enabled").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.enabled); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.comment, (simulationFromFile.Descendants(layerref).Descendants("comment").First().Value)); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.comment); + } + + readSettings.defaultIntArray(EntropyLayerSettings.properties_intarray.bglayers); + + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 0, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer1BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 1, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer2BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 2, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer3BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 3, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer4BG").First().Value)); + } + catch (Exception) + { + // default + } + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 4, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer5BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 5, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer6BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 6, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer7BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 7, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer8BG").First().Value)); + } + catch (Exception) + { + + } + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 8, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer9BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 9, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer10BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 10, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer11BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 11, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer12BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 12, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer13BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 13, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer14BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 14, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer15BG").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.bglayers, 15, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("layer16BG").First().Value)); + } + catch (Exception) + { + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.showDrawn, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("showDrawn").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.showDrawn); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.flipH, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("flipH").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.flipH); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.flipV, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("flipV").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.flipV); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.alignX, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("alignGeom").First().Value)); + readSettings.setInt(EntropyLayerSettings.properties_i.alignY, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("alignGeom").First().Value)); + } + catch (Exception) + { + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.alignX, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("alignGeomX").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.alignX); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.alignY, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("alignGeomY").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.alignY); + } + } + + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.name, simulationFromFile.Descendants(layerref).Descendants("name").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.name); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.shapeIndex, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("shapeIndex").First().Value)); + + // Version 1.9 broke the shape menu continuity as 'S' was inserted before the GDS. + + if ((Convert.ToInt32(tokenVersion[0]) == 1) && (Convert.ToInt32(tokenVersion[1]) < 9)) + { + if (readSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.Sshape) + { + readSettings.setInt(EntropyLayerSettings.properties_i.shapeIndex, (Int32)CommonVars.shapeNames.GEOCORE); //increment to map to the GDS setting in the 1.9 version. + } + } + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.shapeIndex); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s0HorLength, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShapeHorLength").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s0HorLength); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShapeHorOffset").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s0VerLength, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShapeVerLength").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s0VerLength); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShapeVerOffset").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.shape0Tip, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("subShapeTipLocIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.shape0Tip); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s1HorLength, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShape2HorLength").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s1HorLength); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShape2HorOffset").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s1VerLength, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShape2VerLength").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s1VerLength); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShape2VerOffset").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.shape1Tip, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("subShape2TipLocIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.shape1Tip); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s2HorLength, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShape3HorLength").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s2HorLength); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShape3HorOffset").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s2VerLength, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShape3VerLength").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s2VerLength); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("subShape3VerOffset").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.shape2Tip, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("subShape3TipLocIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.shape2Tip); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.subShapeIndex, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("subShapeRefIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.subShapeIndex); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.posIndex, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("posInSubShapeIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.posIndex); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.gHorOffset, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("globalHorOffset").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.gHorOffset); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.gVerOffset, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("globalVerOffset").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.gVerOffset); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.rot, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("rotation").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.rot); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.wobble, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("wobble").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.wobble); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.wobble_RNG, simulationFromFile.Descendants(layerref).Descendants("wobbleRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.wobble_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.sBias, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("sideBias").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.sBias); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.hTBias, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("horTipBias").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.hTBias); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.hTPVar, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("horTipBiasPVar").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.hTPVar); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.hTipPVar_RNG, simulationFromFile.Descendants(layerref).Descendants("horTipBiasPVarRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.hTipPVar_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.hTNVar, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("horTipBiasNVar").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.hTNVar); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.hTipNVar_RNG, simulationFromFile.Descendants(layerref).Descendants("horTipBiasNVarRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.hTipNVar_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.vTBias, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("verTipBias").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.vTBias); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.vTPVar, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("verTipBiasPVar").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.vTPVar); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.vTipPVar_RNG, simulationFromFile.Descendants(layerref).Descendants("verTipBiasPVarRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.vTipPVar_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.vTNVar, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("verTipBiasNVar").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.vTNVar); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.vTipNVar_RNG, simulationFromFile.Descendants(layerref).Descendants("verTipBiasNVarRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.vTipNVar_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.pBias, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("proximityBias").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.pBias); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.pBiasDist, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("proximityIsoDistance").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.pBiasDist); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.proxRays, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("proximitySideRays").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.proxRays); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.iCR, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("innerCRR").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.iCR); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.oCR, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("outerCRR").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.oCR); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.iCV, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("innerCV").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.iCV); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.iCV_RNG, simulationFromFile.Descendants(layerref).Descendants("innerCVRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.iCV_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.oCV, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("outerCV").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.oCV); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.oCV_RNG, simulationFromFile.Descendants(layerref).Descendants("outerCVRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.oCV_RNG); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.edgeSlide, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("edgeSlide").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.edgeSlide); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.eTension, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("edgeSlideTension").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.eTension); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.lwr, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("LWR").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.lwr); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.lwr_RNG, simulationFromFile.Descendants(layerref).Descendants("LWRRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.lwr_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.lwrFreq, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("LWRNoiseFreq").First().Value)); + } + catch (Exception) + { + // Compatability shim for old 3.x projects where setting name in XML was wrong. + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.lwrFreq, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("LWRFreq").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.lwrFreq); + } + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.lwrType, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("LWRNoiseType").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.lwrType); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.lwr2, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("LWR2").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.lwr2); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.lwr2_RNG, simulationFromFile.Descendants(layerref).Descendants("LWR2RNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.lwr2_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.lwr2Freq, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("LWR2NoiseFreq").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.lwr2Freq); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.lwr2Type, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("LWR2NoiseType").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.lwr2Type); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.lwrPreview, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("LWRNoisePreview").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.lwrPreview); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.sCDU, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("sideCDU").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.sCDU); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.sCDU_RNG, simulationFromFile.Descendants(layerref).Descendants("sideCDURNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.sCDU_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.tCDU, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("tipsCDU").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.tCDU); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.tCDU_RNG, simulationFromFile.Descendants(layerref).Descendants("tipsCDURNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.tCDU_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.xOL, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("horOverlay").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.xOL); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.xOL_RNG, simulationFromFile.Descendants(layerref).Descendants("horOverlayRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.xOL_RNG); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.yOL, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("verOverlay").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.yOL); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.yOL_RNG, simulationFromFile.Descendants(layerref).Descendants("verOverlayRNGMapping").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.yOL_RNG); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.xOL_corr, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("correlatedXOverlay").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.xOL_corr); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("correlatedXOverlayLayerIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.xOL_corr_ref); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.yOL_corr, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("correlatedYOverlay").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.yOL_corr); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("correlatedYOverlayLayerIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.yOL_corr_ref); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.CDU_corr, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("correlatedCDU").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.CDU_corr); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("correlatedCDULayerIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.CDU_corr_ref); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.tCDU_corr, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("correlatedTipCDU").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.tCDU_corr); // compatibility shim + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("correlatedTipCDULayerIndex").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.tCDU_corr_ref); // compatibility shim + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.xOL_ref, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.xOL_ref); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.yOL_ref, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.yOL_ref); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.xOL_av, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("averageOverlayX").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.xOL_av); + } + + + // We do this piecewise because 2.0 files have these entries, but only for four layers. + // We want to capture the settings without clobbering them in a one-size-fits-all exception handler. + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 0, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_1").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 1, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_2").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 2, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_3").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 3, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_4").First().Value)); + } + catch (Exception) + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 0, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 1, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 2, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 3, 0); + } + + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 4, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_5").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 5, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_6").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 6, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_7").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 7, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_8").First().Value)); + } + catch (Exception) + { + for (int i = 4; i < 8; i++) + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, i, 0); + } + } + + // v3 added more layers so another piecemeal read. + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 8, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_9").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 9, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_10").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 10, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_11").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 11, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_12").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 12, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_13").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 13, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_14").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 14, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_15").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, 15, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayXReferenceLayer_16").First().Value)); + } + catch (Exception) + { + for (int i = 8; i < CentralProperties.maxLayersForMC; i++) + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, i, 0); + } + } + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.yOL_av, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("averageOverlayY").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.yOL_av); + } + + // We do this piecewise because 2.0 files have these entries, but only for four layers. + // We want to capture the settings without clobbering them in a one-size-fits-all exception handler. + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 0, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_1").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 1, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_2").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 2, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_3").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 3, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_4").First().Value)); + } + catch (Exception) + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 0, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 1, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 2, 0); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 3, 0); + } + + + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 4, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_5").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 5, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_6").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 6, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_7").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 7, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_8").First().Value)); + } + catch (Exception) + { + for (int i = 4; i < 8; i++) + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, i, 0); + } + } + + try + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 8, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_9").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 9, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_10").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 10, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_11").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 11, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_12").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 12, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_13").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 13, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_14").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 14, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_15").First().Value)); + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, 15, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("overlayYReferenceLayer_16").First().Value)); + } + catch (Exception) + { + for (int i = 8; i < CentralProperties.maxLayersForMC; i++) + { + readSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, i, 0); + } + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.lDC1, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("lensDistortionCoeff1").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.lDC1); + } + + try + { + readSettings.setDecimal(EntropyLayerSettings.properties_decimal.lDC2, Convert.ToDecimal(simulationFromFile.Descendants(layerref).Descendants("lensDistortionCoeff2").First().Value)); + } + catch (Exception) + { + readSettings.defaultDecimal(EntropyLayerSettings.properties_decimal.lDC2); + } + + double x = 0; + double y = 0; + double zoom = 1; + try + { + x = Convert.ToDouble(simulationFromFile.Descendants(layerref).Descendants("viewportX").First().Value); + y = Convert.ToDouble(simulationFromFile.Descendants(layerref).Descendants("viewportY").First().Value); + zoom = Convert.ToDouble(simulationFromFile.Descendants(layerref).Descendants("displayZoomFactor").First().Value); + } + catch (Exception) + { + } + viewportLoad?.Invoke(layer, new double[] { x, y, zoom }); + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.bLayerA, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("booleanLayerA").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.bLayerA); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.bLayerB, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("booleanLayerB").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.bLayerB); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.bLayerOpA, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("booleanLayerOpA").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.bLayerOpA); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.bLayerOpB, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("booleanLayerOpB").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.bLayerOpB); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.bLayerOpAB, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("booleanLayerOpAB").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.bLayerOpAB); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.omit, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("omitLayer").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.omit); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.file, simulationFromFile.Descendants(layerref).Descendants("fileToLoad").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.file); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.refLayout, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("geoCoreReferenceLayout").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.refLayout); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.fileType, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("fileType").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.fileType); + } + + bool loadLayoutOK = false; + if (readSettings.getInt(EntropyLayerSettings.properties_i.refLayout) == 1) + { + // Need to read in our layout file. + try + { + loadLayoutOK = loadLayout(layer, readSettings.getString(EntropyLayerSettings.properties_s.file)); + } + catch (Exception) + { + loadLayoutOK = false; + } + if (!loadLayoutOK) + { + // Load error in some form. + // Error path is unclear. + ErrorReporter.showMessage_OK("External file read error. Using project geometry.", readSettings.getString(EntropyLayerSettings.properties_s.file)); + } + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.structure, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("structureFromFile").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.structure); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.structure, simulationFromFile.Descendants(layerref).Descendants("structureNameFromFile").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.structure); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.lD, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("ldFromFile").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.lD); + } + + try + { + readSettings.setString(EntropyLayerSettings.properties_s.lD, simulationFromFile.Descendants(layerref).Descendants("ldNameFromFile").First().Value); + } + catch (Exception) + { + readSettings.defaultString(EntropyLayerSettings.properties_s.lD); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.fill, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("polyFill").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.fill); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.gCSEngine, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("geoCoreShapeEngine").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.gCSEngine); + } + + try + { + readSettings.setInt(EntropyLayerSettings.properties_i.perPoly, Convert.ToInt32(simulationFromFile.Descendants(layerref).Descendants("geoCoreShapeEnginePerPoly").First().Value)); + } + catch (Exception) + { + readSettings.defaultInt(EntropyLayerSettings.properties_i.perPoly); + } + + readSettings.setReloaded(true); + + try + { + readSettings.setFileData(fileDataFromString(simulationFromFile.Descendants(layerref).Descendants("fileData").First().Value)); + } + catch (Exception) + { + readSettings.defaultFileData(); + } + + bool updateGeoCoreGeometryFromFile = false; + if (readSettings.getInt(EntropyLayerSettings.properties_i.refLayout) == 1) + { + // Update the internal layout based on the loaded configuration. + if (loadLayoutOK) + { + updateGeoCoreGeometryFromFile = true; + } + else + { + // Reset the reference layout because user saving this project later will break things as we have reset the LD and structure indices. + readSettings.defaultInt(EntropyLayerSettings.properties_i.refLayout); + readSettings.defaultInt(EntropyLayerSettings.properties_i.lD); + readSettings.defaultInt(EntropyLayerSettings.properties_i.structure); + } + } + + // Compatibility patch for pre-3.0 project files, due to the introduction of more layers. + // Layers 3,4 need to be mapped to 5,6 in the new system + Int32 compatibilityLayerOffset = 0; // to bump layer 3 to layer 5; layer 4 to layer 6. + if ((Convert.ToInt32(tokenVersion[0]) == 1) || + ((Convert.ToInt32(tokenVersion[0]) == 2) && (Convert.ToInt32(tokenVersion[1]) < 1))) + { + compatibilityLayerOffset = 6; + } + else + { + if (Convert.ToInt32(tokenVersion[0]) == 2) + { + compatibilityLayerOffset = 4; + } + } + if (compatibilityLayerOffset != 0) + { + modifyLayerRefs_forLayerChange(ref readSettings, compatibilityLayerOffset); + if (((compatibilityLayerOffset == 6) && ((layer == 2) || (layer == 3))) || + ((compatibilityLayerOffset == 4) && ((layer == 4) || (layer == 5) || (layer == 6) || (layer == 7)))) + { + // Full layer remap + setLayerSettings?.Invoke(readSettings, layer + compatibilityLayerOffset, false, true); + double[] camDetails = viewportSave?.Invoke(layer); + viewportLoad?.Invoke(layer + compatibilityLayerOffset, camDetails); + viewportLoad?.Invoke(layer, new double[] { 0, 0, 1 }); + loadedLayers[layer + compatibilityLayerOffset] = true; + readSettings = new EntropyLayerSettings(); + } + } + setLayerSettings?.Invoke(readSettings, layer, false, false, updateGeoCoreGeometryFromFile); // avoid resuming the UI + loadedLayers[layer] = true; + } + + try + { + suspendSettingsUI?.Invoke(); + + try + { + simulationSettings_nonSim.setString(EntropySettings_nonSim.properties_s.comment, (simulationFromFile.Descendants("settings").Descendants("comment").First().Value)); + } + catch (Exception) + { + simulationSettings_nonSim.defaultString(EntropySettings_nonSim.properties_s.comment); + } + + try + { + simulationSettings_nonSim.setString(EntropySettings_nonSim.properties_s.paComment, (simulationFromFile.Descendants("settings").Descendants("paSearchComment").First().Value)); + } + catch (Exception) + { + simulationSettings_nonSim.defaultString(EntropySettings_nonSim.properties_s.paComment); + } + + try + { + simulationSettings.setValue(EntropySettings.properties_i.nCases, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("numberOfCases").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultValue(EntropySettings.properties_i.nCases); + } + + try + { + simulationSettings.setResolution(Convert.ToDouble(simulationFromFile.Descendants("settings").Descendants("resolution").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultResolution(); + } + + try + { + simulationSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.results, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("displayResults").First().Value)); + } + catch (Exception) + { + simulationSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.results); + } + + try + { + simulationSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.shape, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("displayShape").First().Value)); + } + catch (Exception) + { + simulationSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.shape); + } + + double x = 0; + double y = 0; + double zoom = 1; + try + { + x = Convert.ToDouble(simulationFromFile.Descendants("settings").Descendants("viewportX").First().Value); + y = Convert.ToDouble(simulationFromFile.Descendants("settings").Descendants("viewportY").First().Value); + zoom = Convert.ToDouble(simulationFromFile.Descendants("settings").Descendants("displayZoomFactor").First().Value); + } + catch (Exception) + { + } + viewportLoad?.Invoke(CentralProperties.maxLayersForMC, new double[] { x, y, zoom }); + + int svgCompat = 0; + try + { + svgCompat = Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("generateSVG").First().Value); + } + catch (Exception) + { + } + + if (svgCompat == 1) + { + simulationSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.external, 1); + simulationSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.externalType, (Int32)CommonVars.external_Type.svg); + } + else + { + try + { + simulationSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.external, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("generateExternal").First().Value)); + } + catch (Exception) + { + simulationSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.external); + } + try + { + simulationSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.externalType, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("externalType").First().Value)); + } + catch (Exception) + { + simulationSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.externalType); + } + } + try + { + simulationSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.csv, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("generateCSV").First().Value)); + } + catch (Exception) + { + simulationSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.csv); + } + + try + { + simulationSettings.setValue(EntropySettings.properties_i.linkCDU, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("linkTipandSideCDU").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultValue(EntropySettings.properties_i.linkCDU); + } + + try + { + simulationSettings.setValue(EntropySettings.properties_i.subMode, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("subMode").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultValue(EntropySettings.properties_i.subMode); + } + + try + { + simulationSettings.setValue(EntropySettings.properties_i.cSeg, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("cornerSegments").First().Value)); + } + catch (Exception) + { + try + { + // Compatibility handling for old projects. + double angleStep = Convert.ToDouble(simulationFromFile.Descendants("settings").Descendants("angleStep").First().Value); + simulationSettings.setValue(EntropySettings.properties_i.cSeg, (Int32)(90.0f / angleStep)); + } + catch (Exception) + { + simulationSettings.defaultValue(EntropySettings.properties_i.cSeg); + } + } + + try + { + simulationSettings.setValue(EntropySettings.properties_i.optC, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("optimizeCorners").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultValue(EntropySettings.properties_i.optC); + } + + try + { + simulationSettings.setValue(EntropySettings.properties_i.ler, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("lerFromLWR_by_sqrt2").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultValue(EntropySettings.properties_i.ler); + } + + try + { + simulationSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.greedy, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("greedyMode").First().Value)); + } + catch (Exception) + { + simulationSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.greedy); + } + + try + { + simulationSettings.setValue(EntropySettings.properties_i.rngType, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("rng").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultValue(EntropySettings.properties_i.rngType); + } + + try + { + simulationSettings.setValue(EntropySettings.properties_i.oType, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("outputType").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultValue(EntropySettings.properties_i.oType); + } + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + string ts = "layer" + (i + 1).ToString() + "Operator"; + try + { + simulationSettings.setOperatorValue(EntropySettings.properties_o.layer, i, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants(ts).First().Value)); + } + catch (Exception) + { + simulationSettings.defaultOperator(EntropySettings.properties_o.layer, i); + } + } + + for (int i = 0; i < simulationSettings.getOperator(EntropySettings.properties_o.twoLayer).Length; i++) + { + string ts = "layer" + ((i * 2) + 1).ToString() + "_" + ((i + 1) * 2).ToString() + "Operator"; + try + { + simulationSettings.setOperatorValue(EntropySettings.properties_o.twoLayer, i, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants(ts).First().Value)); + } + catch (Exception) + { + simulationSettings.defaultOperator(EntropySettings.properties_o.twoLayer, i); + } + } + + for (int i = 0; i < simulationSettings.getOperator(EntropySettings.properties_o.fourLayer).Length; i++) + { + int v = (i * simulationSettings.getOperator(EntropySettings.properties_o.fourLayer).Length) + 1; + string ts = "layer" + v.ToString() + (v + 1).ToString() + "_" + (v + 2).ToString() + (v + 3).ToString() + "Operator"; + try + { + simulationSettings.setOperatorValue(EntropySettings.properties_o.fourLayer, i, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants(ts).First().Value)); + } + catch (Exception) + { + simulationSettings.defaultOperator(EntropySettings.properties_o.fourLayer, i); + } + } + + try + { + simulationSettings.setOperatorValue(EntropySettings.properties_o.eightLayer, 0, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("layer1234_5678Operator").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultOperator(EntropySettings.properties_o.eightLayer, 0); + } + + try + { + simulationSettings.setOperatorValue(EntropySettings.properties_o.eightLayer, 1, Convert.ToInt32(simulationFromFile.Descendants("settings").Descendants("layer9101112_13141516Operator").First().Value)); + } + catch (Exception) + { + simulationSettings.defaultOperator(EntropySettings.properties_o.eightLayer, 1); + } + + // Compatibility patch for pre-3.0 project files, due to the introduction of more layers. + if ((Convert.ToInt32(tokenVersion[0]) == 1) || + ((Convert.ToInt32(tokenVersion[0]) == 2) && (Convert.ToInt32(tokenVersion[1]) < 1))) + { + simulationSettings.setOperatorValue(EntropySettings.properties_o.layer, 8, simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 2)); + simulationSettings.defaultOperator(EntropySettings.properties_o.layer, 2); + + simulationSettings.setOperatorValue(EntropySettings.properties_o.layer, 9, simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 3)); + simulationSettings.defaultOperator(EntropySettings.properties_o.layer, 3); + + simulationSettings.setOperatorValue(EntropySettings.properties_o.twoLayer, 4, simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 1)); + simulationSettings.defaultOperator(EntropySettings.properties_o.twoLayer, 1); + } + else + { + if (Convert.ToInt32(tokenVersion[0]) == 2) + { + simulationSettings.setOperatorValue(EntropySettings.properties_o.layer, 8, simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 4)); + simulationSettings.defaultOperator(EntropySettings.properties_o.layer, 4); + + simulationSettings.setOperatorValue(EntropySettings.properties_o.layer, 9, simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 5)); + simulationSettings.defaultOperator(EntropySettings.properties_o.layer, 5); + + simulationSettings.setOperatorValue(EntropySettings.properties_o.twoLayer, 4, simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 2)); + simulationSettings.defaultOperator(EntropySettings.properties_o.twoLayer, 2); + + simulationSettings.setOperatorValue(EntropySettings.properties_o.layer, 10, simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 6)); + simulationSettings.defaultOperator(EntropySettings.properties_o.layer, 6); + + simulationSettings.setOperatorValue(EntropySettings.properties_o.layer, 11, simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 7)); + simulationSettings.defaultOperator(EntropySettings.properties_o.layer, 7); + + simulationSettings.setOperatorValue(EntropySettings.properties_o.twoLayer, 5, simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 3)); + simulationSettings.defaultOperator(EntropySettings.properties_o.twoLayer, 3); + } + } + updateSettingsUIFromSettings?.Invoke(); + } + catch (Exception) + { + ErrorReporter.showMessage_OK("Failed in settings loading", "Error"); + error = true; + } + + try + { + string doeLabel = "DOESettings"; + if (tokenVersion[0] == "1") // backward compatibility + { + doeLabel = "gdsDOESettings"; + } + + suspendDOESettingsUI?.Invoke(); + try + { + simulationSettings.getDOESettings().setString(DOESettings.properties_s.comment, (simulationFromFile.Descendants(doeLabel).Descendants("comment").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setString(DOESettings.properties_s.comment, DOESettings.default_comment); + } + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + string t = "layer" + (i + 1).ToString() + "Affected"; + try + { + simulationSettings.getDOESettings().setLayerAffected(layer:i, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants(t).First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setLayerAffected(layer:i, 0); + } + } + + // Compatibility patch for pre-3.0 project files, due to the introduction of more layers. + if ((Convert.ToInt32(tokenVersion[0]) == 1) || + ((Convert.ToInt32(tokenVersion[0]) == 2) && (Convert.ToInt32(tokenVersion[1]) < 1))) + { + simulationSettings.getDOESettings().setLayerAffected(layer: 8, simulationSettings.getDOESettings().getLayerAffected(2)); + simulationSettings.getDOESettings().setLayerAffected(layer: 2, 0); + simulationSettings.getDOESettings().setLayerAffected(layer: 9, simulationSettings.getDOESettings().getLayerAffected(3)); + simulationSettings.getDOESettings().setLayerAffected(layer: 3, 0); + } + else + { + if (Convert.ToInt32(tokenVersion[0]) == 2) + { + simulationSettings.getDOESettings().setLayerAffected(layer: 8, simulationSettings.getDOESettings().getLayerAffected(4)); + simulationSettings.getDOESettings().setLayerAffected(layer: 4, 0); + simulationSettings.getDOESettings().setLayerAffected(layer: 9, simulationSettings.getDOESettings().getLayerAffected(5)); + simulationSettings.getDOESettings().setLayerAffected(layer: 5, 0); + simulationSettings.getDOESettings().setLayerAffected(layer: 10, simulationSettings.getDOESettings().getLayerAffected(6)); + simulationSettings.getDOESettings().setLayerAffected(layer: 6, 0); + simulationSettings.getDOESettings().setLayerAffected(layer: 11, simulationSettings.getDOESettings().getLayerAffected(7)); + simulationSettings.getDOESettings().setLayerAffected(layer: 7, 0); + } + } + + try + { + simulationSettings.getDOESettings().setDouble(DOESettings.properties_d.rowPitch, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("rowPitch").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setDouble(DOESettings.properties_d.rowPitch, DOESettings.default_rowPitch); + } + + try + { + simulationSettings.getDOESettings().setDouble(DOESettings.properties_d.colPitch, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("colPitch").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setDouble(DOESettings.properties_d.colPitch, DOESettings.default_colPitch); + } + + try + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.rows, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("rows").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.rows, DOESettings.default_rows); + } + + try + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.cols, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("cols").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.cols, DOESettings.default_cols); + } + + try + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.sTile, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("specificTile").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.sTile, DOESettings.default_specificTile); + } + + try + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.sTileRow, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("specificTile_Row").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.sTileRow, DOESettings.default_specificTile_Row); + } + + try + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.sTileCol, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("specificTile_Col").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.sTileCol, DOESettings.default_specificTile_Col); + } + + try + { + simulationSettings.getDOESettings().setDouble(DOESettings.properties_d.colOffset, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("colOffset").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setDouble(DOESettings.properties_d.colOffset, DOESettings.default_colOffset); + } + + try + { + simulationSettings.getDOESettings().setDouble(DOESettings.properties_d.rowOffset, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("rowOffset").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setDouble(DOESettings.properties_d.rowOffset, DOESettings.default_rowOffset); + } + + try + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.uTileList, Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("listOfTiles").First().Value)); + } + catch (Exception) + { + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.uTileList, DOESettings.default_listOfTiles); + } + + try + { + simulationSettings.getDOESettings().setString(DOESettings.properties_s.list, simulationFromFile.Descendants(doeLabel).Descendants("tileList_ColRow").First().Value); + } + catch (Exception) + { + simulationSettings.getDOESettings().setString(DOESettings.properties_s.list, DOESettings.default_trList); + } + + simulationSettings.setTileList(simulationSettings.getDOESettings().getString(DOESettings.properties_s.list), true); + try + { + if (Convert.ToInt32(simulationFromFile.Descendants(doeLabel).Descendants("iDRMConfigured").First().Value) == 1) + { + simulationSettings.getDOESettings().setBool(DOESettings.properties_b.iDRM, true); + simulationSettings.getDOESettings().setInt(DOESettings.properties_i.uTileList, 1); + } + else + { + simulationSettings.getDOESettings().setBool(DOESettings.properties_b.iDRM, false); + } + } + catch (Exception) + { + simulationSettings.getDOESettings().setBool(DOESettings.properties_b.iDRM, false); + } + + double x = 0; + double y = 0; + double zoom = 1; + try + { + x = Convert.ToDouble(simulationFromFile.Descendants(doeLabel).Descendants("viewportX").First().Value); + y = Convert.ToDouble(simulationFromFile.Descendants(doeLabel).Descendants("viewportY").First().Value); + zoom = Convert.ToDouble(simulationFromFile.Descendants(doeLabel).Descendants("displayZoomFactor").First().Value); + } + catch (Exception) + { + } + viewportLoad?.Invoke(CentralProperties.maxLayersForMC + 1, new double[] { x, y, zoom }); + + updateDOESettingsUIFromSettings?.Invoke(); + } + catch (Exception ex) + { + ErrorReporter.showMessage_OK("Failed in DOE loading: " + ex.ToString(), "Error"); + error = true; + } + + try + { + string implantLabel = "implant"; + + suspendImplantUI?.Invoke(); + try + { + implantSettings_.setComment(simulationFromFile.Descendants(implantLabel).Descendants("comment").First().Value); + } + catch (Exception) + { + implantSettings_.setComment(""); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.cRR, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("resistCRR").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.cRR); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.cV, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("resistCRRVar").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.cV); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.h, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("resistHeight_postDevelop").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.h); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.hV, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("resistHeight_postDevelopVar").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.hV); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.w, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("resistWidth").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.w); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.wV, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("resistWidthVar").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.wV); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.tilt, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("tiltAngle").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.tilt); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.tiltV, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("tiltAngleVar").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.tiltV); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.twist, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("twistAngle").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.twist); + } + try + { + implantSettings_.setDouble(EntropyImplantSettings.properties_d.twistV, Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("twistAngleVar").First().Value)); + } + catch (Exception) + { + implantSettings_.defaultDouble(EntropyImplantSettings.properties_d.twistV); + } + try + { + implantSimSettings.setValue(EntropySettings.properties_i.nCases, Convert.ToInt32(simulationFromFile.Descendants(implantLabel).Descendants("numberOfCases").First().Value)); + } + catch (Exception) + { + implantSimSettings.defaultValue(EntropySettings.properties_i.nCases); + } + try + { + implantSimSettings.setValue(EntropySettings.properties_i.cSeg, Convert.ToInt32(simulationFromFile.Descendants(implantLabel).Descendants("cornerSegments").First().Value)); + } + catch (Exception) + { + implantSimSettings.defaultValue(EntropySettings.properties_i.cSeg); + } + try + { + implantSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.csv, Convert.ToInt32(simulationFromFile.Descendants(implantLabel).Descendants("generateCSV").First().Value)); + } + catch (Exception) + { + implantSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.csv); + } + + int svgCompat = 0; + try + { + svgCompat = Convert.ToInt32(simulationFromFile.Descendants(implantLabel).Descendants("generateSVG").First().Value); + } + catch (Exception) + { + } + + if (svgCompat == 1) + { + implantSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.external, 1); + implantSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.externalType, (Int32)CommonVars.external_Type.svg); + } + else + { + try + { + implantSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.external, Convert.ToInt32(simulationFromFile.Descendants(implantLabel).Descendants("generateExternal").First().Value)); + } + catch (Exception) + { + implantSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.external); + } + try + { + implantSettings_nonSim.setValue(EntropySettings_nonSim.properties_i.externalType, Convert.ToInt32(simulationFromFile.Descendants(implantLabel).Descendants("externalTyoe").First().Value)); + } + catch (Exception) + { + implantSettings_nonSim.defaultValue(EntropySettings_nonSim.properties_i.externalType); + } + } + + try + { + implantSimSettings.setValue(EntropySettings.properties_i.rngType, Convert.ToInt32(simulationFromFile.Descendants(implantLabel).Descendants("rngType").First().Value)); + } + catch (Exception) + { + implantSimSettings.defaultValue(EntropySettings.properties_i.rngType); + } + + double x = 0; + double y = 0; + double zoom = 1; + try + { + x = Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("viewportX").First().Value); + y = Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("viewportY").First().Value); + zoom = Convert.ToDouble(simulationFromFile.Descendants(implantLabel).Descendants("displayZoomFactor").First().Value); + } + catch (Exception) + { + } + implantViewportLoad?.Invoke(new double[] { x, y, zoom }); + + updateImplantUIFromSettings?.Invoke(); + } + catch (Exception ex) + { + ErrorReporter.showMessage_OK("Failed in implant loading: " + ex.ToString(), "Error"); + error = true; + } + + resumeUI?.Invoke(); + + if (error) + { + returnString = "an error occurred"; + } + return returnString; + } + } +} diff --git a/Common/Variance/support/VarianceContext.cs b/Common/Variance/support/VarianceContext.cs new file mode 100644 index 0000000..fa9d5ce --- /dev/null +++ b/Common/Variance/support/VarianceContext.cs @@ -0,0 +1,91 @@ +using color; +using keys; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +namespace Variance +{ + public class VarianceContext + { + // This is intended to hold application context settings to allow for cleaner handling of + // commandline options related to headless mode, XML file loading from the command line, viewport switches + + public object previewLock; + public object implantPreviewLock; + public bool implantMode { get; set; } + public string xmlFileArg { get; set; } + public int numberOfThreads { get; set; } + public object referenceUI { get; set; } + public string host { get; set; } + public string port { get; set; } + public bool ssl { get; set; } + public bool perJob { get; set; } + public bool completion { get; set; } + public string emailAddress { get; set; } + public string emailPwd { get; set; } + public Int32 openGLZoomFactor { get; set; } + public double FGOpacity { get; set; } + public double BGOpacity { get; set; } + public bool AA { get; set; } + public bool FilledPolygons { get; set; } + public bool drawPoints { get; set; } + public Colors colors { get; set; } + public bool layerPreviewDOETile { get; set; } + public bool geoCoreCDVariation { get; set; } + public Int32 HTCount { get; set; } + public List rngMappingEquations { get; set; } + public string licenseLocation { get; set; } + public byte[] _certPubicKeyData { get; set; } + public bool friendlyNumber { get; set; } + + // License data. + public SimpleAES aes { get; set; } + public string licenceName { get; set; } + public string licenceType { get; set; } + public string licenceExpiration { get; set; } + + public VarianceContext(bool implantMode_, string xmlFileArg_, int numberOfThreads_, + Int32 HTCount, string refName = "Variance") + { + makeContext(implantMode_, xmlFileArg_, numberOfThreads_, HTCount, refName); + } + + void makeContext(bool implantMode_, string xmlFileArg_, int numberOfThreads_, + Int32 HTCount, string refName) + { + previewLock = new object(); + implantPreviewLock = new object(); + implantMode = implantMode_; + xmlFileArg = xmlFileArg_; + numberOfThreads = numberOfThreads_; + emailAddress = ""; + emailPwd = ""; + host = ""; + port = "587"; + ssl = true; + perJob = false; + completion = false; + openGLZoomFactor = 1; + FilledPolygons = false; + drawPoints = false; + AA = true; + FGOpacity = 0.7; + BGOpacity = 0.5; + colors = new Colors(); + layerPreviewDOETile = false; + geoCoreCDVariation = false; + this.HTCount = HTCount; + rngMappingEquations = new List(); + friendlyNumber = false; + + string _msg = string.Empty; + + aes = new SimpleAES(Arrays.nameKey, Arrays.nameVector); + licenceExpiration = ""; + licenceType = "advanced_permanent"; + licenceName = "GPLv3"; + } + } +} diff --git a/Common/Variance/support/VarianceContextGUI.cs b/Common/Variance/support/VarianceContextGUI.cs new file mode 100644 index 0000000..982a67e --- /dev/null +++ b/Common/Variance/support/VarianceContextGUI.cs @@ -0,0 +1,18 @@ +using System; +using Veldrid; + +namespace Variance +{ + public class VarianceContextGUI + { + public GraphicsBackend backend { get; set; } + public VarianceContext vc; + + public VarianceContextGUI(bool implantMode_, string xmlFileArg_, int numberOfThreads_, + Int32 HTCount, GraphicsBackend backend_, string refName = "Variance") + { + vc = new VarianceContext(implantMode_, xmlFileArg_, numberOfThreads_, HTCount, refName); + backend = backend_; + } + } +} diff --git a/Common/Variance/support/centralProperties.cs b/Common/Variance/support/centralProperties.cs new file mode 100644 index 0000000..e04c300 --- /dev/null +++ b/Common/Variance/support/centralProperties.cs @@ -0,0 +1,13 @@ +namespace Variance +{ + public static class CentralProperties + { + public const string productName = "Variance"; + public const string version = "4.2"; + public const int maxLayersForMC = 16; // maximum number of supported layers in MC system + public const int scaleFactorForOperation = 10000; + public enum typeShapes { none, rectangle, L, T, X, U, S, GEOCORE, BOOLEAN }; + + public const int timer_interval = 1000; + } +} diff --git a/Common/Variance/support/commonVars.cs b/Common/Variance/support/commonVars.cs new file mode 100644 index 0000000..479aee0 --- /dev/null +++ b/Common/Variance/support/commonVars.cs @@ -0,0 +1,2402 @@ +using color; +using entropyRNG; +using Error; +using geoCoreLib; +using keys; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Threading; +using utility; + +namespace Variance +{ + public class CommonVars + { + bool changed; + + public void setChanged(bool val) + { + pSetChanged(val); + } + + void pSetChanged(bool val) + { + changed = val; + } + + public bool isChanged() + { + return pIsChanged(); + } + + bool pIsChanged() + { + return changed; + } + + public enum hashes { gc, settings, entropy, implant, entropyImplant } + + string geoCoreHash; + + string listOfSettingsHash; + + string entropyGeoHash; + + string implantHash; + string entropyImplantHash; + + public string getHash(hashes p) + { + return pGetHash(p); + } + + string pGetHash(hashes p) + { + string ret = ""; + switch (p) + { + case hashes.gc: + ret = geoCoreHash; + break; + case hashes.settings: + ret = listOfSettingsHash; + break; + case hashes.entropy: + ret = entropyGeoHash; + break; + case hashes.implant: + ret = implantHash; + break; + case hashes.entropyImplant: + ret = entropyImplantHash; + break; + } + + return ret; + } + + SimpleAES aes; + + public Thread mainThreadIndex; + Colors colors; + public Colors getColors() + { + return pGetColors(); + } + + Colors pGetColors() + { + return colors; + } + + public void setColors(Colors source) + { + pSetColors(source); + } + + void pSetColors(Colors source) + { + colors = source; + } + + public System.Timers.Timer m_timer { get; set; } + + public bool userCancelQuery { get; set; } // used to track whether user is being queried. + public bool cancelling { get; set; } // used to track whether we are currently in the abort check method, to avoid duplicate calls. + public bool runAbort { get; set; } // whether to abort or not, based on the user response to the dialog tracked by userCancelQuery. + public bool loadAbort { get; set; } // whether to abort or not, used by GDS loading system. + + public enum properties_gl { aa, fill, points } + + bool AA; + bool filledPolygons; + bool drawPoints; + + bool friendlyNumber; + + public void setFriendly(bool val) + { + pSetFriendly(val); + } + + void pSetFriendly(bool val) + { + friendlyNumber = val; + } + + public bool getFriendly() + { + return pGetFriendly(); + } + + bool pGetFriendly() + { + return friendlyNumber; + } + + public void setOpenGLProp(properties_gl p, bool val) + { + pSetOpenGLProp(p, val); + } + + void pSetOpenGLProp(properties_gl p, bool val) + { + switch (p) + { + case properties_gl.aa: + AA = val; + break; + case properties_gl.fill: + filledPolygons = val; + break; + case properties_gl.points: + drawPoints = val; + break; + } + } + + public bool getOpenGLProp(properties_gl p) + { + return pGetOpenGLProp(p); + } + + bool pGetOpenGLProp(properties_gl p) + { + bool ret = false; + switch (p) + { + case properties_gl.aa: + ret = AA; + break; + case properties_gl.fill: + ret = filledPolygons; + break; + case properties_gl.points: + ret = drawPoints; + break; + } + + return ret; + } + + bool layerPreviewDOETile; + + public bool getLayerPreviewDOETile() + { + return pGetLayerPreviewDOETile(); + } + + bool pGetLayerPreviewDOETile() + { + return layerPreviewDOETile; + } + + public void setLayerPreviewDOETile(bool val) + { + pSetLayerPreviewDOETile(val); + } + + void pSetLayerPreviewDOETile(bool val) + { + layerPreviewDOETile = val; + } + + public enum gl_i { zoom } + + Int32 openGLZoomFactor; + + public Int32 getGLInt(gl_i i) + { + return pGetGLInt(i); + } + + Int32 pGetGLInt(gl_i i) + { + int ret = 0; + switch (i) + { + case gl_i.zoom: + ret = openGLZoomFactor; + break; + } + return ret; + } + + public void setGLInt(gl_i i, Int32 val) + { + pSetGLInt(i, val); + } + + void pSetGLInt(gl_i i, Int32 val) + { + switch (i) + { + case gl_i.zoom: + openGLZoomFactor = val; + break; + } + } + + public enum opacity_gl { fg, bg } + double openGLFGOpacity; + double openGLBGOpacity; + + public double getOpacity(opacity_gl o) + { + return pGetOpacity(o); + } + + double pGetOpacity(opacity_gl o) + { + double ret = 0; + switch (o) + { + case opacity_gl.fg: + ret = openGLFGOpacity; + break; + case opacity_gl.bg: + ret = openGLBGOpacity; + break; + } + + return ret; + } + + public void setOpacity(opacity_gl o, double val) + { + pSetOpacity(o, val); + } + + void pSetOpacity(opacity_gl o, double val) + { + switch (o) + { + case opacity_gl.fg: + openGLFGOpacity = val; + break; + case opacity_gl.bg: + openGLBGOpacity = val; + break; + } + } + + int openGLMode; // 0 is VBO, 1 is immediate mode + public object drawingLock { get; set; } + public object implantDrawingLock { get; set; } + + bool geoCoreCDVariation; + + public bool getGCCDV() + { + return pGetGCCDV(); + } + + bool pGetGCCDV() + { + return geoCoreCDVariation; + } + + public void setGCCDV(bool val) + { + pSetGCCDV(val); + } + + void pSetGCCDV(bool val) + { + geoCoreCDVariation = val; + } + + int replayMode; + + public int getReplayMode() + { + return pGetReplayMode(); + } + + int pGetReplayMode() + { + return replayMode; + } + + public void setReplayMode(int val) + { + pSetReplayMode(val); + } + + void pSetReplayMode(int val) + { + replayMode = val; + } + + public Int32 HTCount { get; set; } + + public Storage storage { get; set; } + + // UI list elements that get referenced in DataContext. + public ObservableCollection[] subshapes { get; set; } + public ObservableCollection subShapesList_exp { get; set; } + public ObservableCollection layerNames { get; set; } + + // Collection that we use to populate the custom RNG mapping menus on variations. + public static string boxMuller = "Box-Muller"; + public ObservableCollection rngCustomMapping { get; set; } + + bool simulationRunning; + public bool isSimRunning() + { + return pIsSimRunning(); + } + + bool pIsSimRunning() + { + return simulationRunning; + } + + public void setSimRunning(bool val) + { + pSetSimRunning(val); + } + + void pSetSimRunning(bool val) + { + simulationRunning = val; + } + + public string version { get; set; } + public string author { get; set; } + public string titleText { get; set; } + + string licDuration, licFeatures, licExpiration; + + public enum l { d, f, e } + + public string getL(l L) + { + return pGetL(L); + } + + string pGetL(l L) + { + string ret = ""; + + switch (L) + { + case l.d: + ret = licDuration; + break; + case l.e: + ret = licExpiration; + break; + case l.f: + ret = licFeatures; + break; + } + + return ret; + } + + bool licExpired; + + public bool getE() + { + return pGetE(); + } + + bool pGetE() + { + return licExpired; + } + + public void setE(bool val) + { + pSetE(val); + } + + void pSetE(bool val) + { + licExpired = val; + } + + public string projectFileName = ""; + bool warningShown, geoCoreCDUWarningShown; + + public bool wasWarningShown() + { + return pWarningShown(); + } + + bool pWarningShown() + { + return warningShown; + } + + public void setWarningShown(bool val) + { + pSetWarningShown(val); + } + + void pSetWarningShown(bool val) + { + warningShown = val; + } + + string[] calcMode = new string[] { "AREA", "SPACING_ENCLOSURE", "CHORD", "ANGLE" }; + public enum calcModes { area, enclosure_spacing_overlap, chord, angle }; + string[] spacEncMode = new string[] { "SPACING", "ENCLOSURE", "SPACINGOLD", "ENCLOSUREOLD" }; + public enum areaCalcModes { all, perpoly }; + public enum spacingCalcModes { spacing, enclosure, spacingOld, enclosureOld }; // exp triggers projection from shortest edge for overlap evaluation. + public enum chordCalcElements { none, a, b }; + public enum upperTabNames { twoD, Implant, oneD, Utilities }; + public enum twoDTabNames { layer, settings, DOE, paSearch }; + + public static string[] csvHeader = new string[] { "CDUSVar", "CDUTVar", "LWRVar", "LWRSeed", "LWR2Var", "LWR2Seed", "horTipBiasVar", "verTipBiasVar", "iCVar", "oCVar", "overlayX", "overlayY", "wobbleVar" }; + + public enum external_Type { svg, gds, oas } + List externalTypes = new List() { "SVG", "GDS", "Oasis" }; + + public List getExternalTypes() + { + return externalTypes; + } + + NonSimulationSettings nonSimulationSettings; + + public NonSimulationSettings getNonSimulationSettings() + { + return pGetNonSimulationSettings(); + } + + NonSimulationSettings pGetNonSimulationSettings() + { + return nonSimulationSettings; + } + + EntropyImplantSettings implantSettings; + public EntropyImplantSettings getImplantSettings() + { + return pGetImplantSettings(); + } + + EntropyImplantSettings pGetImplantSettings() + { + return implantSettings; + } + + EntropySettings implantSimulationSettings; + public EntropySettings getImplantSimulationSettings() + { + return pGetImplantSimulationSettings(); + } + + EntropySettings pGetImplantSimulationSettings() + { + return implantSimulationSettings; + } + + EntropySettings_nonSim implantSettings_nonSim; + public EntropySettings_nonSim getImplantSettings_nonSim() + { + return pGetImplantSettings_nonSim(); + } + + EntropySettings_nonSim pGetImplantSettings_nonSim() + { + return implantSettings_nonSim; + } + + bool copyPrepped; + public void setCopy(int index) + { + pSetCopy(index); + } + + void pSetCopy(int index) + { + copyPrepped = true; + pSetCopyLayerSettings(index); + pSetCopyLayerGHSettings(index); + pSetCopyDOEUse(index); + } + + public bool isCopyPrepped() + { + return pIsCopyPrepped(); + } + + bool pIsCopyPrepped() + { + return copyPrepped; + } + + public void clearCopy() + { + pClearCopy(); + } + + void pClearCopy() + { + copyPrepped = false; + } + + public void paste(int index, bool gdsOnly, bool updateGeoCoreGeometryFromFile = false) + { + pPaste(index, gdsOnly, updateGeoCoreGeometryFromFile); + } + + void pPaste(int index, bool gdsOnly, bool updateGeoCoreGeometryFromFile = false) + { + pSetLayerSettings(copyLayerSettings, index, gdsOnly, updateGeoCoreGeometryFromFile); + } + + public void setLayerSettings(EntropyLayerSettings entropyLayerSettings, int index, bool gdsOnly, bool updateGeoCoreGeometryFromFile = false) + { + pSetLayerSettings(entropyLayerSettings, index, gdsOnly, updateGeoCoreGeometryFromFile); + } + + void pSetLayerSettings(EntropyLayerSettings entropyLayerSettings, int index, bool gdsOnly, bool updateGeoCoreGeometryFromFile = false) + { + // This is used by the pasteHandler and clearHandler to set user interface values to align with the settings. + // It is also used by the load from disk file system, using a temporary MCSettings instance as the source + // In the case of the clearHandler, we get sent a new MCLayerSettings instance, so we have to handle that. + // Check our copyFrom reference. We need to do this early before anything could change. + + // Change settings if the license doesn't support them. + if (licFeatures != "advanced") + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.lwrType, (Int32)CommonVars.noiseIndex.perlin); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.gCSEngine, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.edgeSlide, 0); + } + + if (!gdsOnly) + { + if (isCopyPrepped()) + { + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr) == 1) || (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr) == 1) || (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr) == 1)) + { + // User pasting into the correlation layer. Disable correlation settings accordingly. + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == index) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.xOL_corr, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == index) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.yOL_corr, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) == index) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.xOL_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) == index) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.yOL_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == index) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.CDU_corr, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == index) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.tCDU_corr, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, -1); + } + } + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerA) == index) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.bLayerA, -1); + } + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerB) == index) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.bLayerB, -1); + } + } + } + + // Remove any average overlay reference to the layer we're in, just for safety. + entropyLayerSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, index, 0); + entropyLayerSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, index, 0); + + + try + { + if (isCopyPrepped()) + { + getSimulationSettings().getDOESettings().setLayerAffected(index, copyDOEUse); + } + } + catch (Exception) + { + } + + if ((entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.sCDU) != 0.0m) && (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) && + (geoCoreCDVariation == false)) + { + if (!geoCoreCDUWarningShown) + { + geoCoreCDUWarningShown = true; + ErrorReporter.showMessage_OK("Project uses Oasis/GDS CD variation.", "Overriding preference."); + geoCoreCDVariation = true; + } + } + + if (isCopyPrepped()) + { + // Align the external data. + getGeoCoreHandler(index).readValues(copyLayerGHSettings); + } + else + { + getGeoCoreHandler(index).setValid(false); + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) && (entropyLayerSettings.isReloaded())) + { + getGeoCoreHandler(index).setFilename(entropyLayerSettings.getString(EntropyLayerSettings.properties_s.file)); + getGeoCoreHandler(index).setValid(true); + bool updateSuccess = false; + if (updateGeoCoreGeometryFromFile) + { + getGeoCoreHandler(index).getGeo().updateCollections(); + // Get the indices based on the stored structure / layerdatatype + int structureFromFile = Array.IndexOf(getGeoCoreHandler(index).getGeo().getStructureList().ToArray(), entropyLayerSettings.getString(EntropyLayerSettings.properties_s.structure)); + if (structureFromFile != -1) + { + int ldFromFile = Array.IndexOf(getGeoCoreHandler(index).getGeo().getActiveStructureLDList().ToArray(), entropyLayerSettings.getString(EntropyLayerSettings.properties_s.lD)); + if (ldFromFile != -1) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.structure, structureFromFile); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.lD, ldFromFile); + getGeoCoreHandler(index).getGeo().updateGeometry(entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.structure), entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.lD)); + getGeoCoreHandler(index).setPoints(entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.structure), entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.lD)); + // Map our points into the layer's file data, if the layer is active. + entropyLayerSettings.setFileData(getGeoCoreHandler(index).getGeo().points()); + updateSuccess = true; + } + } + + if (!updateSuccess) + { + // Settings could not be mapped to external file data. + ErrorReporter.showMessage_OK("Could not find named structure or layer/datatype. Using stored geometry.", "Layout reference error"); + } + } + + if (!updateGeoCoreGeometryFromFile || (updateGeoCoreGeometryFromFile && !updateSuccess)) + { + getGeoCoreHandler(index).getGeo().structureList_.Clear(); + getGeoCoreHandler(index).getGeo().structureList_.Add(entropyLayerSettings.getString(EntropyLayerSettings.properties_s.structure)); + getGeoCoreHandler(index).getGeo().activeStructure_LayerDataTypeList_.Clear(); + getGeoCoreHandler(index).getGeo().activeStructure_LayerDataTypeList_.Add(entropyLayerSettings.getString(EntropyLayerSettings.properties_s.lD)); + } + } + } + + // Commit our settings to the list. + getLayerSettings(index).adjustSettings(entropyLayerSettings, gdsOnly); + } + + EntropyLayerSettings copyLayerSettings; + public void setCopyLayerSettings(int index) + { + pSetCopyLayerSettings(index); + } + + void pSetCopyLayerSettings(int index) + { + copyLayerSettings.adjustSettings(getLayerSettings(index), gdsOnly: false); + } + + GeoCoreHandler copyLayerGHSettings; + public void setCopyLayerGHSettings(int index) + { + pSetCopyLayerGHSettings(index); + } + + void pSetCopyLayerGHSettings(int index) + { + copyLayerGHSettings.readValues(getGeoCoreHandler(index)); + } + + public void pasteGeoCoreHandler(int index) + { + pPasteGeoCoreHandler(index); + } + + void pPasteGeoCoreHandler(int index) + { + getGeoCoreHandler(index).getGeo().readValues(copyLayerGHSettings.getGeo()); + } + + int copyDOEUse; + + public int getCopyDOEUse() + { + return pGetCopyDOEUse(); + } + + int pGetCopyDOEUse() + { + return copyDOEUse; + } + + void pSetCopyDOEUse(int index) + { + copyDOEUse = getSimulationSettings().getDOESettings().getLayerAffected(index); + } + + EntropySettings simulationSettings; + + public EntropySettings getSimulationSettings() + { + return pGetSimulationSettings(); + } + + EntropySettings pGetSimulationSettings() + { + return simulationSettings; + } + + EntropySettings_nonSim simulationSettings_nonSim; + + public EntropySettings_nonSim getSimulationSettings_nonSim() + { + return pGetSimulationSettings_nonSim(); + } + + EntropySettings_nonSim pGetSimulationSettings_nonSim() + { + return simulationSettings_nonSim; + } + + PASearch paSearch; + public PASearch getPASearch() + { + return pGetPASearch(); + } + + PASearch pGetPASearch() + { + return paSearch; + } + + List listOfSettings; + + public List getListOfSettings() + { + return pGetistOfSettings(); + } + + List pGetistOfSettings() + { + return listOfSettings; + } + + public EntropyLayerSettings getLayerSettings(int i) + { + return pGetLayerSettings(i); + } + + EntropyLayerSettings pGetLayerSettings(int i) + { + return listOfSettings[i]; + } + + public bool isLayerActive(int i) + { + return pIsLayerActive(i); + } + + bool pIsLayerActive(int i) + { + return getLayerSettings(i).isLayerActive(); + } + + public bool interLayerRelationship_2(int i) + { + return pInterLayerRelationship_2(i); + } + + bool pInterLayerRelationship_2(int i) + { + bool status = isLayerActive(i * 2) && isLayerActive((i * 2) + 1); + return status; + } + + public bool interLayerRelationship_4(int i) + { + return pInterLayerRelationship_4(i); + } + + bool pInterLayerRelationship_4(int i) + { + bool status = isLayerActive(i * 4) || isLayerActive((i * 4) + 1); + status = status && (isLayerActive((i * 4) + 2) || isLayerActive((i * 4) + 3)); + + return status; + } + + public ObservableCollection calcMode_names { get; set; } + + List availableShapes; + public List getAvailableShapes() + { + return pGetAvailableShapes(); + } + + List pGetAvailableShapes() + { + return availableShapes; + } + + string[] shapesShortNames = new string[] { "NONE", "RECT", "L", "T", "X", "U", "S", "GEOCORE", "BOOLEAN" }; + public enum shapeNames { none, rect, Lshape, Tshape, Xshape, Ushape, Sshape, GEOCORE, BOOLEAN }; + List availableTipsLocations; + public List getAvailableTipsLocations() + { + return pGetAvailableTipsLocations(); + } + + List pGetAvailableTipsLocations() + { + return availableTipsLocations; + } + + public enum tipLocations { none, L, R, LR, T, B, TB, TL, TR, TLR, BL, BR, BLR, TBL, TBR, all }; + + List availableSubShapePositions; + + public List getAvailableSubShapePositions() + { + return pGetAvailableSubShapePositions(); + } + + List pGetAvailableSubShapePositions() + { + return availableSubShapePositions; + } + + public enum subShapeLocations { TL, TR, BL, BR, TS, RS, BS, LS, C }; + + List noiseTypes; + public List getNoiseTypes() + { + return pGetNoiseTypes(); + } + + List pGetNoiseTypes() + { + return noiseTypes; + } + + public enum noiseIndex { perlin, simplex, opensimplex }; + + List polyFillTypes; + public List getPolyFillTypes() + { + return pGetPolyFillTypes(); + } + + List pGetPolyFillTypes() + { + return polyFillTypes; + } + + public enum PolyFill { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; + + List openGLModeList; + + public List getOpenGLModeList() + { + return pGetOpenGLModeList(); + } + + List pGetOpenGLModeList() + { + return openGLModeList; + } + + SimulationPreview simPreview; + + public SimulationPreview getSimPreview() + { + return pGetSimPreview(); + } + + SimulationPreview pGetSimPreview() + { + return simPreview; + } + + List geoCore_Handlers; + public List getGeoCoreHandlers() + { + return pGetGeoCoreHandlers(); + } + + List pGetGeoCoreHandlers() + { + return geoCore_Handlers; + } + + public GeoCoreHandler getGeoCoreHandler(int index) + { + return pGetGeoCoreHandler(index); + } + + GeoCoreHandler pGetGeoCoreHandler(int index) + { + return geoCore_Handlers[index]; + } + + public ObservableCollection[] structureList { get; set; } + public ObservableCollection[] activeStructure_LayerDataTypeList { get; set; } + + public ObservableCollection structureList_exp { get; set; } + public ObservableCollection activeStructure_LayerDataTypeList_exp { get; set; } + + // These are used to manage layer refresh events. + public enum uiActive { settings, doe, implant } + bool settingsUIActive; + bool DOESettingsUIActive; + bool implantUIActive; + + public bool getActiveUI(uiActive u) + { + return pGetActiveUI(u); + } + + bool pGetActiveUI(uiActive u) + { + bool ret = false; + switch (u) + { + case uiActive.doe: + ret = DOESettingsUIActive; + break; + case uiActive.settings: + ret = settingsUIActive; + break; + case uiActive.implant: + ret = implantUIActive; + break; + } + return ret; + } + + public void setActiveUI(uiActive u, bool val) + { + pSetActiveUI(u, val); + } + + void pSetActiveUI(uiActive u, bool val) + { + switch (u) + { + case uiActive.doe: + DOESettingsUIActive = val; + break; + case uiActive.implant: + implantUIActive = val; + break; + case uiActive.settings: + settingsUIActive = val; + break; + } + } + + public void licenceCheck(VarianceContext varianceContext) + { + pLicenceCheck(varianceContext); + } + + void pLicenceCheck(VarianceContext varianceContext) + { + licDuration = "permanent"; + licFeatures = "advanced"; + licExpiration = ""; + } + + public CommonVars(VarianceContext varianceContext) + { + pCommonVars(varianceContext); + } + + public void reset(VarianceContext varianceContext) + { + pReset(varianceContext); + } + + void pReset(VarianceContext varianceContext) + { + simulationSettings = new EntropySettings(); + nonSimulationSettings = new NonSimulationSettings(CentralProperties.version); + + storage = new Storage(); + warningShown = false; + geoCoreCDUWarningShown = false; + // simPreview set-up + simPreview = new SimulationPreview(ref varianceContext); + runAbort = false; + simulationRunning = false; + + openGLZoomFactor = varianceContext.openGLZoomFactor; + openGLFGOpacity = varianceContext.FGOpacity; + openGLBGOpacity = varianceContext.BGOpacity; + AA = varianceContext.AA; + filledPolygons = varianceContext.FilledPolygons; + drawPoints = varianceContext.drawPoints; + geoCoreCDVariation = varianceContext.geoCoreCDVariation; + layerPreviewDOETile = varianceContext.layerPreviewDOETile; + + friendlyNumber = varianceContext.friendlyNumber; + + HTCount = varianceContext.HTCount; + + // This is our copy layer reference. false denotes no copy buffer is valid. + copyPrepped = false; + + simulationSettings = new EntropySettings(); + nonSimulationSettings = new NonSimulationSettings(CentralProperties.version); + simulationSettings_nonSim = new EntropySettings_nonSim(); + paSearch = new PASearch(); + implantSettings_nonSim = new EntropySettings_nonSim(); + // This will contain our settings for the 2D simulation component + listOfSettings = new List(); + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + listOfSettings.Add(new EntropyLayerSettings()); + listOfSettings[layer].setString(EntropyLayerSettings.properties_s.name, (layer + 1).ToString()); + layerNames[layer] = (layer + 1).ToString(); + // External file data lists + geoCore_Handlers[layer].setValid(false); + geoCore_Handlers[layer].getGeo().reset(); + } + + activeStructure_LayerDataTypeList_exp = activeStructure_LayerDataTypeList[0]; + structureList_exp = structureList[0]; + + // Implant + implantSettings = new EntropyImplantSettings(); + implantSimulationSettings = new EntropySettings(); + implantSimulationSettings.setValue(EntropySettings.properties_i.rngType, (Int32)commonRNG.rngIndex.system_random); + implantSimulationSettings.setValue(EntropySettings.properties_i.optC, 0); // implant shadowing is defined by corners and optimization greatly impacts result. + + settingsUIActive = true; + DOESettingsUIActive = true; + + setHashes(); + } + + void pCommonVars(VarianceContext varianceContext) + { + mainThreadIndex = System.Threading.Thread.CurrentThread; + subshapes = new ObservableCollection[CentralProperties.maxLayersForMC]; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + subshapes[i] = new ObservableCollection() { "1" }; + } + + subShapesList_exp = new ObservableCollection(); + subShapesList_exp = subshapes[0]; + + rngCustomMapping = new ObservableCollection(); + rngCustomMapping.Add(boxMuller); // default. Not removable. + for (int i = 0; i < varianceContext.rngMappingEquations.Count; i++) + { + if (varianceContext.rngMappingEquations[i] != boxMuller) // skip the default. + { + rngCustomMapping.Add(varianceContext.rngMappingEquations[i]); + } + } + + noiseTypes = new List() { "Perlin", "Simplex", "OpenSimplex" }; + + availableSubShapePositions = new List() { "Corner: Top Left", "Corner: Top Right", "Corner: Bottom Left", "Corner: Bottom Right", + "Middle: Top Side", "Middle: Right Side", "Middle: Bottom Side", "Middle: Left Side", + "Center"}; + + availableTipsLocations = new List() { "None", "Left", "Right", "Left & Right", + "Top", "Bottom", "Top & Bottom", + "Top & Left", "Top & Right", "Top & Left & Right", + "Bottom & Left", "Bottom & Right", "Bottom & Left & Right", + "Top & Bottom & Left", "Top & Bottom & Right", + "All"}; + + availableShapes = new List() { "(None)", "Rectangle/Square", "L-shape", "T-shape", "X-shape", "U-shape", "S-shape", "GDS/Oasis", "Boolean" }; + calcMode_names = new ObservableCollection() { "Compute Area Distribution", + "Compute Spacing/Overlap Distribution", + "Compute Chord Distribution", + "Compute Angle Distribution" + }; + polyFillTypes = new List() { "Even/Odd", "Non-zero", "Positive", "Negative" }; + + openGLModeList = new List() { "VBO", "Immediate" }; + + drawingLock = new object(); + implantDrawingLock = new object(); + userCancelQuery = false; + colors = varianceContext.colors; + version = CentralProperties.version; + author = "Phil Stopford (phil.stopford@gmail.com)"; + titleText = CentralProperties.productName + " " + version + " (" + varianceContext.licenceName + ")"; + + copyLayerGHSettings = new GeoCoreHandler(); + copyLayerSettings = new EntropyLayerSettings(); + + layerNames = new ObservableCollection(); + + // External file data lists + geoCore_Handlers = new List(); + structureList = new ObservableCollection[CentralProperties.maxLayersForMC]; + activeStructure_LayerDataTypeList = new ObservableCollection[CentralProperties.maxLayersForMC]; + for (int layer = 0; layer < CentralProperties.maxLayersForMC; layer++) + { + geoCore_Handlers.Add(new GeoCoreHandler()); + geoCore_Handlers[layer].getGeo().baseScale = 1000; + structureList[layer] = geoCore_Handlers[layer].getGeo().structureList_; + activeStructure_LayerDataTypeList[layer] = geoCore_Handlers[layer].getGeo().activeStructure_LayerDataTypeList_; + layerNames.Add((layer + 1).ToString()); + } + structureList_exp = new ObservableCollection(); + activeStructure_LayerDataTypeList_exp = new ObservableCollection(); + + pReset(varianceContext); + } + + public void getBooleanEquation(List linesToWrite) + { + pGetBooleanEquation(linesToWrite); + } + + void pGetBooleanEquation(List linesToWrite) + { + // Boolean equation + string layer12BoolEq = ""; + string layer34BoolEq = ""; + string layer56BoolEq = ""; + string layer78BoolEq = ""; + string layer910BoolEq = ""; + string layer1112BoolEq = ""; + string layer1314BoolEq = ""; + string layer1516BoolEq = ""; + bool layerABoolEq = false; + bool layer1234BoolEq = false; + bool layer5678BoolEq = false; + bool layerBBoolEq = false; + bool layer9101112BoolEq = false; + bool layer13141516BoolEq = false; + + string boolString = ""; + + if (interLayerRelationship_4(0)) + { + layer1234BoolEq = true; + } + + if (interLayerRelationship_4(1)) + { + layer5678BoolEq = true; + } + + if (layer1234BoolEq && layer5678BoolEq) + { + layerABoolEq = true; + } + + if (interLayerRelationship_4(2)) + { + layer9101112BoolEq = true; + } + + if (interLayerRelationship_4(3)) + { + layer13141516BoolEq = true; + } + + if (layer9101112BoolEq && layer13141516BoolEq) + { + layerBBoolEq = true; + } + + if (isLayerActive(0) || isLayerActive(1)) + { + if (layerABoolEq) + { + boolString += "{"; + } + if (layer1234BoolEq) + { + boolString += "["; + } + + if (isLayerActive(0)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 0) == 1) + { + layer12BoolEq = "NOT "; + } + if (listOfSettings[0].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer12BoolEq += "layer0"; + } + else + { + layer12BoolEq += listOfSettings[0].getString(EntropyLayerSettings.properties_s.name); + } + } + + if (interLayerRelationship_2(0)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 0) == 0) + { + layer12BoolEq += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 0) == 1) + { + layer12BoolEq += " OR "; + } + } + + if (isLayerActive(1)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 1) == 1) + { + layer12BoolEq += " NOT "; + } + if (listOfSettings[1].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer12BoolEq += "layer1"; + } + else + { + layer12BoolEq += listOfSettings[1].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(0)) + { + boolString += "("; + } + boolString += layer12BoolEq; + if (interLayerRelationship_2(0)) + { + boolString += ")"; + } + boolString += " "; + } + + if (isLayerActive(2) || isLayerActive(3)) + { + if (isLayerActive(2)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 2) == 1) + { + layer34BoolEq = "NOT "; + } + if (listOfSettings[2].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer34BoolEq += "layer2"; + } + else + { + layer34BoolEq += listOfSettings[2].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(1)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 1) == 0) + { + layer34BoolEq += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 1) == 1) + { + layer34BoolEq += " OR "; + } + } + if (isLayerActive(3)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 3) == 1) + { + layer34BoolEq += " NOT "; + } + if (listOfSettings[3].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer34BoolEq += "layer3"; + } + else + { + layer34BoolEq += listOfSettings[3].getString(EntropyLayerSettings.properties_s.name); + } + } + + if (layer1234BoolEq) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 0) == 0) + { + boolString += "AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 0) == 1) + { + boolString += "OR "; + } + } + + if (interLayerRelationship_2(1)) + { + boolString += "("; + } + boolString += layer34BoolEq; + if (interLayerRelationship_2(1)) + { + boolString += ")"; + } + + if (layer1234BoolEq) + { + boolString += "]"; + } + if (layerABoolEq) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, 0) == 0) + { + boolString += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, 0) == 1) + { + boolString += " OR "; + } + } + + if (isLayerActive(4) || isLayerActive(5)) + { + if (layer5678BoolEq) + { + boolString += "["; + } + + if (isLayerActive(4)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 4) == 1) + { + layer56BoolEq = "NOT "; + } + if (listOfSettings[4].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer56BoolEq += "layer4"; + } + else + { + layer56BoolEq += listOfSettings[4].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(2)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 2) == 0) + { + layer56BoolEq += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 2) == 1) + { + layer56BoolEq += " OR "; + } + } + if (isLayerActive(5)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 5) == 1) + { + layer56BoolEq += " NOT "; + } + if (listOfSettings[5].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer56BoolEq += "layer5"; + } + else + { + layer56BoolEq += listOfSettings[5].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(2)) + { + boolString += "("; + } + boolString += layer56BoolEq; + if (interLayerRelationship_2(2)) + { + boolString += ")"; + } + } + + if (isLayerActive(6) || isLayerActive(7)) + { + if (listOfSettings[6].getInt(EntropyLayerSettings.properties_i.enabled) == 1) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 6) == 1) + { + layer78BoolEq = "NOT "; + } + if (listOfSettings[6].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer78BoolEq += "layer6"; + } + else + { + layer78BoolEq += listOfSettings[6].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(3)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 3) == 0) + { + layer78BoolEq += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 3) == 1) + { + layer78BoolEq += " OR "; + } + } + if (isLayerActive(7)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 7) == 1) + { + layer78BoolEq += " NOT "; + } + if (listOfSettings[7].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer78BoolEq += "layer7"; + } + else + { + layer78BoolEq += listOfSettings[7].getString(EntropyLayerSettings.properties_s.name); + } + } + + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 1) == 0) + { + boolString += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 1) == 1) + { + boolString += " OR "; + } + + if (interLayerRelationship_2(3)) + { + boolString += "("; + } + boolString += layer78BoolEq; + if (interLayerRelationship_2(3)) + { + boolString += ")"; + } + + if (layer5678BoolEq) + { + boolString += "]"; + } + } + + if (layerABoolEq) + { + boolString += "}"; + } + boolString += " "; + } + + switch (simulationSettings.getValue(EntropySettings.properties_i.oType)) + { + case (int)CommonVars.calcModes.area: // area + boolString += "AND"; + break; + case (int)CommonVars.calcModes.enclosure_spacing_overlap: // spacing + boolString += "MIN SPACE/OVERLAP/ENCL TO/WITH"; + break; + case (int)CommonVars.calcModes.chord: // chords + boolString += "MIN CHORDS WITH"; + break; + case (int)CommonVars.calcModes.angle: // angle + boolString += "MIN INTERSECTION ANGLE WITH"; + break; + } + + boolString += " "; + + if (isLayerActive(8) || isLayerActive(9)) + { + if (layerBBoolEq) + { + boolString += "{"; + } + + if (layer9101112BoolEq) + { + boolString += "["; + } + + if (isLayerActive(8)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 8) == 1) + { + layer910BoolEq = "NOT "; + } + if (listOfSettings[8].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer910BoolEq += "layer8"; + } + else + { + layer910BoolEq += listOfSettings[8].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(4)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 4) == 0) + { + layer910BoolEq += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 4) == 1) + { + layer910BoolEq += " OR "; + } + } + if (isLayerActive(9)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 9) == 1) + { + layer910BoolEq += " NOT "; + } + if (listOfSettings[9].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer910BoolEq += "layer9"; + } + else + { + layer910BoolEq += listOfSettings[9].getString(EntropyLayerSettings.properties_s.name); + } + } + + if (interLayerRelationship_2(4)) + { + boolString += "("; + } + + boolString += layer910BoolEq; + + if (interLayerRelationship_2(4)) + { + boolString += ")"; + } + } + + if (isLayerActive(10) || isLayerActive(11)) + { + if (isLayerActive(10)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 10) == 1) + { + layer1112BoolEq = "NOT "; + } + if (listOfSettings[10].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer1112BoolEq += "layer10"; + } + else + { + layer1112BoolEq += listOfSettings[10].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(5)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 5) == 0) + { + layer1112BoolEq += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 5) == 1) + { + layer1112BoolEq += " OR "; + } + } + if (isLayerActive(11)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 11) == 1) + { + layer1112BoolEq += " NOT "; + } + if (listOfSettings[11].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer1112BoolEq += "layer11"; + } + else + { + layer1112BoolEq += listOfSettings[11].getString(EntropyLayerSettings.properties_s.name); + } + } + + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 2) == 0) + { + boolString += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 2) == 1) + { + boolString += " OR "; + } + + if (interLayerRelationship_2(5)) + { + boolString += "("; + } + boolString += layer1112BoolEq; + if (interLayerRelationship_2(5)) + { + boolString += ")"; + } + + if (layer9101112BoolEq) + { + boolString += "]"; + } + } + + if (layerBBoolEq) + { + boolString += " "; + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, 1) == 0) + { + boolString += "AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.eightLayer, 1) == 1) + { + boolString += "OR "; + } + } + + if (layer13141516BoolEq) + { + boolString += "["; + } + + if (isLayerActive(12)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 12) == 1) + { + layer1314BoolEq = "NOT "; + } + if (listOfSettings[12].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer1314BoolEq += "layer12"; + } + else + { + layer1314BoolEq += listOfSettings[12].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(6)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 6) == 0) + { + layer1314BoolEq += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 6) == 1) + { + layer1314BoolEq += " OR "; + } + } + if (isLayerActive(13)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 13) == 1) + { + layer1314BoolEq += " NOT "; + } + if (listOfSettings[13].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer1314BoolEq += "layer13"; + } + else + { + layer1314BoolEq += listOfSettings[13].getString(EntropyLayerSettings.properties_s.name); + } + } + + if (interLayerRelationship_2(6)) + { + boolString += "("; + } + boolString += layer1314BoolEq; + if (interLayerRelationship_2(6)) + { + boolString += ")"; + } + + if (isLayerActive(14) || isLayerActive(15)) + { + if (isLayerActive(14)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 14) == 1) + { + layer1516BoolEq = "NOT "; + } + if (listOfSettings[14].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer1516BoolEq += "layer14"; + } + else + { + layer1516BoolEq += listOfSettings[14].getString(EntropyLayerSettings.properties_s.name); + } + } + if (interLayerRelationship_2(7)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 7) == 0) + { + layer1516BoolEq += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.twoLayer, 7) == 1) + { + layer1516BoolEq += " OR "; + } + } + if (isLayerActive(15)) + { + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.layer, 15) == 1) + { + layer1516BoolEq += " NOT "; + } + if (listOfSettings[15].getString(EntropyLayerSettings.properties_s.name) == "") + { + layer1516BoolEq += "layer15"; + } + else + { + layer1516BoolEq += listOfSettings[15].getString(EntropyLayerSettings.properties_s.name); + } + } + + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 3) == 0) + { + boolString += " AND "; + } + if (simulationSettings.getOperatorValue(EntropySettings.properties_o.fourLayer, 3) == 1) + { + boolString += " OR "; + } + + if (interLayerRelationship_2(7)) + { + boolString += "("; + } + boolString += layer1516BoolEq; + if (interLayerRelationship_2(7)) + { + boolString += ")"; + } + + if (layer13141516BoolEq) + { + boolString += "]"; + } + } + if (layerBBoolEq) + { + boolString += "}"; + } + + linesToWrite.Add("Equation: " + boolString); + } + + public void getSimulationSettings_implant(List linesToWrite) + { + pGetSimulationSettings_implant(linesToWrite); + } + + void pGetSimulationSettings_implant(List linesToWrite) + { + // Simulation settings + linesToWrite.Add("Simulation Settings:"); + linesToWrite.Add(" Number of Cases: " + implantSimulationSettings.getValue(EntropySettings.properties_i.nCases).ToString()); + linesToWrite.Add(" Edge resolution: " + implantSimulationSettings.getResolution().ToString()); + linesToWrite.Add(" Corner segments: " + implantSimulationSettings.getValue(EntropySettings.properties_i.cSeg).ToString()); + if (implantSimulationSettings.getValue(EntropySettings.properties_i.optC) == 1) + { + linesToWrite.Add(" Override corner angle step by edge resolution: yes"); + } + else + { + linesToWrite.Add(" Override corner angle step by edge resolution: no"); + } + linesToWrite.Add("RNG: " + commonRNG.rngTypes[implantSimulationSettings.getValue(EntropySettings.properties_i.rngType)]); + linesToWrite.Add(""); + } + + public void getSimulationSettings(List linesToWrite) + { + pGetSimulationSettings(linesToWrite); + } + + void pGetSimulationSettings(List linesToWrite) + { + // Simulation settings + linesToWrite.Add("Simulation Settings:"); + linesToWrite.Add(" Number of Cases: " + simulationSettings.getValue(EntropySettings.properties_i.nCases).ToString()); + linesToWrite.Add(" Edge resolution: " + simulationSettings.getResolution().ToString()); + linesToWrite.Add(" Corner segments: " + simulationSettings.getValue(EntropySettings.properties_i.cSeg).ToString()); + if (simulationSettings.getValue(EntropySettings.properties_i.optC) == 1) + { + linesToWrite.Add(" Override corner angle step by edge resolution: yes"); + } + else + { + linesToWrite.Add(" Override corner angle step by edge resolution: no"); + } + if (simulationSettings.getValue(EntropySettings.properties_i.linkCDU) == 1) + { + linesToWrite.Add(" Linked tip/side CDU: yes"); + } + else + { + linesToWrite.Add(" Linked tip/side CDU: no"); + } + if (simulationSettings.getValue(EntropySettings.properties_i.ler) == 1) + { + linesToWrite.Add(" LER: LWR/sqrt(2)"); + } + else + { + linesToWrite.Add(" LER: LWR/2"); + } + linesToWrite.Add("RNG: " + commonRNG.rngTypes[simulationSettings.getValue(EntropySettings.properties_i.rngType)]); + linesToWrite.Add(""); + } + + public void getLayerSettings(Int32 layer, ref List linesToWrite, bool onlyActive) + { + pGetLayerSettings(layer, ref linesToWrite, onlyActive); + } + + void pGetLayerSettings(Int32 layer, ref List linesToWrite, bool onlyActive) + { + string layerName = ""; + if (!onlyActive || (onlyActive && (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.enabled) == 1))) + { + // Layer was active in simulation. + string layerRefString = "Layer " + layer.ToString(); + layerName = listOfSettings[layer].getString(EntropyLayerSettings.properties_s.name); + if (layerName == "") + { + layerName = "layer" + layer.ToString(); + } + if (!onlyActive) + { + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.enabled) == 1) + { + linesToWrite.Add("ACTIVE"); + } + else + { + linesToWrite.Add("INACTIVE"); + } + } + linesToWrite.Add(layerRefString + " Name: " + layerName); + string shapeType = layerRefString + " Shape: "; + int shapeParts = 1; + bool externalShape = false; + linesToWrite.Add(shapeType + availableShapes[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.shapeIndex)]); + switch (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.shapeIndex)) + { + case (int)CentralProperties.typeShapes.L: + shapeParts = 2; + break; + case (int)CentralProperties.typeShapes.T: + shapeParts = 2; + break; + case (int)CentralProperties.typeShapes.U: + shapeParts = 2; + break; + case (int)CentralProperties.typeShapes.X: + shapeParts = 2; + break; + case (int)CentralProperties.typeShapes.S: + shapeParts = 3; + break; + case (int)CentralProperties.typeShapes.GEOCORE: + externalShape = true; + break; + } + if (externalShape) + { + linesToWrite.Add("Layout File: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.file)); + + linesToWrite.Add("Layout Cell: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.structure)); + linesToWrite.Add("Layout Layer/Datatype: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.lD)); + linesToWrite.Add("Contouring: " + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.gCSEngine).ToString()); + linesToWrite.Add("Per-Poly: " + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.perPoly).ToString()); + linesToWrite.Add("Poly Fill Type: " + polyFillTypes[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.fill)]); + linesToWrite.Add("Horizontal Offset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.gHorOffset).ToString()); + linesToWrite.Add("Vertical Offset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.gVerOffset).ToString()); + linesToWrite.Add("Horizontal Overlay: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.xOL).ToString()); + linesToWrite.Add("Horizontal Overlay RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.xOL_RNG)); + linesToWrite.Add("Vertical Overlay: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.yOL).ToString()); + linesToWrite.Add("Vertical Overlay RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.yOL_RNG)); + linesToWrite.Add("Side Bias: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.sBias).ToString()); + linesToWrite.Add("Side CDU: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.sCDU).ToString()); + linesToWrite.Add("Side CDU RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.sCDU_RNG)); + string[] tempArray = summaryFile_LitData(layer); + for (int i = 0; i < tempArray.Length; i++) + { + linesToWrite.Add(tempArray[i]); + } + } + else + { + // Internal shape + for (int part = 0; part < shapeParts; part++) + { + linesToWrite.Add("Subshape " + part.ToString() + ": "); + switch (part) + { + case 0: + linesToWrite.Add(" HLength: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength).ToString()); + linesToWrite.Add(" VLength: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength).ToString()); + linesToWrite.Add(" HOffset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset).ToString()); + linesToWrite.Add(" VOffset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset).ToString()); + linesToWrite.Add(" TipLocations: " + availableTipsLocations[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.shape0Tip)]); + break; + case 1: + linesToWrite.Add(" HLength: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength).ToString()); + linesToWrite.Add(" VLength: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength).ToString()); + linesToWrite.Add(" HOffset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset).ToString()); + linesToWrite.Add(" VOffset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset).ToString()); + linesToWrite.Add(" TipLocations: " + availableTipsLocations[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.shape1Tip)]); + break; + case 2: + linesToWrite.Add(" HLength: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength).ToString()); + linesToWrite.Add(" VLength: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength).ToString()); + linesToWrite.Add(" HOffset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset).ToString()); + linesToWrite.Add(" VOffset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset).ToString()); + linesToWrite.Add(" TipLocations: " + availableTipsLocations[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.shape2Tip)]); + break; + } + } + + // Subshape reference + linesToWrite.Add("SubshapeReference: " + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.subShapeIndex).ToString()); + // Subshape positioning + linesToWrite.Add("PositionInSubshape: " + availableSubShapePositions[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.posIndex)].ToString()); + + // Global offsets. + linesToWrite.Add("Horizontal Offset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.gHorOffset).ToString()); + linesToWrite.Add("Vertical Offset: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.gVerOffset).ToString()); + + // Rotation + linesToWrite.Add("Rotation: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.rot).ToString()); + // Wobble + linesToWrite.Add("Wobble: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.wobble).ToString()); + linesToWrite.Add("Wobble RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.wobble_RNG)); + + // Biases + linesToWrite.Add("Side Bias: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.sBias).ToString()); + linesToWrite.Add("HorTip Bias: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.hTBias).ToString()); + linesToWrite.Add(" HorTip Bias +ve Var: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.hTPVar).ToString()); + linesToWrite.Add(" HorTip Bias +ve Var RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.hTipPVar_RNG)); + linesToWrite.Add(" HorTip Bias -ve Var: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.hTNVar).ToString()); + linesToWrite.Add(" HorTip Bias -ve Var RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.hTipNVar_RNG)); + linesToWrite.Add("VerTip Bias: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.vTBias).ToString()); + linesToWrite.Add(" VerTip Bias +ve Var: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.vTPVar).ToString()); + linesToWrite.Add(" VerTip Bias +ve Var RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.vTipPVar_RNG)); + linesToWrite.Add(" VerTip Bias -ve Var: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.vTNVar).ToString()); + linesToWrite.Add(" VerTip Bias -ve Var RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.vTipNVar_RNG)); + linesToWrite.Add("Proximity Bias: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.pBias).ToString()); + linesToWrite.Add(" Proximity Bias Isolated Distance: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.pBiasDist).ToString()); + linesToWrite.Add(" Proximity Bias Side Rays: " + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.proxRays).ToString()); + + // Corner rounding. + linesToWrite.Add("Inner CRR: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.iCR).ToString()); + linesToWrite.Add(" Inner CR Var: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.iCV).ToString()); + linesToWrite.Add(" Inner CR Var RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.iCV_RNG)); + linesToWrite.Add("Outer CRR: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.oCR).ToString()); + linesToWrite.Add(" Outer CR Var: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.oCV).ToString()); + linesToWrite.Add(" Outer CR Var RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.oCV_RNG)); + + // CDU/LWR + linesToWrite.Add("LWR: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.lwr).ToString()); + linesToWrite.Add("LWR RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.lwr_RNG)); + linesToWrite.Add("LWR Frequency: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.lwrFreq).ToString()); + linesToWrite.Add("LWR Noise: " + noiseTypes[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.lwrType)].ToString()); + linesToWrite.Add("LWR2: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.lwr2).ToString()); + linesToWrite.Add("LWR2 RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.lwr2_RNG)); + linesToWrite.Add("LWR2 Frequency: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.lwr2Freq).ToString()); + linesToWrite.Add("LWR2 Noise: " + noiseTypes[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.lwr2Type)].ToString()); + linesToWrite.Add("Side CDU: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.sCDU).ToString()); + linesToWrite.Add("Side CDU RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.sCDU_RNG)); + linesToWrite.Add("Tips CDU: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.tCDU).ToString()); + linesToWrite.Add("Tips CDU RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.tCDU_RNG)); + + // Overlay + linesToWrite.Add("Horizontal Overlay: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.xOL).ToString()); + linesToWrite.Add("Horizontal Overlay RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.xOL_RNG)); + linesToWrite.Add("Vertical Overlay: " + listOfSettings[layer].getDecimal(EntropyLayerSettings.properties_decimal.yOL).ToString()); + linesToWrite.Add("Vertical Overlay RNG Mapping: " + listOfSettings[layer].getString(EntropyLayerSettings.properties_s.yOL_RNG)); + // Correlation data + string[] tempArray = summaryFile_LitData(layer); + for (int i = 0; i < tempArray.Length; i++) + { + linesToWrite.Add(tempArray[i]); + } + } + linesToWrite.Add(""); + } + } + + string[] summaryFile_LitData(int layer) + { + try + { + string xOverlayCorrString = "X Overlay correlation: "; + string yOverlayCorrString = "Y Overlay correlation: "; + string xOverlayRefString = ""; + string yOverlayRefString = ""; + string xOverlayRefAvString = ""; + string yOverlayRefAvString = ""; + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_av) == 1) + { + xOverlayRefAvString = "ACTIVE: "; + xOverlayRefString = "INACTIVE: "; + } + else + { + xOverlayRefString = "ACTIVE: "; + xOverlayRefAvString = "INACTIVE: "; + } + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_av) == 1) + { + yOverlayRefAvString = "ACTIVE: "; + yOverlayRefString = "INACTIVE: "; + } + else + { + yOverlayRefString = "ACTIVE: "; + yOverlayRefAvString = "INACTIVE: "; + } + xOverlayRefString += "X Overlay reference layer: "; + xOverlayRefAvString += "X Overlay reference layers: "; + yOverlayRefString += "Y Overlay reference layer: "; + yOverlayRefAvString += "Y Overlay reference layers: "; + + string cduCorrString = "CDU correlation: "; + string tipCDUCorrString = "Tip CDU correlation: "; + + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == -1) + { + xOverlayCorrString += "None"; + } + else + { + if (listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_corr_ref)].getString(EntropyLayerSettings.properties_s.name) == "") + { + xOverlayCorrString += listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_corr_ref)].getString(EntropyLayerSettings.properties_s.name); + } + else + { + xOverlayCorrString += "layer" + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_corr_ref).ToString(); + } + } + + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == -1) + { + yOverlayCorrString += "None"; + } + else + { + if (listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_corr_ref)].getString(EntropyLayerSettings.properties_s.name) == "") + { + yOverlayCorrString += listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_corr_ref)].getString(EntropyLayerSettings.properties_s.name); + } + else + { + yOverlayCorrString += "layer" + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_corr_ref).ToString(); + } + } + + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_ref) == -1) + { + xOverlayRefString += "None"; + } + else + { + if (listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_ref)].getString(EntropyLayerSettings.properties_s.name) == "") + { + xOverlayRefString += listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_ref)].getString(EntropyLayerSettings.properties_s.name); + } + else + { + xOverlayRefString += "layer" + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.xOL_ref).ToString(); + } + } + + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_ref) == -1) + { + yOverlayRefString += "None"; + } + else + { + if (listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_ref)].getString(EntropyLayerSettings.properties_s.name) == "") + { + yOverlayRefString += listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_ref)].getString(EntropyLayerSettings.properties_s.name); + } + else + { + yOverlayRefString += "layer" + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.yOL_ref).ToString(); + } + } + + string xOLAV_layers = ""; + + for (int tmp = 0; tmp < listOfSettings[layer].getIntArray(EntropyLayerSettings.properties_intarray.xOLRefs).Length; tmp++) + { + if (listOfSettings[layer].getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, tmp) == 1) + { + xOLAV_layers += (tmp + 1).ToString() + " "; + } + } + + if (xOLAV_layers == "") + { + xOverlayRefAvString += "None"; + } + else + { + xOverlayRefAvString += xOLAV_layers; + } + + string yOLAV_layers = ""; + + for (int tmp = 0; tmp < listOfSettings[layer].getIntArray(EntropyLayerSettings.properties_intarray.yOLRefs).Length; tmp++) + { + if (listOfSettings[layer].getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, tmp) == 1) + { + yOLAV_layers += (tmp + 1).ToString() + " "; + } + } + + if (yOLAV_layers == "") + { + yOverlayRefAvString += "None"; + } + else + { + yOverlayRefAvString += yOLAV_layers; + } + + + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == -1) + { + cduCorrString += "None"; + } + else + { + if (listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.CDU_corr_ref)].getString(EntropyLayerSettings.properties_s.name) == "") + { + cduCorrString += listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.CDU_corr_ref)].getString(EntropyLayerSettings.properties_s.name); + } + else + { + cduCorrString += "layer" + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.CDU_corr_ref).ToString(); + } + } + + + if (listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == -1) + { + tipCDUCorrString += "None"; + } + else + { + if (listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref)].getString(EntropyLayerSettings.properties_s.name) == "") + { + tipCDUCorrString += listOfSettings[listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref)].getString(EntropyLayerSettings.properties_s.name); + } + else + { + tipCDUCorrString += "layer" + listOfSettings[layer].getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref).ToString(); + } + } + + string[] returnData = new string[8]; + returnData[0] = xOverlayCorrString; + returnData[1] = yOverlayCorrString; + returnData[2] = xOverlayRefString; + returnData[3] = yOverlayRefString; + returnData[4] = xOverlayRefAvString; + returnData[5] = yOverlayRefAvString; + returnData[6] = cduCorrString; + returnData[7] = tipCDUCorrString; + return returnData; + } + catch (Exception) + { + return new string[] { "" }; + } + } + + public void getUtilitiesSettings(List linesToWrite) + { + pGetUtilitiesSettings(linesToWrite); + } + + void pGetUtilitiesSettings(List linesToWrite) + { + linesToWrite.Add("Utilities Settings:"); + linesToWrite.Add(" Email Server: " + nonSimulationSettings.host); + linesToWrite.Add(" Email Port: " + nonSimulationSettings.port); + linesToWrite.Add(" Email Port: " + nonSimulationSettings.ssl.ToString()); + linesToWrite.Add(" Email Address: " + nonSimulationSettings.emailAddress); + linesToWrite.Add(" Email On Completion: " + nonSimulationSettings.emailOnCompletion.ToString()); + linesToWrite.Add(" Email Per Job: " + nonSimulationSettings.emailPerJob.ToString()); + } + + public void getDOESettings(List linesToWrite) + { + pGetDOESettings(linesToWrite); + } + + void pGetDOESettings(List linesToWrite) + { + // Layout DOE settings + string layersAffected = ""; + for (int i = 0; i < simulationSettings.getDOESettings().getLayersAffected().Length; i++) + { + if (simulationSettings.getDOESettings().getLayerAffected(i) == 1) + { + string layerName = listOfSettings[i].getString(EntropyLayerSettings.properties_s.name); + if (layerName == "") + { + layerName = "(layer" + i.ToString() + ") "; + } + layersAffected += layerName; + } + } + if (layersAffected != "") + { + linesToWrite.Add("Layout DOE Settings:"); + linesToWrite.Add(" Affected layers: " + layersAffected); + linesToWrite.Add(" Column Offset: " + simulationSettings.getDOESettings().getDouble(DOESettings.properties_d.colOffset).ToString()); + linesToWrite.Add(" Row Offset: " + simulationSettings.getDOESettings().getDouble(DOESettings.properties_d.rowOffset).ToString()); + linesToWrite.Add(" Column Pitch: " + simulationSettings.getDOESettings().getDouble(DOESettings.properties_d.colPitch).ToString()); + linesToWrite.Add(" Row Pitch: " + simulationSettings.getDOESettings().getDouble(DOESettings.properties_d.rowPitch).ToString()); + } + } + + public void setHashes() + { + pSetHashes(); + } + + void pSetHashes() + { + geoCoreHash = Utils.GetMD5Hash(geoCore_Handlers); + listOfSettingsHash = Utils.GetMD5Hash(listOfSettings); + entropyGeoHash = Utils.GetMD5Hash(simulationSettings); + implantHash = Utils.GetMD5Hash(implantSettings); + entropyImplantHash = Utils.GetMD5Hash(implantSimulationSettings); + changed = false; + } + + public string[] getHashes() + { + return pGetHashes(); + } + + string[] pGetHashes() + { + string[] hashes = new string[5]; + hashes[0] = Utils.GetMD5Hash(geoCore_Handlers); + hashes[1] = Utils.GetMD5Hash(listOfSettings); + hashes[2] = Utils.GetMD5Hash(simulationSettings); + hashes[3] = Utils.GetMD5Hash(implantSettings); + hashes[4] = Utils.GetMD5Hash(implantSimulationSettings); + + return hashes; + } + + public void setHashes(string[] hashes) + { + pSetHashes(hashes); + } + + void pSetHashes(string[] hashes) + { + geoCoreHash = hashes[0]; + listOfSettingsHash = hashes[1]; + entropyGeoHash = hashes[2]; + implantHash = hashes[3]; + entropyImplantHash = hashes[4]; + } + + public void checkChanged() + { + pCheckChanged(); + } + + void pCheckChanged() + { + string tmp = Utils.GetMD5Hash(geoCore_Handlers); + if ((geoCoreHash != null) && (tmp != geoCoreHash)) + { + changed = true; + return; + } + + tmp = Utils.GetMD5Hash(listOfSettings); + if ((listOfSettingsHash != null) && (tmp != listOfSettingsHash)) + { + changed = true; + return; + } + + tmp = Utils.GetMD5Hash(simulationSettings); + if ((entropyGeoHash != null) && (tmp != entropyGeoHash)) + { + changed = true; + return; + } + + tmp = Utils.GetMD5Hash(implantSettings); + if ((implantHash != null) && (tmp != implantHash)) + { + changed = true; + return; + } + + tmp = Utils.GetMD5Hash(implantSimulationSettings); + if ((entropyImplantHash != null) && (tmp != entropyImplantHash)) + { + changed = true; + return; + } + + changed = false; + } + + public bool nonGaussianInputs() + { + return pNonGaussianInputs(); + } + + bool pNonGaussianInputs() + { + bool nonGaussianvalues = true; + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + nonGaussianvalues = listOfSettings[i].nonGaussianValues(); + if (nonGaussianvalues) + { + break; + } + } + + return nonGaussianvalues; + } + } +} diff --git a/Common/Variance/support/nonSimulationSettings.cs b/Common/Variance/support/nonSimulationSettings.cs new file mode 100644 index 0000000..11a749d --- /dev/null +++ b/Common/Variance/support/nonSimulationSettings.cs @@ -0,0 +1,34 @@ +using geoLib; +using System.Collections.Generic; + +namespace Variance +{ + public class NonSimulationSettings + { + public string version { get; set; } + + public string host { get; set; } + public string port { get; set; } + public string emailAddress { get; set; } + public string emailPwd { get; set; } + public bool emailOnCompletion { get; set; } + public bool emailPerJob { get; set; } + public bool ssl { get; set; } + public List> extractedTile { get; set; } // put this here because we don't want to track this directly. + + public NonSimulationSettings(string _version) + { + pNonSimulationSettings(_version); + } + + void pNonSimulationSettings(string _version) + { + version = _version; + extractedTile = new List>(); // to hold extracted tile List for each layer. + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + extractedTile.Add(new List()); + } + } + } +} \ No newline at end of file diff --git a/Common/Variance/support/previewShape.cs b/Common/Variance/support/previewShape.cs new file mode 100644 index 0000000..8b85c9d --- /dev/null +++ b/Common/Variance/support/previewShape.cs @@ -0,0 +1,2035 @@ +using ClipperLib; // tiled layout handling, Layout biasing/CDU. +using color; +using Error; +using geoLib; +using geoWrangler; +using Noise; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using utility; + +namespace Variance +{ + using Path = List; + using Paths = List>; + + public class PreviewShape + { + bool DOEDependency; // due to the DOE grid, we need this to sort out offsets. This includes buried references in Booleans. The min X/Y values for this case need to be at least the col/row offset. + double doeMinX, doeMinY; + + Fragmenter fragment; + // Class for our preview shapes. + List previewPoints; // list of polygons defining the shape(s) that will be drawn. In the complex case, we populate this from complexPoints. + public List getPoints() + { + return pGetPoints(); + } + + List pGetPoints() + { + return previewPoints; + } + + public GeoLibPointF[] getPoints(int index) + { + return pGetPoints(index); + } + + GeoLibPointF[] pGetPoints(int index) + { + return previewPoints[index]; + } + + public void addPoints(GeoLibPointF[] poly) + { + pAddPoints(poly); + } + + void pAddPoints(GeoLibPointF[] poly) + { + previewPoints.Add(poly.ToArray()); + } + + public void setPoints(List newPoints) + { + pSetPoints(newPoints); + } + + void pSetPoints(List newPoints) + { + previewPoints = newPoints.ToList(); + } + + public void clearPoints() + { + pClearPoints(); + } + + void pClearPoints() + { + previewPoints.Clear(); + } + + List drawnPoly; // to track drawn vs enabled polygons. Can then use for filtering elsewhere. + + public bool getDrawnPoly(int index) + { + return pGetDrawnPoly(index); + } + + bool pGetDrawnPoly(int index) + { + return drawnPoly[index]; + } + + List geoCoreOrthogonalPoly; + MyColor color; + + public MyColor getColor() + { + return pGetColor(); + } + + MyColor pGetColor() + { + return color; + } + + public void setColor(MyColor c) + { + pSetColor(c); + } + + void pSetColor(MyColor c) + { + color = new MyColor(c); + } + + double xOffset; + double yOffset; + + int _settingsIndex; // track originating layer. + + public Int32 getIndex() + { + return pGetIndex(); + } + + Int32 pGetIndex() + { + return _settingsIndex; + } + + void rectangle_offset(EntropyLayerSettings entropyLayerSettings) + { + string posInSubShapeString = ((CommonVars.subShapeLocations)entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex)).ToString(); + double tmp_xOffset = 0; + double tmp_yOffset = 0; + + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + // Vertical offset needed to put reference corner at world center + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = Convert.ToDouble(tmp_yOffset / 2); + } + } + yOffset -= tmp_yOffset; + + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + + // Half the value for horizontal centering conditions + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset = Convert.ToDouble(tmp_xOffset / 2); + } + } + xOffset += tmp_xOffset; + } + + void lShape_offset(EntropyLayerSettings entropyLayerSettings) + { + string posInSubShapeString = ((CommonVars.subShapeLocations)entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex)).ToString(); + double tmp_xOffset = 0; + double tmp_yOffset = 0; + + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + // Vertical offset needed to put reference corner at world center + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + } + else + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + } + + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = Convert.ToDouble(tmp_yOffset / 2); + } + } + yOffset -= tmp_yOffset; + + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 1) && ((posInSubShapeString == "LS") || (posInSubShapeString == "BL") || (posInSubShapeString == "TL"))) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); // essentially the same in X as the RS for subshape 1. + } + else + { + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + } + else + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)); + } + + // Half the value for horizontal centering conditions + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_xOffset = Convert.ToDouble(tmp_xOffset / 2); + } + else + { + tmp_xOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + } + } + } + } + + xOffset += tmp_xOffset; + } + + void tShape_offset(EntropyLayerSettings entropyLayerSettings) + { + string posInSubShapeString = ((CommonVars.subShapeLocations)entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex)).ToString(); + double tmp_xOffset = 0; + double tmp_yOffset = 0; + + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 1) && ((posInSubShapeString == "BR") || (posInSubShapeString == "BL") || (posInSubShapeString == "BS"))) + { + tmp_yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + } + else + { + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = Convert.ToDouble(tmp_yOffset / 2); + } + } + else + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = Convert.ToDouble(tmp_yOffset / 2); + } + tmp_yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + } + + } + } + yOffset -= tmp_yOffset; + + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 1) && ((posInSubShapeString == "LS") || (posInSubShapeString == "BL") || (posInSubShapeString == "TL"))) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); // essentially the same in X as the RS for subshape 1. + } + else + { + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + } + else + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)); + } + + // Half the value for horizontal centering conditions + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_xOffset = Convert.ToDouble(tmp_xOffset / 2); + } + else + { + tmp_xOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + } + } + } + } + + xOffset += tmp_xOffset; + } + + void xShape_offset(EntropyLayerSettings entropyLayerSettings) + { + string posInSubShapeString = ((CommonVars.subShapeLocations)entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex)).ToString(); + double tmp_xOffset = 0; + double tmp_yOffset = 0; + + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 1) && ((posInSubShapeString == "BR") || (posInSubShapeString == "BL") || (posInSubShapeString == "BS"))) + { + tmp_yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + } + else + { + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + // Vertical offset needed to put reference corner at world center + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = Convert.ToDouble(tmp_yOffset / 2); + } + } + else + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = Convert.ToDouble(tmp_yOffset / 2); + } + tmp_yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + } + + } + } + yOffset -= tmp_yOffset; + + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 1) && ((posInSubShapeString == "LS") || (posInSubShapeString == "BL") || (posInSubShapeString == "TL"))) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)); + } + else + { + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + } + else + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)); + } + + // Half the value for horizontal centering conditions + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_xOffset = Convert.ToDouble(tmp_xOffset / 2); + } + else + { + tmp_xOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + } + } + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 1) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)); + } + } + } + + xOffset += tmp_xOffset; + } + + void uShape_offset(EntropyLayerSettings entropyLayerSettings) + { + string posInSubShapeString = ((CommonVars.subShapeLocations)entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex)).ToString(); + double tmp_xOffset = 0; + double tmp_yOffset = 0; + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = Convert.ToDouble(tmp_yOffset / 2); + } + } + yOffset -= tmp_yOffset; + + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + + // Half the value for horizontal centering conditions + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset = Convert.ToDouble(tmp_xOffset / 2); + } + } + } + else + { + // Subshape 2 is always docked against top edge of subshape 1 in U. + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "BL") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength) / 2); + } + + // Subtract the value for a subshape 2 bottom edge requirement + if ((posInSubShapeString == "BL") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "BS")) + { + tmp_yOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + } + } + yOffset -= tmp_yOffset; + + // Subshape 2 is always H-centered in U. Makes it easy. + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) / 2); + + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "RS")) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + } + + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "BL") || + (posInSubShapeString == "LS")) + { + tmp_xOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + } + } + xOffset += tmp_xOffset; + } + + void sShape_offset(EntropyLayerSettings entropyLayerSettings) + { + string posInSubShapeString = ((CommonVars.subShapeLocations)entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex)).ToString(); + double tmp_xOffset = 0; + double tmp_yOffset = 0; + + switch (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex)) + { + case 0: + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = Convert.ToDouble(tmp_yOffset / 2); + } + } + + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + + // Half the value for horizontal centering conditions + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset = Convert.ToDouble(tmp_xOffset / 2); + } + } + break; + + case 1: + // Subshape 2 is always vertically offset relative to bottom edge of subshape 1 in S. + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "BL") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength) / 2); + } + + // Subtract the value for a subshape 2 bottom edge requirement + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS")) + { + tmp_yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + } + } + + // Subshape 2 is always pinned to left edge in S. Makes it easy. + + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)); + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "C") || + (posInSubShapeString == "BS")) + { + tmp_xOffset /= 2; + } + } + + break; + + case 2: + tmp_yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + // Subshape 3 is always offset relative to top edge of subshape 1 in S. + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS") || + (posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "BL") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_yOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset)); + + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength) / 2); + } + + // Subtract the value for a subshape 2 bottom edge requirement + if ((posInSubShapeString == "BL") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "BS")) + { + tmp_yOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength)); + } + } + + // Subshape 3 is always pinned to right edge in S. Makes it easy. + tmp_xOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "BL") || + (posInSubShapeString == "LS")) + { + tmp_xOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength)); + } + + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength) / 2); + } + break; + } + + yOffset -= tmp_yOffset; + xOffset += tmp_xOffset; + } + + void customShape_offset(EntropyLayerSettings entropyLayerSettings) + { + return; // disabling this because it affects geometry in annoying ways. + string posInSubShapeString = ((CommonVars.subShapeLocations)entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex)).ToString(); + + // Get the bounding box. + Clipper c = new Clipper(); + c.PreserveCollinear = true; + Paths sourcePolyData = new Paths(); + Paths resizedPolyData = new Paths(); + for (int poly = 0; poly < previewPoints.Count; poly++) + { + if (!drawnPoly[poly]) + { + Path path_ = new Path(); + for (int pt = 0; pt < previewPoints[poly].Count(); pt++) + { + path_.Add(new IntPoint(Convert.ToInt64(previewPoints[poly][pt].X * CentralProperties.scaleFactorForOperation), + Convert.ToInt64(previewPoints[poly][pt].Y * CentralProperties.scaleFactorForOperation))); + } + sourcePolyData.Add(path_); + } + } + + IntRect bounds = Clipper.GetBounds(sourcePolyData); + double minY = Math.Min(bounds.top, bounds.bottom) / CentralProperties.scaleFactorForOperation; + double maxY = Math.Max(bounds.top, bounds.bottom) / CentralProperties.scaleFactorForOperation; + + double minX = Math.Min(bounds.left, bounds.right) / CentralProperties.scaleFactorForOperation; + double maxX = Math.Max(bounds.left, bounds.right) / CentralProperties.scaleFactorForOperation; + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (int)CommonVars.shapeNames.GEOCORE) + { + minX = Math.Min(0, minX); + minY = Math.Min(0, minY); + } + else if (DOEDependency) + { + minX = Math.Min(doeMinX, minX); + minY = Math.Min(doeMinY, minY); + } + + double tmp_xOffset = 0; + double tmp_yOffset = 0; + + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "TR") || + (posInSubShapeString == "TS")) + { + // Vertical offset needed to put reference corner at world center + tmp_yOffset = -maxY; + } + + if ((posInSubShapeString == "BL") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "BS")) + { + // Vertical offset needed to put reference corner at world center + tmp_yOffset = -minY; + } + + // Half the value for a vertical centering requirement + if ((posInSubShapeString == "RS") || + (posInSubShapeString == "LS") || + (posInSubShapeString == "C")) + { + tmp_yOffset = -(minY + (maxY - minY) / 2.0f); + } + yOffset -= tmp_yOffset; + + if ((posInSubShapeString == "TR") || + (posInSubShapeString == "BR") || + (posInSubShapeString == "RS")) + { + tmp_xOffset = -maxX; + } + + if ((posInSubShapeString == "TL") || + (posInSubShapeString == "BL") || + (posInSubShapeString == "LS")) + { + tmp_xOffset = -minX; + } + + // Half the value for horizontal centering conditions + if ((posInSubShapeString == "TS") || + (posInSubShapeString == "BS") || + (posInSubShapeString == "C")) + { + tmp_xOffset = -(minX + (maxX - minX) / 2.0f); + } + + xOffset += tmp_xOffset; + + for (Int32 poly = 0; poly < previewPoints.Count(); poly++) + { + for (Int32 point = 0; point < previewPoints[poly].Count(); point++) + { + double px = previewPoints[poly][point].X + xOffset; + double py = previewPoints[poly][point].Y - yOffset; + + previewPoints[poly][point] = new GeoLibPointF(px, py); + } + if ((previewPoints[poly][0].X != previewPoints[poly][previewPoints[poly].Count() - 1].X) || + (previewPoints[poly][0].Y != previewPoints[poly][previewPoints[poly].Count() - 1].Y)) + { + ErrorReporter.showMessage_OK("Start and end not the same - previewShape", "Oops"); + } + } + } + + void doOffsets(EntropyLayerSettings entropyLayerSettings) + { + // Use our shape-specific offset calculation methods : + xOffset = 0; + yOffset = 0; + + switch (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex)) + { + case (Int32)CentralProperties.typeShapes.rectangle: + rectangle_offset(entropyLayerSettings); + break; + case (Int32)CentralProperties.typeShapes.L: + lShape_offset(entropyLayerSettings); + break; + case (Int32)CentralProperties.typeShapes.T: + tShape_offset(entropyLayerSettings); + break; + case (Int32)CentralProperties.typeShapes.X: + xShape_offset(entropyLayerSettings); + break; + case (Int32)CentralProperties.typeShapes.U: + uShape_offset(entropyLayerSettings); + break; + case (Int32)CentralProperties.typeShapes.S: + sShape_offset(entropyLayerSettings); + break; + case (Int32)CentralProperties.typeShapes.BOOLEAN: + case (Int32)CentralProperties.typeShapes.GEOCORE: + // customShape_offset(entropyLayerSettings); + break; + default: + break; + } + + // Now for global offset. + xOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.gHorOffset)); + yOffset -= Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.gVerOffset)); + } + + public PreviewShape() + { + init(); + } + + void init() + { + // Stub to enable direct drive of preview data, primarily for the implant system. + previewPoints = new List(); + drawnPoly = new List(); + geoCoreOrthogonalPoly = new List(); + color = MyColor.Black; + } + + public PreviewShape(PreviewShape source) + { + init(source); + } + + void init(PreviewShape source) + { + _settingsIndex = source._settingsIndex; + previewPoints = source.previewPoints.ToList(); + drawnPoly = source.drawnPoly.ToList(); + geoCoreOrthogonalPoly = source.geoCoreOrthogonalPoly.ToList(); + color = new MyColor(source.color); + } + + public PreviewShape(CommonVars commonVars, Int32 settingsIndex, Int32 subShapeIndex, Int32 mode, bool doPASearch, bool previewMode, Int32 currentRow, Int32 currentCol) + { + xOffset = 0; + yOffset = 0; + init(commonVars, settingsIndex, subShapeIndex, mode, doPASearch, previewMode, currentRow, currentCol); + } + + public PreviewShape(CommonVars commonVars, ChaosSettings jobSettings_, Int32 settingsIndex, Int32 subShapeIndex, Int32 mode, bool doPASearch, bool previewMode, Int32 currentRow, Int32 currentCol) + { + xOffset = 0; + yOffset = 0; + init(commonVars, jobSettings_, settingsIndex, subShapeIndex, mode, doPASearch, previewMode, currentRow, currentCol); + } + + bool exitEarly = false; + + void distortion(CommonVars commonVars, Int32 settingsIndex) + { + for (Int32 poly = 0; poly < previewPoints.Count(); poly++) + { + // Now let's get some barrel distortion sorted out. Only for non-drawn polygons, and skip if both coefficients are zero to avoid overhead. + if ((!drawnPoly[poly]) && ((commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lDC1) != 0) || (commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lDC2) != 0))) + { + int pCount = previewPoints[poly].Count(); + Parallel.For(0, pCount, (point) => + // for (Int32 point = 0; point < pCount; point++) + { + double px = previewPoints[poly][point].X; + double py = previewPoints[poly][point].Y; + + // Coefficients during testing. + /* + double k1 = 1000.0; + double k2 = 500.0; + */ + + // Need to calculate a new 'radius' from the origin for each point in the polygon, then scale the X/Y values accordingly in the polygon. + // Use scale factor to try and guarantee a -1 to +1 value range + px /= CentralProperties.scaleFactorForOperation; + py /= CentralProperties.scaleFactorForOperation; + + double oRadius = Math.Sqrt(Utils.myPow(px, 2) + Utils.myPow(py, 2)); + // Polynomial radial distortion. + // rd = r(1 + (k1 * r^2) + (k2 * r^4)) from Zhang, 1999 (https://www.microsoft.com/en-us/research/wp-content/uploads/2016/11/zhan99.pdf) + // we only want a scaling factor for our X, Y coordinates. + // '1 -' or '1 +' drive the pincushion/barrel tone. Coefficients being negative will have the same effect, so just pick a direction and stick with it. + int amplifier = 1000; // scales up end-user values to work within this approach. + double t1 = Convert.ToDouble(commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lDC1)) * amplifier * Utils.myPow(Math.Abs(oRadius), 2); + double t2 = Convert.ToDouble(commonVars.getLayerSettings(settingsIndex).getDecimal(EntropyLayerSettings.properties_decimal.lDC2)) * Utils.myPow(amplifier, 2) * Utils.myPow(Math.Abs(oRadius), 4); + double sFactor = 1 - (t1 + t2); + + px *= sFactor * CentralProperties.scaleFactorForOperation; + py *= sFactor * CentralProperties.scaleFactorForOperation; + + previewPoints[poly][point] = new GeoLibPointF(px, py); + + // Refragment + previewPoints[poly] = fragment.fragmentPath(previewPoints[poly]); + }); + } + } + } + + void doNoise(int noiseType, int seed, double freq, double amount, double jitterScale) + { + // Gets a -1 to +1 noise field. We get a seed from our RNG of choice unless the layer preview mode is set, where a fixed seed is used. + // Random constants to mitigate continuity effects in noise that cause nodes in the noise across multiple layers, due to periodicity. + double x_const = 123489.1928734; + double y_const = 891243.0982134; + + object noiseSource; + + switch (noiseType) + { + case (Int32)CommonVars.noiseIndex.opensimplex: + noiseSource = new OpenSimplexNoise(seed); + break; + case (Int32)CommonVars.noiseIndex.simplex: + noiseSource = new SimplexNoise(seed); + break; + default: + noiseSource = new PerlinNoise(seed); + break; + } + + // Need to iterate our preview points. + for (int poly = 0; poly < previewPoints.Count(); poly++) + { + if ((previewPoints[poly].Count() <= 1) || (drawnPoly[poly])) + { + continue; + } + GeoLibPointF[] mcPoints = previewPoints[poly].ToArray(); + int ptCount = mcPoints.Count(); + + // Create our jittered polygon in a new list to avoid breaking normal computation, etc. by modifying the source. + object jitterLock = new object(); + GeoLibPointF[] jitteredPoints = new GeoLibPointF[ptCount]; + + // We could probably simply cast rays in the raycaster and use those, but for now reinvent the wheel here... + GeoLibPointF[] normals = new GeoLibPointF[ptCount]; + GeoLibPointF[] previousNormals = new GeoLibPointF[ptCount]; + double dx = 0; + double dy = 0; + // Pre-calculate these for the threading to be an option. + // This is a serial evaluation as we need both the previous and the current normal for each point. + Parallel.For(0, ptCount - 1, (pt) => + // for (Int32 pt = 0; pt < ptCount - 1; pt++) + { + if (pt == 0) + { + // First vertex needs special care. + dx = mcPoints[0].X - mcPoints[ptCount - 2].X; + dy = mcPoints[0].Y - mcPoints[ptCount - 2].Y; + } + else + { + dx = mcPoints[pt + 1].X - mcPoints[pt].X; + dy = mcPoints[pt + 1].Y - mcPoints[pt].Y; + } + normals[pt] = new GeoLibPointF(-dy, dx); + }); + normals[normals.Length - 1] = new GeoLibPointF(normals[0]); + + int nLength = normals.Length; + Parallel.For(1, nLength, (pt) => + // for (int pt = 1; pt < nLength; pt++) + { + previousNormals[pt] = new GeoLibPointF(normals[pt - 1]); + }); + + previousNormals[0] = new GeoLibPointF(normals[normals.Length - 2]); + + Parallel.For(0, ptCount - 1, pt => + // for (int pt = 0; pt < ptCount - 1; pt++) + { + // We need to average the normals of two edge segments to get the vector we need to displace our point along. + // This ensures that we handle corners and fluctuations in a reasonable manner. + GeoLibPointF averagedEdgeNormal = new GeoLibPointF((previousNormals[pt].X + normals[pt].X) / 2.0f, (previousNormals[pt].Y + normals[pt].Y) / 2.0f); + // Normalize our vector length. + double length = Math.Sqrt(Utils.myPow(averagedEdgeNormal.X, 2) + Utils.myPow(averagedEdgeNormal.Y, 2)); + double normalTolerance = 1E-3; + if (length < normalTolerance) + { + length = normalTolerance; + } + averagedEdgeNormal.X /= length; + averagedEdgeNormal.Y /= length; + + // Use a tolerance as we're handling floats; we don't expect a normalized absolute value generally above 1.0, ignoring the float error. + /* + if ((Math.Abs(averagedEdgeNormal.X) - 1 > normalTolerance) || (Math.Abs(averagedEdgeNormal.Y) - 1 > normalTolerance)) + { + ErrorReporter.showMessage_OK("averageNormal exceeded limits: X:" + averagedEdgeNormal.X.ToString() + ",Y:" + averagedEdgeNormal.Y.ToString(), "oops"); + } + */ + + // We can now modify the position of our point and stuff it into our jittered list. + double jitterAmount = 0; + + switch (noiseType) + { + case (Int32)CommonVars.noiseIndex.opensimplex: + jitterAmount = ((OpenSimplexNoise)noiseSource).Evaluate(freq * (mcPoints[pt].X + x_const), freq * (mcPoints[pt].Y + y_const)); + break; + case (Int32)CommonVars.noiseIndex.simplex: + jitterAmount = ((SimplexNoise)noiseSource).GetNoise(freq * (mcPoints[pt].X + x_const), freq * (mcPoints[pt].Y + y_const)); + break; + default: + jitterAmount = ((PerlinNoise)noiseSource).Noise(freq * (mcPoints[pt].X + x_const), freq * (mcPoints[pt].Y + y_const), 0); + break; + } + + jitterAmount *= jitterScale; + + double jitteredX = mcPoints[pt].X; + jitteredX += jitterAmount * averagedEdgeNormal.X; + + double jitteredY = mcPoints[pt].Y; + jitteredY += jitterAmount * averagedEdgeNormal.Y; + + jitteredPoints[pt] = new GeoLibPointF(jitteredX, jitteredY); + }); + jitteredPoints[ptCount - 1] = new GeoLibPointF(jitteredPoints[0]); + + // Push back to mcPoints for further processing. + previewPoints[poly] = jitteredPoints.ToArray(); + } + } + + void applyNoise(bool previewMode, CommonVars commonVars, ChaosSettings jobSettings, int settingsIndex) + { + + EntropyLayerSettings entropyLayerSettings = commonVars.getLayerSettings(settingsIndex); + + double lwrConversionFactor; + if (commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.ler) == 1) + { + // On the basis that LWR result of two uncorrelated LER variations so should be treated as RSS(). + lwrConversionFactor = Math.Sqrt(2); + } + else + { + lwrConversionFactor = 0.5f; + } + + // LWR, skip if not requested to avoid runtime pain + if (((!previewMode) || (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.lwrPreview) == 1)) && (entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.lwr) != 0)) + { + double jitterScale = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.lwr)) / lwrConversionFactor; // LWR jitter of edge; use RSS for stricter assessment + if (!previewMode && (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.lwrPreview) == 1) && !jobSettings.getPreviewMode()) + { + // This used to be easier, but now we have the case of a non-preview mode, but the layer setting calls for a preview. + jitterScale *= jobSettings.getValue(ChaosSettings.properties.LWRVar, settingsIndex); + } + + doNoise( + noiseType: entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.lwrType), + seed: jobSettings.getInt(ChaosSettings.ints.lwrSeed, settingsIndex), + freq: Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.lwrFreq)), + amount: Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.lwr)), + jitterScale: jitterScale + ); + } + + // LWR2, skip if not requested to avoid runtime pain + if (((!previewMode) || (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.lwrPreview) == 1)) && (entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.lwr2) != 0)) + { + double jitterScale = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.lwr2)) / lwrConversionFactor; // LWR jitter of edge; use RSS for stricter assessment + if (!previewMode && (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.lwrPreview) == 1) && !jobSettings.getPreviewMode()) + { + // This used to be easier, but now we have the case of a non-preview mode, but the layer setting calls for a preview. + jitterScale *= jobSettings.getValue(ChaosSettings.properties.LWR2Var, settingsIndex); + } + + doNoise( + noiseType: entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.lwr2Type), + seed: jobSettings.getInt(ChaosSettings.ints.lwr2Seed, settingsIndex), + freq: Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.lwr2Freq)), + amount: Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.lwr2)), + jitterScale: jitterScale + ); + } + } + + void proximityBias(CommonVars commonVars, ChaosSettings jobSettings, int settingsIndex) + { + // Proximity biasing - where isolated edges get bias based on distance to nearest supporting edge. + + EntropyLayerSettings entropyLayerSettings = commonVars.getLayerSettings(settingsIndex); + + bool proxBiasNeeded = ((entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.pBias) != 0) && (entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.pBiasDist) != 0)); + + if (!proxBiasNeeded) + { + return; + } + + bool debug = false; + bool linear = false; + + List updatedPolys = new List(); + List preOverlapMergePolys = new List(); + List updatedDrawn = new List(); + + Paths clippedLines = new Paths(); + Paths dRays = new Paths(); + + // Scale up our geometry for processing. Force a clockwise point order here due to potential upstream point order changes (e.g. polygon merging) + Paths sourceGeometry = GeoWrangler.pathsFromPointFs(previewPoints, CentralProperties.scaleFactorForOperation); + + // sourceGeometry = GeoWrangler.removeKeyHoles(sourceGeometry, 1); + + int sCount = sourceGeometry.Count(); + for (int poly = 0; poly < sCount; poly++) + { + if ((sourceGeometry[poly].Count() <= 1) || (drawnPoly[poly])) + { + updatedPolys.Add(previewPoints[poly]); + if (drawnPoly[poly]) + { + updatedDrawn.Add(true); + } + else + { + updatedDrawn.Add(false); + } + // Nothing to do with drawn or zero count entries. + continue; + } + + Path sourcePoly = sourceGeometry[poly].ToList(); + Path deformedPoly = new Path(); + + // Threading operation here gets more tricky than the distance handler. We have a less clear trade off of threading based on the emission edge (the polygon being biased) vs the multisampling emission. + // In batch calculation mode, this tradeoff gets more awkward. + // Threading both options also causes major performance degradation as far too many threads are spawned for the host system. + bool multiSampleThread = false; + bool emitThread = false; + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.proxRays) > 1) + { + multiSampleThread = true; + // for multipolygon scenarios, avoid threading the multisampling and instead favor threading emitting edge. + if (sourceGeometry.Count > 1) + { + emitThread = true; + multiSampleThread = false; + } + } + else + { + emitThread = true; + } + + RayCast rc = new RayCast(sourcePoly, sourceGeometry, Convert.ToInt32(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.pBiasDist) * CentralProperties.scaleFactorForOperation), false, false, entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.proxRays), emitThread, multiSampleThread); + + clippedLines = rc.getClippedRays().ToList(); + if (debug) + { + dRays = rc.getClippedRays().ToList(); + } + + // We hope to get the same number of clipped lines back as the number of points that went in.... + int cLCount = clippedLines.Count; + for (int line = 0; line < cLCount; line++) + { + Int64 displacedX = sourcePoly[line].X; + Int64 displacedY = sourcePoly[line].Y; + + double lineLength = rc.getRayLength(line); + + // No biasing - ray never made it beyond the surface. Short-cut the + if (lineLength == 0) + { + deformedPoly.Add(new IntPoint(clippedLines[line][0])); + continue; + } + if (lineLength < 0) + { + lineLength *= -1; + } + + // Calculate our bias based on this distance and apply it. + double biasScaling = (lineLength / CentralProperties.scaleFactorForOperation) / Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.pBiasDist)); + + if (biasScaling > 1) + { + biasScaling = 1; + } + + // Probably should be a sigmoid, but using this for now. + double displacedAmount = 0; + + if (linear) + { + displacedAmount = biasScaling * Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.pBias)) * CentralProperties.scaleFactorForOperation; + } + else + { + // Using sine to make a ease-in/ease-out effect. + displacedAmount = Math.Sin(Utils.toRadians(biasScaling * 90.0f)) * Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.pBias)) * CentralProperties.scaleFactorForOperation; + } + + // Use our cast ray from rc to get a normalized average + IntPoint averagedEdgeNormal = GeoWrangler.intPoint_distanceBetweenPoints(clippedLines[line][clippedLines[line].Count() - 1], clippedLines[line][0]); + + // Normalize our vector length. + double aX = averagedEdgeNormal.X / lineLength; + double aY = averagedEdgeNormal.Y / lineLength; + + displacedY += (Int64)(displacedAmount * aY); + displacedX += (Int64)(displacedAmount * aX); + + deformedPoly.Add(new IntPoint(displacedX, displacedY)); + } + preOverlapMergePolys.Add(GeoWrangler.pointFFromPath(deformedPoly, CentralProperties.scaleFactorForOperation)); + deformedPoly.Add(new IntPoint(deformedPoly[0])); + } + + // Check for overlaps and process as needed post-biasing. + processOverlaps(commonVars, settingsIndex, preOverlapMergePolys, forceOverride: false, PolyFillType.pftNonZero); + + if (debug) + { + for (int ray = 0; ray < dRays.Count; ray++) + { + previewPoints.Add(GeoWrangler.pointFFromPath(dRays[ray], CentralProperties.scaleFactorForOperation)); + drawnPoly.Add(true); + } + } + } + + void init(CommonVars commonVars, Int32 settingsIndex, Int32 subShapeIndex, Int32 mode, bool doPASearch, bool previewMode, Int32 currentRow, Int32 currentCol) + { + ChaosSettings jobSettings_ = new ChaosSettings(previewMode, commonVars.getListOfSettings(), commonVars.getSimulationSettings()); + init(commonVars, jobSettings_, settingsIndex, subShapeIndex, mode, doPASearch, previewMode, currentRow, currentCol); + } + + void init(CommonVars commonVars, ChaosSettings chaosSettings, Int32 settingsIndex, Int32 subShapeIndex, Int32 mode, bool doPASearch, bool previewMode, Int32 currentRow, Int32 currentCol, EntropyLayerSettings entropyLayerSettings = null, bool doClockwiseGeoFix = true, bool process_overlaps = true) + { + _settingsIndex = settingsIndex; + try + { + DOEDependency = false; + fragment = new Fragmenter(commonVars.getSimulationSettings().getResolution(), CentralProperties.scaleFactorForOperation); + previewPoints = new List(); + drawnPoly = new List(); + geoCoreOrthogonalPoly = new List(); + color = MyColor.Black; // overridden later. + + if (entropyLayerSettings == null) + { + entropyLayerSettings = commonVars.getLayerSettings(settingsIndex); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) + { + init_geoCore(commonVars, chaosSettings, settingsIndex, entropyLayerSettings, mode, doPASearch, previewMode, process_overlaps, doClockwiseGeoFix); + // Get our offsets configured. We need to check for DOE settings here, to prevent relocation of extracted polygons within the tile during offset evaluation. + if (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(settingsIndex) == 1) + { + DOEDependency = true; + doeMinX = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colOffset); + doeMinY = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowOffset); + } + doOffsets(entropyLayerSettings); + } + else // not geoCore related. + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.BOOLEAN) + { + try + { + init_boolean(commonVars, chaosSettings, settingsIndex, subShapeIndex, mode, doPASearch, previewMode, currentRow, currentCol, entropyLayerSettings); + // Get our offsets configured. + // Is any input layer coming from a GDS DOE tile? We need to check for DOE settings here, to prevent relocation of extracted polygons within the tile during offset evaluation. + int boolLayer = entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerA); + while (boolLayer > 0) + { + DOEDependency = (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(boolLayer) == 1); + if (DOEDependency) + { + break; + } + boolLayer = commonVars.getLayerSettings(boolLayer).getInt(EntropyLayerSettings.properties_i.bLayerA); + } + if (!DOEDependency) + { + boolLayer = entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerB); + while (boolLayer > 0) + { + DOEDependency = (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(boolLayer) == 1); + if (DOEDependency) + { + break; + } + boolLayer = commonVars.getLayerSettings(boolLayer).getInt(EntropyLayerSettings.properties_i.bLayerB); + } + } + if (DOEDependency) + { + doeMinX = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.colOffset); + doeMinY = commonVars.getSimulationSettings().getDOESettings().getDouble(DOESettings.properties_d.rowOffset); + } + + doOffsets(entropyLayerSettings); + } + catch (Exception) + { + } + exitEarly = true; // avoid second pass of distortion, etc. + } + else + { + if (mode == 0) + { + // Basic shape - 5 points to make a closed preview. 5th is identical to 1st. + GeoLibPointF[] tempArray = new GeoLibPointF[5]; + + // Need exception handling here for overflow cases? + Decimal bottom_leftX = 0, bottom_leftY = 0; + Decimal top_leftX = 0, top_leftY = 0; + Decimal top_rightX = 0, top_rightY = 0; + Decimal bottom_rightX = 0, bottom_rightY = 0; + if (subShapeIndex == 0) + { + bottom_leftX = 0; + bottom_leftY = 0; + top_leftX = 0; + top_leftY = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength); + top_rightX = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength); + top_rightY = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength); + bottom_rightX = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength); + bottom_rightY = 0; + xOffset = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset)); + yOffset = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset)); + } + if (subShapeIndex == 1) + { + bottom_leftX = 0; + bottom_leftY = 0; + top_leftX = 0; + top_leftY = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength); + top_rightX = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength); + top_rightY = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength); + bottom_rightX = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength); + bottom_rightY = 0; + xOffset = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset) + entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)); + yOffset = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset) + entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + } + if (subShapeIndex == 2) + { + bottom_leftX = 0; + bottom_leftY = 0; + top_leftX = 0; + top_leftY = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength); + top_rightX = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength); + top_rightY = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength); + bottom_rightX = entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength); + bottom_rightY = 0; + xOffset = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset) + entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset)); + yOffset = -Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset) + entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength) + entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset)); + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.Sshape) + { + yOffset += Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); // offset our subshape to put it in the correct place in the UI. + } + } + + // Populate array. + tempArray[0] = new GeoLibPointF((double)bottom_leftX, (double)bottom_leftY); + tempArray[1] = new GeoLibPointF((double)top_leftX, (double)top_leftY); + tempArray[2] = new GeoLibPointF((double)top_rightX, (double)top_rightY); + tempArray[3] = new GeoLibPointF((double)bottom_rightX, (double)bottom_rightY); + tempArray[4] = new GeoLibPointF(tempArray[0]); + + // Apply our deltas + int tLength = tempArray.Length; + Parallel.For(0, tLength, (i) => + //for (Int32 i = 0; i < tLength; i++) + { + tempArray[i].X += xOffset; + tempArray[i].Y += yOffset; + }); + previewPoints.Add(tempArray); + drawnPoly.Add(true); + } + else + { + // Complex shape + try + { + EntropyShape complexPoints = new EntropyShape(commonVars.getSimulationSettings(), commonVars.getListOfSettings(), settingsIndex, doPASearch, previewMode, chaosSettings); + previewPoints.Add(complexPoints.getPoints()); + drawnPoly.Add(false); + } + catch (Exception) + { + + } + } + // Get our offsets configured. + doOffsets(entropyLayerSettings); + + int pCount = previewPoints.Count; + for (Int32 poly = 0; poly < pCount; poly++) + { + int ptCount = previewPoints[poly].Count(); + Parallel.For(0, ptCount, (point) => + // for (Int32 point = 0; point < ptCount; point++) + { + double px = previewPoints[poly][point].X + xOffset; + double py = previewPoints[poly][point].Y - yOffset; + + previewPoints[poly][point] = new GeoLibPointF(px, py); + }); + if ((previewPoints[poly][0].X != previewPoints[poly][previewPoints[poly].Count() - 1].X) || + (previewPoints[poly][0].Y != previewPoints[poly][previewPoints[poly].Count() - 1].Y)) + { + ErrorReporter.showMessage_OK("Start and end not the same - previewShape", "Oops"); + } + } + } + } + + if ((!exitEarly) && (mode == 1)) + { + // Apply lens distortion. + distortion(commonVars, settingsIndex); + // Noise and proximity biasing. + applyNoise(previewMode, commonVars, chaosSettings, settingsIndex); + proximityBias(commonVars, chaosSettings, settingsIndex); + } + } + catch (Exception) + { + } + } + + void init_geoCore(CommonVars commonVars, ChaosSettings chaosSettings, int settingsIndex, EntropyLayerSettings entropyLayerSettings, Int32 mode, bool doPASearch, bool previewMode, bool process_overlaps, bool forceClockwise) + { + // We'll use these to shift the points around. + double xOverlayVal = 0.0f; + double yOverlayVal = 0.0f; + + xOffset = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.gHorOffset) + entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset)); + yOffset = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.gVerOffset) + entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset)); + + if (mode == 1) + { + // We need this check and early return because previewShape is now used in the layer preview + // mode to handle bias on geoCore elements. Populating this when the layer is not enabled + // causes the shared structure with the simulation engine to be defined and breaks everything. + // Instead we just make a zero area polygon (to avoid issues downstream) and return early. + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.enabled) == 0) + { + previewPoints.Add(new GeoLibPointF[4]); + for (int i = 0; i < 4; i++) + { + previewPoints[0][i] = new GeoLibPointF(0, 0); + } + drawnPoly.Add(false); + geoCoreOrthogonalPoly.Add(true); + return; + } + // OK. We need to crop our layout based on the active tile if there is a DOE flag set. + bool tileHandlingNeeded = false; + if (commonVars.getSimulationSettings().getDOESettings().getLayerAffected(settingsIndex) == 1) + { + tileHandlingNeeded = true; + } + + if (previewMode && tileHandlingNeeded) + { + if (!commonVars.getLayerPreviewDOETile()) + { + tileHandlingNeeded = false; + } + } + + // Get overlay figured out. + if (!previewMode) + { + xOverlayVal = (chaosSettings.getValue(ChaosSettings.properties.overlayX, settingsIndex) * Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.xOL))); + yOverlayVal = (chaosSettings.getValue(ChaosSettings.properties.overlayY, settingsIndex) * Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.yOL))); + + // Handle overlay reference setting + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_av) == 1) // overlay average + { + List overlayValues = new List(); + for (int avgolref_x = 0; avgolref_x < entropyLayerSettings.getIntArray(EntropyLayerSettings.properties_intarray.xOLRefs).Length; avgolref_x++) + { + if (entropyLayerSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, avgolref_x) == 1) + { + overlayValues.Add(chaosSettings.getValue(ChaosSettings.properties.overlayX, avgolref_x) * Convert.ToDouble(commonVars.getLayerSettings(avgolref_x).getDecimal(EntropyLayerSettings.properties_decimal.xOL))); // Overlay shift + } + } + + xOverlayVal += overlayValues.Average(); + } + else // vanilla overlay reference mode + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) != -1) + { + xOverlayVal += (chaosSettings.getValue(ChaosSettings.properties.overlayX, entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref)) * Convert.ToDouble(commonVars.getLayerSettings(entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref)).getDecimal(EntropyLayerSettings.properties_decimal.xOL))); + } + } + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_av) == 1) // overlay average + { + List overlayValues = new List(); + for (int avgolref_y = 0; avgolref_y < entropyLayerSettings.getIntArray(EntropyLayerSettings.properties_intarray.yOLRefs).Length; avgolref_y++) + { + if (entropyLayerSettings.getIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, avgolref_y) == 1) + { + overlayValues.Add(chaosSettings.getValue(ChaosSettings.properties.overlayY, avgolref_y) * Convert.ToDouble(commonVars.getLayerSettings(avgolref_y).getDecimal(EntropyLayerSettings.properties_decimal.yOL))); // Overlay shift + } + } + + yOverlayVal += overlayValues.Average(); + } + else // vanilla overlay reference mode + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) != -1) + { + yOverlayVal += (chaosSettings.getValue(ChaosSettings.properties.overlayY, entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref)) * Convert.ToDouble(commonVars.getLayerSettings(entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref)).getDecimal(EntropyLayerSettings.properties_decimal.yOL))); + } + } + } + + // Decouple the geometry here to avoid manipulation going back to original source. + List tempPolyList = new List(); + if (tileHandlingNeeded) + { + tempPolyList = commonVars.getNonSimulationSettings().extractedTile[settingsIndex].ToList(); + } + else + { + tempPolyList = entropyLayerSettings.getFileData().ToList(); + } + try + { + double minx = tempPolyList[0][0].X; + double miny = tempPolyList[0][0].Y; + double maxx = tempPolyList[0][0].X; + double maxy = tempPolyList[0][0].Y; + int tPCount = tempPolyList.Count; + for (Int32 poly = 0; poly < tPCount; poly++) + { + double min_x = tempPolyList[poly].Min(p => p.X); + double min_y = tempPolyList[poly].Min(p => p.Y); + double max_x = tempPolyList[poly].Max(p => p.X); + double max_y = tempPolyList[poly].Max(p => p.Y); + + if (min_x < minx) + { + minx = min_x; + } + if (min_y < miny) + { + miny = min_y; + } + if (max_x > maxx) + { + maxx = max_x; + } + if (max_y > maxy) + { + maxy = max_y; + } + } + + GeoLibPointF bb_mid = new GeoLibPointF(minx + (maxx - minx) / 2.0f, miny + (maxy - miny) / 2.0f); + bb_mid.X += xOverlayVal + (double)entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.gHorOffset) + (double)entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorOffset); + bb_mid.Y += yOverlayVal + (double)entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.gVerOffset) + (double)entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset); + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.perPoly) == 1) + { + bb_mid = null; + } + + for (int poly = 0; poly < tPCount; poly++) + { + GeoLibPointF[] tempPoly; + + if (tileHandlingNeeded) + { + // Poly is already closed - presents a problem if we use contouring. + int arraySize = tempPolyList[poly].Count(); + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.gCSEngine) == 1) + { + if ((tempPolyList[poly][0].X == tempPolyList[poly][tempPolyList[poly].Length - 1].X) && (tempPolyList[poly][0].Y == tempPolyList[poly][tempPolyList[poly].Length - 1].Y)) + { + arraySize--; + } + } + + tempPoly = new GeoLibPointF[arraySize]; + + Parallel.For(0, arraySize, (pt) => + // for (int pt = 0; pt < arraySize; pt++) + { + tempPoly[pt] = new GeoLibPointF(tempPolyList[poly][pt].X + xOffset, tempPolyList[poly][pt].Y + yOffset); + }); + } + else + { + int polySize = entropyLayerSettings.getFileData()[poly].Count(); + + tempPoly = new GeoLibPointF[polySize]; + + Parallel.For(0, polySize, (pt) => + // for (Int32 pt = 0; pt < polySize; pt++) + { + tempPoly[pt] = new GeoLibPointF(entropyLayerSettings.getFileData()[poly][pt].X + xOffset, entropyLayerSettings.getFileData()[poly][pt].Y + yOffset); + }); + } + + bool drawn = false; + + // Compatibility shim - we need to toggle this behavior due to the ILB passing in mixed orientation geometry that we don't want to clobber. + // However, external geometry may need this spin fixing. Although the upper levels should also re-spin geometry properly - we don't assume this. + if (forceClockwise) + { + tempPoly = GeoWrangler.clockwiseAndReorder(tempPoly); // force clockwise order and lower-left at 0 index. + } + + // Strip termination points. Set shape will take care of additional clean-up if needed. + tempPoly = GeoWrangler.stripTerminators(tempPoly, false); + + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.gCSEngine) == 0) + { + previewPoints.Add(fragment.fragmentPath(tempPoly.ToArray())); + geoCoreOrthogonalPoly.Add(false); // We need to populate the list, but in this non-contoured case, the value doesn't matter. + } + else + { + // Feed tempPoly to shape engine. + ShapeLibrary shape = new ShapeLibrary(entropyLayerSettings); + + shape.setShape(entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex), tempPoly.ToArray()); // feed the shape engine with the geometry using our optional parameter. + EntropyShape complexPoints = new EntropyShape(commonVars.getSimulationSettings(), commonVars.getListOfSettings(), settingsIndex, doPASearch, previewMode, chaosSettings, shape, bb_mid); + // Add resulting shape to the previewPoints. + previewPoints.Add(complexPoints.getPoints()); + // This list entry does matter - we need to choose the right expansion method in case contouring has been chosen, but the + // polygon is not orthogonal. + geoCoreOrthogonalPoly.Add(shape.geoCoreShapeOrthogonal); + } + drawnPoly.Add(drawn); + } + } + catch (Exception) + { + } + + // Overlay + if (!previewMode) + { + int pCount = previewPoints.Count; + for (int poly = 0; poly < pCount; poly++) + { + if (!drawnPoly[poly]) + { + int ptCount = previewPoints[poly].Count(); + Parallel.For(0, ptCount, (pt) => + // for (int pt = 0; pt < ptCount; pt++) + { + previewPoints[poly][pt].X += xOverlayVal; + previewPoints[poly][pt].Y += yOverlayVal; + }); + } + } + } + + // Biasing and CDU thanks to clipperLib + // Note that we have to guard against a number of situations here + // We do not want to re-bias contoured geoCore data - it's been done already. + // Additionally, we don't want to assume an overlap for processing where none exists : we'll get back an empty polygon. + double globalBias_Sides = Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.sBias)); + globalBias_Sides += (chaosSettings.getValue(ChaosSettings.properties.CDUSVar, settingsIndex) * Convert.ToDouble(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.sCDU)) / 2); + List resizedLayoutData = new List(); + try + { + if (globalBias_Sides > Double.Epsilon) + { + List new_Drawn = new List(); + + int pCount = previewPoints.Count; + for (int poly = 0; poly < pCount; poly++) + { + // Need to iterate across all polygons and only bias in this manner either: + // non-contoured mode + // contoured, but non-orthogonal polygons. + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.gCSEngine) == 0) || + ((!geoCoreOrthogonalPoly[poly]) && (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.gCSEngine) == 1))) + { + Paths resizedPolyData = new Paths(); + Path gdsPointData = GeoWrangler.pathFromPointF(previewPoints[poly], CentralProperties.scaleFactorForOperation); + ClipperOffset co = new ClipperOffset(); + co.AddPath(gdsPointData, JoinType.jtMiter, EndType.etClosedPolygon); + co.Execute(ref resizedPolyData, Convert.ToDouble(globalBias_Sides * CentralProperties.scaleFactorForOperation)); + + // Store our polygon data (note that we could have ended up with two or more polygons due to reduction) + try + { + for (int rPoly = 0; rPoly < resizedPolyData.Count(); rPoly++) + { + GeoLibPointF[] rPolyData = GeoWrangler.pointFFromPath(resizedPolyData[rPoly], CentralProperties.scaleFactorForOperation); + resizedLayoutData.Add(rPolyData); + + // We need to track our drawn state as we could have a polygon count change. + new_Drawn.Add(drawnPoly[poly]); + } + } + catch (Exception) + { + } + } + else + { + new_Drawn.Add(drawnPoly[poly]); + } + + // In case of contoured mode, with orthogonal polygon, we need to store this: + if (geoCoreOrthogonalPoly[poly] && (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.gCSEngine) == 1)) + { + // Decouple out of paranoia. + resizedLayoutData.Add(previewPoints[poly].ToArray()); + } + } + + previewPoints = resizedLayoutData.ToList(); + drawnPoly = new_Drawn.ToList(); + } + } + catch (Exception) + { + + } + + if (process_overlaps) + { + processOverlaps(commonVars, settingsIndex, previewPoints, forceOverride: false, (PolyFillType)commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.fill)); + } + } + else + { + // Drawn polygons only. + // Needed to take this approach, otherwise fileData gets tied to the previewPoints list and things go wrong quickly. + // .ToList() was insufficient to avoid the link. + for (Int32 poly = 0; poly < entropyLayerSettings.getFileData().Count(); poly++) + { + int arraySize = entropyLayerSettings.getFileData()[poly].Length; + GeoLibPointF[] tmp = new GeoLibPointF[arraySize]; + Parallel.For(0, arraySize, (pt) => + // for (Int32 pt = 0; pt < arraySize; pt++) + { + tmp[pt] = new GeoLibPointF(entropyLayerSettings.getFileData()[poly][pt].X + xOffset, + entropyLayerSettings.getFileData()[poly][pt].Y + yOffset); + }); + previewPoints.Add(tmp); + bool drawn = true; + drawnPoly.Add(drawn); + } + } + } + + void init_boolean(CommonVars commonVars, ChaosSettings chaosSettings, Int32 settingsIndex, Int32 subShapeIndex, Int32 mode, bool doPASearch, bool previewMode, Int32 currentRow, Int32 currentCol, EntropyLayerSettings entropyLayerSettings) + { + // Get our two layers' geometry. Avoid keyholes in the process. + int layerAIndex = entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerA); + if ((settingsIndex == layerAIndex) || (layerAIndex < 0)) + { + return; + } + EntropyLayerSettings layerA = commonVars.getLayerSettings(layerAIndex); + PreviewShape a_pShape = new PreviewShape(commonVars, layerAIndex, layerA.getInt(EntropyLayerSettings.properties_i.subShapeIndex), mode: 1, doPASearch, previewMode, currentRow, currentCol); + + int layerBIndex = entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerB); + if ((settingsIndex == layerBIndex) || (layerBIndex < 0)) + { + return; + } + EntropyLayerSettings layerB = commonVars.getLayerSettings(layerBIndex); + PreviewShape b_pShape = new PreviewShape(commonVars, layerBIndex, layerB.getInt(EntropyLayerSettings.properties_i.subShapeIndex), mode: 1, doPASearch, previewMode, currentRow, currentCol); + + // We need to map the geometry into Paths for use in the Boolean + Paths layerAPaths = GeoWrangler.pathsFromPointFs(a_pShape.getPoints(), CentralProperties.scaleFactorForOperation); + Paths layerBPaths = GeoWrangler.pathsFromPointFs(b_pShape.getPoints(), CentralProperties.scaleFactorForOperation); + + // Now this gets interesting. We leverage the Boolean engine in ChaosEngine to get the result we want. + // This should probably be relocated at some point, but for now, it's an odd interaction. + Paths booleanPaths = ChaosEngine.customBoolean( + firstLayerOperator: entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerOpA), + firstLayer: layerAPaths, + secondLayerOperator: entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerOpB), + secondLayer: layerBPaths, + booleanFlag: entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.bLayerOpAB) + ); + + // This is set later, if needed, to force an early return from the overlap processing path. + bool forceOverride = false; + int bpCount = booleanPaths.Count; + Parallel.For(0, bpCount, (i) => + // for (int i = 0; i < bpCount; i++) + { + try + { + booleanPaths[i] = GeoWrangler.close(booleanPaths[i]); + } + catch (Exception) + { + + } + }); + + // Scale back down again. + List booleanGeo = GeoWrangler.pointFsFromPaths(booleanPaths, CentralProperties.scaleFactorForOperation); + + // Process the geometry according to mode, etc. + // We do this by treating our geometry as a geocore source and calling init with this to set up our instance properties. + // Feels a little hacky, but it ought to work. + EntropyLayerSettings tempSettings = new EntropyLayerSettings(); + tempSettings.adjustSettings(entropyLayerSettings, gdsOnly: false); + tempSettings.setInt(EntropyLayerSettings.properties_i.shapeIndex, (int)CommonVars.shapeNames.GEOCORE); + tempSettings.setInt(EntropyLayerSettings.properties_i.gCSEngine, 1); + tempSettings.setFileData(booleanGeo.ToList()); + drawnPoly.Clear(); + previewPoints.Clear(); + init(commonVars, chaosSettings, settingsIndex, subShapeIndex, mode, doPASearch, previewMode, currentRow, currentCol, tempSettings, doClockwiseGeoFix: true, process_overlaps: false); // Avoid the baked-in point order reprocessing which breaks our representation. + + processOverlaps(commonVars, settingsIndex, previewPoints, forceOverride, (PolyFillType)commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.fill)); + } + + void processOverlaps(CommonVars commonVars, Int32 settingsIndex, List sourceData, bool forceOverride = false, PolyFillType pft = PolyFillType.pftNonZero) + { + // Filter drawn, process those, then do not-drawn. This allows for element counts to change. + List drawnStuff = new List(); + List notDrawnStuff = new List(); + int sCount = sourceData.Count; + for (int i = 0; i < sCount; i++) + { + if (drawnPoly[i]) + { + drawnStuff.Add(sourceData[i]); + } + else + { + notDrawnStuff.Add(sourceData[i]); + } + } + List processed_Drawn = processOverlaps_core(commonVars, drawnStuff, forceOverride, pft); + + List processed_NotDrawn = processOverlaps_core(commonVars, notDrawnStuff, forceOverride, pft); + + previewPoints.Clear(); + drawnPoly.Clear(); + + int pdCount = processed_Drawn.Count; + int pndCount = processed_NotDrawn.Count; + + for (int i = 0; i < pdCount; i++) + { + previewPoints.Add(processed_Drawn[i]); + drawnPoly.Add(true); + } + + for (int i = 0; i < pndCount; i++) + { + previewPoints.Add(processed_NotDrawn[i]); + drawnPoly.Add(false); + } + + } + + List processOverlaps_core(CommonVars commonVars, List sourceData, bool forceOverride = false, PolyFillType pft = PolyFillType.pftNonZero) + { + try + { + // Can the tessellator help us out here? + // return GeoWrangler.makeKeyHole(sourceData); + + Clipper c = new Clipper(); + c.PreserveCollinear = true; + Paths sourcePolyData = GeoWrangler.pathsFromPointFs(sourceData, CentralProperties.scaleFactorForOperation); + Paths resizedPolyData = new Paths(); + + // Union isn't always robust, so get a bounding box and run an intersection boolean to rationalize the geometry. + IntRect bounds = Clipper.GetBounds(sourcePolyData); + Path bounding = new Path(); + bounding.Add(new IntPoint(bounds.left, bounds.bottom)); + bounding.Add(new IntPoint(bounds.left, bounds.top)); + bounding.Add(new IntPoint(bounds.right, bounds.top)); + bounding.Add(new IntPoint(bounds.right, bounds.bottom)); + + // c.AddPath(bounding, PolyType.ptClip, true); + c.AddPaths(sourcePolyData, PolyType.ptClip, true); + c.AddPaths(sourcePolyData, PolyType.ptSubject, true); + + c.Execute(ClipType.ctIntersection, resizedPolyData, pft, pft); + + // Avoid the overlap handling if we don't actually need to do it. + + bool returnEarly = false; + + int rpdCount = resizedPolyData.Count; + int sCount = sourceData.Count; + + if (rpdCount == sCount) + { + returnEarly = true; + for (int i = 0; i < rpdCount; i++) + { + // Clipper drops the closing vertex. + if (resizedPolyData[i].Count != sourceData[i].Length - 1) + { + returnEarly = false; + break; + } + } + } + + if (returnEarly) + { + // Secondary check + c.Clear(); + + c.AddPath(bounding, PolyType.ptClip, true); + // c.AddPaths(sourcePolyData, PolyType.ptClip, true); + c.AddPaths(sourcePolyData, PolyType.ptSubject, true); + + c.Execute(ClipType.ctIntersection, resizedPolyData, pft, pft); + + // Decompose to outers and cutters + Paths[] decomp = GeoWrangler.getDecomposed(resizedPolyData); + + Paths outers = decomp[(int)GeoWrangler.type.outer]; + Paths cutters = decomp[(int)GeoWrangler.type.cutter]; + + int oCount = outers.Count; + int cCount = cutters.Count; + + // Is any cutter fully enclosed wtihin an outer? + for (int outer = 0; outer < oCount; outer++) + { + double origArea = Math.Abs(Clipper.Area(outers[outer])); + for (int cutter = 0; cutter < cCount; cutter++) + { + c.Clear(); + c.AddPath(outers[outer], PolyType.ptSubject, true); + c.AddPath(cutters[cutter], PolyType.ptClip, true); + Paths test = new Paths(); + c.Execute(ClipType.ctUnion, test, PolyFillType.pftPositive, PolyFillType.pftPositive); + + double uArea = 0; + for (int i = 0; i < test.Count; i++) + { + uArea += Math.Abs(Clipper.Area(test[i])); + } + + if (Math.Abs(uArea - origArea) < double.Epsilon) + { + returnEarly = false; + break; + } + } + if (!returnEarly) + { + break; + } + } + + if (returnEarly) + { + return sourceData.ToList(); + } + } + + resizedPolyData = GeoWrangler.close(resizedPolyData); + + // Here, we can run into trouble....we might have a set of polygons which need to get keyholed. For example, where we have fully enclosed 'cutters' within an outer boundary. + // Can geoWrangler help us out here? + resizedPolyData = GeoWrangler.makeKeyHole(resizedPolyData).ToList(); + //resizedPolyData = GeoWrangler.sanitize(resizedPolyData).ToList(); + + if (resizedPolyData.Count() == 0) + { + return sourceData; + } + + // We got some resulting geometry from our Boolean so let's process it to send back to the caller. + List refinedData = new List(); + + Fragmenter f = new Fragmenter(commonVars.getSimulationSettings().getResolution(), CentralProperties.scaleFactorForOperation); + + resizedPolyData = GeoWrangler.close(resizedPolyData); + + rpdCount = resizedPolyData.Count; + + for (int rPoly = 0; rPoly < rpdCount; rPoly++) + { + // We have to refragment as the overlap processing changed the geometry heavily. + refinedData.Add(f.fragmentPath(GeoWrangler.pointFFromPath(resizedPolyData[rPoly], CentralProperties.scaleFactorForOperation))); + } + + return refinedData.ToList(); + } + catch (Exception) + { + return sourceData.ToList(); + } + } + } +} diff --git a/Common/Variance/support/replay.cs b/Common/Variance/support/replay.cs new file mode 100644 index 0000000..2710649 --- /dev/null +++ b/Common/Variance/support/replay.cs @@ -0,0 +1,448 @@ +using Error; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using utility; + +namespace Variance +{ + public class Replay + { + bool valid; + + public bool isValid() + { + return pIsValid(); + } + + bool pIsValid() + { + return valid; + } + + ChaosSettings chaosSettings; + public ChaosSettings getChaosSettings() + { + return pGetChaosSettings(); + } + + ChaosSettings pGetChaosSettings() + { + return chaosSettings; + } + + string result; + public string getResult() + { + return pGetResult(); + } + + string pGetResult() + { + return result; + } + + CommonVars commonVars_; + List parsed; + int max; + string listOfSettingsHash, entropyGeoHash, geoCoreHash; + int col, row; // for tile extraction. + + public enum properties_i { max, col, row } + + public Int32 getValue(properties_i p) + { + return pGetValue(p); + } + + Int32 pGetValue(properties_i p) + { + int ret = 0; + switch (p) + { + case properties_i.col: + ret = col; + break; + case properties_i.row: + ret = row; + break; + case properties_i.max: + ret = max; + break; + } + return ret; + } + + public Replay(ref CommonVars commonVars) + { + pReplay(ref commonVars); + } + + public void replay_loadCSV(string filename) + { + pLoadCSV(filename); + } + + void pReplay(ref CommonVars commonVars) + { + commonVars_ = commonVars; + parsed = new List(); + pReset(); + } + + void pLoadCSV(string filename) + { + try + { + // Carve up the filename to see whether we have col and row specified. + string[] tokens = filename.Split(new char[] { '_' }); + // Format is of the form _col0_row0.csv + string rowString = tokens[tokens.Length - 1].Split(new char[] { '.' })[0]; + string colString = tokens[tokens.Length - 2].Split(new char[] { '_' })[0]; + + // Attempting to bullet-proof things against random user naming. + if ((rowString.Substring(0, 3) == "row") && (rowString.Substring(0, 3) == "col")) + { + // Have to fix the indices to align with the expectations in the engine. + rowString = rowString.Substring(3, rowString.Length - 3); + row = Convert.ToInt32(rowString) + 1; + colString = colString.Substring(3, colString.Length - 3); + col = Convert.ToInt32(colString) + 1; + } + + // Need to set the simulation settings data to match our DOE tile. + + } + catch (Exception) + { + + } + + try + { + string[] lines = File.ReadAllLines(filename); + + // Header, and two hash lines make 3 - we also expect at least one result. + if (lines.Length < 4) + { + throw new Exception("Invalid file structure"); + } + + // Check for replay hashes in the CSV file. + Array.Reverse(lines); // speed up the search. + + bool lFound = false; + int lIndex = -1; + bool ehFound = false; + int eIndex = -1; + bool gFound = false; + int gIndex = -1; + for (int i = 0; i < lines.Length; i++) + { + if (lines[i].StartsWith("lHash")) + { + lFound = true; + lIndex = i; + // Validate that we got the expected strings and extract the checksum data. + try + { + listOfSettingsHash = lines[i].Split(new char[] { ',' })[1]; + } + catch (Exception) + { + throw new Exception("Checksum data not found."); + } + } + else if (lines[i].StartsWith("eHash")) + { + ehFound = true; + eIndex = i; + // Validate that we got the expected strings and extract the checksum data. + try + { + entropyGeoHash = lines[i].Split(new char[] { ',' })[1]; + } + catch (Exception) + { + throw new Exception("Checksum data not found."); + } + } + else if (lines[i].StartsWith("gHash")) + { + gFound = true; + gIndex = i; + // Validate that we got the expected strings and extract the checksum data. + try + { + geoCoreHash = lines[i].Split(new char[] { ',' })[1]; + } + catch (Exception) + { + throw new Exception("Checksum data not found."); + } + } + if (lFound && ehFound && gFound) + { + Array.Reverse(lines); + break; + } + } + + // Compare the hashes with the loaded project. + if (!hashCheck()) + { + ErrorReporter.showMessage_OK("CSV checksum does not match loaded project.\r\nTrying to continue.", "Data mismatch"); + } + + parsed.Clear(); + + int terminatingRow = Math.Max(Math.Max(lIndex, gIndex), eIndex) + 1; + + // Avoid the hash lines. + for (int line = 0; line < lines.Length - terminatingRow; line++) + { + parsed.Add(lines[line].Split(new char[] { ',' })); + } + + chaosSettings = new ChaosSettings(true, commonVars_.getListOfSettings(), commonVars_.getSimulationSettings()); + getState(0); // set initial state. + + valid = true; + } + catch (Exception) + { + pReset(); + } + + max = parsed.Count - 1; + } + + public void getState(int index) + { + pGetState(index); + } + + void pGetState(int index) + { + // Compare the hashes with the loaded project. + // In case the user changed a value and then changed it back, we allow the validity flag to be restored. + if (!hashCheck()) + { + ErrorReporter.showMessage_OK("CSV checksum does not match loaded project.", "Data mismatch"); + valid = false; + } + else + { + valid = true; + } + + if (index == 0) + { + index++; // due to header. Callsites don't need to think about the header, we map around it. + } + if (!valid || (index >= parsed.Count)) + { + return; + } + + string searchString = ""; + int colIndex = 0; + // Find out which layers we have active. + bool[] activeLayers = new bool[CentralProperties.maxLayersForMC]; + Parallel.For(0, CentralProperties.maxLayersForMC, (i) => + // for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + activeLayers[i] = (commonVars_.getLayerSettings(i).getInt(EntropyLayerSettings.properties_i.enabled) == 1); + }); + + for (int i = 0; i < CentralProperties.maxLayersForMC; i++) + { + if (!activeLayers[i]) + { + continue; + } + + for (int j = 0; j < CommonVars.csvHeader.Length; j++) + { + searchString = CommonVars.csvHeader[j] + (i).ToString(); + colIndex = Array.IndexOf(parsed[0], searchString); + switch (CommonVars.csvHeader[j]) + { + case "CDUSVar": + chaosSettings.setValue(ChaosSettings.properties.CDUSVar, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "CDUTVar": + chaosSettings.setValue(ChaosSettings.properties.CDUTVar, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "LWRVar": + chaosSettings.setValue(ChaosSettings.properties.LWRVar, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "LWRSeed": + chaosSettings.setInt(ChaosSettings.ints.lwrSeed, i, Convert.ToInt32(parsed[index][colIndex])); + break; + case "LWR2Var": + chaosSettings.setValue(ChaosSettings.properties.LWR2Var, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "LWR2Seed": + chaosSettings.setInt(ChaosSettings.ints.lwr2Seed, i, Convert.ToInt32(parsed[index][colIndex])); + break; + case "horTipBiasVar": + chaosSettings.setValue(ChaosSettings.properties.hTipBiasVar, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "verTipBiasVar": + chaosSettings.setValue(ChaosSettings.properties.vTipBiasVar, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "iCVar": + chaosSettings.setValue(ChaosSettings.properties.icVar, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "oCVar": + chaosSettings.setValue(ChaosSettings.properties.ocVar, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "overlayX": + chaosSettings.setValue(ChaosSettings.properties.overlayX, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "overlayY": + chaosSettings.setValue(ChaosSettings.properties.overlayY, i, Convert.ToDouble(parsed[index][colIndex])); + break; + case "wobbleVar": + chaosSettings.setValue(ChaosSettings.properties.wobbleVar, i, Convert.ToDouble(parsed[index][colIndex])); + break; + } + } + } + + // Result parsing. + switch (commonVars_.getSimulationSettings().getValue(EntropySettings.properties_i.oType)) + { + case (int)CommonVars.calcModes.area: + if (commonVars_.getSimulationSettings().getValue(EntropySettings.properties_i.subMode) == (int)CommonVars.areaCalcModes.all) + { + searchString = "Total Area"; + } + else + { + searchString = "Minimum Area"; + } + + colIndex = Array.IndexOf(parsed[0], searchString); + result = parsed[index][colIndex]; + try + { + result = Convert.ToDouble(result).ToString("0.##"); + } + catch (Exception) + { + // possibly no numeric data, so exception could be expected. + } + break; + + case (int)CommonVars.calcModes.enclosure_spacing_overlap: + switch (commonVars_.getSimulationSettings().getValue(EntropySettings.properties_i.subMode)) + { + case (int)CommonVars.spacingCalcModes.spacing: + case (int)CommonVars.spacingCalcModes.spacingOld: + searchString = "Spacing"; + break; + case (int)CommonVars.spacingCalcModes.enclosure: + case (int)CommonVars.spacingCalcModes.enclosureOld: + searchString = "Enclosure"; + break; + } + + colIndex = Array.IndexOf(parsed[0], searchString); + result = parsed[index][colIndex]; + try + { + result = Convert.ToDouble(result).ToString("0.##"); + } + catch (Exception) + { + // possibly no numeric data, so exception could be expected. + } + break; + + case (int)CommonVars.calcModes.chord: // chord output + string[] searchStrings = new string[] { "AMinTopChord", "AMinBottomChord", "BMinLeftChord", "BMinRightChord" }; + string[] resultValues = new string[searchStrings.Length]; + for (int i = 0; i < searchStrings.Length; i++) + { + colIndex = Array.IndexOf(parsed[0], searchStrings[i]); + result = parsed[index][colIndex]; + try + { + result = Convert.ToDouble(result).ToString("0.##"); + } + catch (Exception) + { + // possibly no numeric data, so exception could be expected. + } + resultValues[i] = result; + } + result = resultValues[0]; + for (int i = 1; i < resultValues.Length; i++) + { + result += "," + resultValues[i]; + } + break; + + case (int)CommonVars.calcModes.angle: // angle output + searchString = "MinIntersectionAngle"; + colIndex = Array.IndexOf(parsed[0], searchString); + result = parsed[index][colIndex]; + break; + } + } + + public void reset() + { + pReset(); + } + + void pReset() + { + valid = false; + chaosSettings = null; + col = -1; + row = -1; + parsed.Clear(); + max = 0; + } + + bool hashCheck() + { + // Avoid changing the 'project differs from disk file' side of things. + string[] oldHashes = commonVars_.getHashes(); + bool wasChanged = commonVars_.isChanged(); + + // Ensure our hash is current. + commonVars_.setHashes(); + string losh = Utils.GetMD5Hash(commonVars_.getListOfSettings()); + string ssth = Utils.GetMD5Hash(commonVars_.getSimulationSettings()); + string geoch = Utils.GetMD5Hash(commonVars_.getGeoCoreHandlers()); + + // restore the values to avoid trouble. + commonVars_.setHashes(oldHashes); + commonVars_.setChanged(wasChanged); + + bool returnVal = (listOfSettingsHash == losh) && (entropyGeoHash == ssth); + + // Reloaded projects with baked geoCore data don't have the full set of input data so the hash will fail. Skip it. + bool checkGeoCore = true; + for (int layer = 0; layer < commonVars_.getListOfSettings().Count; layer++) + { + if ((commonVars_.getLayerSettings(layer).isReloaded()) && (commonVars_.getLayerSettings(layer).getInt(EntropyLayerSettings.properties_i.refLayout) == 0)) + { + checkGeoCore = false; + } + } + + if (checkGeoCore) + { + returnVal = returnVal && (geoCoreHash == geoch); + } + + return returnVal; + } + } +} \ No newline at end of file diff --git a/Common/Variance/support/shapeLibrary.cs b/Common/Variance/support/shapeLibrary.cs new file mode 100644 index 0000000..551018a --- /dev/null +++ b/Common/Variance/support/shapeLibrary.cs @@ -0,0 +1,1725 @@ +using geoLib; +using geoWrangler; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Variance +{ + public class ShapeLibrary + { + Int32 shapeIndex; + public Boolean shapeValid { get; set; } + public Boolean geoCoreShapeOrthogonal { get; set; } + public MyVertex[] Vertex { get; set; } + public MyRound[] round1 { get; set; } + public Boolean[] tips { get; set; } + EntropyLayerSettings layerSettings; + + public ShapeLibrary(EntropyLayerSettings mcLayerSettings) + { + pShapeLibrary(mcLayerSettings); + } + + void pShapeLibrary(EntropyLayerSettings mcLayerSettings) + { + shapeValid = false; + layerSettings = mcLayerSettings; + } + + public ShapeLibrary(Int32 shapeIndex, EntropyLayerSettings mcLayerSettings) + { + pShapeLibrary(shapeIndex, mcLayerSettings); + } + + void pShapeLibrary(Int32 shapeIndex, EntropyLayerSettings mcLayerSettings) + { + this.shapeIndex = shapeIndex; + shapeValid = false; + layerSettings = mcLayerSettings; + pSetShape(shapeIndex); + } + + public void setShape(Int32 shapeIndex, GeoLibPointF[] sourcePoly = null) + { + pSetShape(shapeIndex, sourcePoly); + } + + void pSetShape(Int32 shapeIndex, GeoLibPointF[] sourcePoly = null) + { + try + { + this.shapeIndex = shapeIndex; + switch (shapeIndex) + { + case (Int32)CommonVars.shapeNames.rect: + rectangle(); + break; + case (Int32)CommonVars.shapeNames.Lshape: + Lshape(); + break; + case (Int32)CommonVars.shapeNames.Tshape: + Tshape(); + break; + case (Int32)CommonVars.shapeNames.Xshape: + crossShape(); + break; + case (Int32)CommonVars.shapeNames.Ushape: + Ushape(); + break; + case (Int32)CommonVars.shapeNames.Sshape: + Sshape(); + break; + case (Int32)CommonVars.shapeNames.GEOCORE: + if (layerSettings.getInt(EntropyLayerSettings.properties_i.gCSEngine) == 1) + { + customShape(sourcePoly); + } + break; + default: + break; + } + } + catch (Exception) + { + + } + } + + void configureArrays() + { + double vertexCount = 0; + switch (shapeIndex) + { + case (Int32)CommonVars.shapeNames.rect: // rectangle + vertexCount = 9; + break; + case (Int32)CommonVars.shapeNames.Lshape: // L + vertexCount = 13; + break; + case (Int32)CommonVars.shapeNames.Tshape: // T + vertexCount = 17; + break; + case (Int32)CommonVars.shapeNames.Xshape: // Cross + vertexCount = 25; + break; + case (Int32)CommonVars.shapeNames.Ushape: // U + vertexCount = 17; + break; + case (Int32)CommonVars.shapeNames.Sshape: // S + vertexCount = 25; + break; + default: + break; + } + int arrayLength = (Int32)vertexCount; + Vertex = new MyVertex[arrayLength]; + tips = new Boolean[arrayLength]; + Parallel.For(0, arrayLength, (i) => + // for (Int32 i = 0; i < arrayLength; i++) + { + tips[i] = false; + }); + + arrayLength = (Int32)Math.Floor(vertexCount / 2) + 1; + round1 = new MyRound[arrayLength]; + Parallel.For(0, arrayLength, (i) => + // for (Int32 i = 0; i < arrayLength; i++) + { + round1[i] = new MyRound(); + }); + } + + void rectangle() + { + configureArrays(); + + // Sort out the tips by setting 'true' to center vertex that defines tip in each case. + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip)) + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + tips[1] = true; + tips[8] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[1] = true; + tips[8] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[3] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[3] = true; + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[1] = true; + tips[3] = true; + tips[8] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[3] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[1] = true; + tips[3] = true; + tips[5] = true; + tips[8] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[1] = true; + tips[7] = true; + tips[8] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[5] = true; + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[1] = true; + tips[5] = true; + tips[7] = true; + tips[8] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[3] = true; + tips[7] = true; + tips[1] = true; + tips[8] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[3] = true; + tips[7] = true; + tips[5] = true; + break; + default: // All + tips[3] = true; + tips[7] = true; + tips[1] = true; + tips[8] = true; + tips[5] = true; + break; + } + + // NOTE: + // Subshape offsets are applied later to simplify ellipse generation + // Horizontal and vertical global offsets are applied in callsite. + // Repositioning with respect to subshape reference is also applied in callsite. + + double tmpX = 0.0; + double tmpY = 0.0; + Vertex[0] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) / 2); + Vertex[1] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + Vertex[2] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2; + Vertex[3] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + Vertex[4] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY -= (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) / 2); + Vertex[5] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY = 0.0; + Vertex[6] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2); + tmpY = 0.0; + Vertex[7] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + processEdgesForRounding(); + + shapeValid = true; + } + + void Tshape() + { + configureArrays(); + // Sort out the tips by setting 'true' to center vertex that defines tip in each case. + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip)) + { + case (int)CommonVars.tipLocations.none: // None + break; + case (int)CommonVars.tipLocations.L: // Left + tips[1] = true; + break; + case (int)CommonVars.tipLocations.R: // Right + tips[5] = true; + tips[13] = true; + break; + case (int)CommonVars.tipLocations.LR: // Left and right + tips[1] = true; + tips[5] = true; + tips[13] = true; + break; + case (int)CommonVars.tipLocations.T: // Top + tips[3] = true; + break; + case (int)CommonVars.tipLocations.B: // Bottom + tips[15] = true; + break; + case (int)CommonVars.tipLocations.TB: // Top and Bottom + tips[3] = true; + tips[15] = true; + break; + case (int)CommonVars.tipLocations.TL: // Top and Left + tips[3] = true; + tips[1] = true; + break; + case (int)CommonVars.tipLocations.TR: // Top and Right + tips[3] = true; + tips[5] = true; + tips[13] = true; + break; + case (int)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[1] = true; + tips[3] = true; + tips[5] = true; + tips[13] = true; + break; + case (int)CommonVars.tipLocations.BL: // Bottom and Left + tips[15] = true; + tips[1] = true; + break; + case (int)CommonVars.tipLocations.BR: // Bottom and Right + tips[15] = true; + tips[5] = true; + tips[13] = true; + break; + case (int)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[1] = true; + tips[15] = true; + tips[5] = true; + tips[13] = true; + break; + case (int)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[1] = true; + tips[3] = true; + tips[15] = true; + break; + case (int)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[3] = true; + tips[5] = true; + tips[13] = true; + tips[15] = true; + break; + default: // All + tips[1] = true; + tips[3] = true; + tips[5] = true; + tips[13] = true; + tips[15] = true; + break; + } + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape1Tip)) + { + case (int)CommonVars.tipLocations.none: // None + break; + case (int)CommonVars.tipLocations.L: // Left + break; + case (int)CommonVars.tipLocations.R: // Right + tips[9] = true; + break; + case (int)CommonVars.tipLocations.LR: // Left and right + tips[9] = true; + break; + case (int)CommonVars.tipLocations.T: // Top + tips[7] = true; + break; + case (int)CommonVars.tipLocations.B: // Bottom + tips[11] = true; + break; + case (int)CommonVars.tipLocations.TB: // Top and Bottom + tips[7] = true; + tips[11] = true; + break; + case (int)CommonVars.tipLocations.TL: // Top and Left + tips[7] = true; + break; + case (int)CommonVars.tipLocations.TR: // Top and Right + tips[7] = true; + tips[9] = true; + break; + case (int)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[7] = true; + tips[9] = true; + break; + case (int)CommonVars.tipLocations.BL: // Bottom and Left + tips[11] = true; + break; + case (int)CommonVars.tipLocations.BR: // Bottom and Right + tips[11] = true; + tips[9] = true; + break; + case (int)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[11] = true; + tips[9] = true; + break; + case (int)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[7] = true; + tips[11] = true; + break; + case (int)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[7] = true; + tips[9] = true; + tips[11] = true; + break; + default: // All + tips[7] = true; + tips[9] = true; + tips[11] = true; + break; + } + + // NOTE: + // Subshape offsets are applied later to simplify ellipse generation + // Horizontal and vertical global offsets are applied in callsite. + + double tmpX = 0.0; + double tmpY = 0.0; + Vertex[0] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) / 2); + Vertex[1] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + Vertex[2] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2); + Vertex[3] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2); + Vertex[4] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY = (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) - (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) + + (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)) - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerOffset))))) / 2; + Vertex[5] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) + Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + Vertex[6] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + Vertex[7] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + Vertex[8] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength) / 2); + Vertex[9] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength) / 2); + Vertex[10] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + Vertex[11] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + tmpX -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength) / 2); + Vertex[12] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)) / 2; + Vertex[13] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY = 0; + Vertex[14] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength) / 2); + Vertex[15] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + processEdgesForRounding(); + + shapeValid = true; + } + + void Lshape() + { + configureArrays(); + // Sort out the tips by setting 'true' to center vertex that defines tip in each case. + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip)) + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + tips[1] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[1] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[3] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[11] = true; + tips[3] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[1] = true; + tips[3] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[3] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[1] = true; + tips[3] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[11] = true; + tips[1] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[11] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[1] = true; + tips[5] = true; + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[1] = true; + tips[11] = true; + tips[3] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[11] = true; + tips[3] = true; + tips[5] = true; + break; + default: // All + tips[1] = true; + tips[5] = true; + tips[11] = true; + tips[3] = true; + break; + } + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape1Tip)) + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + // this.tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + // this.tips[5] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[7] = true; + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[7] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[7] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[11] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[11] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[7] = true; + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[7] = true; + tips[11] = true; + tips[9] = true; + break; + default: // All + tips[9] = true; + tips[7] = true; + tips[11] = true; + break; + } + + // NOTE: + // Subshape offsets are applied later to simplify ellipse generation + // Horizontal and vertical global offsets are applied in callsite. + // Repositioning with respect to subshape reference is also applied in callsite. + double tmpX = 0.0; + double tmpY = 0.0; + Vertex[0] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) / 2); + Vertex[1] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) / 2); + Vertex[2] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2); + Vertex[3] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2); + Vertex[4] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY -= (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength))) / 2; + Vertex[5] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY -= (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength))) / 2; + Vertex[6] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) / 2; + Vertex[7] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) / 2; + Vertex[8] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2; + Vertex[9] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2; + Vertex[10] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX -= (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) + Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength))) / 2; + Vertex[11] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + processEdgesForRounding(); + + shapeValid = true; + } + + void Ushape() + { + configureArrays(); + // Sort out the tips by setting 'true' to center vertex that defines tip in each case. + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip)) + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + tips[1] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[13] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[1] = true; + tips[13] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[3] = true; + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[3] = true; + tips[11] = true; + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[1] = true; + tips[3] = true; + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[3] = true; + tips[11] = true; + tips[13] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[1] = true; + tips[3] = true; + tips[11] = true; + tips[13] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[1] = true; + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[13] = true; + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[1] = true; + tips[13] = true; + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[1] = true; + tips[3] = true; + tips[11] = true; + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[3] = true; + tips[11] = true; + tips[13] = true; + tips[15] = true; + break; + default: // All + tips[1] = true; + tips[3] = true; + tips[11] = true; + tips[13] = true; + tips[15] = true; + break; + } + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape1Tip)) + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[5] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + // this.tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[7] = true; + // this.tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[5] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[5] = true; + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[7] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[5] = true; + tips[7] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[7] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[7] = true; + tips[9] = true; + break; + default: // All + tips[5] = true; + tips[7] = true; + tips[9] = true; + break; + } + + // NOTE: + // Subshape offsets are applied later to simplify ellipse generation + // Horizontal and vertical global offsets are applied in callsite. + // Repositioning with respect to subshape reference is also applied in callsite. + double tmpX = 0.0; + double tmpY = 0.0; + Vertex[0] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) / 2); + Vertex[1] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + Vertex[2] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)) / 2); + Vertex[3] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)) / 2); + Vertex[4] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2; + Vertex[5] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2; + Vertex[6] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) / 2; + Vertex[7] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) / 2; + Vertex[8] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2; + Vertex[9] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + Vertex[10] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) - (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)) + Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)))) / 2; + Vertex[11] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + Vertex[12] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY = tmpY / 2; + Vertex[13] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY = 0; + Vertex[14] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = tmpX / 2; + Vertex[15] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + processEdgesForRounding(); + + shapeValid = true; + } + + void crossShape() + { + configureArrays(); + // Sort out the tips. + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip)) + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + tips[1] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[13] = true; + tips[21] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[1] = true; + tips[9] = true; + tips[13] = true; + tips[21] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[11] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[1] = true; + tips[9] = true; + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[11] = true; + tips[13] = true; + tips[21] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[1] = true; + tips[9] = true; + tips[11] = true; + tips[13] = true; + tips[21] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[1] = true; + tips[9] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[13] = true; + tips[21] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[1] = true; + tips[9] = true; + tips[13] = true; + tips[21] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[11] = true; + tips[1] = true; + tips[9] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[13] = true; + tips[11] = true; + tips[23] = true; + tips[21] = true; + break; + default: // All + tips[1] = true; + tips[9] = true; + tips[13] = true; + tips[21] = true; + tips[11] = true; + tips[23] = true; + break; + } + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape1Tip)) + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[17] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[5] = true; + tips[17] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[7] = true; + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[3] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[3] = true; + tips[7] = true; + tips[15] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[5] = true; + tips[7] = true; + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[7] = true; + tips[15] = true; + tips[17] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[5] = true; + tips[7] = true; + tips[15] = true; + tips[17] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[3] = true; + tips[5] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[3] = true; + tips[17] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[3] = true; + tips[5] = true; + tips[17] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[5] = true; + tips[3] = true; + tips[7] = true; + tips[15] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[3] = true; + tips[7] = true; + tips[15] = true; + tips[17] = true; + tips[19] = true; + break; + default: // All + tips[5] = true; + tips[17] = true; + tips[3] = true; + tips[7] = true; + tips[15] = true; + tips[19] = true; + break; + } + + // NOTE: + // Subshape offsets are applied later to simplify ellipse generation + // Horizontal and vertical global offsets are applied in callsite. + + double tmpX = 0.0; + double tmpY = 0.0; + Vertex[0] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)) / 2); + Vertex[1] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + Vertex[2] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)); + tmpX = tmpX / 2; + Vertex[3] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + tmpX = tmpX * 2; + Vertex[4] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2); + Vertex[5] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2); + Vertex[6] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = tmpX / 2; + Vertex[7] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX = 0.0; + Vertex[8] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY = (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) - (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) + Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset))) / 2); + Vertex[9] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + Vertex[10] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2; + Vertex[11] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + Vertex[12] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY = (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) - (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) + Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset))) / 2); + Vertex[13] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)) + Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + Vertex[14] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + // Need midpoint of edge + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + tmpX += ((Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength))) / 2) / 2; // midpoint + tmpX -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)); + Vertex[15] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)); + // tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); // full distance + tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)); + Vertex[16] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2; + Vertex[17] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2; + Vertex[18] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + // Need midpoint of edge + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + tmpX += ((Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength))) / 2) / 2; // midpoint + tmpX -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorOffset)); + Vertex[19] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + Vertex[20] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY -= (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)) / 2); + Vertex[21] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + + tmpY = 0.0; + Vertex[22] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2); + Vertex[23] = new MyVertex(tmpX, tmpY, typeDirection.down1, true, false, typeVertex.center); + + processEdgesForRounding(); + + shapeValid = true; + } + + void Sshape() + { + configureArrays(); + // Sort out the tips by setting 'true' to center vertex that defines tip in each case. + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip)) + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + tips[1] = true; + tips[9] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[13] = true; + tips[21] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[1] = true; + tips[9] = true; + tips[13] = true; + tips[21] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[11] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[1] = true; + tips[9] = true; + tips[11] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[11] = true; + tips[13] = true; + tips[21] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[1] = true; + tips[9] = true; + tips[11] = true; + tips[13] = true; + tips[21] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[1] = true; + tips[9] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[13] = true; + tips[21] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[1] = true; + tips[9] = true; + tips[13] = true; + tips[21] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[1] = true; + tips[9] = true; + tips[11] = true; + tips[23] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[11] = true; + tips[13] = true; + tips[21] = true; + tips[23] = true; + break; + default: // All + tips[1] = true; + tips[9] = true; + tips[11] = true; + tips[13] = true; + tips[21] = true; + tips[23] = true; + break; + } + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape1Tip)) // Bottom notch + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.R: // Right + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[3] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[3] = true; + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[3] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[3] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[3] = true; + tips[5] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[5] = true; + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[5] = true; + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[3] = true; + tips[7] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[3] = true; + tips[5] = true; + tips[7] = true; + break; + default: // All + tips[3] = true; + tips[5] = true; + tips[7] = true; + break; + } + switch (layerSettings.getInt(EntropyLayerSettings.properties_i.shape2Tip)) // Top notch + { + case (Int32)CommonVars.tipLocations.none: // None + break; + case (Int32)CommonVars.tipLocations.L: // Left + break; + case (Int32)CommonVars.tipLocations.R: // Right + tips[17] = true; + break; + case (Int32)CommonVars.tipLocations.LR: // Left and right + tips[17] = true; + break; + case (Int32)CommonVars.tipLocations.T: // Top + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.B: // Bottom + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.TB: // Top and Bottom + tips[15] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.TL: // Top and Left + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.TR: // Top and Right + tips[17] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.TLR: // Top and Left and Right + tips[17] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.BL: // Bottom and Left + tips[15] = true; + break; + case (Int32)CommonVars.tipLocations.BR: // Bottom and Right + tips[15] = true; + tips[17] = true; + break; + case (Int32)CommonVars.tipLocations.BLR: // Bottom and Left and Right + tips[15] = true; + tips[17] = true; + break; + case (Int32)CommonVars.tipLocations.TBL: // Top and Bottom and Left + tips[17] = true; + tips[19] = true; + break; + case (Int32)CommonVars.tipLocations.TBR: // Top and Bottom and Right + tips[15] = true; + tips[17] = true; + tips[19] = true; + break; + default: // All + tips[15] = true; + tips[17] = true; + tips[19] = true; + break; + } + + // NOTE: + // Subshape offsets are applied later to simplify ellipse generation + // Horizontal and vertical global offsets are applied in callsite. + // Repositioning with respect to subshape reference is also applied in callsite. + double tmpX = 0.0; + double tmpY = 0.0; + Vertex[0] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY = (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)) / 2); + Vertex[1] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)); + Vertex[2] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) / 2); + Vertex[3] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)); + Vertex[4] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)) / 2; + Vertex[5] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerOffset)) + Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + Vertex[6] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)) / 2; + Vertex[7] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + tmpX = 0; + Vertex[8] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY = (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) - tmpY) / 2; + Vertex[9] = new MyVertex(tmpX, tmpY, typeDirection.left1, true, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + Vertex[10] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2; + Vertex[11] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + // Center so no rounding definition + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + Vertex[12] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY = tmpY - (Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset)) / 2); + Vertex[13] = new MyVertex(tmpX, tmpY, typeDirection.right1, true, false, typeVertex.center); + // Center so no rounding definition + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset)); + Vertex[14] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = tmpX - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength) / 2); + Vertex[15] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2HorOffset)); + Vertex[16] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY -= Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength) / 2); + Vertex[17] = new MyVertex(tmpX, tmpY, typeDirection.right1, false, false, typeVertex.center); + + tmpY = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)) - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerLength)) - Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2VerOffset)); + Vertex[18] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX += Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s2HorLength) / 2); + Vertex[19] = new MyVertex(tmpX, tmpY, typeDirection.up1, false, false, typeVertex.center); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + Vertex[20] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpY /= 2; + Vertex[21] = new MyVertex(tmpX, tmpY, typeDirection.right1, false, false, typeVertex.center); + + tmpY = 0; + Vertex[22] = new MyVertex(tmpX, tmpY, typeDirection.tilt1, true, false, typeVertex.corner); + + tmpX = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)) / 2; + Vertex[23] = new MyVertex(tmpX, tmpY, typeDirection.down1, false, false, typeVertex.center); + + processEdgesForRounding(); + + shapeValid = true; + } + + void processEdgesForRounding() + { + int horEdge = Vertex.Length - 2; // deal with padding. + int verEdge = 1; + for (int r = 0; r < round1.Length - 1; r++) + { + try + { + round1[r].index = r * 2; + round1[r].horFace = horEdge; + round1[r].verFace = verEdge; + + // Figure out our corner type. First is a special case. + if (r == 0) + { + round1[r].direction = typeRound.exter; + round1[r].MaxRadius = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.oCR)); + } + else + { + if ( + (Vertex[round1[r].verFace].direction == typeDirection.right1) && (Vertex[round1[r].horFace].direction == typeDirection.up1) && (horEdge < verEdge) || + (Vertex[round1[r].verFace].direction == typeDirection.left1) && (Vertex[round1[r].horFace].direction == typeDirection.up1) && (horEdge > verEdge) || + (Vertex[round1[r].verFace].direction == typeDirection.right1) && (Vertex[round1[r].horFace].direction == typeDirection.down1) && (horEdge > verEdge) || + (Vertex[round1[r].verFace].direction == typeDirection.left1) && (Vertex[round1[r].horFace].direction == typeDirection.down1) && (horEdge < verEdge) + ) + { + round1[r].direction = typeRound.exter; + round1[r].MaxRadius = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.oCR)); + } + else + { + round1[r].direction = typeRound.inner; + round1[r].MaxRadius = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.iCR)); + } + } + + // Small fudge for the 0 case + if (r == 0) + { + horEdge = -1; + } + + // Change our edge configuration for the next loop. We need to handle overflow references as well + if (r % 2 == 0) + { + horEdge += 4; + horEdge = horEdge % Vertex.Length; + } + else + { + verEdge += 4; + verEdge = verEdge % Vertex.Length; + } + } + catch (Exception e) + { + string t = e.ToString(); + } + }; + + // First and last are the same. + round1[round1.Length - 1] = round1[0]; + } + + // Intended to take geometry from an external source and map it into our shape engine. + void customShape(GeoLibPointF[] sourcePoly) + { + if (sourcePoly == null) + { + shapeValid = false; + return; + } + + // Note that we assume the point order matches our general primitives; might need upstream review to ensure this is being + // fed correctly. + // Upstream should trim array to ensure end point is different from start point, but we'll force the issue here for robustness. + sourcePoly = GeoWrangler.stripTerminators(sourcePoly, true); + sourcePoly = GeoWrangler.stripColinear(sourcePoly); + // Strip the terminator again to meet the requirements below. + sourcePoly = GeoWrangler.stripTerminators(sourcePoly, false); + sourcePoly = GeoWrangler.clockwise(sourcePoly); + + // We need to look at our incoming shape to see whether it's orthogonal and suitable for contouring. + geoCoreShapeOrthogonal = GeoWrangler.orthogonal(sourcePoly); + + if (!geoCoreShapeOrthogonal) + { + customShape_nonOrthogonal(sourcePoly); + } + else + { + customShape_orthogonal(sourcePoly); + } + + shapeValid = true; + } + + void customShape_nonOrthogonal(GeoLibPointF[] sourcePoly) + { + int sCount = sourcePoly.Length; + Vertex = new MyVertex[sCount + 1]; // add one to close. + // Assign shape vertices to Vertex and move on. EntropyShape will know what to do. + Parallel.For(0, sCount, (pt) => + // for (int pt = 0; pt < sCount; pt++) + { + Vertex[pt] = new MyVertex(sourcePoly[pt].X, sourcePoly[pt].Y, typeDirection.tilt1, false, false, typeVertex.corner); + }); + // Close the shape. + Vertex[Vertex.Length - 1] = new MyVertex(Vertex[0]); + } + + void customShape_orthogonal(GeoLibPointF[] sourcePoly) + { + int sCount = sourcePoly.Length; + Int32 vertexCount = (sCount * 2) + 1; // assumes no point in midpoint of edges, and 1 to close. + Vertex = new MyVertex[vertexCount]; + tips = new Boolean[vertexCount]; + Int32 vertexCounter = 0; // set up our vertex counter. + + Parallel.For(0, vertexCount, (i) => + // for (Int32 i = 0; i < vertexCount; i++) + { + tips[i] = false; + }); + + Int32 roundCount = sourcePoly.Length + 1; + round1 = new MyRound[roundCount]; + Parallel.For(0, roundCount, (i) => + // for (Int32 i = 0; i < roundCount; i++) + { + round1[i] = new MyRound(); + }); + + // Set up first rounding entry + round1[0].direction = typeRound.exter; + round1[0].MaxRadius = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.oCR)); + round1[0].verFace = 1; + round1[0].horFace = vertexCount - 2; + round1[round1.Length - 1] = round1[0]; // close the loop + + // Set up first vertex. + Vertex[0] = new MyVertex(sourcePoly[0].X, sourcePoly[0].Y, typeDirection.tilt1, false, false, typeVertex.corner); + vertexCounter++; + // Set up first midpoint. + Vertex[1] = new MyVertex((sourcePoly[0].X + sourcePoly[1].X) / 2.0f, (sourcePoly[0].Y + sourcePoly[1].Y) / 2.0f, typeDirection.left1, true, false, typeVertex.center); + if ((layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.L) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.LR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TBL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BLR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TLR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.all)) + { + tips[vertexCounter] = true; + } + vertexCounter++; + + // Also set our end points + Vertex[vertexCount - 2] = new MyVertex((sourcePoly[0].X + sourcePoly[sourcePoly.Length - 1].X) / 2.0f, + (sourcePoly[0].Y + sourcePoly[sourcePoly.Length - 1].Y) / 2.0f, typeDirection.down1, false, false, typeVertex.center); + + // Figure out our rounding characteristics. + + // First edge is always vertical, left facing. + bool vertical = true; + bool left = true; + bool up = false; + + for (int pt = 1; pt < roundCount - 1; pt++) + { + // Link to our vertical/horizontal edges + round1[pt].index = vertexCounter; + if (pt % 2 == 1) + { + round1[pt].verFace = vertexCounter - 1; + round1[pt].horFace = vertexCounter + 1; + } + else + { + round1[pt].verFace = vertexCounter + 1; + round1[pt].horFace = vertexCounter - 1; + } + + // Register our corner point into the vertex array. + Vertex[vertexCounter] = new MyVertex(sourcePoly[pt].X, sourcePoly[pt].Y, typeDirection.tilt1, false, false, typeVertex.corner); + vertexCounter++; + + // Now we have to wrangle the midpoint. + + Int32 next = (pt + 1) % sourcePoly.Length; // wrap to polygon length + + // Find the normal for the edge to the next point. + + double dx = sourcePoly[next].X - sourcePoly[pt].X; + double dy = sourcePoly[next].Y - sourcePoly[pt].Y; + + // Set up our midpoint for convenience. + GeoLibPointF midPt = new GeoLibPointF(sourcePoly[pt].X + dx / 2.0f, sourcePoly[pt].Y + dy / 2.0f); + + // The normal, to match convention in the distance calculation is assessed from this point to the next point. + + // Get average angle for this vertex based on angles from line segments. + // http://stackoverflow.com/questions/1243614/how-do-i-calculate-the-normal-vector-of-a-line-segmen + GeoLibPointF normalPt = new GeoLibPointF(-dy, dx); + + // Vertical edge has a normal with an X value non-zero and Y value ~0. + if (Math.Abs(normalPt.X) > 0.01) // treating a 0.01 difference as being ~0 + { + vertical = true; + } + else + { + vertical = false; + } + + // Assess the normal to establish directionn + if (vertical) + { + if (normalPt.X < 0) // left facing vertical edge has normal with negative X value. + { + left = true; + } + else + { + left = false; + } + } + else + { + if (normalPt.Y < 0) // down facing horizontal edge has normal with negative Y value. + { + up = false; + } + else + { + up = true; + } + } + + if (!vertical) + { + if (up) + { + Vertex[vertexCounter] = new MyVertex(midPt.X, midPt.Y, typeDirection.up1, vertical, false, typeVertex.center); + if ((layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.T) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TB) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TBL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TBR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TLR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.all)) + { + tips[vertexCounter] = true; + } + } + else + { + Vertex[vertexCounter] = new MyVertex(midPt.X, midPt.Y, typeDirection.down1, vertical, false, typeVertex.center); + if ((layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.B) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TB) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TBL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TBR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BLR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.all)) + { + tips[vertexCounter] = true; + } + } + } + else + { + if (left) + { + Vertex[vertexCounter] = new MyVertex(midPt.X, midPt.Y, typeDirection.left1, vertical, false, typeVertex.center); + if ((layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.L) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.LR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TBL) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BLR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TLR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.all)) + { + tips[vertexCounter] = true; + } + } + else + { + Vertex[vertexCounter] = new MyVertex(midPt.X, midPt.Y, typeDirection.right1, vertical, false, typeVertex.center); + if ((layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.R) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.LR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TBR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.BLR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.TLR) || + (layerSettings.getInt(EntropyLayerSettings.properties_i.shape0Tip) == (Int32)CommonVars.tipLocations.all)) + { + tips[vertexCounter] = true; + } + } + } + vertexCounter++; + } + + // Reprocess our corners for inner/outer rounding based on horFace/verFace directions + Parallel.For(0, roundCount, (pt) => + // for (int pt = 0; pt < roundCount; pt++) + { + bool outerVertex = false; + + // Only certain changes in direction correspond to an outer vertex, for a clockwise ordered series of points. + if ( + (pt == 0) || (pt == round1.Length - 1) || + ((round1[pt].verFace < round1[pt].horFace) && + ((Vertex[round1[pt].verFace].direction == typeDirection.left1) && (Vertex[round1[pt].horFace].direction == typeDirection.up1))) || + ((round1[pt].verFace > round1[pt].horFace) && + ((Vertex[round1[pt].horFace].direction == typeDirection.up1) && (Vertex[round1[pt].verFace].direction == typeDirection.right1))) || + ((round1[pt].verFace < round1[pt].horFace) && + ((Vertex[round1[pt].verFace].direction == typeDirection.right1) && (Vertex[round1[pt].horFace].direction == typeDirection.down1))) || + ((round1[pt].verFace > round1[pt].horFace) && + ((Vertex[round1[pt].horFace].direction == typeDirection.down1) && (Vertex[round1[pt].verFace].direction == typeDirection.left1))) + ) + { + outerVertex = true; + } + + if (outerVertex) + { + round1[pt].direction = typeRound.exter; + round1[pt].MaxRadius = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.oCR)); + } + else + { + round1[pt].direction = typeRound.inner; + round1[pt].MaxRadius = Convert.ToDouble(layerSettings.getDecimal(EntropyLayerSettings.properties_decimal.iCR)); + } + + Vertex[round1[pt].index].inner = !outerVertex; + }); + } + } +} diff --git a/Common/Variance/support/simpleAES.cs b/Common/Variance/support/simpleAES.cs new file mode 100644 index 0000000..c2032aa --- /dev/null +++ b/Common/Variance/support/simpleAES.cs @@ -0,0 +1,175 @@ +using System; +using System.IO; +using System.Security.Cryptography; + +namespace Variance +{ + public class SimpleAES + { + // Change these keys + private byte[] Key;// = { 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 }; + private byte[] Vector;// = { 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 252, 112, 79, 32, 114, 156 }; + + private ICryptoTransform EncryptorTransform, DecryptorTransform; + private System.Text.UTF8Encoding UTFEncoder; + + public SimpleAES() + { + Key = new byte[] { + 32, 161, 218, 27, 238, 106, 241, 131, 89, 76, 230, 247, 200, 133, 154, 136, + 189, 69, 240, 250, 171, 103, 69, 190, 141, 44, 11, 90, 118, 170, 210, 237 + }; // 32 + Vector = new byte[] { + 201, 149, 239, 100, 109, 190, 178, 165, 225, 145, 132, 65, 122, 128, 40, 254 + }; // 16 + init(); + } + + public SimpleAES(byte[] key, byte[] vector) + { + this.Key = key; + this.Vector = vector; + init(); + } + + private void init() + { + //This is our encryption method + RijndaelManaged rm = new RijndaelManaged(); + + //Create an encryptor and a decryptor using our encryption method, key, and vector. + EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector); + DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector); + + //Used to translate bytes to text and vice versa + UTFEncoder = new System.Text.UTF8Encoding(); + } + + /// -------------- Two Utility Methods (not used but may be useful) ----------- + /// Generates an encryption key. + static public byte[] GenerateEncryptionKey() + { + //Generate a Key. + RijndaelManaged rm = new RijndaelManaged(); + rm.GenerateKey(); + return rm.Key; + } + + /// Generates a unique encryption vector + static public byte[] GenerateEncryptionVector() + { + //Generate a Vector + RijndaelManaged rm = new RijndaelManaged(); + rm.GenerateIV(); + return rm.IV; + } + + /// ----------- The commonly used methods ------------------------------ + /// Encrypt some text and return a string suitable for passing in a URL. + public string EncryptToString(string TextValue) + { + return ByteArrToString(Encrypt(TextValue)); + } + + /// Encrypt some text and return an encrypted byte array. + public byte[] Encrypt(string TextValue) + { + //Translates our text value into a byte array. + Byte[] bytes = UTFEncoder.GetBytes(TextValue); + + //Used to stream the data in and out of the CryptoStream. + MemoryStream memoryStream = new MemoryStream(); + + /* + * We will have to write the unencrypted bytes to the stream, + * then read the encrypted result back from the stream. + */ + #region Write the decrypted value to the encryption stream + CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write); + cs.Write(bytes, 0, bytes.Length); + cs.FlushFinalBlock(); + #endregion + + #region Read encrypted value back out of the stream + memoryStream.Position = 0; + byte[] encrypted = new byte[memoryStream.Length]; + memoryStream.Read(encrypted, 0, encrypted.Length); + #endregion + + //Clean up. + cs.Close(); + memoryStream.Close(); + + return encrypted; + } + + /// The other side: Decryption methods + public string DecryptString(string EncryptedString) + { + return Decrypt(StrToByteArray(EncryptedString)); + } + + /// Decryption when working with byte arrays. + public string Decrypt(byte[] EncryptedValue) + { + #region Write the encrypted value to the decryption stream + MemoryStream encryptedStream = new MemoryStream(); + CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write); + decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length); + decryptStream.FlushFinalBlock(); + #endregion + + #region Read the decrypted value from the stream. + encryptedStream.Position = 0; + Byte[] decryptedBytes = new Byte[encryptedStream.Length]; + encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length); + encryptedStream.Close(); + #endregion + return UTFEncoder.GetString(decryptedBytes); + } + + /// Convert a string to a byte array. NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so). + // System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); + // return encoding.GetBytes(str); + // However, this results in character values that cannot be passed in a URL. So, instead, I just + // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100). + public byte[] StrToByteArray(string str) + { + if (str.Length == 0) + throw new Exception("Invalid string value in StrToByteArray"); + + byte val; + byte[] byteArr = new byte[str.Length / 3]; + int i = 0; + int j = 0; + do + { + val = byte.Parse(str.Substring(i, 3)); + byteArr[j++] = val; + i += 3; + } + while (i < str.Length); + return byteArr; + } + + // Same comment as above. Normally the conversion would use an ASCII encoding in the other direction: + // System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + // return enc.GetString(byteArr); + public string ByteArrToString(byte[] byteArr) + { + byte val; + string tempStr = ""; + for (int i = 0; i <= byteArr.GetUpperBound(0); i++) + { + val = byteArr[i]; + if (val < 10) + tempStr += "00" + val.ToString(); + else if (val < 100) + tempStr += "0" + val.ToString(); + else + tempStr += val.ToString(); + } + return tempStr; + } + } +} diff --git a/Common/Variance/support/simulationPreview.cs b/Common/Variance/support/simulationPreview.cs new file mode 100644 index 0000000..5175b52 --- /dev/null +++ b/Common/Variance/support/simulationPreview.cs @@ -0,0 +1,283 @@ +using geoLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +namespace Variance +{ + public class SimulationPreview + { + VarianceContext varianceContext; + + List simShapes; + public List getSimShapes() + { + return pGetSimShapes(); + } + + List pGetSimShapes() + { + return simShapes; + } + + List> previewShapes; + + public List> getPreviewShapes() + { + return pGetPreviewShapes(); + } + + List> pGetPreviewShapes() + { + return previewShapes; + } + + public List getLayerPreviewShapes(int layer) + { + return pGetLayerPreviewShapes(layer); + } + + List pGetLayerPreviewShapes(int layer) + { + return previewShapes[layer]; + } + + public GeoLibPointF[] getLayerPreviewShapePoly(int layer, int poly) + { + return pGetLayerPreviewShapePoly(layer, poly); + } + + GeoLibPointF[] pGetLayerPreviewShapePoly(int layer, int poly) + { + return previewShapes[layer][poly]; + } + + List points; + + public List getPoints() + { + return pGetPoints(); + } + + List pGetPoints() + { + return points; + } + + public GeoLibPointF[] getPoints(int index) + { + return pGetPoints(index); + } + + GeoLibPointF[] pGetPoints(int index) + { + return points[index]; + } + + string resultText; + + public string getResult() + { + return pGetResult(); + } + + string pGetResult() + { + return resultText; + } + + Int32 xOffset = 0; + Int32 yOffset = 0; + + void doOffsets(EntropyLayerSettings entropyLayerSettings) + { + // OK. Now we need to pay attention to the subshape reference settings. + /* + * 0: Top left + * 1: Top right + * 2: Bottom left + * 3: Bottom right + * 4: Top middle + * 5: Right middle + * 6: Bottom middle + * 7: Left middle + * 8: Center center + */ + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.TL) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.TR) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.TS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.RS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.LS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.C)) + { + // Vertical offset needed to put reference corner at world center + // Our coordinates have placed bottom left at 0,0 so negative offsets needed (note origin comment above) + // Find our subshape reference. + Int32 tmp_yOffset = 0; + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_yOffset = Convert.ToInt32(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0VerLength)); + } + else + { + tmp_yOffset = Convert.ToInt32(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1VerLength)); + } + + // Half the value for a vertical centering requirement + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.RS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.LS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.C)) + { + tmp_yOffset = Convert.ToInt32(tmp_yOffset / 2); + } + yOffset += tmp_yOffset; + } + + // Coordinates placed bottom left at 0,0. + Int32 tmp_xOffset = 0; + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 1) + { + tmp_xOffset = -1 * Convert.ToInt32(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + } + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.TR) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.BR) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.TS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.RS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.BS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.C)) + { + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.subShapeIndex) == 0) + { + tmp_xOffset -= Convert.ToInt32(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s0HorLength)); + } + else + { + tmp_xOffset -= Convert.ToInt32(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.s1HorLength)); + } + + // Half the value for horizontal centering conditions + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.TS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.BS) || + (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.posIndex) == (int)CommonVars.subShapeLocations.C)) + { + tmp_xOffset = Convert.ToInt32(tmp_xOffset / 2); + } + } + xOffset += tmp_xOffset; + + // Now for global offset. + xOffset += Convert.ToInt32(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.gHorOffset)); + yOffset -= Convert.ToInt32(entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.gVerOffset)); + } + + public SimulationPreview(ref VarianceContext varianceContext) + { + pSimulationPreview(ref varianceContext); + } + + void pSimulationPreview(ref VarianceContext _varianceContext) + { + varianceContext = _varianceContext; + simShapes = new List(); + previewShapes = new List>(); + points = new List(); + points.Add(new GeoLibPointF[1]); + } + + public SimulationPreview(ref VarianceContext _varianceContext, List simShapes, List> previewShapes, List points) + { + pSimulationPreview(ref _varianceContext, simShapes, previewShapes, points); + } + + void pSimulationPreview(ref VarianceContext _varianceContext, List simShapes, List> previewShapes, List points) + { + varianceContext = _varianceContext; + this.points = points.ToList(); + this.simShapes = simShapes.ToList(); + this.previewShapes = previewShapes.ToList(); + } + + void updatePreview(List simShapes) + { + try + { + this.simShapes = simShapes.ToList(); + } + catch (Exception) + { + // Doesn't matter. + } + } + + public void updatePreview(string resultText) + { + pUpdatePreview(resultText); + } + + void pUpdatePreview(string resultText) + { + this.resultText = resultText; + } + + public void updatePreview(SimResultPackage resultPackage) + { + pUpdatePreview(resultPackage); + } + + void pUpdatePreview(SimResultPackage resultPackage) + { + if (Monitor.IsEntered(varianceContext.previewLock)) + { + updatePreview(resultPackage.getPreviewResult().getSimShapes(), resultPackage.getPreviewResult().getPreviewShapes(), + resultPackage.getPreviewResult().getPoints(), resultPackage.getMeanAndStdDev()); + } + } + + public void updatePreview(List simShapes, List> previewShapes, List points, string resultText) + { + pUpdatePreview(simShapes, previewShapes, points, resultText); + } + + void pUpdatePreview(List simShapes, List> previewShapes, List points, string resultText) + { + try + { + updatePreview(simShapes, previewShapes, points); + } + catch (Exception) + { + // Doesn't matter. + } + try + { + updatePreview(resultText); + } + catch (Exception) + { + // Doesn't matter. + } + } + + void updatePreview(List simShapes, List> previewShapes, List points) + { + updatePreview(simShapes); + try + { + this.previewShapes = previewShapes.ToList(); + } + catch (Exception) + { + // Doesn't matter. + } + try + { + this.points = points.ToList(); + } + catch (Exception) + { + // Doesn't matter. + } + } + } +} diff --git a/Common/Variance/support/utilityFuncs.cs b/Common/Variance/support/utilityFuncs.cs new file mode 100644 index 0000000..6d3a45e --- /dev/null +++ b/Common/Variance/support/utilityFuncs.cs @@ -0,0 +1,607 @@ +using entropyRNG; +using Error; +using info.lundin.math; // string to equation mapping. +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using utility; + +namespace Variance +{ + public static class UtilityFuncs + { + public static double getCustomMappedRandomNumber(string equation, EntropySettings settings) + { + return pGetCustomMappedRandomNumber(equation, settings); + } + + static double pGetCustomMappedRandomNumber(string equation, EntropySettings settings) + { + double value = 1E-15; + + double xvalue = pGetRandomDouble(settings); + while (xvalue < value) + { + xvalue = pGetRandomDouble(settings); + } + + double yvalue = pGetRandomDouble(settings); + while (yvalue < value) + { + yvalue = pGetRandomDouble(settings); + } + + double zvalue = pGetRandomDouble(settings); + while (zvalue < value) + { + zvalue = pGetRandomDouble(settings); + } + + try + { + ExpressionParser parser = new ExpressionParser(); + parser.Values.Add("x", xvalue); + parser.Values.Add("y", yvalue); + parser.Values.Add("z", zvalue); + // Substitute any Box-Muller queries with the full form. + equation = equation.Replace("_gxy", "(sqrt(-2 * ln(y)) * cos(2 * PI * x))"); + equation = equation.Replace("_gyz", "(sqrt(-2 * ln(z)) * cos(2 * PI * y))"); + equation = equation.Replace("_gxz", "(sqrt(-2 * ln(z)) * cos(2 * PI * x))"); + value = parser.Parse(equation); + } + catch (Exception e) + { + ErrorReporter.showMessage_OK(e.ToString(), "RNG mapper error"); + } + + return value; + } + + public static double getGaussianRandomNumber3(EntropySettings settings) + { + return pGetGaussianRandomNumber3(settings); + } + + static double pGetGaussianRandomNumber3(EntropySettings settings) + { + double value = 1.0f; + switch (settings.getValue(EntropySettings.properties_i.rngType)) + { + case (Int32)commonRNG.rngIndex.crypto: + value = Crypto_RNG.random_gauss3()[0]; + break; + case (Int32)commonRNG.rngIndex.mtwister: + value = MersenneTwister_RNG.random_gauss3()[0]; + break; + default: + value = RNG.random_gauss3()[0]; + break; + } + return value; + } + + public static double getGaussianRandomNumber(EntropySettings settings) + { + return pGetGaussianRandomNumber(settings); + } + + static double pGetGaussianRandomNumber(EntropySettings settings) + { + double value = 1.0f; + switch (settings.getValue(EntropySettings.properties_i.rngType)) + { + case (Int32)commonRNG.rngIndex.crypto: + value = Crypto_RNG.random_gauss()[0]; + break; + case (Int32)commonRNG.rngIndex.mtwister: + value = MersenneTwister_RNG.random_gauss()[0]; + break; + default: + value = RNG.random_gauss()[0]; + break; + } + return value; + } + + public static Int32 getRandomInt(EntropySettings settings) + { + return pGetRandomInt(settings); + } + + static Int32 pGetRandomInt(EntropySettings settings) + { + Int32 value = 1; + switch (settings.getValue(EntropySettings.properties_i.rngType)) + { + case (Int32)commonRNG.rngIndex.crypto: + value = Crypto_RNG.nextint(); + break; + case (Int32)commonRNG.rngIndex.mtwister: + value = MersenneTwister_RNG.nextint(); + break; + default: + value = RNG.nextint(); + break; + } + return value; + } + + public static double getRandomDouble(EntropySettings settings) + { + return pGetRandomDouble(settings); + } + + static double pGetRandomDouble(EntropySettings settings) + { + double value = 1.0f; + switch (settings.getValue(EntropySettings.properties_i.rngType)) + { + case (Int32)commonRNG.rngIndex.crypto: + value = Crypto_RNG.nextdouble(); + break; + case (Int32)commonRNG.rngIndex.mtwister: + value = MersenneTwister_RNG.nextdouble(); + break; + default: + value = RNG.nextdouble(); + break; + } + return value; + } + + public static void resetDebugLog(string filename) + { + if (filename == "") + { + return; + } + File.WriteAllText(filename, ""); + } + + public static void debugLog(string filename, string debugString) + { + if (filename == "") + { + return; + } + + using (StreamWriter sw = File.AppendText(filename)) + { + sw.WriteLine(debugString); + } + } + + public static double do1DCalculation_3sig_edge( + double layer1_overlayx, double layer1_overlayy, + double layer1_cdu, double layer1_lwr, + double layer1_addvar, + double layer2_overlayx, double layer2_overlayy, + double layer2_cdu, double layer2_lwr, + double layer2_addvar) + { + return Math.Sqrt( + Utils.myPow(layer1_overlayx, 2) + + Utils.myPow(layer1_overlayy, 2) + + Utils.myPow(layer2_overlayx, 2) + + Utils.myPow(layer2_overlayy, 2) + + Utils.myPow((layer1_cdu / 2), 2) + + Utils.myPow((layer2_cdu / 2), 2) + + Utils.myPow((layer1_lwr / 2), 2) + + Utils.myPow((layer2_lwr / 2), 2) + + Utils.myPow((layer1_addvar / 2), 2) + + Utils.myPow((layer2_addvar / 2), 2)); + } + + public static double do1DCalculation_3sig( + double layer1_overlayx, double layer1_overlayy, + double layer1_cdu, double layer1_lwr, + double layer1_bias, double layer1_addvar, + double layer2_overlayx, double layer2_overlayy, + double layer2_cdu, double layer2_lwr, + double layer2_bias, double layer2_addvar, double minIns) + { + double edgeVal = do1DCalculation_3sig_edge(layer1_overlayx, layer1_overlayy, layer1_cdu, layer1_lwr, layer1_addvar, + layer2_overlayx, layer2_overlayy, layer2_cdu, layer2_lwr, layer2_addvar); + return minIns + edgeVal + (0.5 * (layer1_bias + layer2_bias)); + } + + public static double do1DCalculation_4sig( + double layer1_overlayx, double layer1_overlayy, + double layer1_cdu, double layer1_lwr, + double layer1_bias, double layer1_addvar, + double layer2_overlayx, double layer2_overlayy, + double layer2_cdu, double layer2_lwr, + double layer2_bias, double layer2_addvar, double minIns) + { + double edgeVal = (4.0f / 3.0f) * do1DCalculation_3sig_edge(layer1_overlayx, layer1_overlayy, layer1_cdu, layer1_lwr, layer1_addvar, + layer2_overlayx, layer2_overlayy, layer2_cdu, layer2_lwr, layer2_addvar); + return minIns + edgeVal + (0.5 * (layer1_bias + layer2_bias)); + } + + public static double do1DCalculation_nsig(double n, + double layer1_overlayx, double layer1_overlayy, + double layer1_cdu, double layer1_lwr, + double layer1_bias, double layer1_addvar, + double layer2_overlayx, double layer2_overlayy, + double layer2_cdu, double layer2_lwr, + double layer2_bias, double layer2_addvar, double minIns) + { + double edgeVal = (n / 3.0f) * do1DCalculation_3sig_edge(layer1_overlayx, layer1_overlayy, layer1_cdu, layer1_lwr, layer1_addvar, + layer2_overlayx, layer2_overlayy, layer2_cdu, layer2_lwr, layer2_addvar); + return minIns + edgeVal + (0.5 * (layer1_bias + layer2_bias)); + } + + public static bool readiDRMCSVFile(ref CommonVars commonVars, string fileName) + { + return pReadiDRMCSVFile(ref commonVars, fileName); + } + + static bool pReadiDRMCSVFile(ref CommonVars commonVars, string fileName) + { + bool reading = false; + List tilesToRun = new List(); // will be col,row + try + { + using (StreamReader sr = new StreamReader(fileName)) + { + char[] csvSeparators = new char[] { ',' }; + char[] equalSeparators = new char[] { '=' }; + string[] parsedString; + + reading = true; + // Read in non-CSV data first + // Pattern line + sr.ReadLine(); + // Now we have the meat of the data we need. + string tempString = sr.ReadLine(); + parsedString = tempString.Split(csvSeparators); + if (parsedString.Count() >= 6) + { + // We have 6 values to extract from this line. + // X-offset, Y-offset, X pitch, Y pitch, rows, cols + // Convert from um to nm in the process. + // Take the second result of the split which is the numeric value. Convert it to double, multiply by 1000 to convert units. Make int. + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.colOffset, (1000 * Convert.ToDouble(parsedString[0].Split(equalSeparators)[1]))); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.rowOffset, (1000 * Convert.ToDouble(parsedString[1].Split(equalSeparators)[1]))); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.colPitch, (1000 * Convert.ToDouble(parsedString[2].Split(equalSeparators)[1]))); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.rowPitch, (1000 * Convert.ToDouble(parsedString[3].Split(equalSeparators)[1]))); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.rows, Convert.ToInt32(Convert.ToDouble(parsedString[4].Split(equalSeparators)[1]))); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.cols, Convert.ToInt32(Convert.ToDouble(parsedString[5].Split(equalSeparators)[1]))); + } + else + { + // We need to break here. + ErrorReporter.showMessage_OK("CSV file doesn't match expectations.", "Aborting."); + return false; + } + + sr.ReadLine(); // skip a line that we don't need. + + while (!sr.EndOfStream) + { + // Assuming Pass/Fail,Column,Row,Co-ord X,Co-ord Y,,,,,,,,,,,,, + tempString = sr.ReadLine(); + parsedString = tempString.Split(csvSeparators); + if ((parsedString[0] == "") || (parsedString[0] == "Occupy matrix")) + { + break; + } + else + { + if (Convert.ToInt32(parsedString[0]) == 1) + { + // Pass case - need to add to list. + tilesToRun.Add(new Int32[2] { Convert.ToInt32(parsedString[1]), Convert.ToInt32(parsedString[2]) }); + } + } + } + } + + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.iDRM, true); + commonVars.getSimulationSettings().getDOESettings().setTileList_ColRow(tilesToRun); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 1); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTile, 0); + + } + catch (Exception) + { + return reading; + } + + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.iDRM, true); + commonVars.getSimulationSettings().getDOESettings().setTileList_ColRow(tilesToRun); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 1); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTile, 0); + return reading; + } + + public static bool readQuiltCSVFile(ref CommonVars commonVars, string fileName) + { + return pReadQuiltCSVFile(ref commonVars, fileName); + } + + static bool pReadQuiltCSVFile(ref CommonVars commonVars, string fileName) + { + bool reading = false; + List tilesToRun = new List(); // will be col,row + try + { + using (StreamReader sr = new StreamReader(fileName)) + { + reading = true; + char[] csvSeparators = new char[] { ',' }; + char[] equalSeparators = new char[] { '=' }; + string[] parsedString; + + // Read in non-CSV data first + // Pattern line + string check = sr.ReadLine(); + if (!check.StartsWith("Quilt")) + { + return false; + } + // Now we have the meat of the data we need. + string tempString = sr.ReadLine(); + parsedString = tempString.Split(csvSeparators); + if (parsedString.Count() >= 6) + { + // We have 6 values to extract from this line. + // X-offset, Y-offset, X pitch, Y pitch, rows, cols + // Convert from um to nm in the process. + // Take the second result of the split which is the numeric value. Convert it to double, multiply by 1000 to convert units. Make int. + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.colOffset, Convert.ToDouble(parsedString[0])); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.rowOffset, Convert.ToDouble(parsedString[1])); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.colPitch, Convert.ToDouble(parsedString[2])); + commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.rowPitch, Convert.ToDouble(parsedString[3])); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.rows, Convert.ToInt32(parsedString[4])); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.cols, Convert.ToInt32(parsedString[5])); + } + else + { + // We need to break here. + ErrorReporter.showMessage_OK("CSV file doesn't match expectations.", "Aborting."); + return false; + } + } + reading = false; + } + catch (Exception) + { + return reading; + } + + commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.quilt, true); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 0); + commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTile, 0); + return reading; + } + + static void extractValuesFromSummaryFile(DOEResults doeResults, string[] DOETokens, string filename) + { + string DOEName = DOETokens[0]; + // Get our index in doeResults for convenience + Int32 index = 0; + bool foundDOE = false; + while (index < doeResults.getResults().Count()) + { + if (doeResults.getResults()[index].getName() == DOEName) + { + foundDOE = true; + break; + } + index++; + } + + if (!foundDOE) + { + // int oops = 1; + } + + StreamReader file = new StreamReader(filename); + // Our col and row indices have prefixes; need to remove and obtain the index. + string[] tempArray = DOETokens[1].Split('l'); + Int32 column = Convert.ToInt32(tempArray[1]); + tempArray = DOETokens[2].Split('w'); + Int32 row = Convert.ToInt32(tempArray[1]); + + // Store our cell in the DOE list. + doeResults.getResults()[index].AddCellToDOE(column, row); + + bool headerRead = false; + bool eqtnFound = false; + string line; + List header = new List(); + while ((line = file.ReadLine()) != null) + { + if (line.Contains("mean and standard deviation")) + { + headerRead = true; + doeResults.getResults()[index].setDOEHeaderInformation(header); + // We have a result line. + // We need to carve it up. Happily, we know our format and can rely on it! + string leaderString = "result "; + + leaderString = leaderString + line.Substring(leaderString.Length, 1) + ": "; + + int meanStart = line.LastIndexOf("x", StringComparison.CurrentCulture); + + // We need to replace our ',' in the result string to avoid issues with the CSV format. + string resultLine = line.Substring(meanStart, line.Length - meanStart); + string[] resultLineTokens = resultLine.Split(','); + resultLine = resultLineTokens[0] + "(" + resultLineTokens[1].Substring(1, resultLineTokens[1].Length - 1) + ")"; + + // Populate our cell-level list of results for the DOEName, with the list of result strings that we find in the file. + doeResults.getResults()[index].AddResultToCell(column, row, leaderString + resultLine); + } + else + { + if (!eqtnFound) + { + string searchString = "Equation"; + if ((line.Length > searchString.Length) && (line.Substring(0, searchString.Length) == searchString)) + { + eqtnFound = true; + } + } + if ((!headerRead) && (eqtnFound)) + { + header.Add(line); + } + } + } + } + + public static string generateDOESummaryFile(DOEResults doeResults, string path) + { + return pGenerateDOESummaryFile(doeResults, path); + } + + static string pGenerateDOESummaryFile(DOEResults doeResults, string path) + { + bool error = false; + string summaryFile = ""; + try + { + for (int result = 0; result < doeResults.getResults().Count; result++) + { + // We walk our doeResults, collected by name, and summarize each one in a grid layout in CSV. + // Retrieve the grid size from our results. + int colCount = 0; + int rowCount = 0; + for (int cell = 0; cell < doeResults.getResults()[result].getCells().Count(); cell++) + { + int col = doeResults.getResults()[result].getCells()[cell].getColIndex(); + int row = doeResults.getResults()[result].getCells()[cell].getRowIndex(); + if (col > colCount) + { + colCount = col; + } + if (row > rowCount) + { + rowCount = row; + } + } + + // Deal with array size vs index offset. + colCount++; + rowCount++; + + // Create our 2D string array to match our DOE results. + string[,] doeResultsSummaryGrid = new string[colCount, rowCount]; + + // Populate cells where results are available; empty cells will be indicated. + for (int cell = 0; cell < doeResults.getResults()[result].getCells().Count(); cell++) + { + string resultString = ""; + int resultCount = doeResults.getResults()[result].getCells()[cell].getResults().getValues().Count(); + for (int resultIndex = 0; resultIndex < resultCount; resultIndex++) + { + resultString += doeResults.getResults()[result].getCells()[cell].getResults().getValues()[resultIndex]; + + // To work with our CSV format, we use ';' to separate multiple results in the same field. + if ((resultCount > 1) && (resultIndex != resultCount - 1)) + { + resultString += ";"; + } + } + // No result for cell, so indicate to user. + if (resultString == "") + { + resultString = "No result(s)"; + } + + // Assign result string to corresponding cell of grid. + doeResultsSummaryGrid[doeResults.getResults()[result].getCells()[cell].getColIndex(), doeResults.getResults()[result].getCells()[cell].getRowIndex()] = resultString; + } + + // Now we have our grid, we need to save it out. + summaryFile = Path.Combine(path, doeResults.getResults()[result].getName() + "_DOESummary.txt"); + + List resultStringList = doeResults.getResults()[result].getHeaderInformation().ToList(); + + // Compile our string list that we will write. + for (int row = 0; row < rowCount; row++) + { + string resultsRow = ""; + for (int col = 0; col < colCount; col++) + { + resultsRow += doeResultsSummaryGrid[col, row]; + if ((colCount > 1) && (col != colCount - 1)) + { + resultsRow += ","; + } + } + resultStringList.Add(resultsRow); + } + + File.WriteAllLines(summaryFile, resultStringList); + } + } + catch (Exception) + { + error = true; + } + if (!error) + { + return "Summary written to: " + summaryFile; + } + else + { + return ""; + } + } + + public static string summarizeDOEResults(string path, string[] summaryFilesFound) + { + return pSummarizeDOEResults(path, summaryFilesFound); + } + + static string pSummarizeDOEResults(string path, string[] summaryFilesFound) + { + // We need to account for the possibility of more than one DOE run being in the folder. + // We're only targeting the summary files (not CSV). + // File name is of the form userFileName_colX_rowY_summary.txt + + if (summaryFilesFound.Length == 0) + { + return ""; + } + + Int32 index = 0; + + string fileToRead = Path.Combine(path, summaryFilesFound[index]); + + char[] tokens = new char[] { '_' }; + string[] DOETokens = summaryFilesFound[index].Split(tokens); + // Create our DOE results instance. This will contain all of DOEs and collect all of their results as well. + DOEResults doeResults = new DOEResults(DOETokens[0]); + extractValuesFromSummaryFile(doeResults, DOETokens, fileToRead); + + index++; + while (index < summaryFilesFound.Length) + { + fileToRead = Path.Combine(path, summaryFilesFound[index]); + DOETokens = summaryFilesFound[index].Split(tokens); + + bool found = false; + for (int result = 0; result < doeResults.getResults().Count(); result++) + { + if (doeResults.getResults()[result].getName() == DOETokens[0]) + { + found = true; + break; + } + } + + if (!found) // New DOE name, need to add it to our list. + { + doeResults.AddResult(DOETokens[0]); + } + extractValuesFromSummaryFile(doeResults, DOETokens, fileToRead); + index++; + } + return generateDOESummaryFile(doeResults, path); + } + } +} diff --git a/Common/Variance_hl/Variance_hl.csproj b/Common/Variance_hl/Variance_hl.csproj new file mode 100644 index 0000000..cb1f14e --- /dev/null +++ b/Common/Variance_hl/Variance_hl.csproj @@ -0,0 +1,180 @@ + + + + netcoreapp3.1 + Debug;Release;Release_obf + + + + TRACE;DISABLELICENSE + + + + TRACE;DISABLELICENSE + + + + TRACE + + + + + + + + + + + + chaos\chaosEngine.cs + + + chaos\chaosEngine_implant.cs + + + chaos\chaosSettings.cs + + + chaos\chaosSettings_implant.cs + + + DOE\DOEResults.cs + + + DOE\DOESettings.cs + + + engines\angleHandler.cs + + + engines\areaHandler.cs + + + engines\chordHandler.cs + + + engines\distanceHandler.cs + + + entropy\entropy.cs + + + entropy\entropyLayerSettings.cs + + + entropy\entropySettings.cs + + + entropy\entropySettings_nonSim.cs + + + entropy\entropyShape.cs + + + entropy\entropy_geo.cs + + + entropy\entropy_implant.cs + + + entropy\implantSettings.cs + + + entropy\paSearchSettings.cs + + + entropy\sampler_geo.cs + + + entropy\sampler_implant.cs + + + results\results.cs + + + results\results_implant.cs + + + results\simResultPackage.cs + + + support\centralProperties.cs + + + support\commonVars.cs + + + support\Email.cs + + + support\nonSimulationSettings.cs + + + support\previewShape.cs + + + support\replay.cs + + + support\shapeLibrary.cs + + + support\simpleAES.cs + + + support\simulationPreview.cs + + + support\Storage.cs + + + support\SVGBuilder.cs + + + support\utilityFuncs.cs + + + support\VarianceContext.cs + + + + + + {576cba59-f35e-4f45-905c-26927e2e441a} + color + + + {663a7d25-5255-4b85-b94d-53c431426339} + entropyRNG + + + + {87c2783d-ac80-4684-875c-f06237e9cc3f} + geoLib + + + {1d7842b4-12c0-4e11-a6a9-77ceb55f156c} + geoWrangler + + + + + {ff8ede08-8236-49a0-a82e-3b6208b81431} + Noise + + + {c3255560-6437-4eff-8948-971a76c6e9ab} + utility + + + + + + + + + + + + + diff --git a/Common/Variance_hl/errorReporter.cs b/Common/Variance_hl/errorReporter.cs new file mode 100644 index 0000000..4890e19 --- /dev/null +++ b/Common/Variance_hl/errorReporter.cs @@ -0,0 +1,12 @@ +using System; + +namespace Error +{ + public class ErrorReporter + { + public static void showMessage_OK(string stringToDisplay, string caption) + { + Console.WriteLine(caption + ": " + stringToDisplay); + } + } +} diff --git a/Common/keys.cs b/Common/keys.cs new file mode 100644 index 0000000..9f2e330 --- /dev/null +++ b/Common/keys.cs @@ -0,0 +1,21 @@ +namespace keys +{ + static class Arrays + { + public static byte[] nameKey = { + 99, 219, 117, 66, 0, 105, 168, 252, 10, 53, 58, 203, 75, 210, 179, 1, + 148, 22, 25, 84, 216, 171, 7, 189, 214, 185, 100, 12, 168, 195, 229, 18 + }; // 32 + public static byte[] nameVector = { + 227, 220, 222, 240, 209, 34, 113, 32, 127, 153, 225, 109, 102, 198, 95, 135 + }; // 16 + + public static byte[] validationKey = { + 226, 72, 244, 239, 123, 211, 173, 46, 7, 250, 241, 223, 75, 24, 243, 244, + 215, 57, 153, 92, 200, 204, 168, 167, 52, 113, 10, 251, 35, 88, 164, 220 + }; // 32 + public static byte[] validationVector = { + 204, 4, 125, 112, 27, 65, 102, 203, 178, 215, 159, 198, 222, 126, 163, 185 + }; // 16 + } +} \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..23f1199 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,43 @@ + + + + Windows + Linux + macOS + + true + true + + + + $(MSBuildThisFileDirectory) + $(TopLevelDirectory)artifacts\ + + + $(ArtifactsDir)obj\$(BuildOS)\$(MSBuildProjectName)\ + + + $(ArtifactsDir)bin\$(MSBuildProjectName)\ + + 1.0.13 + + + + win-x64 + libveldrid-spirv.dll + + + + linux-x64 + libveldrid-spirv.so + + + + osx-x64 + libveldrid-spirv.dylib + + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000..dfa1c36 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,49 @@ + + + + + + + + + + false + true + + $(OutputPath) + $(OutputAppPath)\Contents\MonoBundle\ + + + + + + + + + + <_DelItems3 Include="$(OutputPath)*.xml" /> + + + <_DelItems4 Include="$(OutputPath)*.pdb" /> + + + + + + + + + + + + + + + + + + + + diff --git a/Documentation/bugreport.html b/Documentation/bugreport.html new file mode 100644 index 0000000..5b62fd5 --- /dev/null +++ b/Documentation/bugreport.html @@ -0,0 +1,230 @@ + + + + +Variance - Reference + + + + + +

Bug Report

+
+
+

Choose your operating system and processor from the menus below :

+

+ + + + GHz

+

Please fill out the amount of memory in your machine :

+

+ + GB +

+

If you know it, please choose the .NET or Mono version :

+

+ +

+

Please describe your problem in the box below :

+

+ +

+

Hitting submit will hopefully cause an email to be opened, ready to send, in your email client. If you need to attach a project file, please take the opportunity prior to sending it.

+

+ + +

+
+
+ + diff --git a/Documentation/ilb_test_case_overview.html b/Documentation/ilb_test_case_overview.html new file mode 100644 index 0000000..7ff0c85 --- /dev/null +++ b/Documentation/ilb_test_case_overview.html @@ -0,0 +1,615 @@ + + + + +ILB - Test Case Overview + + + + + + + +
+
+ + +

ILB Test Case Overview

+

The ILB system has lots of complexity and so there are a large number of test cases to cover different aspects. This provides an overview of each test case, and the expected result..

+ +
+ +

3

+

Layer 3 is a union of 1 and 2. This should be a simple test

+

Layer 5 is 4-3 and this lightly tests the keyholer injects an edge

+ + + + + + +
+ + + +
+
+ +
+ +

4

+

Layer 3 is a union of 1 and 2. This should be a simple test

+

Layer 5 is 4-3, with a proximity bias applied. If the output from the Boolean is not clean, the proximity bias will fail so this is used to ensure clean output from this case.

+ + + + + + +
+ + + +
+
+ +
+ +

5

+

Layer 5 is 4-1, with corner rounding applied. This tests the inner and outer corner rounding results, including the rounding around the keyhole. Numeric errors could close the keyhole and unclean geometry will fail the rounding.

+

Layer 6 is 5-2. This is a test that there is no additional keyhole insertion and also tests that the result is a clean cut (no keyhole collapse or fragments).

+ + + + + + +
+ + + +
+
+ +
+ +

6

+

Layer 3 is a union of 1 and 2. This should be a simple test

+

Layer 5 is 4-3, with a proximity bias applied. If the output from the Boolean is not clean, the proximity bias will fail so this is used to ensure clean output from this case. Overlap merging is tested, and the keyholer is also tested here.

+

Layer 7 is 5-6. This tests the internal keyhole removal, Boolean, keyhole injection (twice, one for each cutter). The keyhole system is sensitive to cutter order (at the time of writing), but it should be the case that one cutter is connected to the outer perimeter, and an internal connection is made between the two cutters.

+ + + + + + + + + +
+ + + +
+ +
+
+ +
+ +

7

+

Layer 3 is 2-1, yielding a keyholed polygon

+

Layer 4 is 2-1, yielding an offset keyholed polygon

+

Layer 5 is 3 || 4. This tests keyhole removal and keyhole injection where the second hole has a different keyhole location.

+ + + + + + + + + +
+ + + +
+ +
+
+ +
+ +

8

+

Layer 3 is a multipolygon single-pass difference test of 2-1, yielding a single keyholed polygon with two holes.

+ + + + + + +
+ + +
+
+ +
+ +

9

+

Layer 3 is a multipolygon single-pass difference test of 2-1, yielding a single keyholed polygon with two holes.

+

Layer 4 is 2-3. This is a test of the sliver/gap removal mechanisms and the result should also be compatible with the contouring engine, so this is tested as well..

+ + + + + + +
+ + + +
+
+ +
+ +

10

+

Simple multi-cut test, used to compare the keyhole result with the 10_broken test.

+ + + + + + +
+ + +
+
+ +
+ +

10_broken

+

Simple multi-cut test, used to compare the keyhole result with the 10 test. The keyholer result should find the correct edge for the slightly shifted top right cutter.

+ + + + + + +
+ + +
+
+ +
+ +

11

+

Layer 1 is a baked pointset from a keyholed polygon (exported and then loaded from GDS).

+

Layer 3 is 1-2. This is a test of the gap removal mechanisms, and keyhole injection for orthogonal geometry - the two cutters should be connected because that is the shortest solution found.

+ + + + + + +
+ + + +
+
+ +
+ +

12

+

Layer 3 is 1 || 2. Simple union test.

+

Layer 5 is 4 - 1.

+

Layer 6 is 5 - 2.

+

Layer 7 is 4 - 3. Should be identical to layer 6.

+ + + + + + + + + + +
+ + + +
+ + + +
+
+ +
+ +

13

+

Layer 5 is 4-1.

+

Layer 6 is 5-2. This is a test of the gap removal mechanisms, and keyhole injection. Numeric precision can lead to keyhole loss, resulting in artifacts, and/or contouring rejection.

+ + + + + + +
+ + + +
+
+ +
+ +

14

+

Layer 1 is a baked pointset of two sliver polygons (exported and then loaded from GDS).

+

Layer 3 is 1 && 2. This is a test of the sliver removal mechanisms and ensures the result is contouring-compatible.

+ + + + + + +
+ + + +
+
+ +
+ +

15

+

Layer 5 is a baked pointset of a keyholed polygon (exported and then loaded from GDS).

+

Layer 6 is 5 - 2, resulting in a keyholed polygon with rounding applied to test the result is clean and contour-compatible.

+

Layer 7 is 6 && 6. This is a test of the error introduced during the keyhole merging manipulation. The geometry is merged during this operation, and due to the sharp angles in this region, the raycaster will never find this option. As a result, the required keyhole is created elsewhere.

+ + + + + + + + + + +
+ + + +
+ + +
+
+ +
+ +

16

+

Layer 3 is a union of 1 and 2. This should be a simple test

+

Layer 5 is 4-3, with a proximity bias applied. If the output from the Boolean is not clean, the proximity bias will fail so this is used to ensure clean output from this case. Overlap merging is tested, and the keyholer is also tested here. A rotation of -55 degrees is applied deliberately

+

Layer 7 is 5-6. This tests the internal keyhole removal, Boolean, keyhole injection (twice, one for each cutter). The shortest path is found to connect the cutters as below.

+ + + + + + + + + +
+ + + +
+ +
+
+ +
+ +

17

+

Layer 3 is a union of 1 and 2. This should be a simple test

+

Layer 5 is 4-3, with a proximity bias applied. If the output from the Boolean is not clean, the proximity bias will fail so this is used to ensure clean output from this case. Overlap merging is tested, and the keyholer is also tested here. A rotation of -60 degrees is applied deliberately

+

Layer 7 is 5-6. This tests the internal keyhole removal, Boolean, keyhole injection (twice, one for each cutter). This is designed to force an overlap between the cutters which causes the internal keyhole system to a non-orthogonal evaluation. The 'bridge' between the cutters in this situation arises from the overlap, not a keyhole, so a single keyhole is injected to the outer perimeter.

+ + + + + + + + + +
+ + + +
+ +
+
+ +
+ +

18

+

Layer 1 is a tiled DOE layout dataset, loaded from GDS. The DOE is set to use the first entry of the second row.

+

Layer 3 is 1-2. This tests that the correct tile is located, repositioned and the Boolean succeeds. If the 'use DOE tile for preview' setting is off, the Boolean is applied to the first tile.

+ + + + + + + + + + +
+ + + +
+ + + +
+
+ + +
+ +

Keyholed Ortho Test

+

This is intended to test the removal of the keyhole in the simulation pipeline. If the keyhole is removed, the distance check will not report against the keyhole but the real outer edge.

+ + + + + + +
+ + + +
+
+ + +
+ +

Keyholed Ortho Inversion Test

+

This is intended to test the removal of the sliver/keyhole in the simulation pipeline. If the keyhole/sliver is removed, the distance check will not report against the former keyhole (potential sliver) but the real outer edge.

+ + + + + + +
+ + + +
+
+ +
+
+ + diff --git a/Documentation/ilb_testcase_images/003_001.png b/Documentation/ilb_testcase_images/003_001.png new file mode 100644 index 0000000..e21f0c3 Binary files /dev/null and b/Documentation/ilb_testcase_images/003_001.png differ diff --git a/Documentation/ilb_testcase_images/003_002.png b/Documentation/ilb_testcase_images/003_002.png new file mode 100644 index 0000000..1e71913 Binary files /dev/null and b/Documentation/ilb_testcase_images/003_002.png differ diff --git a/Documentation/ilb_testcase_images/004_001.png b/Documentation/ilb_testcase_images/004_001.png new file mode 100644 index 0000000..c1dd2f8 Binary files /dev/null and b/Documentation/ilb_testcase_images/004_001.png differ diff --git a/Documentation/ilb_testcase_images/004_002.png b/Documentation/ilb_testcase_images/004_002.png new file mode 100644 index 0000000..18e273c Binary files /dev/null and b/Documentation/ilb_testcase_images/004_002.png differ diff --git a/Documentation/ilb_testcase_images/005_001.png b/Documentation/ilb_testcase_images/005_001.png new file mode 100644 index 0000000..977ef30 Binary files /dev/null and b/Documentation/ilb_testcase_images/005_001.png differ diff --git a/Documentation/ilb_testcase_images/005_002.png b/Documentation/ilb_testcase_images/005_002.png new file mode 100644 index 0000000..5789114 Binary files /dev/null and b/Documentation/ilb_testcase_images/005_002.png differ diff --git a/Documentation/ilb_testcase_images/006_001.png b/Documentation/ilb_testcase_images/006_001.png new file mode 100644 index 0000000..9e53f5b Binary files /dev/null and b/Documentation/ilb_testcase_images/006_001.png differ diff --git a/Documentation/ilb_testcase_images/006_002.png b/Documentation/ilb_testcase_images/006_002.png new file mode 100644 index 0000000..efc962f Binary files /dev/null and b/Documentation/ilb_testcase_images/006_002.png differ diff --git a/Documentation/ilb_testcase_images/006_003.png b/Documentation/ilb_testcase_images/006_003.png new file mode 100644 index 0000000..43da71d Binary files /dev/null and b/Documentation/ilb_testcase_images/006_003.png differ diff --git a/Documentation/ilb_testcase_images/007_001.png b/Documentation/ilb_testcase_images/007_001.png new file mode 100644 index 0000000..6258f4d Binary files /dev/null and b/Documentation/ilb_testcase_images/007_001.png differ diff --git a/Documentation/ilb_testcase_images/007_002.png b/Documentation/ilb_testcase_images/007_002.png new file mode 100644 index 0000000..672935d Binary files /dev/null and b/Documentation/ilb_testcase_images/007_002.png differ diff --git a/Documentation/ilb_testcase_images/007_003.png b/Documentation/ilb_testcase_images/007_003.png new file mode 100644 index 0000000..a5667ae Binary files /dev/null and b/Documentation/ilb_testcase_images/007_003.png differ diff --git a/Documentation/ilb_testcase_images/008_001.png b/Documentation/ilb_testcase_images/008_001.png new file mode 100644 index 0000000..0bbf1d6 Binary files /dev/null and b/Documentation/ilb_testcase_images/008_001.png differ diff --git a/Documentation/ilb_testcase_images/009_001.png b/Documentation/ilb_testcase_images/009_001.png new file mode 100644 index 0000000..80aba51 Binary files /dev/null and b/Documentation/ilb_testcase_images/009_001.png differ diff --git a/Documentation/ilb_testcase_images/009_002.png b/Documentation/ilb_testcase_images/009_002.png new file mode 100644 index 0000000..40f3066 Binary files /dev/null and b/Documentation/ilb_testcase_images/009_002.png differ diff --git a/Documentation/ilb_testcase_images/010_001.png b/Documentation/ilb_testcase_images/010_001.png new file mode 100644 index 0000000..daa0246 Binary files /dev/null and b/Documentation/ilb_testcase_images/010_001.png differ diff --git a/Documentation/ilb_testcase_images/010b_001.png b/Documentation/ilb_testcase_images/010b_001.png new file mode 100644 index 0000000..2f7351e Binary files /dev/null and b/Documentation/ilb_testcase_images/010b_001.png differ diff --git a/Documentation/ilb_testcase_images/011_001.png b/Documentation/ilb_testcase_images/011_001.png new file mode 100644 index 0000000..4c28fe7 Binary files /dev/null and b/Documentation/ilb_testcase_images/011_001.png differ diff --git a/Documentation/ilb_testcase_images/011_002.png b/Documentation/ilb_testcase_images/011_002.png new file mode 100644 index 0000000..7adc2e3 Binary files /dev/null and b/Documentation/ilb_testcase_images/011_002.png differ diff --git a/Documentation/ilb_testcase_images/012_001.png b/Documentation/ilb_testcase_images/012_001.png new file mode 100644 index 0000000..a18a9ce Binary files /dev/null and b/Documentation/ilb_testcase_images/012_001.png differ diff --git a/Documentation/ilb_testcase_images/012_002.png b/Documentation/ilb_testcase_images/012_002.png new file mode 100644 index 0000000..66e3d42 Binary files /dev/null and b/Documentation/ilb_testcase_images/012_002.png differ diff --git a/Documentation/ilb_testcase_images/012_003.png b/Documentation/ilb_testcase_images/012_003.png new file mode 100644 index 0000000..cb64840 Binary files /dev/null and b/Documentation/ilb_testcase_images/012_003.png differ diff --git a/Documentation/ilb_testcase_images/012_004.png b/Documentation/ilb_testcase_images/012_004.png new file mode 100644 index 0000000..37673ed Binary files /dev/null and b/Documentation/ilb_testcase_images/012_004.png differ diff --git a/Documentation/ilb_testcase_images/013_001.png b/Documentation/ilb_testcase_images/013_001.png new file mode 100644 index 0000000..3e192d7 Binary files /dev/null and b/Documentation/ilb_testcase_images/013_001.png differ diff --git a/Documentation/ilb_testcase_images/013_002.png b/Documentation/ilb_testcase_images/013_002.png new file mode 100644 index 0000000..9d37f2a Binary files /dev/null and b/Documentation/ilb_testcase_images/013_002.png differ diff --git a/Documentation/ilb_testcase_images/014_001.png b/Documentation/ilb_testcase_images/014_001.png new file mode 100644 index 0000000..00cb93c Binary files /dev/null and b/Documentation/ilb_testcase_images/014_001.png differ diff --git a/Documentation/ilb_testcase_images/014_002.png b/Documentation/ilb_testcase_images/014_002.png new file mode 100644 index 0000000..12ce8e9 Binary files /dev/null and b/Documentation/ilb_testcase_images/014_002.png differ diff --git a/Documentation/ilb_testcase_images/015_001.png b/Documentation/ilb_testcase_images/015_001.png new file mode 100644 index 0000000..67a8572 Binary files /dev/null and b/Documentation/ilb_testcase_images/015_001.png differ diff --git a/Documentation/ilb_testcase_images/015_002.png b/Documentation/ilb_testcase_images/015_002.png new file mode 100644 index 0000000..33e4945 Binary files /dev/null and b/Documentation/ilb_testcase_images/015_002.png differ diff --git a/Documentation/ilb_testcase_images/015_003.png b/Documentation/ilb_testcase_images/015_003.png new file mode 100644 index 0000000..5d59ea7 Binary files /dev/null and b/Documentation/ilb_testcase_images/015_003.png differ diff --git a/Documentation/ilb_testcase_images/016_001.png b/Documentation/ilb_testcase_images/016_001.png new file mode 100644 index 0000000..fa46746 Binary files /dev/null and b/Documentation/ilb_testcase_images/016_001.png differ diff --git a/Documentation/ilb_testcase_images/016_002.png b/Documentation/ilb_testcase_images/016_002.png new file mode 100644 index 0000000..0f2f07d Binary files /dev/null and b/Documentation/ilb_testcase_images/016_002.png differ diff --git a/Documentation/ilb_testcase_images/016_003.png b/Documentation/ilb_testcase_images/016_003.png new file mode 100644 index 0000000..30d9b90 Binary files /dev/null and b/Documentation/ilb_testcase_images/016_003.png differ diff --git a/Documentation/ilb_testcase_images/017_001.png b/Documentation/ilb_testcase_images/017_001.png new file mode 100644 index 0000000..9f9c9d5 Binary files /dev/null and b/Documentation/ilb_testcase_images/017_001.png differ diff --git a/Documentation/ilb_testcase_images/017_002.png b/Documentation/ilb_testcase_images/017_002.png new file mode 100644 index 0000000..763b055 Binary files /dev/null and b/Documentation/ilb_testcase_images/017_002.png differ diff --git a/Documentation/ilb_testcase_images/017_003.png b/Documentation/ilb_testcase_images/017_003.png new file mode 100644 index 0000000..49231fc Binary files /dev/null and b/Documentation/ilb_testcase_images/017_003.png differ diff --git a/Documentation/ilb_testcase_images/018_001.png b/Documentation/ilb_testcase_images/018_001.png new file mode 100644 index 0000000..b28df98 Binary files /dev/null and b/Documentation/ilb_testcase_images/018_001.png differ diff --git a/Documentation/ilb_testcase_images/018_002.png b/Documentation/ilb_testcase_images/018_002.png new file mode 100644 index 0000000..e43e658 Binary files /dev/null and b/Documentation/ilb_testcase_images/018_002.png differ diff --git a/Documentation/ilb_testcase_images/018_003.png b/Documentation/ilb_testcase_images/018_003.png new file mode 100644 index 0000000..b236f48 Binary files /dev/null and b/Documentation/ilb_testcase_images/018_003.png differ diff --git a/Documentation/ilb_testcase_images/018_004.png b/Documentation/ilb_testcase_images/018_004.png new file mode 100644 index 0000000..f5109c6 Binary files /dev/null and b/Documentation/ilb_testcase_images/018_004.png differ diff --git a/Documentation/ilb_testcase_images/sim001_001.png b/Documentation/ilb_testcase_images/sim001_001.png new file mode 100644 index 0000000..9655526 Binary files /dev/null and b/Documentation/ilb_testcase_images/sim001_001.png differ diff --git a/Documentation/ilb_testcase_images/sim001_002.png b/Documentation/ilb_testcase_images/sim001_002.png new file mode 100644 index 0000000..2a307c7 Binary files /dev/null and b/Documentation/ilb_testcase_images/sim001_002.png differ diff --git a/Documentation/ilb_testcase_images/sim002_001.png b/Documentation/ilb_testcase_images/sim002_001.png new file mode 100644 index 0000000..01dbd2d Binary files /dev/null and b/Documentation/ilb_testcase_images/sim002_001.png differ diff --git a/Documentation/ilb_testcase_images/sim002_002.png b/Documentation/ilb_testcase_images/sim002_002.png new file mode 100644 index 0000000..741798d Binary files /dev/null and b/Documentation/ilb_testcase_images/sim002_002.png differ diff --git a/Documentation/images/1d.png b/Documentation/images/1d.png new file mode 100644 index 0000000..f11d663 Binary files /dev/null and b/Documentation/images/1d.png differ diff --git a/Documentation/images/Eto_360_Gtk.png b/Documentation/images/Eto_360_Gtk.png new file mode 100644 index 0000000..4711bbd Binary files /dev/null and b/Documentation/images/Eto_360_Gtk.png differ diff --git a/Documentation/images/Eto_360_Gtk_2.png b/Documentation/images/Eto_360_Gtk_2.png new file mode 100644 index 0000000..63d8ff8 Binary files /dev/null and b/Documentation/images/Eto_360_Gtk_2.png differ diff --git a/Documentation/images/Eto_360_Gtk_3.png b/Documentation/images/Eto_360_Gtk_3.png new file mode 100644 index 0000000..4326209 Binary files /dev/null and b/Documentation/images/Eto_360_Gtk_3.png differ diff --git a/Documentation/images/Eto_360_dark_mac_2.png b/Documentation/images/Eto_360_dark_mac_2.png new file mode 100644 index 0000000..d83f5ad Binary files /dev/null and b/Documentation/images/Eto_360_dark_mac_2.png differ diff --git a/Documentation/images/Eto_360_implant_mac.png b/Documentation/images/Eto_360_implant_mac.png new file mode 100644 index 0000000..c8eb729 Binary files /dev/null and b/Documentation/images/Eto_360_implant_mac.png differ diff --git a/Documentation/images/Eto_360_mac_1.png b/Documentation/images/Eto_360_mac_1.png new file mode 100644 index 0000000..568afce Binary files /dev/null and b/Documentation/images/Eto_360_mac_1.png differ diff --git a/Documentation/images/Eto_360_pasearch_mac.png b/Documentation/images/Eto_360_pasearch_mac.png new file mode 100644 index 0000000..d48ee91 Binary files /dev/null and b/Documentation/images/Eto_360_pasearch_mac.png differ diff --git a/Documentation/images/Eto_360_simulation_mac.png b/Documentation/images/Eto_360_simulation_mac.png new file mode 100644 index 0000000..5deb9f1 Binary files /dev/null and b/Documentation/images/Eto_360_simulation_mac.png differ diff --git a/Documentation/images/Eto_400_WPF.png b/Documentation/images/Eto_400_WPF.png new file mode 100644 index 0000000..5f691e6 Binary files /dev/null and b/Documentation/images/Eto_400_WPF.png differ diff --git a/Documentation/images/Eto_400_WPF_2.png b/Documentation/images/Eto_400_WPF_2.png new file mode 100644 index 0000000..ab84bc2 Binary files /dev/null and b/Documentation/images/Eto_400_WPF_2.png differ diff --git a/Documentation/images/Lshape.png b/Documentation/images/Lshape.png new file mode 100644 index 0000000..7052093 Binary files /dev/null and b/Documentation/images/Lshape.png differ diff --git a/Documentation/images/Sshape.png b/Documentation/images/Sshape.png new file mode 100644 index 0000000..e63876d Binary files /dev/null and b/Documentation/images/Sshape.png differ diff --git a/Documentation/images/T_EdgeSlide_015.png b/Documentation/images/T_EdgeSlide_015.png new file mode 100644 index 0000000..55f94d2 Binary files /dev/null and b/Documentation/images/T_EdgeSlide_015.png differ diff --git a/Documentation/images/T_EdgeSlide_035.png b/Documentation/images/T_EdgeSlide_035.png new file mode 100644 index 0000000..b528ed5 Binary files /dev/null and b/Documentation/images/T_EdgeSlide_035.png differ diff --git a/Documentation/images/T_noEdgeSlide.png b/Documentation/images/T_noEdgeSlide.png new file mode 100644 index 0000000..ae812fc Binary files /dev/null and b/Documentation/images/T_noEdgeSlide.png differ diff --git a/Documentation/images/Tshape.png b/Documentation/images/Tshape.png new file mode 100644 index 0000000..11001a6 Binary files /dev/null and b/Documentation/images/Tshape.png differ diff --git a/Documentation/images/Ushape.png b/Documentation/images/Ushape.png new file mode 100644 index 0000000..89cb67c Binary files /dev/null and b/Documentation/images/Ushape.png differ diff --git a/Documentation/images/Xshape.png b/Documentation/images/Xshape.png new file mode 100644 index 0000000..cafa421 Binary files /dev/null and b/Documentation/images/Xshape.png differ diff --git a/Documentation/images/angleCalc_1.png b/Documentation/images/angleCalc_1.png new file mode 100644 index 0000000..c7ba454 Binary files /dev/null and b/Documentation/images/angleCalc_1.png differ diff --git a/Documentation/images/angleCalc_2.png b/Documentation/images/angleCalc_2.png new file mode 100644 index 0000000..3472cfe Binary files /dev/null and b/Documentation/images/angleCalc_2.png differ diff --git a/Documentation/images/areaCalc_1.png b/Documentation/images/areaCalc_1.png new file mode 100644 index 0000000..25b4c20 Binary files /dev/null and b/Documentation/images/areaCalc_1.png differ diff --git a/Documentation/images/areaCalc_2.png b/Documentation/images/areaCalc_2.png new file mode 100644 index 0000000..8fd6ffe Binary files /dev/null and b/Documentation/images/areaCalc_2.png differ diff --git a/Documentation/images/backgroundLayers.png b/Documentation/images/backgroundLayers.png new file mode 100644 index 0000000..44c7495 Binary files /dev/null and b/Documentation/images/backgroundLayers.png differ diff --git a/Documentation/images/biasGDS.png b/Documentation/images/biasGDS.png new file mode 100644 index 0000000..1f0b618 Binary files /dev/null and b/Documentation/images/biasGDS.png differ diff --git a/Documentation/images/biasGDS_area.png b/Documentation/images/biasGDS_area.png new file mode 100644 index 0000000..04b770f Binary files /dev/null and b/Documentation/images/biasGDS_area.png differ diff --git a/Documentation/images/calculation_time_by_type.png b/Documentation/images/calculation_time_by_type.png new file mode 100644 index 0000000..9445396 Binary files /dev/null and b/Documentation/images/calculation_time_by_type.png differ diff --git a/Documentation/images/chordCalc_1.png b/Documentation/images/chordCalc_1.png new file mode 100644 index 0000000..f16a148 Binary files /dev/null and b/Documentation/images/chordCalc_1.png differ diff --git a/Documentation/images/chordCalc_2.png b/Documentation/images/chordCalc_2.png new file mode 100644 index 0000000..7aba241 Binary files /dev/null and b/Documentation/images/chordCalc_2.png differ diff --git a/Documentation/images/chordCalc_3.png b/Documentation/images/chordCalc_3.png new file mode 100644 index 0000000..e2335e7 Binary files /dev/null and b/Documentation/images/chordCalc_3.png differ diff --git a/Documentation/images/chordCalc_4.png b/Documentation/images/chordCalc_4.png new file mode 100644 index 0000000..7b1262c Binary files /dev/null and b/Documentation/images/chordCalc_4.png differ diff --git a/Documentation/images/comparison_multithread.png b/Documentation/images/comparison_multithread.png new file mode 100644 index 0000000..69663b0 Binary files /dev/null and b/Documentation/images/comparison_multithread.png differ diff --git a/Documentation/images/contextmenu.png b/Documentation/images/contextmenu.png new file mode 100644 index 0000000..bf60ef6 Binary files /dev/null and b/Documentation/images/contextmenu.png differ diff --git a/Documentation/images/custom_RNG.png b/Documentation/images/custom_RNG.png new file mode 100644 index 0000000..c806d9e Binary files /dev/null and b/Documentation/images/custom_RNG.png differ diff --git a/Documentation/images/custom_RNG_applied.png b/Documentation/images/custom_RNG_applied.png new file mode 100644 index 0000000..1d84ddd Binary files /dev/null and b/Documentation/images/custom_RNG_applied.png differ diff --git a/Documentation/images/custom_RNG_menu.png b/Documentation/images/custom_RNG_menu.png new file mode 100644 index 0000000..28d8ec8 Binary files /dev/null and b/Documentation/images/custom_RNG_menu.png differ diff --git a/Documentation/images/distanceCalc_1.png b/Documentation/images/distanceCalc_1.png new file mode 100644 index 0000000..bbd3d85 Binary files /dev/null and b/Documentation/images/distanceCalc_1.png differ diff --git a/Documentation/images/distanceCalc_2.png b/Documentation/images/distanceCalc_2.png new file mode 100644 index 0000000..e05ddba Binary files /dev/null and b/Documentation/images/distanceCalc_2.png differ diff --git a/Documentation/images/distanceCalc_Filtering.png b/Documentation/images/distanceCalc_Filtering.png new file mode 100644 index 0000000..e2e0474 Binary files /dev/null and b/Documentation/images/distanceCalc_Filtering.png differ diff --git a/Documentation/images/distanceCalc_enclosure.png b/Documentation/images/distanceCalc_enclosure.png new file mode 100644 index 0000000..ac5d362 Binary files /dev/null and b/Documentation/images/distanceCalc_enclosure.png differ diff --git a/Documentation/images/distanceCalc_enclosure_overlap.png b/Documentation/images/distanceCalc_enclosure_overlap.png new file mode 100644 index 0000000..7f5132a Binary files /dev/null and b/Documentation/images/distanceCalc_enclosure_overlap.png differ diff --git a/Documentation/images/distanceCalc_wrongOrder.png b/Documentation/images/distanceCalc_wrongOrder.png new file mode 100644 index 0000000..7f3d8bb Binary files /dev/null and b/Documentation/images/distanceCalc_wrongOrder.png differ diff --git a/Documentation/images/distanceCalc_wrongOrder_shortestEdge.png b/Documentation/images/distanceCalc_wrongOrder_shortestEdge.png new file mode 100644 index 0000000..fe83891 Binary files /dev/null and b/Documentation/images/distanceCalc_wrongOrder_shortestEdge.png differ diff --git a/Documentation/images/filled_geometry.png b/Documentation/images/filled_geometry.png new file mode 100644 index 0000000..25b4c20 Binary files /dev/null and b/Documentation/images/filled_geometry.png differ diff --git a/Documentation/images/flippedH_center.png b/Documentation/images/flippedH_center.png new file mode 100644 index 0000000..caaca4c Binary files /dev/null and b/Documentation/images/flippedH_center.png differ diff --git a/Documentation/images/flipped_nocenter.png b/Documentation/images/flipped_nocenter.png new file mode 100644 index 0000000..e78be2e Binary files /dev/null and b/Documentation/images/flipped_nocenter.png differ diff --git a/Documentation/images/gds.png b/Documentation/images/gds.png new file mode 100644 index 0000000..7685a85 Binary files /dev/null and b/Documentation/images/gds.png differ diff --git a/Documentation/images/gdsDOE_1.png b/Documentation/images/gdsDOE_1.png new file mode 100644 index 0000000..c43da4c Binary files /dev/null and b/Documentation/images/gdsDOE_1.png differ diff --git a/Documentation/images/gdsDOE_2.png b/Documentation/images/gdsDOE_2.png new file mode 100644 index 0000000..f2c8ded Binary files /dev/null and b/Documentation/images/gdsDOE_2.png differ diff --git a/Documentation/images/gdsDOE_3.png b/Documentation/images/gdsDOE_3.png new file mode 100644 index 0000000..a3cc071 Binary files /dev/null and b/Documentation/images/gdsDOE_3.png differ diff --git a/Documentation/images/gdsDOE_layout.png b/Documentation/images/gdsDOE_layout.png new file mode 100644 index 0000000..ef6adeb Binary files /dev/null and b/Documentation/images/gdsDOE_layout.png differ diff --git a/Documentation/images/gds_contour.png b/Documentation/images/gds_contour.png new file mode 100644 index 0000000..0cf7e14 Binary files /dev/null and b/Documentation/images/gds_contour.png differ diff --git a/Documentation/images/gds_contour_merging.png b/Documentation/images/gds_contour_merging.png new file mode 100644 index 0000000..5ebc597 Binary files /dev/null and b/Documentation/images/gds_contour_merging.png differ diff --git a/Documentation/images/gds_contour_path.png b/Documentation/images/gds_contour_path.png new file mode 100644 index 0000000..e0d65b7 Binary files /dev/null and b/Documentation/images/gds_contour_path.png differ diff --git a/Documentation/images/geometric_equation.png b/Documentation/images/geometric_equation.png new file mode 100644 index 0000000..bf962c9 Binary files /dev/null and b/Documentation/images/geometric_equation.png differ diff --git a/Documentation/images/ilb_12bg.png b/Documentation/images/ilb_12bg.png new file mode 100644 index 0000000..0c88db6 Binary files /dev/null and b/Documentation/images/ilb_12bg.png differ diff --git a/Documentation/images/ilb_3.png b/Documentation/images/ilb_3.png new file mode 100644 index 0000000..99ec22c Binary files /dev/null and b/Documentation/images/ilb_3.png differ diff --git a/Documentation/images/ilb_keyhole.png b/Documentation/images/ilb_keyhole.png new file mode 100644 index 0000000..0269f4b Binary files /dev/null and b/Documentation/images/ilb_keyhole.png differ diff --git a/Documentation/images/ilb_keyhole_proxbias.png b/Documentation/images/ilb_keyhole_proxbias.png new file mode 100644 index 0000000..fc59f18 Binary files /dev/null and b/Documentation/images/ilb_keyhole_proxbias.png differ diff --git a/Documentation/images/ilb_noOmit12.PNG b/Documentation/images/ilb_noOmit12.PNG new file mode 100644 index 0000000..44a892f Binary files /dev/null and b/Documentation/images/ilb_noOmit12.PNG differ diff --git a/Documentation/images/ilb_no_keyhole.png b/Documentation/images/ilb_no_keyhole.png new file mode 100644 index 0000000..c0d1e08 Binary files /dev/null and b/Documentation/images/ilb_no_keyhole.png differ diff --git a/Documentation/images/ilb_omit12.png b/Documentation/images/ilb_omit12.png new file mode 100644 index 0000000..86a265e Binary files /dev/null and b/Documentation/images/ilb_omit12.png differ diff --git a/Documentation/images/ilb_tip_proxBias.PNG b/Documentation/images/ilb_tip_proxBias.PNG new file mode 100644 index 0000000..0cb9f99 Binary files /dev/null and b/Documentation/images/ilb_tip_proxBias.PNG differ diff --git a/Documentation/images/implant.png b/Documentation/images/implant.png new file mode 100644 index 0000000..87d5caf Binary files /dev/null and b/Documentation/images/implant.png differ diff --git a/Documentation/images/layerSettings_1.png b/Documentation/images/layerSettings_1.png new file mode 100644 index 0000000..d9dc9fa Binary files /dev/null and b/Documentation/images/layerSettings_1.png differ diff --git a/Documentation/images/layerSettings_2.png b/Documentation/images/layerSettings_2.png new file mode 100644 index 0000000..5a5ca6f Binary files /dev/null and b/Documentation/images/layerSettings_2.png differ diff --git a/Documentation/images/layerSettings_3.png b/Documentation/images/layerSettings_3.png new file mode 100644 index 0000000..a1b737b Binary files /dev/null and b/Documentation/images/layerSettings_3.png differ diff --git a/Documentation/images/layerSettings_4.png b/Documentation/images/layerSettings_4.png new file mode 100644 index 0000000..656bf05 Binary files /dev/null and b/Documentation/images/layerSettings_4.png differ diff --git a/Documentation/images/layerSettings_biasEtch.png b/Documentation/images/layerSettings_biasEtch.png new file mode 100644 index 0000000..a5cc19b Binary files /dev/null and b/Documentation/images/layerSettings_biasEtch.png differ diff --git a/Documentation/images/layerSettings_layoutOrigin.png b/Documentation/images/layerSettings_layoutOrigin.png new file mode 100644 index 0000000..3c34cec Binary files /dev/null and b/Documentation/images/layerSettings_layoutOrigin.png differ diff --git a/Documentation/images/layerSettings_rotation.png b/Documentation/images/layerSettings_rotation.png new file mode 100644 index 0000000..73cc33f Binary files /dev/null and b/Documentation/images/layerSettings_rotation.png differ diff --git a/Documentation/images/layerSettings_subShapes.png b/Documentation/images/layerSettings_subShapes.png new file mode 100644 index 0000000..7052093 Binary files /dev/null and b/Documentation/images/layerSettings_subShapes.png differ diff --git a/Documentation/images/layerSettings_tips.png b/Documentation/images/layerSettings_tips.png new file mode 100644 index 0000000..f0d2dc4 Binary files /dev/null and b/Documentation/images/layerSettings_tips.png differ diff --git a/Documentation/images/layerSettings_tips_2.png b/Documentation/images/layerSettings_tips_2.png new file mode 100644 index 0000000..f9b91c9 Binary files /dev/null and b/Documentation/images/layerSettings_tips_2.png differ diff --git a/Documentation/images/layout_export_1.png b/Documentation/images/layout_export_1.png new file mode 100644 index 0000000..b98db03 Binary files /dev/null and b/Documentation/images/layout_export_1.png differ diff --git a/Documentation/images/layout_export_2.png b/Documentation/images/layout_export_2.png new file mode 100644 index 0000000..2f928ea Binary files /dev/null and b/Documentation/images/layout_export_2.png differ diff --git a/Documentation/images/layout_export_3.png b/Documentation/images/layout_export_3.png new file mode 100644 index 0000000..df98ed5 Binary files /dev/null and b/Documentation/images/layout_export_3.png differ diff --git a/Documentation/images/lens_k1_0_k2_3.png b/Documentation/images/lens_k1_0_k2_3.png new file mode 100644 index 0000000..5ab656d Binary files /dev/null and b/Documentation/images/lens_k1_0_k2_3.png differ diff --git a/Documentation/images/lens_k1_1.3_k2_0.png b/Documentation/images/lens_k1_1.3_k2_0.png new file mode 100644 index 0000000..2dcdf06 Binary files /dev/null and b/Documentation/images/lens_k1_1.3_k2_0.png differ diff --git a/Documentation/images/lens_k1_1.3_k2_3.png b/Documentation/images/lens_k1_1.3_k2_3.png new file mode 100644 index 0000000..0f9a3f3 Binary files /dev/null and b/Documentation/images/lens_k1_1.3_k2_3.png differ diff --git a/Documentation/images/ler_preview_opensimplex.png b/Documentation/images/ler_preview_opensimplex.png new file mode 100644 index 0000000..feb57fb Binary files /dev/null and b/Documentation/images/ler_preview_opensimplex.png differ diff --git a/Documentation/images/ler_preview_perlin.png b/Documentation/images/ler_preview_perlin.png new file mode 100644 index 0000000..432c561 Binary files /dev/null and b/Documentation/images/ler_preview_perlin.png differ diff --git a/Documentation/images/ler_preview_perlin_lowFreqLayer1.png b/Documentation/images/ler_preview_perlin_lowFreqLayer1.png new file mode 100644 index 0000000..b551f10 Binary files /dev/null and b/Documentation/images/ler_preview_perlin_lowFreqLayer1.png differ diff --git a/Documentation/images/ler_preview_perlin_lowFreqLayer1_highFreqLayer2.png b/Documentation/images/ler_preview_perlin_lowFreqLayer1_highFreqLayer2.png new file mode 100644 index 0000000..6290c97 Binary files /dev/null and b/Documentation/images/ler_preview_perlin_lowFreqLayer1_highFreqLayer2.png differ diff --git a/Documentation/images/multipoly_flip.png b/Documentation/images/multipoly_flip.png new file mode 100644 index 0000000..475d4a2 Binary files /dev/null and b/Documentation/images/multipoly_flip.png differ diff --git a/Documentation/images/multipoly_flipValign.png b/Documentation/images/multipoly_flipValign.png new file mode 100644 index 0000000..af9c5bf Binary files /dev/null and b/Documentation/images/multipoly_flipValign.png differ diff --git a/Documentation/images/multipoly_rotation.png b/Documentation/images/multipoly_rotation.png new file mode 100644 index 0000000..3b86abc Binary files /dev/null and b/Documentation/images/multipoly_rotation.png differ diff --git a/Documentation/images/multipoly_rotation_perpoly.png b/Documentation/images/multipoly_rotation_perpoly.png new file mode 100644 index 0000000..3c4245d Binary files /dev/null and b/Documentation/images/multipoly_rotation_perpoly.png differ diff --git a/Documentation/images/overlap_ler.png b/Documentation/images/overlap_ler.png new file mode 100644 index 0000000..8502fac Binary files /dev/null and b/Documentation/images/overlap_ler.png differ diff --git a/Documentation/images/overlap_raytrace.png b/Documentation/images/overlap_raytrace.png new file mode 100644 index 0000000..13cdd92 Binary files /dev/null and b/Documentation/images/overlap_raytrace.png differ diff --git a/Documentation/images/overlap_raytrace_shortestEdge.png b/Documentation/images/overlap_raytrace_shortestEdge.png new file mode 100644 index 0000000..4ac0764 Binary files /dev/null and b/Documentation/images/overlap_raytrace_shortestEdge.png differ diff --git a/Documentation/images/pa_search.png b/Documentation/images/pa_search.png new file mode 100644 index 0000000..964a0a1 Binary files /dev/null and b/Documentation/images/pa_search.png differ diff --git a/Documentation/images/proxBias.png b/Documentation/images/proxBias.png new file mode 100644 index 0000000..7a9fb67 Binary files /dev/null and b/Documentation/images/proxBias.png differ diff --git a/Documentation/images/proxBias_LER.PNG b/Documentation/images/proxBias_LER.PNG new file mode 100644 index 0000000..be2a362 Binary files /dev/null and b/Documentation/images/proxBias_LER.PNG differ diff --git a/Documentation/images/rays_0.PNG b/Documentation/images/rays_0.PNG new file mode 100644 index 0000000..d004a7b Binary files /dev/null and b/Documentation/images/rays_0.PNG differ diff --git a/Documentation/images/rays_1.PNG b/Documentation/images/rays_1.PNG new file mode 100644 index 0000000..7d9b7c3 Binary files /dev/null and b/Documentation/images/rays_1.PNG differ diff --git a/Documentation/images/rays_2.PNG b/Documentation/images/rays_2.PNG new file mode 100644 index 0000000..4441c40 Binary files /dev/null and b/Documentation/images/rays_2.PNG differ diff --git a/Documentation/images/rays_4.PNG b/Documentation/images/rays_4.PNG new file mode 100644 index 0000000..f90078d Binary files /dev/null and b/Documentation/images/rays_4.PNG differ diff --git a/Documentation/images/replay.png b/Documentation/images/replay.png new file mode 100644 index 0000000..5bebb0f Binary files /dev/null and b/Documentation/images/replay.png differ diff --git a/Documentation/images/u_rays_0.PNG b/Documentation/images/u_rays_0.PNG new file mode 100644 index 0000000..ac79112 Binary files /dev/null and b/Documentation/images/u_rays_0.PNG differ diff --git a/Documentation/images/u_rays_1.PNG b/Documentation/images/u_rays_1.PNG new file mode 100644 index 0000000..404accd Binary files /dev/null and b/Documentation/images/u_rays_1.PNG differ diff --git a/Documentation/images/u_rays_2.PNG b/Documentation/images/u_rays_2.PNG new file mode 100644 index 0000000..9e7a385 Binary files /dev/null and b/Documentation/images/u_rays_2.PNG differ diff --git a/Documentation/images/u_rays_4.PNG b/Documentation/images/u_rays_4.PNG new file mode 100644 index 0000000..c15431e Binary files /dev/null and b/Documentation/images/u_rays_4.PNG differ diff --git a/Documentation/images/utilities.png b/Documentation/images/utilities.png new file mode 100644 index 0000000..c806d9e Binary files /dev/null and b/Documentation/images/utilities.png differ diff --git a/Documentation/images/versions/420.png b/Documentation/images/versions/420.png new file mode 100644 index 0000000..8deafef Binary files /dev/null and b/Documentation/images/versions/420.png differ diff --git a/Documentation/images/versions/_blank.png b/Documentation/images/versions/_blank.png new file mode 100644 index 0000000..395be91 Binary files /dev/null and b/Documentation/images/versions/_blank.png differ diff --git a/Documentation/implant.html b/Documentation/implant.html new file mode 100644 index 0000000..418f5de --- /dev/null +++ b/Documentation/implant.html @@ -0,0 +1,181 @@ + + + + +Variance - Reference + + + + + +

Overview of Implant calculation

+

This is a tilted implant shadowing calculation system. It currently does not account for corner rounding in the resist other than the top corner rounding of the resist profile. The contour is generated from the internal shape engine.

+ +

The preview state shows the mean, minimum and maximum shadowing for the nominal resist contour (i.e. the implant 3-sigma is applied to the mean as appropriate). The Monte Carlo system evaluates all sources of variation and determines the mean and standard deviation.

+

The majority of the controls are self-explanatory, especially when one is already familiar with the multi-layer Monte Carlo system. Note that linear resolution values are not available because shadowing is a result of interaction with corners. Accuracy is therefore directly dependent on the corner resolution, which is defined by the corner segment value. Higher values yield a greater resolution.

+

The summary file output will report the effective resolution (i.e. edge resolution / accuracy, angular resolution / accuracy). You can also choose to export CSV and/or SVG output files, just like in the multilayer Monte Carlo system. Electing to save SVGs will cause considerable memory consumption during the run as the geometry is stored rather than cleared. The CSV is essentially free-of-cost, except for the time taken to write the file to disk at the end of the run.

+

Please consider that 90 degree tilt conditions (through variation) will result in an infinite shadow being cast. This condition is not ignored and will result in your entire run having an infinite mean and invalid standard deviation. You should ensure that your implant conditions do not cause this to arise.

+ + diff --git a/Documentation/implementations.html b/Documentation/implementations.html new file mode 100644 index 0000000..451d817 --- /dev/null +++ b/Documentation/implementations.html @@ -0,0 +1,285 @@ + + + + +Variance - Reference + + + + + +

Implementations

+ +

Eto.Forms

+

This is used to provide a UI from a common code-base for the tool. The images below are indicative of the user interface, with some notes about issues/limitations where applicable.

+
+ +

WPF

+

Known issues:

+
    +
  • None.
  • +
+ + + + + + + + + +
+ + + +
+ +
+ +

Mac

+

Known issues:

+
    +
  • At least 2x worse performance compared to Windows, due to platform issues.
  • +
+ + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + +
+ +

GTK2

+

Known issues:

+
    +
  • The user interface under GTK2 has opaque backgrounds to labels that look a little odd
  • +
  • At least 2x worse performance compared to Windows, due to platform issues.
  • +
+ + + + + + + + + +
+ + +
+ + + +
+
+ +

Headless Mode

+

The headless executable runs in a console and suits systems with no compatible GUI system. It expects a project file as an argument. This project file will be loaded and the simulation evaluated without further action. Output will be to a CSV file named after the project file. Memory usage is slightly lower and simulations run in ~10% less time due to reduced overhead.

+
+
    +
  • --1thread : specifics only a single thread should be used.
  • +
  • --implant : lets the tool know the project file should be used to run an implant simulation.
  • +
  • --email (file) : reads email settings from the file specified.
  • +
  • --emailPerJob : tells system to send email per job (requires valid configuration from --email).
  • +
  • --emailOnCompletion : tells system to send email per batch (requires valid configuration from --email).
  • +
+
+ +
+

Email Configuration

+

The headless system supports email notification. Configuration is through a mix of commandline arguments and a text file-based list of settings. The settings text file is to be specified as a parameter to the --email argument and should be of the form below. If ssl is omitted, a secure email connection will not be used. A configuration file is used to avoid parameters being observable in the process list of the host system (e.g. the password).

+ +

+ address : myemail@gmail.com
+ password : mypassword
+ server: smtp.gmail.com
+ port: 785
+ ssl
+

+
+ + + diff --git a/Documentation/index.html b/Documentation/index.html new file mode 100644 index 0000000..0bdc3b0 --- /dev/null +++ b/Documentation/index.html @@ -0,0 +1,16 @@ + + +Variance Documentation + + + + + + + + + + + + + diff --git a/Documentation/license_overview.html b/Documentation/license_overview.html new file mode 100644 index 0000000..3fa7e3f --- /dev/null +++ b/Documentation/license_overview.html @@ -0,0 +1,328 @@ + + + + +Variance - Licence + + + + +

License

+

GNU Public License v3

+

TERMS AND CONDITIONS

+

0. Definitions.

+

“This License” refers to version 3 of the GNU General Public License.

+ +

“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.

+ +

“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.

+ +

To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.

+ +

A “covered work” means either the unmodified Program or a work based on the Program.

+ +

To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.

+ +

To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.

+ +

An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.

+ +

1. Source Code.

+

The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.

+ +

A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.

+ +

The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.

+ +

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.

+ +

The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.

+ +

The Corresponding Source for a work in source code form is that same work.

+ +

2. Basic Permissions.

+

All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.

+ +

You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.

+ +

Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

+ +

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

+

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.

+ +

When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.

+ +

4. Conveying Verbatim Copies.

+

You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.

+ +

You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.

+ +

5. Conveying Modified Source Versions.

+

You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:

+ +

a) The work must carry prominent notices stating that you modified it, and giving a relevant date.

+

b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.

+

c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.

+

d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.

+

A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

+ +

6. Conveying Non-Source Forms.

+

You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:

+ +

a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.

+

b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.

+

c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.

+

d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.

+

e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.

+

A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.

+ +

A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.

+ +

“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.

+ +

If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).

+ +

The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.

+ +

Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.

+ +

7. Additional Terms.

+

“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.

+ +

When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.

+ +

Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:

+ +

a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or

+

b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or

+

c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or

+

d) Limiting the use for publicity purposes of names of licensors or authors of the material; or

+

e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or

+

f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.

+

All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.

+ +

If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.

+ +

Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.

+ +

8. Termination.

+

You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).

+ +

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

+ +

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

+ +

Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.

+ +

9. Acceptance Not Required for Having Copies.

+

You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.

+ +

10. Automatic Licensing of Downstream Recipients.

+

Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.

+ +

An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

+ +

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.

+ +

11. Patents.

+

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.

+ +

A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.

+ +

Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

+ +

In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.

+ +

If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

+ +

If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.

+ +

A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.

+ +

Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

+ +

12. No Surrender of Others' Freedom.

+

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.

+ +

13. Use with the GNU Affero General Public License.

+

Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.

+ +

14. Revised Versions of this License.

+

The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

+ +

Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.

+ +

If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

+ +

Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.

+ +

15. Disclaimer of Warranty.

+

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

+ +

16. Limitation of Liability.

+

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

+ +

17. Interpretation of Sections 15 and 16.

+

If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.

+ +

END OF TERMS AND CONDITIONS

+ + + diff --git a/Documentation/licenses_acknowledgements.html b/Documentation/licenses_acknowledgements.html new file mode 100644 index 0000000..7f0de0b --- /dev/null +++ b/Documentation/licenses_acknowledgements.html @@ -0,0 +1,310 @@ + + + + +Variance - Reference + + + + +

Licenses

+ +

ClipperLib

+

Copyright © 2010-2019 Angus Johnson.

+

Boost Software License 1.0 (BSL-1.0)

+

Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following:

+

The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ + +

KDTree

+

The MIT License (MIT)

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ + +

Mersenne Twister

+

Artistic License 1.0

+

Preamble

+

The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications.

+

Definitions:

+

"Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification.

+

"Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below.

+

"Copyright Holder" is whoever is named in the copyright or copyrights for the package.

+

"You" is you, if you're thinking about copying or distributing this Package.

+

"Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.)

+

"Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it.

+

1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers.

+

2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version.

+

3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following:

+

a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package.

+

b) use the modified Package only within your corporation or organization.

+

c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version.

+

d) make other distribution arrangements with the Copyright Holder.

+

4.You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following:

+

a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version.

+

b) accompany the distribution with the machine-readable source of the Package with your modifications.

+

c) give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version.

+

d) make other distribution arrangements with the Copyright Holder.

+

5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package's interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded.

+

6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whoever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called "undump" or "unexec" methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package.

+

7. C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language.

+

8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package.

+

9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission.

+

10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

+

The End

+ + +

LibTessDotNet

+

Copyright © 2012-2019 Rémi Gillig

+

SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)

+

Copyright © 2011 Silicon Graphics, Inc.

+

All Rights Reserved.

+

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice including the dates of first publication and either this permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+

Except as contained in this notice, the name of Silicon Graphics, Inc. shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Silicon Graphics, Inc.

+ + +

Eto.Forms

+

AUTHORS

+

Copyright © 2011-2015 Curtis Wensley. All Rights Reserved.

+

Copyright © 2012-2013 Vivek Jhaveri. All Rights Reserved.

+ +

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

+ +

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

+

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

+

3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.

+

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ + +

Eto.Veldrid

+

Copyright © 2019 Robert Martens

+

The MIT License (MIT)

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ + +

MathParser

+

Patrik Lundin, http://www.lundin.info Copyright © 2002-2016 Patrik Lundin

+

Microsoft Public License (MS-PL)

+ +

This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.

+ +

1. Definitions

+

The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.

+

A "contribution" is the original software, or any additions or changes to the software.

+

A "contributor" is any person that distributes its contribution under this license.

+

"Licensed patents" are a contributor's patent claims that read directly on its contribution.

+ +

2. Grant of Rights

+

(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.

+

(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.

+ +

3. Conditions and Limitations

+

(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.

+

(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.

+

(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.

+

(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.

+

(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.

+ + +

"Miscellaneous Utility Library" Software Licence

+ +

Version 1.0

+ +

Copyright © 2004-2008 Jon Skeet and Marc Gravell.

+

All rights reserved.

+ +

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

+ +

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

+

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

+

3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment:

+ +

"This product includes software developed by Jon Skeetand Marc Gravell. Contact skeet@pobox.com, or see http://www.pobox.com/~skeet/)."

+ +

Alternately, this acknowledgment may appear in the software itself,if and wherever such third-party acknowledgments normally appear.

+ +

4. The name "Miscellaneous Utility Library" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact skeet@pobox.com.

+ +

5. Products derived from this software may not be called "Miscellaneous Utility Library", nor may "Miscellaneous Utility Library" appear in their name, without prior written permission of Jon Skeet.

+ +

THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ + +

QLicense

+ +

The MIT License (MIT)

+ +

Copyright © 2015-2016 TonyTonyQ

+ +

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+ +

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+ +

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ + + diff --git a/Documentation/main.html b/Documentation/main.html new file mode 100644 index 0000000..07060d4 --- /dev/null +++ b/Documentation/main.html @@ -0,0 +1,344 @@ + + + + +Variance - Reference + + + +

Variance (4.2)

+
+

Phil Stopford

+
+ +

Introduction

+
+

Variance is a production-proven, high performance geometrical variation study engine, using Monte Carlo approaches. One area of focus is the definition of ground rules for semiconductor processes.

+

Variance writes out result summaries and, optionally, CSV files and/or SVG images that can be reviewed to understand the results of runs. Mean and standard deviation readouts are displayed during runs. The CSV files lend themselves to use in JMP or similar, and can be used with the project file directly in the tool to inspect specific cases from a run.

+

DOE summaries can also be created for easier review.

+
+ +

Features

+
+ +

Basic Calculations

+
+
    +
  • 1D calculation system with 'n' sigma output
  • +
+
+ +

Implant Calculations

+
+
    +
  • Advanced shadowing Monte Carlo engine for tilted implants.
  • +
+
+
+
+ +

Fast, efficient workflow

+
+

Simulation input:

+
    +
  • Define your input shapes, or use external layout files.
  • +
      +
    • Copy/paste layer settings, and background layer display make set-up very simple.
    • +
    • External layout support is extensive:
    • +
        +
      • GDS and Oasis, uncompressed.
      • +
      • Layout geometry can be used to drive contour generation.
      • +
      • Layout geometry can be updated from the file on-disk when the project is loaded.
      • +
      • Hierarchical layout is supported.
      • +
      • Pattern generator derived layout can be used in DOE configurations.
      • +
      +
    • Layer shape can be defined using a Boolean of two other layers, including the results of another Boolean.
    • +
        +
      • Further enhanced support for keyholing (one or more cutters fully enclosed within another polygon), including handling of pre-existing keyholes.
      • +
      • Auto-removal of interior walls (keyholes) at input to simulation engine pipeline.
      • +
      +
    +
  • Extensive range of shape definition parameters:
  • +
      +
    • Shapes are defined using subshapes (rectangles).
    • +
    • Each subshape has arbitrary tip definitions, allowing for selective adjustment of specific edges.
    • +
    • Composite shape has additional controls
    • +
        +
      • Independent side and tip biasing.
      • +
      • Independent convex and concave corner rounding.
      • +
      +
    • Shape flipping (H/V, re-center).
    • +
    • Edge tension model to reproduce line narrowing.
    • +
    • Pitch effect biasing, iPitch effect biasing, including keyholed geometry.
    • +
    +
  • Define your variations and type of variation (default is Gaussian, but custom distributions per-variation are supported.)
  • +
      +
    • Independent tip and side CDU variation.
    • +
    • Independent tip and side bias variation.
    • +
    • Independent horizontal and vertical tip variation, including asymmetry.
    • +
    • Independently link variation sources together between any input layers, if desired.
    • +
        +
      • X overlay, Y overlay, side CDU and tip CDU are all independently configurable.
      • +
      • Side and tip CDU variation can be linked, globally, if desired.
      • +
      +
    • Make X, Y overlay variations relative to one or more layers, if desired.
    • +
    • Line edge roughness.
    • +
    • Lens distortion : short and long range, pincushion/barrel distortion.
    • +
    • Wobble (rotational variation)
    • +
    +
  • Export of the layer contours to GDSII or Oasis is available, now also from within any viewport.
  • +
+

Simulation Configuration:

+

If you know the variations and want to evaluate them:

+
    +
  • Choose your calculation mode : area, chords, overlap/spacing, intersection angle.
  • +
  • Set up the number of cases to evaluate.
  • +
  • Summary file is always showing inputs and outputs for a given simulation.
  • +
  • Choose whether to output the full set of run data to CSV (important for replaying simulations).
  • +
      +
    • Export to CSV is now fully multithreaded, so runs much faster than before.
    • +
    +
  • Support for outputting simulation geometry to GDSII, Oasis, or SVG (SVG was only option prior to this release).
  • +
      +
    • Export of the geometry now happens during the run, eliminating the memory overhead (at the cost of runtime increase).
    • +
    +
  • Set up your arbitrary layer relationships to define the calculation.
  • +
      +
    • For example, [(layer 1) AND NOT (layer 2)] AND [layer 9 OR layer 10)]
    • +
    +
  • Run the simulation.
  • +
      +
    • Runtime is reduced (where possible) through adaptive geometry decimation.
    • +
    +
+

If you want to review certain results in depth, use the replay system to look at specific cases.

+

If you want to find variations that permit the desired result, use PA Search:

+
    +
  • Set up the layers and simulation as usual, then use this mode to scope out values for the 'unknown' variations.
  • +
  • Tag one or more variation fields on any active layer(s) in the simulation, with limits on the search radius of values.
  • +
  • Define pass criteria based on calculation type for min/max screening of results fields.
  • +
+

User interface:

+
    +
  • Consistent, multi-platform GUI (Windows, Mac, Linux).
  • +
      +
    • User interface is resizable.
    • +
    • Native platform look-and-feel is preserved, rather than modified, on macOS and Linux (GTK).
    • +
    +
  • Large modern viewport used throughout:
  • +
      +
    • The optimal framework is automatically used on the platform being used (Vulkan, OpenGL, Direct3D, Metal). If desired, this can be overridden.
    • +
    • Drag and cursor key navigation
    • +
    • Wheel and key zoom
    • +
    • Customizable preferences (colors, zoom, antialiasing, opacity, fill).
    • +
    • Save the view to SVG file.
    • +
    • Background layers : see your other layers' contours in the current layer.
    • +
    +
  • Add comments to layers, DOE and simulation settings for documentation.
  • +
+
+
+
+ +

Other

+
+
    +
  • E-mail notification (per-run / job).
  • +
  • Ability to batch-generate summary files of DOEs.
  • +
  • Headless binary (no GUI at all), to permit automation
  • +
+
+
+
+ +

Code

+
+
    +
  • Avoidance of home-brew code for fundamentals, where possible - rely on proven systems.
  • +
  • Core is cross-platform via .NET Core framework (should be 3.1 for best results). Mono is no longer needed.
  • +
      +
    • Headless is neutral.
    • +
    +
+
+
+ + + diff --git a/Documentation/mc_image.png b/Documentation/mc_image.png new file mode 100644 index 0000000..f6f9596 Binary files /dev/null and b/Documentation/mc_image.png differ diff --git a/Documentation/montecarlo.html b/Documentation/montecarlo.html new file mode 100644 index 0000000..ab887f7 --- /dev/null +++ b/Documentation/montecarlo.html @@ -0,0 +1,197 @@ + + + + +Variance - Reference + + + + + +

Overview of Monte Carlo System

+

The calculation system is intended to work between two inputs in terms of source shape data. Given the number of layers and permutations offered by the system, let's group the inputs:

+
    +
  • A1: layer 1, layer 2, layer 3, layer 4
  • +
  • A2: layer 5, layer 6, layer 7, layer 8
  • +
  • B1: layer 9, layer 10, layer 11, layer 12
  • +
  • B2: layer 13, layer 14, layer 15, layer 16
  • +
+

and

+
    +
  • A: A1, A2
  • +
  • B: B1, B2
  • +
+

For a simulation to be possible, you need to have A and B enabled. That means you need at least one active layer in A1 or A2, and one active layer in B1 or B2.

+

Consider, for example, (PC not CT) over RX. PC and CT could be defined in any of the A1 or A2 layers with a Boolean to cut the PC with the CT mask. RX could then be in any of the B1 or B2 layers.

+ + + diff --git a/Documentation/montecarlo_customRNGMapping.html b/Documentation/montecarlo_customRNGMapping.html new file mode 100644 index 0000000..199bfcd --- /dev/null +++ b/Documentation/montecarlo_customRNGMapping.html @@ -0,0 +1,232 @@ + + + + +Variance - Reference + + + + + +

Custom RNG Mapping

+

+ +

By default, Variance uses a Gaussian distribution for its inputs. This is achieved by mapping a uniform distribution into a Gaussian, through application of the Box-Muller transform. You can, however, choose to define a custom mapping equation and apply it to as many inputs as you like.

+

Some notes about custom mapping:

+
    +
  • Custom mapping equations within the project will be written in-full to the project file, and also recorded in output summary files.
  • +
  • Custom mapping equations will be loaded from project files, and added to the internal list. They will remain available for use in other projects until manually deleted (in the Utils tab).
  • +
  • Input parameters set to use a custom mapping equation will have red labels in the UI, to make review easier.
  • +
  • Use of custom mapping will disable standard-deviation reporting in the UI during simulation runs, including PA search.
  • +
  • Use of custom mapping will require offline analysis (through the CSV output option) to understand the distribution of results.
  • +
+ +

+ +

Adding/Editing/Removing Equations

+ +

+ +

Custom mapping equations are entered into, or removed from, the system under the Utils tab. The equations are then available for selection by double-clicking on the label in the user interface (next to the numeric field), which will cause a menu to be displayed listing the available equations.

+ +

The underlying uniformally distributed RNG is available for access through several independent variables (i.e. they are independent calls to the RNG): x, y, z. In this way, you can reproduce the Box-Muller transform with :

+ +

sqrt(-2 * ln(y)) * cos(2 * PI * x)

+ +

This is the unscaled form; if you were working with 3 sigma normal inputs, you would need to compensate with a /3.0

+ +

For convenience, there are also three unscaled Box-Muller transformations (_gxy, _gyz, _gxz) available for use in the expression:

+
    +
  • _gxy == (sqrt(-2 * ln(y)) * cos(2 * PI * x))
  • +
  • _gyz == (sqrt(-2 * ln(z)) * cos(2 * PI * y))
  • +
  • _gxz == (sqrt(-2 * ln(z)) * cos(2 * PI * x))
  • +
+ +

When adding an equation, the tool will validate the entry. Errors must be rectified before the equation can be added. Only unique equations will be added - duplicates will be silently ignored.

+ +

Supported operators and functions

+

+, -, *, /, ^, %

+

^ is raised to (power) for example 3^2

+

% is the modulo operator

+ +

sqrt, sin, cos, tan, atan, acos, asin, acotan, exp, ln, log, sinh, cosh, tanh, abs, ceil, floor, fac, sfac, round, fpart. fac, sfac are factorial and semi-factorial functions. fpart returns the decimal part of a value.

+ +

!, ==, !=, ||, &&, >, < , >=, <= : Logical operators, 1.0 means true, 0.0 means false. If an expression evaluates to anything other than 1.0 it is considered false.

+ +

Supported constants

+

PI

+

Euler

+

false (0.0)

+

infinity

+ + + diff --git a/Documentation/montecarlo_doe.html b/Documentation/montecarlo_doe.html new file mode 100644 index 0000000..9428b6b --- /dev/null +++ b/Documentation/montecarlo_doe.html @@ -0,0 +1,197 @@ + + + + +Variance - Reference + + + + + +

DOE

+ +

Layers that are using GDS or Oasis for input will have a 'use for DOE' checkbox in their settings.

+

The offset values allow you to define the lower left corner position of the first tile of interest, with respect to the 0,0 world position.

+

‘Use Specific Tiles’ allows you to use the described syntax to define which tiles should be evaluated.

+

‘Use iDRM CSV’ allows you to load in an iDRM CSV file and the tool will then automatically run all pass tiles for the simulation.

+

‘Use Quilt CSV’ allows you to load in a CSV file from the Quilt pattern generator. This will automatically configure the DOE grid to match the Quilt output.

+ +

By default, the system will work from the origin, and the DOE layout is expected to have its lower left corner at the origin. Negative column and row offsets are supported. The lower left corner of the extracted tile is repositioned at the world origin for the simulation, so you can configure interacting shapes without worrying about the location of the DOE tile.

+

The system will run the simulations configured for each tile in each row, running from left to right. At the time of writing, the user has the option to denote one specific tile (row/column combination) in the DOE layout for evaluation instead of the full set of tiles. For the settings shown earlier, with the specific tile set, the simulation result looks like this.

+

Duplicated polygons in the same layer are ignored during tile extraction; partial overlaps between polygons are resolved with a Union() operation to create a single polygon island of the final shape. The DOE tile can be contoured using the shape engine as well.

+ +

Assuming CDU/biasing is enabled, the tile extraction is performed before biasing/CDU and subsequent overlap resolution.

+

Note that the layer panel previews can be configured to show the full DOE layout or the extracted tile.

+ + + + diff --git a/Documentation/montecarlo_layerSettings.html b/Documentation/montecarlo_layerSettings.html new file mode 100644 index 0000000..fafeca9 --- /dev/null +++ b/Documentation/montecarlo_layerSettings.html @@ -0,0 +1,192 @@ + + + + +Variance - Reference + + + + + +

Layer settings

+ +

Most of these should be self-explanatory in terms of Process Assumption derived inputs. Note that some inputs are per-shape and others are per-edge. The labels indicate the case.

+

Note that the ‘Enabled’ button is what makes the layer available to the simulation or not. The button will not be available until both the horizontal length and vertical length of Sub-Shape 1 are defined. We’ll cover sub-shapes shortly. For now, we’ll keep it simple. Once you enter a length and width, and select ‘rectangle/square’ from the wide drop-down menu, you will see the preview contains a rectangle with the given dimensions.

+ +

You’ll also notice that for a default zoom of 1.0, each grid line in the preview is 10 nm. Note that you can zoom the viewport with the mouse wheel, but the zoom value on the panel won’t change – this is by-design, to allow you to manually reset the zoom.

+

Enabling the layer with some outer corner rounding, the preview will show the new shape. Note that the preview shows the nominal case. Variation values are applied for the simulation itself.

+ +

With the layer enabled, the ‘show drawn’ checkbox becomes available. Setting this on will allow you to see the drawn shape at the same time as the derived shape.

+ + + + diff --git a/Documentation/montecarlo_layerSettings_LOP.html b/Documentation/montecarlo_layerSettings_LOP.html new file mode 100644 index 0000000..467cc12 --- /dev/null +++ b/Documentation/montecarlo_layerSettings_LOP.html @@ -0,0 +1,195 @@ + + + + +Variance - Reference + + + + +
+ +

Layout Origin Parameters

+

For all shape types, the sub-shape reference menu is available. For basic shapes (and GDS or Oasis), only 1 entry is available and so this menu is not useful. For complex shapes that have multiple sub-shapes, you can choose the sub-shape to use. The ‘position inside sub-shape’ menu will then place the chosen region of that sub-shape at the origin of the simulation world.

+ +

In addition to this, you can then apply an offset in the horizontal and vertical directions.

+

Rotation is also supported, and is applied counter-clockwise.

+ +

Rotation is also correctly applied in the multi-polygon contour case.

+ +

Per-polygon rotation is also available (also applies to wobble). Overlaps from rotation are merged.

+ +
+ + + + diff --git a/Documentation/montecarlo_layerSettings_bglayers.html b/Documentation/montecarlo_layerSettings_bglayers.html new file mode 100644 index 0000000..dd4bbbc --- /dev/null +++ b/Documentation/montecarlo_layerSettings_bglayers.html @@ -0,0 +1,192 @@ + + + + +Variance - Reference + + + + +
+ +

Background Layers

+
    +
  • This is purely a viewport effect - the background layers are not included in the current layer's input to the simulation.
  • +
  • The drawing of background layers is not affected by the flip options in the active layer.
  • +
  • The implementation works with DOE layers (foreground and background)
  • +
  • It is supported by copy/paste and also load/save of project files.
  • +
+

+
+ + + diff --git a/Documentation/montecarlo_layerSettings_biasEtch.html b/Documentation/montecarlo_layerSettings_biasEtch.html new file mode 100644 index 0000000..155021a --- /dev/null +++ b/Documentation/montecarlo_layerSettings_biasEtch.html @@ -0,0 +1,241 @@ + + + + +Variance - Reference + + + + +
+ +

Bias and Etch Parameters

+

Side bias is applied to all sides of the shape that are not defined as tips.

+

Note that tips have a variation on their bias. The variation is split to permit positive and negative maximum variation values. Internally, a variation type random number for each type generated. A value < 0.5 causes a negative tip variation to be applied, otherwise a positive variation is applied. The variation is correlated if the tip and side CDU is correlated.

+ +

Proximity dependent bias is evaluated for each point on the layer. It is assessed after all other dimensional variations are applied (CDU, LER/LWR). For each point, a visibility calculation is performed. The initial ray is cast along the point's normal. The system also permits additional rays to be cast to the side. These rays are emitted at increments of (90 / number of side rays). Increasing the number of rays yields a more accurate result, but increases the calculation time for the shape. Note, as below, that keyholed geometry may result due to overlaps. This keyholed representation is required for some of the calculation approaches to work successfully. The keyhole is positioned to minimize mathematical errors in each case.

+ + + + + + + + + +
+ + + +
+ + + +
+

Note that artifacts and asymmetry can arise from insufficient rays being used, as shown below. Work continues to improve the algorithm, but this is something to be aware of in the current approach.

+ + + + + + + + + +
+ + + +
+ + + +
+

As noted earlier, keyholed geometry is created in case of fully enclosed holes in the geometry. Using keyholed geometry in conjunction with proximity biasing may result in artifacts around the keyhole region, arising from the complex geometry. Also, note also that the keyhole insertion may be different from any evident in the 'drawn' case in these situations, arising from internal attempts to reduce mathematical errors.

+

Please also refer to the order-of-operations section to understand how lens distortion, proximity biasing and LER are applied in combination.

+ +
+ +
+
+

GDS/Oasis Note

+

Side CDU can be enabled for GDS/Oasis shapes, but should only be used with care. Biasing is performed uniformally to increase or decrease the shape boundary. This may not reflect the OPC contours (process) and could also lead to algorithm fails in case of self-intersections. A preference is available to enable/disable this setting for this type of geometry; projects loaded with side CDU for these types of layers will override this preference if it is off.

+

An effort is made to handle self-intersections (as shown below). The polygon fill type menu (defaulting to 'non-zero') allows for adjustments, but 'non-zero' will usually be correct. Note that there is no guarantee that the result will work with all calculation modes, however.

+

The keyholes generated from the overlap processing are also evident in the images below.

+ +

 

+ +
+
+ + + diff --git a/Documentation/montecarlo_layerSettings_boolean.html b/Documentation/montecarlo_layerSettings_boolean.html new file mode 100644 index 0000000..19689cd --- /dev/null +++ b/Documentation/montecarlo_layerSettings_boolean.html @@ -0,0 +1,204 @@ + + + + +Variance - Reference + + + + +
+
+ +

Boolean

+

In Boolean mode, you can set up an arbitrary Boolean equation from two active layers. The input layers include variations during simulation, and the output of the Boolean will see its own variations applied. An example scenario would be the reproduction of a spacer deposition pitch effect on a grating that has been processed with a cut mask. You could define the grating in layer 1, and the cut mask in layer 2. Layer 3 could then be (layer 1 NOT layer 2), and you could then apply the proximity biasing for the spacer deposition in layer 3.

+

Some notes:

+
    +
  • Layers feeding a Boolean need to be enabled.
  • +
  • LWR/LER from input layers is not previewed in the Boolean layer unless 'show' is set on the input layer(s). This allows for respective contributions to be configured and visualized.
  • +
  • There are a number of complex scenarios that arise with Booleans, including limitations on contouring the solution. An overview is provided here.
  • +
+

+

+

The resulting geometry is available for contouring as usual. Note that the contouring pipeline is the same as for geoCore contouring, with the same limitations regarding orthogonal shapes for biasing of tips. Proximity biasing, etc. are all fully supported.

+

+ +

Layers that are enabled and referenced in Booleans can, and usually should, be omitted from the simulation. This is configured using the checkboxes.

+

+

+ +
+
+ + + + diff --git a/Documentation/montecarlo_layerSettings_edgeSlide.html b/Documentation/montecarlo_layerSettings_edgeSlide.html new file mode 100644 index 0000000..1c9f7f0 --- /dev/null +++ b/Documentation/montecarlo_layerSettings_edgeSlide.html @@ -0,0 +1,191 @@ + + + + +Variance - Reference + + + + +
+ +

Edge Slide

+

The midpoint of edges can slide according to a sigmoid function based on the previous and next edge length ratios. The tension value governs the amount of slide for a given ratio - a 1:1 ratio will always put the midpoint in the centre of the edge.

+ +

 

+ +

 

+ +
+ + + diff --git a/Documentation/montecarlo_layerSettings_export.html b/Documentation/montecarlo_layerSettings_export.html new file mode 100644 index 0000000..883aeed --- /dev/null +++ b/Documentation/montecarlo_layerSettings_export.html @@ -0,0 +1,204 @@ + + + + +Variance - Reference + + + + +
+ +

Export to Layout

+

Export to layout allows the user to export the contours of the selected layer to a layout file. Drawn polygons are not exported. In the resulting file dialog, the export format can be selected (GDSII or Oasis) and a name provided. The contours for the layer will then be exported. The resulting layout file will have a 0.01 nm grid and the points are placed as closely matched to the Variance internal representation as possible (given that the layout files require points on a grid, where Variance has no such internal limitation).

+ + + + + + + + + +
+ + +
+ + + +
+

Contours with more than 8000 points on a polygon may fail to export due to format limitations.

+
+ + + diff --git a/Documentation/montecarlo_layerSettings_flip.html b/Documentation/montecarlo_layerSettings_flip.html new file mode 100644 index 0000000..f1de11b --- /dev/null +++ b/Documentation/montecarlo_layerSettings_flip.html @@ -0,0 +1,193 @@ + + + + +Variance - Reference + + + + +
+ +

Flip

+

Options are available to flip the shape horizontally and/or vertically as well as re-centering the flipped shape on to the drawn shape.

+ +

 

+ +

The flip options also work correctly with multi-polygon contour layers.

+ +

 

+ +
+ + + diff --git a/Documentation/montecarlo_layerSettings_geoCore.html b/Documentation/montecarlo_layerSettings_geoCore.html new file mode 100644 index 0000000..a7d82dd --- /dev/null +++ b/Documentation/montecarlo_layerSettings_geoCore.html @@ -0,0 +1,197 @@ + + + + +Variance - Reference + + + + +
+
+ +

GDS / Oasis

+

These modes eliminate the subshape setting. You can choose the cell and layer/datatype combination. You can add the layer to the DOE system, and also apply the layout configuration to all other layers in the tool using the displayed controls.

+ +

The contour option feeds the internal shape engine with the geometry from the layout file. This permits tips, corner rounding, etc. to be applied to each individual polygon in the layout file.

+ +

Polygons are not merged until after contouring has been applied : the input geometry is faithful to the GDS/Oasis source data set.

+ +

Contouring can also be used with polygons derived from paths in layout files.

+ +

Checking the 'reference' box will set the project to look for the layout file on re-load. If no file is found, a warning will be reported and the baked geometry in the project file will be used. If a layout file is found, it will be read in. The layout file will be queried for the same structure and layer/datatype combination. If either is not found, the baked geometry in the project file will be used. Assuming matching entries are found, the geometry from the layout will be used in preference to the baked geometry. This allows for a project file to be used in regression testing scenarios.

+
+
+ + + + diff --git a/Documentation/montecarlo_layerSettings_litho.html b/Documentation/montecarlo_layerSettings_litho.html new file mode 100644 index 0000000..d0aa574 --- /dev/null +++ b/Documentation/montecarlo_layerSettings_litho.html @@ -0,0 +1,214 @@ + + + + +Variance - Reference + + + + +
+ +

Lithography Parameters

+

The corner rounding definitions should be fairly obvious. LWR is per-shape and is currently mapped to LER based on the simulation setting option (LWR/2 or LWR/sqrt(2)). There are several noise methods available (Perlin, Simplex, OpenSimplex) with configurable freqency. To see the nominal LER, the 'Show' checkbox can be set.

+ +

 

+ + +

Two layers of noise can be applied, allowing a low frequency noise to be modified by a high frequency noise.

+ +

 

+ + +

Overlay is a global overlay unless you choose a reference layer in the basic case. You can also use the 'Av' (for average) checkbox to allow multiple layers to be referenced. In this situation, the average overlay value of the reference layers is used as the reference position for positioning the active layer.

+

Correlation options are available to link the variation value between layers. This means that the random number value(s) for overlay and/or CDU from the correlated layer(s) will be used to evaluate the overlay and CDU of this layer. For the same overlay and CDU 3-sigma inputs, the correlated shapes will be linked. Choosing ‘0’ means no correlation in each case.

+

As noted, LWR to LER conversion methodology is user-selectable. Choices are LER = LWR/2 or LER = LWR/sqrt(2).

+

Wobble describes the 3-sigma rotational variation of the shape. This is only applicable to non-GDS/Oasis shapes as PV bands should encompass this variation already.

+

Lens distortion can be applied using the k1 and k2 lens coefficients, using the model described by Zhang. The lens radius, r, is the distance from the world origin. k1 applies over r^2. k2 applies over r^4, defining a long range distortion effect compared to k1.

+ +

 

+ +

 

+ +

Please also refer to the order-of-operations section to understand how lens distortion, proximity biasing and LER are applied in combination.

+

GDS/Oasis Note

+
+

Side CDU can be enabled for GDS/Oasis shapes, but should only be used with care. Biasing is performed uniformally to increase or decrease the shape boundary. This may not reflect the OPC contours (process) and could also lead to algorithm fails in case of self-intersections. A preference is available to enable/disable this setting for this type of geometry; projects loaded with side CDU for these types of layers will override this preference if it is off.

+

An effort is made to handle self-intersections (as shown below). The polygon fill type menu (defaulting to 'non-zero') allows for adjustments, but 'non-zero' will usually be correct. Note that there is no guarantee that the result will work with all calculation modes, however.

+ +

 

+ +
+
+ + + diff --git a/Documentation/montecarlo_layerSettings_orderop.html b/Documentation/montecarlo_layerSettings_orderop.html new file mode 100644 index 0000000..3a831f1 --- /dev/null +++ b/Documentation/montecarlo_layerSettings_orderop.html @@ -0,0 +1,192 @@ + + + + +Variance - Reference + + + + +
+ +

Order of Operation

+

The advanced processing modes (lens distortion, proximity biasing and LER) have a specific order of operation in the system:

+
    +
  1. Lens distortion
  2. +
  3. Proximity biasing
  4. +
  5. LER
  6. +
+

This is not configurable. The flow respects the scale of the effects (lens distortion can affect proximity). To preserve LER, it is applied last. If an enhancement is requested, it will be considered.

+
+ + + diff --git a/Documentation/montecarlo_layerSettings_subshapes.html b/Documentation/montecarlo_layerSettings_subshapes.html new file mode 100644 index 0000000..c24a264 --- /dev/null +++ b/Documentation/montecarlo_layerSettings_subshapes.html @@ -0,0 +1,234 @@ + + + + +Variance - Reference + + + + +
+ +

Sub-Shapes

+

Sub-shapes are the basic building blocks for shapes inside the tool. Each sub-shape is a rectangle (which is why the rectangle only has one sub-shape available to configure, and also one sub-shape reference). This is also why sub-shape inputs are not available for GDS or Oasis input.

+

If you select a complex shape, you will see the user interface offer a second sub-shape input box. The sub-shapes in the drawn mode are color-coded for easier identification.

+ +

In some cases, the Sub-shape 2 offsets may not be available (or only one may be exposed). This is a result of the shape configuration (e.g. for an L-shape, neither offset is available since the two sub-shapes must abut and a vertical offset would yield a T-shape).

+
+ +
+
+ +

L-shape

+

The Subshape1 entity defines the vertical arm of the L. The Subshape2 entity defines the horizontal arm of the L, abutted to the bottom right corner of the vertical arm.

+ +
+
+ +
+
+ +

T-shape

+

The Subshape1 entity defines the vertical arm of the T. The Subshape2 entity defines the horizontal arm of the T, abutted to the right edge of the vertical arm.

+ +
+
+ +
+
+ +

Cross-shape

+

The Subshape1 entity defines the vertical component of the cross. The Subshape2 entity defines the horizontal components of the cross.

+ +
+
+ +
+
+ +

U-shape

+

The Subshape1 entity defines the outer perimeter of the U. Subshape2 defines the notch that is cut into the Subshape1.

+ +
+
+ +
+
+ +

S-shape

+

The Subshape1 entity defines the outer perimeter of the S. Subshape2 defines the notch that is cut into the lower left of Subshape1. Subshape3 defines the notch that is cut into the upper right of Subshape1.

+ +
+
+ + + diff --git a/Documentation/montecarlo_layerSettings_tips.html b/Documentation/montecarlo_layerSettings_tips.html new file mode 100644 index 0000000..bd407c1 --- /dev/null +++ b/Documentation/montecarlo_layerSettings_tips.html @@ -0,0 +1,189 @@ + + + + +Variance - Reference + + + + +
+ +

Tip Locations

+

For each sub-shape, you can define which locations are to be considered as tips. Vertical and horizontal tips can receive different biases and variations of those biases.

+ +

Note that you can choose any combination of edges that you like to define tips :

+ +
+ + + diff --git a/Documentation/montecarlo_limitations.html b/Documentation/montecarlo_limitations.html new file mode 100644 index 0000000..822afa3 --- /dev/null +++ b/Documentation/montecarlo_limitations.html @@ -0,0 +1,189 @@ + + + + +Variance - Reference + + + + + +

Limitations

+
    +
  • High numbers of points in shapes directly impact runtime for (spacing/enclosure) and chord modes.
  • +
  • Overlap handling is layer order sensitive – this can be adjusted with the 'use shortest edge' option.
  • +
  • Contouring of in-layer Boolean or external layout data is only available for orthogonal geometry. Irregular shapes, including keyholed polygons, cannot be contoured.
  • +
  • Chord evaluation may not work for key-hole geometry - the identification of the chords (top/bottom/left/right) could break. This is a fundamental limitation of the calculation methodology.
  • +
+ + + diff --git a/Documentation/montecarlo_pasearch.html b/Documentation/montecarlo_pasearch.html new file mode 100644 index 0000000..c7e00e4 --- /dev/null +++ b/Documentation/montecarlo_pasearch.html @@ -0,0 +1,198 @@ + + + + +Variance - Reference + + + + +
+ +

PA Search

+

+

Process Assumption (PA) Search mode allows you to reverse the direction of the calculation. You can specify one or more result conditions (for chords, for example) to set the minimum/maximum result condition you would like, and the minimum number of pass cases you would like the system to find that satisy that condition. The evaluation will stop when either the (very large) internal number of maximum cases is run, or the minimum number of pass cases has been found. Note that, in multi-threaded cases, you may get more than the minimum number of pass cases due to the parallel computation - in the single threaded mode, this will not happen.

+

To use the PA Search system, set up the layers and simulation parameters in the usual way. Note that some parameters in the simulation settings are not relevant to PA search mode:

+
    +
  • The number of cases: in PA search mode, the engine will run until the number of pass cases is found, or a very large internal limit is met.
  • +
  • The CSV and SVG options: in PA search mode, CSV and SVG output is not available.
  • +
+

Once the base simulation has been set up (or loaded from disk), move to the PA Search tab. Here, set the minimum number of pass cases to be sought and the result criteria (additional filters will be shown for the chord case)

+

For each layer, flag which PAs should be sought, and the maximum variation that should be explored. Note that the runtime to find pass cases will increase with the extent of the range being sought. Note that this range will be used instead of the value assigned in the layer tab - it's not applied in addition to the layer's defined value for the PA in question.

+

When ready, use the familiar 'Single CPU' or 'Multi CPU' button to start the run.

+

During the run, the mean and standard deviation of the results that passed the result criteria is reported. At the end of the run, the mean and standard deviation of each 'sought' PA is reported. Note that the viewport update may be noticeably more intermittent in this mode, depending on the difficulty in finding matching cases. Only matching cases are displayed and used for the analysis.

+

Note that the output of a summary file, along with CSV and SVG files is not available in this mode. The settings here are also not stored in, or loaded from, project files.

+

Be aware that the search can take a very long time, or fail to complete, if you set very narrow filter criteria with very broad input ranges. This is due to the sampling of the full input space, which means the likelihood of finding a passing result within narrow filter criteria becomes small. For example, setting a 100 nm position range for an overlap area case between two 10 nm x 10 nm shapes, for a 95 nm filter in the overlap area, will cause a lengthy search - almost all values sampled in the 100 nm range will fail the criteria and represent wasted time and computation.

+
+ + + diff --git a/Documentation/montecarlo_replay.html b/Documentation/montecarlo_replay.html new file mode 100644 index 0000000..a141e63 --- /dev/null +++ b/Documentation/montecarlo_replay.html @@ -0,0 +1,188 @@ + + + + +Variance - Reference + + + + + +

Replay

+ +

Replay allows you to use the CSV file for a project to replay the simulation, even for DOE tiles. In this way, you can inspect fail cases to understand the root cause. Note that the layer and simulation settings in the tool must be matched to those originally used to perform the run. This is tracked by embedded checksum data at the bottom of the CSV file. If there is a difference, you will get an error message because the simulation cannot be reproduced. Removing or changing the checksum data will not avoid the error in this situation.

+

To use replay, ensure the CSV option is set when you run the simulation. With the project that generated the CSV file loaded, go to the simulation tab. Use the 'load' button in the Replay section and find the CSV file in the file dialog that is displayed. The system will then read the file. Assuming no checksum error is reported, you will now be able to activate replay mode with the checkbox. The case number can be entered directly into the numeric field, or you can scrub through the available cases. To leave replay mode, de-select the checkbox.

+

In replay mode, the calculation is re-run by the engine and reported alongside the value recorded in the CSV. This is intentional.

+

Please note that the replay system is version-specific in its current form: it is not guaranteed that a future version will work with project and CSV data from an earlier version.

+ + + diff --git a/Documentation/montecarlo_saveload.html b/Documentation/montecarlo_saveload.html new file mode 100644 index 0000000..da3a92d --- /dev/null +++ b/Documentation/montecarlo_saveload.html @@ -0,0 +1,184 @@ + + + + +Variance - Reference + + + + + +

Save / Load of Simulation Settings

+

The tool has support for loading project files from previous versions. Missing settings are given their default value. For projects prior to 2.1, the layers are mapped into the new 8 layer system (layer 3 becomes layer 5, layer 4 becomes layer 6) and reference/correlation settings are also updated.

+ + + diff --git a/Documentation/montecarlo_simSettings.html b/Documentation/montecarlo_simSettings.html new file mode 100644 index 0000000..f137191 --- /dev/null +++ b/Documentation/montecarlo_simSettings.html @@ -0,0 +1,276 @@ + + + + +Variance - Reference + + + + + +

Simulation Settings

+

+
    +
  • Number of cases: The total number of cases to evaluate. Note that the engine will sometimes encounter a configuration that cannot be evaluated and will reject it, so the total number of results may differ from the number of cases you request.
  • +
  • Resolution: This defines the minimum distance between points. This is used internally to fragment straight edges after the first stage of the shape generation. A second stage is used after LWR is applied, to try and ensure that large LWR values haven't unduly separated points on the edge. In the second stage, there is a limitation when there is insufficient space to fragment - at least 2x the resolution value is needed to inject a point, to have a distance >= resolution to the points either side.
  • +
  • Corner Segments: The corners of the shapes are defined using a sweep from 0 to 90 degrees. This 90 degree sweep is divided up into segments. The more segments, the greater the accuracy (90 segments correspond to a 1 degree angular resolution). Note that this is overridden by the 'optimize corner pt density' option.
  • +
  • LER as LWR/sqrt(2): This, when set, causes LER to be calculated with a larger value than the more conservative, but strictly incorrect, LWR/2 approach that is often used.
  • +
  • Optimize corner pt density: When set, this overrides (if necessary) the angular resolution used to define corners. In this mode, the limiting factor wil be the linear distance between points, based on the edge resolution setting. This reduces calculation time significantly if the corners are packed tightly with points.
  • +
  • Link variation for tip and side CDU: This correlates the variation between tip and side CDU for the runs. This matches the old tool behavior, but may not be desired in all cases.
  • +
  • Total number of points: Just a readout of how many points make up the result contours.
  • +
+

The resolution and corner segment values allow you a good degree of control over the fidelity of the shapes being fed into the simulation engine, but do note that the increasing number of points will have an impact on calculation time per run. Nearest neighbor and chord length calculation time scales with increasing numbers of points.

+

There are some additional options available:

+
    +
  • Display results for each case : This draws the result out for the current case, in the preview region
  • +
  • Display input shapes for each case: This draws the contours being delivered to the simulation engine for each case.
  • +
  • Create SVG file for each case: This causes the tool to write out the input and output contours for each run to a numbered SVG file that can be referenced to the numbered result in the CSV output. Colors are preserved. NOTE : This will cause significant memory footprint as the contours are retained in memory until the end of the run.
  • +
  • CSV. With this set, the default case, a CSV file will be generated with all of the result values and variation values. This can take some time for larger runs, and the files can also be large. Disabling this avoids the lengthy file generation, but it doesn't save any memory or CPU time during runs.
  • +
  • Use all CPUs (multi CPU). With this active, all CPUs will be used for the simulation runs. With it deselected, one CPU core will be left free so that the user can do work as the simulation is processed.
  • +
  • RNG Type. A choice of RNG is available to the user. Default is System.Random. Additionaly options are a Mersenne Twister or the Cryptographic RNG. The Mersenne Twister should be faster, but it hasn't been well benchmarked yet. The Cryptographic RNG adds a 10% overhead, but avoids a predictable distribution.
  • +
+

The top right ‘result for this run’ will report the value(s) determined for the current run.

+

To run on a single processor, use ‘Single CPU’, otherwise use ‘Multiple CPU’.

+
    +

    Note that during a multiple CPU run, the readout, progress bar and preview may update inconsistently and infrequently. This does not reflect the speed of the computation, but is just a consequence of the available spare capacity in the system to update the interface during the calculations. This should almost never happen for the usual case of the hardware-accelerated OpenGL viewports. For software OpenGL, the likelihood is higher. Slow machines will suffer more.

    +
+ +
+ +

Geometric Equation

+

This is where the layer relationships are set up for the simulation. Note that the layer equation looks like this :

+
+

{[(Layer 1 AND/OR Layer 2) AND/OR (Layer 3 AND/OR Layer 4)] AND/OR [(Layer 5 AND/OR Layer 6) AND/OR (Layer 7 AND/OR Layer 8)]}

+

-------

+

{[(Layer 9 AND/OR Layer 10) AND/OR (Layer 11 AND/OR Layer 12)] AND/OR [(Layer 13 AND/OR Layer 14) AND/OR (Layer 15 AND/OR Layer 16)]}

+
+

This reflects the internal flow - the layers are processed piecewise in the way described above.

+ +
+ +
+ +

Area

+ +

By default, the total area is output in the current version of the system, summed across all input polygons. For multi-polygon cases where a minimum overlap area calculation is desired, the 'Per Poly' option can be set. One such example would be contact hole evaluations.

+ +
+ +
+ +

Distance (Spacing/Enclosure, Overlap)

+

When the shapes do not overlap, distance finds the minimum distance between points on one shape and points on the other.

+ +

In the case of an overlap event, a maximum overlap value is reported with negative sign to indicate the opposite nature of the value.

+ +

If the "shortest edge" option is checked, the overlap is evaluated by casting rays from the shortest edge and finding the longest ray length to the other side of the overlap. Rays are cast orthogonal to the edge segment. This use of the shortest edge makes the overlap detection neutral to the configuration of the layers. The evaluation of the shortest edge adds some small overhead to the calculation routine, but the benefit more than compensates:

+ +

In the absence of the "shortest edge" setting, the overlap is calculated using lines projected from the part of the overlap defined by the layer5/6/7/8 edges, which are projected until they intersect the edge from layer 1/2/3/4. If the layer order is reversed, the reported result will not be what you expect.

+ +

The debug option gives you the ability to see the rays being cast, to help visualize how the engine is assessing your simulation. No results are gathered with the debug mode set.

+ +

 

+ +

Averaged normals are used as a basis for the raycast, to handle rough geometry from LER.

+ + +

When the enclosure checkbox is set, the enclosure value is assessed.

+ +

When the shapes overlap, the same projection approach is used to determine the maximum distance beyond the edge, This is reported as a negative value to indicate there is an absence of full enclosure :

+ +
+ +
+ +

Chord

+ +

Minimum chord length is measured with a fixed expectation that the result from Geometric Equation A is oriented to lie in the horizontal direction and the reqsult from Geometric Equation B is vertically oriented. This enables the top/bottom/left/right chord determination. Ignoring this will mean that the top/bottom and left/right result pairs will be transposed in the CSV output.

+

Any shapes are handled.

+ +

 

+ +

You can deselect pairs of chords. Those chords not measured will be reported as N/A in the output file.

+

To reinforce the earlier note, the example below shows how chord location is dependent on the horizontal and vertical orientation expectations for the geometric equations.

+ +
+ +
+ +

Angle

+

Intersection angle is delivered by the logical AND of polygons.

+ +

 

+ +
+ + + diff --git a/Documentation/montecarlo_summary.html b/Documentation/montecarlo_summary.html new file mode 100644 index 0000000..fa978f5 --- /dev/null +++ b/Documentation/montecarlo_summary.html @@ -0,0 +1,537 @@ + + + + +Variance - Reference + + + + + +

Summary File

+

A summary file is generated for each run automatically. This records the run, the date of the run, the calculation. For each result, the mean and standard deviation are reported along with the number of cases evaluated for each result. For each input layer, the settings are shown. The simulation settings (corner segments, edge resolution, number of cases) are recorded.

+ +
+

Example – Typical Case (8 layers)

+
+

+Variance 3.0 (Phil Stopford)
+Results summary for job: D:\Variance\bm300_8threads.txt run on : Thursday, September 7, 2017. Runtime: 69.05 seconds
+
+Equation: [(Layer 1 AND Layer 2) AND (Layer 3 AND Layer 4)] AND [(Layer 5 AND Layer 6) AND (Layer 7 AND Layer 8)]
+
+result 0 mean and standard deviation for 125000 cases: x: 710.77, s: 94.92
+
+Layer settings for job
+
+Layer 0 Name: Layer 1
+Layer 0 Shape: Rectangle/Square
+Subshape 0: 
+  HLength: 40
+  VLength: 40
+  HOffset: 0
+  VOffset: 0
+  TipLocations: None
+SubshapeReference: 0
+PositionInSubshape: Center
+Horizontal Offset: 0
+Vertical Offset: 0
+Rotation: 0
+Wobble: 0
+Side Bias: 0
+HorTip Bias: 0
+  HorTip Bias +ve Var: 0
+  HorTip Bias -ve Var: 0
+VerTip Bias: 0
+  VerTip Bias +ve Var: 0
+  VerTip Bias -ve Var: 0
+Inner CRR: 0
+  Inner CR Var: 0
+Outer CRR: 60
+  Outer CR Var: 0
+LWR: 5
+LWR Frequency: 0.2
+LWR Noise: Perlin
+Side CDU: 0
+Tips CDU: 0
+Horizontal Overlay: 10
+Vertical Overlay: 10
+X Overlay correlation: None
+Y Overlay correlation: None
+INACTIVE: X Overlay reference layer: None
+INACTIVE: Y Overlay reference layer: None
+ACTIVE: X Overlay reference layers: 2 3 4 9 10 11 12 
+ACTIVE: Y Overlay reference layers: 2 3 4 9 10 11 12 
+CDU correlation: None
+Tip CDU correlation: None
+
+Layer 1 Name: Layer 2
+Layer 1 Shape: Rectangle/Square
+Subshape 0: 
+  HLength: 40
+  VLength: 40
+  HOffset: 0
+  VOffset: 0
+  TipLocations: None
+SubshapeReference: 0
+PositionInSubshape: Center
+Horizontal Offset: 0
+Vertical Offset: 0
+Rotation: 0
+Wobble: 0
+Side Bias: 0
+HorTip Bias: 0
+  HorTip Bias +ve Var: 0
+  HorTip Bias -ve Var: 0
+VerTip Bias: 0
+  VerTip Bias +ve Var: 0
+  VerTip Bias -ve Var: 0
+Inner CRR: 0
+  Inner CR Var: 0
+Outer CRR: 60
+  Outer CR Var: 0
+LWR: 5
+LWR Frequency: 0.2
+LWR Noise: Perlin
+Side CDU: 0
+Tips CDU: 0
+Horizontal Overlay: 10
+Vertical Overlay: 10
+X Overlay correlation: None
+Y Overlay correlation: None
+ACTIVE: X Overlay reference layer: None
+ACTIVE: Y Overlay reference layer: None
+INACTIVE: X Overlay reference layers: None
+INACTIVE: Y Overlay reference layers: None
+CDU correlation: None
+Tip CDU correlation: None
+
+Layer 2 Name: Layer 3
+Layer 2 Shape: Rectangle/Square
+Subshape 0: 
+  HLength: 40
+  VLength: 40
+  HOffset: 0
+  VOffset: 0
+  TipLocations: None
+SubshapeReference: 0
+PositionInSubshape: Center
+Horizontal Offset: 0
+Vertical Offset: 0
+Rotation: 0
+Wobble: 0
+Side Bias: 0
+HorTip Bias: 0
+  HorTip Bias +ve Var: 0
+  HorTip Bias -ve Var: 0
+VerTip Bias: 0
+  VerTip Bias +ve Var: 0
+  VerTip Bias -ve Var: 0
+Inner CRR: 0
+  Inner CR Var: 0
+Outer CRR: 60
+  Outer CR Var: 0
+LWR: 5
+LWR Frequency: 0.2
+LWR Noise: Perlin
+Side CDU: 0
+Tips CDU: 0
+Horizontal Overlay: 10
+Vertical Overlay: 10
+X Overlay correlation: None
+Y Overlay correlation: None
+ACTIVE: X Overlay reference layer: None
+ACTIVE: Y Overlay reference layer: None
+INACTIVE: X Overlay reference layers: None
+INACTIVE: Y Overlay reference layers: None
+CDU correlation: None
+Tip CDU correlation: None
+
+Layer 3 Name: Layer 4
+Layer 3 Shape: Rectangle/Square
+Subshape 0: 
+  HLength: 40
+  VLength: 40
+  HOffset: 0
+  VOffset: 0
+  TipLocations: None
+SubshapeReference: 0
+PositionInSubshape: Center
+Horizontal Offset: 0
+Vertical Offset: 0
+Rotation: 0
+Wobble: 0
+Side Bias: 0
+HorTip Bias: 0
+  HorTip Bias +ve Var: 0
+  HorTip Bias -ve Var: 0
+VerTip Bias: 0
+  VerTip Bias +ve Var: 0
+  VerTip Bias -ve Var: 0
+Inner CRR: 0
+  Inner CR Var: 0
+Outer CRR: 60
+  Outer CR Var: 0
+LWR: 5
+LWR Frequency: 0.2
+LWR Noise: Perlin
+Side CDU: 0
+Tips CDU: 0
+Horizontal Overlay: 10
+Vertical Overlay: 10
+X Overlay correlation: None
+Y Overlay correlation: None
+ACTIVE: X Overlay reference layer: None
+ACTIVE: Y Overlay reference layer: None
+INACTIVE: X Overlay reference layers: None
+INACTIVE: Y Overlay reference layers: None
+CDU correlation: None
+Tip CDU correlation: None
+
+Layer 8 Name: Layer 5
+Layer 8 Shape: Rectangle/Square
+Subshape 0: 
+  HLength: 40
+  VLength: 40
+  HOffset: 0
+  VOffset: 0
+  TipLocations: None
+SubshapeReference: 0
+PositionInSubshape: Center
+Horizontal Offset: 0
+Vertical Offset: 0
+Rotation: 0
+Wobble: 0
+Side Bias: 0
+HorTip Bias: 0
+  HorTip Bias +ve Var: 0
+  HorTip Bias -ve Var: 0
+VerTip Bias: 0
+  VerTip Bias +ve Var: 0
+  VerTip Bias -ve Var: 0
+Inner CRR: 0
+  Inner CR Var: 0
+Outer CRR: 60
+  Outer CR Var: 0
+LWR: 5
+LWR Frequency: 0.2
+LWR Noise: Perlin
+Side CDU: 0
+Tips CDU: 0
+Horizontal Overlay: 10
+Vertical Overlay: 10
+X Overlay correlation: None
+Y Overlay correlation: None
+ACTIVE: X Overlay reference layer: None
+ACTIVE: Y Overlay reference layer: None
+INACTIVE: X Overlay reference layers: None
+INACTIVE: Y Overlay reference layers: None
+CDU correlation: None
+Tip CDU correlation: None
+
+Layer 9 Name: Layer 6
+Layer 9 Shape: Rectangle/Square
+Subshape 0: 
+  HLength: 40
+  VLength: 40
+  HOffset: 0
+  VOffset: 0
+  TipLocations: None
+SubshapeReference: 0
+PositionInSubshape: Center
+Horizontal Offset: 0
+Vertical Offset: 0
+Rotation: 0
+Wobble: 0
+Side Bias: 0
+HorTip Bias: 0
+  HorTip Bias +ve Var: 0
+  HorTip Bias -ve Var: 0
+VerTip Bias: 0
+  VerTip Bias +ve Var: 0
+  VerTip Bias -ve Var: 0
+Inner CRR: 0
+  Inner CR Var: 0
+Outer CRR: 60
+  Outer CR Var: 0
+LWR: 5
+LWR Frequency: 0.2
+LWR Noise: Perlin
+Side CDU: 0
+Tips CDU: 0
+Horizontal Overlay: 10
+Vertical Overlay: 10
+X Overlay correlation: None
+Y Overlay correlation: None
+ACTIVE: X Overlay reference layer: None
+ACTIVE: Y Overlay reference layer: None
+INACTIVE: X Overlay reference layers: None
+INACTIVE: Y Overlay reference layers: None
+CDU correlation: None
+Tip CDU correlation: None
+
+Layer 10 Name: Layer 7
+Layer 10 Shape: Rectangle/Square
+Subshape 0: 
+  HLength: 40
+  VLength: 40
+  HOffset: 0
+  VOffset: 0
+  TipLocations: None
+SubshapeReference: 0
+PositionInSubshape: Center
+Horizontal Offset: 0
+Vertical Offset: 0
+Rotation: 0
+Wobble: 0
+Side Bias: 0
+HorTip Bias: 0
+  HorTip Bias +ve Var: 0
+  HorTip Bias -ve Var: 0
+VerTip Bias: 0
+  VerTip Bias +ve Var: 0
+  VerTip Bias -ve Var: 0
+Inner CRR: 0
+  Inner CR Var: 0
+Outer CRR: 60
+  Outer CR Var: 0
+LWR: 5
+LWR Frequency: 0.2
+LWR Noise: Perlin
+Side CDU: 0
+Tips CDU: 0
+Horizontal Overlay: 10
+Vertical Overlay: 10
+X Overlay correlation: None
+Y Overlay correlation: None
+ACTIVE: X Overlay reference layer: None
+ACTIVE: Y Overlay reference layer: None
+INACTIVE: X Overlay reference layers: None
+INACTIVE: Y Overlay reference layers: None
+CDU correlation: None
+Tip CDU correlation: None
+
+Layer 11 Name: Layer 8
+Layer 11 Shape: Rectangle/Square
+Subshape 0: 
+  HLength: 40
+  VLength: 40
+  HOffset: 0
+  VOffset: 0
+  TipLocations: None
+SubshapeReference: 0
+PositionInSubshape: Center
+Horizontal Offset: 0
+Vertical Offset: 0
+Rotation: 0
+Wobble: 0
+Side Bias: 0
+HorTip Bias: 0
+  HorTip Bias +ve Var: 0
+  HorTip Bias -ve Var: 0
+VerTip Bias: 0
+  VerTip Bias +ve Var: 0
+  VerTip Bias -ve Var: 0
+Inner CRR: 0
+  Inner CR Var: 0
+Outer CRR: 60
+  Outer CR Var: 0
+LWR: 5
+LWR Frequency: 0.2
+LWR Noise: Perlin
+Side CDU: 0
+Tips CDU: 0
+Horizontal Overlay: 10
+Vertical Overlay: 10
+X Overlay correlation: None
+Y Overlay correlation: None
+ACTIVE: X Overlay reference layer: None
+ACTIVE: Y Overlay reference layer: None
+INACTIVE: X Overlay reference layers: None
+INACTIVE: Y Overlay reference layers: None
+CDU correlation: None
+Tip CDU correlation: None
+
+Simulation Settings:
+  Number of Cases: 125000
+  Edge resolution: 1
+  Corner segments: 90
+  Override corner angle step by edge resolution: no
+  Linked tip/side CDU: yes
+  LER: LWR/sqrt(2)
+RNG: System.Random
+
+

+
+
+ + diff --git a/Documentation/montecarlo_viewports.html b/Documentation/montecarlo_viewports.html new file mode 100644 index 0000000..e7254de --- /dev/null +++ b/Documentation/montecarlo_viewports.html @@ -0,0 +1,204 @@ + + + + +Variance - Reference + + + + + +

Viewports

+

The viewport system uses the optimal native system for the platform being used (Vulkan, OpenGL, Direct3D, Metal). You can zoom with your mouse wheel and also move around using the WASD keys. If you get lost in the viewport, hit ‘r’ and the viewport will go back to the origin and default zoom. 'f' will freeze/thaw the viewport, preventing mouse input changing the camera position and zoom until thawed. 'n' and 'm' will zoom in/out. Tooltips will be displayed on mouse hover, providing a reference for the user.

+

Context menus are available in viewports - simply right click. Note that the implant and DOE menus lack some of the entries.

+ +

+ +

Most of the entries should be self-explanatory, but an overview is below:

+
    +
  • Reset: resets the view zoom and camera location to the default values.
  • +
  • Display Options : allows for toggle antialiasing, fill or the display of points in the viewport.
  • +
  • Freeze/Thaw : 'Freeze' will lock the viewport position and zoom at the current values. 'Thaw' will remove the lock.
  • +
  • Save bookmark : This will save the current view location.
  • +
  • Load bookmark : This will load a saved view.
  • +
  • Use location for all viewports : Applies the current view to all viewports in the system.
  • +
  • Zoom Extents : zooms and repositions the camera to display all content in the viewport. See note below for DOE previews.
  • +
  • Zoom In / Zoom Out : zooms in or out by one step.
  • +
  • Fast Zoom In / Fast Zoom Out : zooms in or out by a multiple of steps.
  • +
  • Save SVG : writes the viewport content to an SVG.
  • +
  • Save Layout : writes the viewport content to a GDSII or Oasis file.
  • +
+ +

For layer previews involving a DOE tile (configured under the preferences), 'zoom extents' will consider the extracted geometry for the extents unless 'show drawn' is active, in which case the full layout is considered.

+ + + diff --git a/Documentation/navbar.html b/Documentation/navbar.html new file mode 100644 index 0000000..70156f4 --- /dev/null +++ b/Documentation/navbar.html @@ -0,0 +1,492 @@ + + + + +Navbar + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Introduction

+
+

Licensing

+
+

Features

+
+

->Features - Basic

+
+

->Features - Implant

+
+

->Features - MC

+
+

->Features - Other

+
+

->Features - Code

+
+

Changelog

+
+

Performance

+
+

Implementations

+
+

->Eto.Forms

+
+

-->WPF

+
+

-->macOS

+
+

-->GTK2

+
+

->Headless

+
+

-->Email Notification

+
+

Overview - 1D

+
+

Overview - Implant

+
+

Overview - MonteCarlo

+
+

->Layer Settings

+
+

-->Subshapes

+
+

--->L-Shape

+
+

--->T-Shape

+
+

--->+-Shape

+
+

--->U-Shape

+
+

--->S-Shape

+
+

-->GDS / Oasis

+
+

-->Boolean

+
+

--->Overview

+
+

-->Midpoint Slide

+
+

-->Tip Locations

+
+

-->Layout Origin

+
+

-->Bias and Etch

+
+

-->Lithography

+
+

-->Flip

+
+

-->Background Layers

+
+

-->Export to Layout

+
+

-->Order of Operation

+
+

->Settings

+
+

-->Geometric Equation

+
+

-->Area

+
+

-->Spacing

+
+

--->Enclosure

+
+

-->Chord

+
+

-->Angle

+
+

->Replay

+
+

->DOE

+
+

->PA Search

+
+

->Custom RNG Mapping

+
+

->Limitations

+
+

->Save/Load

+
+

->Viewports

+
+

->Summary

+
+

Overview - Utilities

+
+

->DOE Summary

+
+

->Email Notification

+
+

->Display Prefs

+
+

->GDS/Oasis Prefs

+
+

Bug Report

+
+

Licenses/Acknowledgements

+
+

->ClipperLib

+
+

->KDTree

+
+

->Mersenne Twister

+
+

->LibTessDotNet

+
+

->Eto.Forms

+
+

->Eto.Veldrid

+
+

->MathParser

+
+

->Miscellaneous Utility Library

+
+
+ + \ No newline at end of file diff --git a/Documentation/performance.html b/Documentation/performance.html new file mode 100644 index 0000000..29a1ef9 --- /dev/null +++ b/Documentation/performance.html @@ -0,0 +1,204 @@ + + + + +Variance - Reference + + + + + +

Performance

+

Different calculation modes have different levels of performance. They all scale with the number of runs and threading resource available.

+
+ +
+

The implant Monte Carlo engine is derived from the multi-layer system, but works slightly differently. On a quad-core i7-6700k, it processes 25000 iterations/second (250k cases in ~ 10 seconds, for 90 corner segments), on Windows.

+ +

Performance on Mac and Linux/GTK is generally half of that on Windows. This appears to be due to the underlying Mono framework on those platforms, which imposes limits on the multithreading system (single-threaded performance is comparable).

+ +

Benchmark

+

Runtime is essentially linear with the number of cases, for both single and multi-threaded modes. Multithreaded provides a significant boost in performance.

+
+ +
+ +

Runtime also scales linearly with the number of layers involved in the calculation, independent of the layer configuration. Area runtimes are below for 250k cases using the average overlay project.

+
    +
  • 2 Layers : 16 seconds
  • +
  • 3 Layers : 23 seconds
  • +
  • 4 Layers : 30 seconds
  • +
  • 5 Layers : 36 seconds
  • +
  • 6 Layers : 42 seconds
  • +
  • 7 Layers : 59 seconds
  • +
  • 8 Layers : 54 seconds
  • +
  • 16 Layers : 108 seconds
  • +
+ +

Memory

+

Memory is aggressively held under control through the Garbage Collector. Each result, assuming no SVG is created, needs 1.5 KB RAM to be stored during a run. SVG greatly increases this.

+ + + diff --git a/Documentation/releases.html b/Documentation/releases.html new file mode 100644 index 0000000..66398fe --- /dev/null +++ b/Documentation/releases.html @@ -0,0 +1,297 @@ + + + + +Variance - Reference + + + + + + + + +
+ +

Variance Release History

+ +
+ +

New to 4.2 (Feb 01 2020)

+ + + + + +
+ 4.2 +
+
+
    +
  • Independent alignment of X and Y for flipped shapes.
  • +
  • General enhancements and fixes from library work.
  • +
  • Moved to .NET Core 3.1.
  • +
+
+
+ +
+ +

New to 4.1 (Nov 20 2019)

+
+
    +
  • Performance tuning.
  • +
  • Modern viewport.
  • +
      +
    • Faster, and automatically works with the best implementation on each platform (Vulkan, OpenGL, Direct3D11, Metal)
    • +
    +
  • Moved to newer .NET framework (4.7.2) and .NET standard 2.0 libraries.
  • +
+
+
+ +
+ +

New to 4.0.1 (Sep 23 2019)

+
+
    +
  • Added an option for the 'friendly' numeric output.
  • +
  • Fixed 'update' label jumping around.
  • +
  • Histograms (10 buckets) provided in summary output for each result.
  • +
+
+
+ +
+ +

New to 4.0 (Sep 13 2019)

+
+
    +
  • Background geometry is now re-evaluated with foreground changes.
  • +
      +
    • Particularly useful for ILB workflows.
    • +
    +
  • Geometry pipeline enhancements continue.
  • +
      +
    • Performance optimizations.
    • +
    • Keyholer enhancements, particularly for handling pre-existing keyholes and complex ILB scenarios.
    • +
    • Sliver removal in ILB pipeline - removes spikes from inversion of keyholed geometry.
    • +
    • Interior wall removal (from keyholes) at calculation stage (best effort).
    • +
    • For non-spacing/enclosure calculations, auto-decimation is used to simplify the analysis.
    • +
        +
      • Gains in performance can be significant, geometry permitting
      • +
      +
    • Overlap handling in shape generation has been made more robust.
    • +
    +
  • A sampling engine has been implemented, allowing for different sampling strategies to be explored.
  • +
      +
    • Input sample points are now pre-calculated (except for PA search).
    • +
    +
  • Export enhancements.
  • +
      +
    • Viewport contents can now be written to GDSII or Oasis files, supplementing the SVG feature.
    • +
    • Simulation geometry can be written to GDSII or Oasis files, supplementing the SVG feature.
    • +
    • Export of simulation geometry is now performed on-the-fly rather than at the end of the simulation. Greatly reduces memory load, but there is a significant cost in runtime.
    • +
    • Exporting of simulation data to CSV now runs multithreaded.
    • +
    +
  • Large values are now reported in a friendly way.
  • +
  • Viewport performance and reliability improvements.
  • +
+
+
+ +
+ + + diff --git a/Documentation/simple.html b/Documentation/simple.html new file mode 100644 index 0000000..1ae56cb --- /dev/null +++ b/Documentation/simple.html @@ -0,0 +1,177 @@ + + + + +Variance - Reference + + + + + +

Overview of 1D calculation

+

This is a basic 1D calculation. It is not suitable for interacting systems or complex cases. It will suffice for basic spacing checks (e.g. PC side to RX edge). The calculation is provided on the page, and the tool offers the ability to request a rule value for ‘n’ sigma in addition to the usual 3 and 4 sigma cases.

+ + + diff --git a/Documentation/utils.html b/Documentation/utils.html new file mode 100644 index 0000000..940c303 --- /dev/null +++ b/Documentation/utils.html @@ -0,0 +1,227 @@ + + + + +Variance - Reference + + + + + +

Utilities

+

The Utilities tab is where miscellaneous tools and settings can be found that do not find a ready home elsewhere in the application.

+ +

DOE Summary

+

+

This tool can be used to generate a CSV file that summarizes all of the results from a DOE. The results are presented in a grid. Each result is of the form 'result 0: x: 17.01(s: 2.67)'. Multiple results from the same cell in the DOE are separated by ';' and have their result number indicated (e.g. 'result 0: x: 17.01(s: 2.67);result 1: x: 16.75(s: 2.66)'.

+
+

Equation: (Layer 1) MIN SPACE/OVERLAP/ENCL TO/WITH (Layer 3)

+

,
+ ,
+ ,
+ result 0: x: 17.01(s: 2.67),result 0: x: 17.01(s: 2.67)

+
+

The tool will process any and all DOEs in the directory that you specify, creating one summary file per DOE that is found.

+ + +

Email Notification

+

+

This tool offers notification options for job/batch completion. The settings should be straightforward and available from your provider. You can determine whether they are correctly set using the 'Test' button to send a mail. The 'from' and 'to' addresses will be the same.

+

The email received when jobs are completed will be of the form:

+
+

+ (Subject) Variance run completed : ..\..\..\VxC14.xml
+ (Body) x: 706.69, s: 108.8

+
+

In the case of run failure, the subject line will have 'aborted' in place of 'completed'. The subject line lends itself to filtering. In case of mistakes, the email is deliberately terse to avoid problems if the address is incorrect. Nothing can be inferred from the content and no attachments are sent. The subject line does contain the full path and job XML reference, to provide context for the user to know which jobs are complete.

+

These settings are remembered across sessions, and are stored in the user's registry. On non-Windows platforms, the registry replacement system (e.g. from Mono or Wine) may be readable by other users, so caution is advised.

+ + +

Display Preferences

+

+

This tool offers preferences to configure the viewport appearance and look-and-feel.

+

These settings are remembered across sessions, and are stored in the user's registry.

+
    +
  • Zoom increment : how quickly the viewport zooms in/out
  • +
  • Antialiasing : whether the lines are drawn smoothed or stepped
  • +
  • (BG/FG) opacity : the opacity of the shapes in the viewport. The opacity is applied to the fill in filled polygons, and the contour otherwise.
  • +
  • Fill : whether the shapes are drawn filled or not. 'Drawn' polygons are never filled to avoid confusion.
  • +
  • Reset : resets the preferences to defaults
  • +
+

+

The color squares show the current colors assigned to different elements in the viewport. Click on a square to bring up a color picker in order to change the colors as-desired. The changes will be applied across the interface without further action, although the individual layer viewports may only update once 'nudged' (e.g. zooming)

+ + +

GDS/Oasis Preferences

+

+

This tool offers preferences to configure aspects related to GDS/Oasis files.

+

These settings are remembered across sessions, and are stored in the user's registry.

+
    +
  • Allow CD Variation : permit side CDU to be applied to the geometry
  • +
  • Use DOE Tile for Layer Preview : whether the extracted DOE tile or the full layout should be displayed in the layer preview
  • +
+ + + diff --git a/Eto/Common/Variance.cs b/Eto/Common/Variance.cs new file mode 100644 index 0000000..e7228f7 --- /dev/null +++ b/Eto/Common/Variance.cs @@ -0,0 +1,36 @@ +using Eto; +using Eto.Forms; +using System; +using System.ComponentModel; + +namespace Variance +{ + public class VarianceApplication : Application + { + bool doPrompts; // pass this as a reference to allow UI to decide whether prompts are shown or not. + VarianceContextGUI varianceContext; + public VarianceApplication(Platform platform, VarianceContextGUI vContext) : base(platform) + { + varianceContext = vContext; + } + + protected override void OnInitialized(EventArgs e) + { + MainForm = new MainForm(ref doPrompts, varianceContext); + base.OnInitialized(e); + MainForm.Show(); + } + + protected override void OnTerminating(CancelEventArgs e) + { + base.OnTerminating(e); + + if (doPrompts) + { + var result = MessageBox.Show(MainForm, "Are you sure you want to quit?", MessageBoxButtons.YesNo, MessageBoxType.Question); + if (result == DialogResult.No) + e.Cancel = true; + } + } + } +} diff --git a/Eto/Common/headless.cs b/Eto/Common/headless.cs new file mode 100644 index 0000000..c46f285 --- /dev/null +++ b/Eto/Common/headless.cs @@ -0,0 +1,499 @@ +using Error; +using QLicense; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Threading; + +namespace Variance +{ + public class Headless + { + class ConsoleSpinner + { + int counter; + string[] sequence; + + public ConsoleSpinner() + { + counter = 0; + sequence = new string[] { "/", "-", "\\", "|" }; + sequence = new string[] { ".", "o", "0", "o" }; + sequence = new string[] { "+", "x" }; + sequence = new string[] { "V", "<", "^", ">" }; + sequence = new string[] { ". ", ".. ", "... ", "...." }; + } + + public void Turn() + { + counter++; + + if (counter >= sequence.Length) + counter = 0; + + Console.Write(sequence[counter]); + Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop); + } + } + + public VarianceContext varianceContext; + ConsoleSpinner cs; + + CommonVars commonVars; + Entropy entropyControl; + + public Headless(VarianceContext varianceContext) + { + pHeadless(varianceContext); + } + + void pHeadless(VarianceContext _varianceContext) + { + core(_varianceContext); + } + + void core(VarianceContext _varianceContext) + { + varianceContext = _varianceContext; + commonVars = new CommonVars(varianceContext); + varianceContext.emailPwd = varianceContext.aes.EncryptToString(varianceContext.emailPwd); + entropyControl = new Entropy(ref varianceContext, commonVars); + commonVars.getNonSimulationSettings().emailOnCompletion = varianceContext.completion; + commonVars.getNonSimulationSettings().emailPerJob = varianceContext.perJob; + commonVars.getNonSimulationSettings().emailAddress = varianceContext.emailAddress; + commonVars.getNonSimulationSettings().emailPwd = varianceContext.emailPwd; + commonVars.getNonSimulationSettings().host = varianceContext.host; + commonVars.getNonSimulationSettings().ssl = varianceContext.ssl; + commonVars.getNonSimulationSettings().port = varianceContext.port; + commonVars.storage.setLayerSettings = setLayerSettings; + } + + public void updateReadout(object sender, System.Timers.ElapsedEventArgs e) + { + pUpdateReadout(); + } + + void pUpdateReadout() + { + if ((entropyControl.sw_Preview.Elapsed.TotalMilliseconds - entropyControl.timeOfLastPreviewUpdate) < commonVars.m_timer.Interval) + { + return; + } + try + { + if (entropyControl.sw.IsRunning) + { + entropyControl.swTime += entropyControl.sw.Elapsed.TotalSeconds; + } + entropyControl.sw.Stop(); + if (varianceContext.implantMode) + { + entropyControl.timeOfFlight_implant(entropyControl.swTime); + } + else + { + entropyControl.timeOfFlight(entropyControl.swTime, false); + } + if (Monitor.TryEnter(varianceContext.previewLock)) + { + try + { + List t = new List(); + if (varianceContext.implantMode) + { + Console.WriteLine("Converging on: " + entropyControl.getImplantResultPackage().getMeanAndStdDev()); + t = entropyControl.getImplantResultPackage().getHistograms(50); + } + else + { + Console.WriteLine("Converging on: " + entropyControl.getResultPackage().getMeanAndStdDev()); + t = entropyControl.getResultPackage().getHistograms(50); + } + for (int l = 0; l < t.Count; l++) + { + Console.WriteLine(t[l]); + } + } + finally + { + Monitor.Exit(varianceContext.previewLock); + } + } + entropyControl.sw.Reset(); + entropyControl.sw.Start(); + entropyControl.timeOfLastPreviewUpdate = entropyControl.sw_Preview.Elapsed.Milliseconds; + } + catch (Exception) + { + //Console.WriteLine("died in updatereadout"); + //Console.ReadLine(); + } + } + + void summary() + { + List t = new List(); + if (varianceContext.implantMode) + { + Console.WriteLine("Converged on: " + entropyControl.getImplantResultPackage().getMeanAndStdDev()); + t = entropyControl.getImplantResultPackage().getHistograms(50); + } + else + { + Console.WriteLine("Converged on: " + entropyControl.getResultPackage().getMeanAndStdDev()); + t = entropyControl.getResultPackage().getHistograms(50); + } + for (int l = 0; l < t.Count; l++) + { + Console.WriteLine(t[l]); + } + } + + void updateSimUIST(bool doPASearch, SimResultPackage resultPackage, string resultString) + { + if (varianceContext.implantMode) + { + writeToConsole("Converging on: " + entropyControl.getImplantResultPackage().getMeanAndStdDev()); + } + else + { + writeToConsole("Converging on: " + entropyControl.getResultPackage().getMeanAndStdDev()); + } + } + + void directProgress(Int32 current, Int32 total) + { + Console.WriteLine(((current / (float)total) * 100.0f).ToString("0.##") + "% of results saved"); + } + + public void writeToConsole(string myString) + { + Console.WriteLine(myString); + } + + void abortRun() + { + if (!commonVars.cancelling) + { + if ((commonVars.runAbort) && (!commonVars.userCancelQuery)) + { + commonVars.userCancelQuery = true; + commonVars.cancelling = true; + Console.WriteLine("Abort and save results so far? (y/n) "); + string userInput = Console.ReadLine(); + if (userInput.ToUpper().StartsWith("Y")) + { + commonVars.runAbort = true; + } + else + { + commonVars.runAbort = false; + } + commonVars.userCancelQuery = false; + } + commonVars.cancelling = false; + } + } + + void abortRunMT(SimResultPackage resultPackage, CancellationTokenSource cancelSource, CancellationToken cancellationToken) + { + if (!commonVars.cancelling) + { + if ((commonVars.runAbort) && (!commonVars.userCancelQuery)) + { + commonVars.userCancelQuery = true; + commonVars.cancelling = true; + Console.WriteLine("Abort and save results so far? (y/n) "); + string userInput = Console.ReadLine(); + if (userInput.ToUpper().StartsWith("Y")) + { + commonVars.runAbort = true; + } + else + { + commonVars.runAbort = false; + } + commonVars.userCancelQuery = false; + + if (commonVars.runAbort) + { + resultPackage.setState(false); + cancelSource.Cancel(); + cancellationToken.ThrowIfCancellationRequested(); + } + } + commonVars.cancelling = false; + } + } + + public void cancelHandler(object sender, ConsoleCancelEventArgs e) + { + commonVars.runAbort = true; + } + + void hlRun(string csvFile) + { + Console.CancelKeyPress += cancelHandler; + + entropyControl.updateStatus = writeLine; + entropyControl.directProgress = directProgress; + entropyControl.clearAbortFlagFunc = clearAbortFlag; + entropyControl.abortRunFunc = abortRun; + entropyControl.abortRunFuncMT = abortRunMT; + entropyControl.updateSimUIFunc = updateSimUIST; + entropyControl.updateSimUIMTFunc = updateSimUIMT; + entropyControl.updateProgressBarFunc = updateProgress; + entropyControl.simRunningFunc = simRunning; + entropyControl.postSimUIFunc = summary; + + string tmp; + if (commonVars.getFriendly()) + { + tmp = utility.Utils.friendlyNumber(commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.nCases)); + } + else + { + tmp = commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.nCases).ToString(); + } + Console.WriteLine("Starting run for " + tmp + " cases."); + entropyControl.swTime = 0.0; + bool threaded = true; + if (varianceContext.numberOfThreads == 1) + { + threaded = false; + } + + entropyControl.EntropyRun(commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.nCases), csvFile, threaded, false); + } + + void hlImplantRun(string csvFile) + { + Console.CancelKeyPress += cancelHandler; + + entropyControl.updateStatus = writeLine; + entropyControl.directProgress = directProgress; + entropyControl.clearAbortFlagFunc = clearAbortFlag; + entropyControl.abortRunFunc = abortRun; + entropyControl.abortRunFuncMT = abortRunMT; + entropyControl.updateImplantSimUIFunc = updateSimUIST; + entropyControl.updateImplantSimUIMTFunc = updateSimUIMT; + entropyControl.implantSimRunningUIFunc = simRunning; + Console.WriteLine("Starting run for " + commonVars.getImplantSimulationSettings().getValue(EntropySettings.properties_i.nCases).ToString() + " cases."); + entropyControl.swTime = 0.0; + bool threaded = true; + if (varianceContext.numberOfThreads == 1) + { + threaded = false; + } + + entropyControl.entropyRun_implant(commonVars.getImplantSimulationSettings().getValue(EntropySettings.properties_i.nCases), csvFile, threaded); + } + + void clearAbortFlag() + { + commonVars.runAbort = false; + } + + void updateSimUIMT() + { + commonVars.m_timer.Elapsed += new System.Timers.ElapsedEventHandler(updateReadout); + } + + void updateProgress(double val) + { + Console.WriteLine((val * 100.0f).ToString("0.##") + "% complete"); + } + + void writeLine(string statusLine) + { + Console.WriteLine(statusLine); + } + + void simRunning() + { + commonVars.setSimRunning(true); + } + + public void setLayerSettings(EntropyLayerSettings readSettings, int layer, bool gdsOnly, bool resumeUI = false, bool updateGeoCoreGeometryFromFile = false) + { + // Ignore resumeUI - only for GUI modes. + pSetLayerSettings(readSettings, layer, gdsOnly, resumeUI, updateGeoCoreGeometryFromFile); + } + + void pSetLayerSettings(EntropyLayerSettings entropyLayerSettings, int settingsIndex, bool gdsOnly, bool resumeUI, bool updateGeoCoreGeometryFromFile = false) + { + // This is used by the pasteHandler and clearHandler to set user interface values to align with the settings. + // It is also used by the load from disk file system, using a temporary MCSettings instance as the source + // In the case of the clearHandler, we get sent a new MCLayerSettings instance, so we have to handle that. + // Check our copyFrom reference. We need to do this early before anything could change. + + // Change settings if the license doesn't support them. + if (commonVars.getL(CommonVars.l.f) != "advanced") + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.lwrType, (Int32)CommonVars.noiseIndex.perlin); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.lwr2Type, (Int32)CommonVars.noiseIndex.perlin); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.gCSEngine, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.edgeSlide, 0); + } + + if (!gdsOnly) + { + if (commonVars.isCopyPrepped()) + { + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr) == 1) || (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr) == 1) || (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr) == 1)) + { + // User pasting into the correlation layer. Disable correlation settings accordingly. + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_corr_ref) == settingsIndex) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.xOL_corr, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.xOL_corr_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_corr_ref) == settingsIndex) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.yOL_corr, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.yOL_corr_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.xOL_ref) == settingsIndex) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.xOL_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.yOL_ref) == settingsIndex) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.yOL_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.CDU_corr_ref) == settingsIndex) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.CDU_corr, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.CDU_corr_ref, -1); + } + if (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.tCDU_corr_ref) == settingsIndex) + { + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.tCDU_corr, 0); + entropyLayerSettings.setInt(EntropyLayerSettings.properties_i.tCDU_corr_ref, -1); + } + } + } + } + + // Remove any average overlay reference to the layer we're in, just for safety. + entropyLayerSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.xOLRefs, settingsIndex, 0); + entropyLayerSettings.setIntArrayValue(EntropyLayerSettings.properties_intarray.yOLRefs, settingsIndex, 0); + + try + { + // Call with '-1' can be triggered by load of project file where the copyFrom isn't set because we're direct driving the DOE flags. + if (commonVars.isCopyPrepped()) + { + commonVars.getSimulationSettings().getDOESettings().setLayerAffected(settingsIndex, commonVars.getCopyDOEUse()); + } + } + catch (Exception) + { + } + + if ((entropyLayerSettings.getDecimal(EntropyLayerSettings.properties_decimal.sCDU) != 0.0m) && (entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) && + (varianceContext.geoCoreCDVariation == false)) + { + ErrorReporter.showMessage_OK("Project uses Oasis/GDS CD variation.", "Overriding preference."); + } + + if (commonVars.isCopyPrepped()) + { + // Align the external data. + commonVars.pasteGeoCoreHandler(settingsIndex); + // commonVars.getGeoCoreHandler(settingsIndex).readValues(commonVars.copyLayerGHSettings); + } + else + { + commonVars.getGeoCoreHandler(settingsIndex).setValid(false); + if ((entropyLayerSettings.getInt(EntropyLayerSettings.properties_i.shapeIndex) == (Int32)CommonVars.shapeNames.GEOCORE) && (entropyLayerSettings.isReloaded())) + { + commonVars.getGeoCoreHandler(settingsIndex).setFilename(entropyLayerSettings.getString(EntropyLayerSettings.properties_s.file)); + commonVars.getGeoCoreHandler(settingsIndex).setValid(true); + if (updateGeoCoreGeometryFromFile) + { + commonVars.getGeoCoreHandler(settingsIndex).setPoints(commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.structure), commonVars.getLayerSettings(settingsIndex).getInt(EntropyLayerSettings.properties_i.lD)); + } + } + } + + // Commit our settings to the list. + commonVars.getLayerSettings(settingsIndex).adjustSettings(entropyLayerSettings, gdsOnly); + + } + + public void doStuff() + { + pDoStuff(); + } + + void pDoStuff() + { + Console.WriteLine(""); + Console.WriteLine(commonVars.titleText + ": headless mode"); + Console.WriteLine("brought to you by its creator: " + commonVars.author); + Console.WriteLine(); + + Console.WriteLine(); + if (varianceContext.xmlFileArg == "") + { + Console.WriteLine("No input file specified."); + Console.WriteLine("Quitting."); + } + else + { + // Test that file actually exists. + bool fileOK = File.Exists(varianceContext.xmlFileArg); + if (!fileOK) + { + ErrorReporter.showMessage_OK("File does not exist. Exiting.", "Error: "); + return; + } + else + { + string[] tokens = varianceContext.xmlFileArg.Split(new char[] { '.' }); + // XML file? + if ((tokens[tokens.Length - 1].ToUpper() != "VARIANCE") && (tokens[tokens.Length - 1].ToUpper() != "XML")) + { + ErrorReporter.showMessage_OK("Valid input file is expected. Exiting.", "Error: "); + return; + } + } + + Console.Write("Loading from " + varianceContext.xmlFileArg + "...."); + commonVars.storage.setLayerSettings = setLayerSettings; + string loadOK = commonVars.storage.loadSimulationSettings(CentralProperties.version, varianceContext.xmlFileArg, commonVars.getSimulationSettings(), commonVars.getSimulationSettings_nonSim(), commonVars.getListOfSettings(), commonVars.getImplantSimulationSettings(), commonVars.getImplantSettings_nonSim(), commonVars.getImplantSettings(), commonVars.getNonSimulationSettings()); + if (loadOK == "") + { + // Loaded fine. + Console.WriteLine("OK"); + commonVars.projectFileName = varianceContext.xmlFileArg; + string csvFile = varianceContext.xmlFileArg.Substring(0, varianceContext.xmlFileArg.Length - 3) + "csv"; + Console.WriteLine("Results will be written to: " + csvFile); + Console.WriteLine("Initializing settings for simulation"); + try + { + if (varianceContext.implantMode) + { + hlImplantRun(csvFile); + } + else + { + hlRun(csvFile); + } + } + catch (Exception ex) + { + Console.WriteLine("Something went wrong: " + ex.Message.ToString()); + } + } + else + { + // Something happened. + Console.WriteLine("not OK: " + loadOK); + } + } + } + } +} diff --git a/Eto/Resources/1dcalc.jpg b/Eto/Resources/1dcalc.jpg new file mode 100644 index 0000000..78eac26 Binary files /dev/null and b/Eto/Resources/1dcalc.jpg differ diff --git a/Eto/Resources/mc_image.png b/Eto/Resources/mc_image.png new file mode 100644 index 0000000..f6f9596 Binary files /dev/null and b/Eto/Resources/mc_image.png differ diff --git a/Eto/Resources/mc_image_int.png b/Eto/Resources/mc_image_int.png new file mode 100644 index 0000000..aaf7292 Binary files /dev/null and b/Eto/Resources/mc_image_int.png differ diff --git a/Eto/Resources/resources.cs b/Eto/Resources/resources.cs new file mode 100644 index 0000000..4a71630 --- /dev/null +++ b/Eto/Resources/resources.cs @@ -0,0 +1,18 @@ +using Eto.Drawing; + +namespace resources +{ + public static class images + { + public static Bitmap oneDImage() + { + return Bitmap.FromResource("resources.1dcalc.jpg"); + } + + public static Bitmap mcImage() + { + return Bitmap.FromResource("resources.mc_image.png"); + } + } +} + diff --git a/Eto/Resources/resources.csproj b/Eto/Resources/resources.csproj new file mode 100644 index 0000000..e6e64f9 --- /dev/null +++ b/Eto/Resources/resources.csproj @@ -0,0 +1,32 @@ + + + + netcoreapp3.1 + Debug;Release;Release_obf + + + + false + + + + false + + + + + + + + + + + + + + + + + + + diff --git a/Eto/Variance.Gtk/Monte_Carlo_2550495b_ico.ico b/Eto/Variance.Gtk/Monte_Carlo_2550495b_ico.ico new file mode 100644 index 0000000..5751add Binary files /dev/null and b/Eto/Variance.Gtk/Monte_Carlo_2550495b_ico.ico differ diff --git a/Eto/Variance.Gtk/Program.cs b/Eto/Variance.Gtk/Program.cs new file mode 100644 index 0000000..e66e292 --- /dev/null +++ b/Eto/Variance.Gtk/Program.cs @@ -0,0 +1,113 @@ +using Eto.Forms; +using Eto.Veldrid; +using Eto.Veldrid.Gtk; +using OpenTK; +using System; +using Variance; +using Veldrid; + +namespace Variance.Gtk +{ + public static class MainClass + { + [STAThread] + public static void Main(string[] args) + { + string xmlFile = ""; + int numberOfThreads = -1; // -1 corresponds to using all threads that are detected. + int graphicsMode = -1; + + if (args.Length > 0) + { + int oneThreadIndex = Array.IndexOf(args, "--1thread"); + int threadsIndex = Array.IndexOf(args, "--threads"); + int graphicsIndex = Array.IndexOf(args, "--graphicsMode"); + + if (oneThreadIndex != -1) + { + numberOfThreads = -1; + } + else + { + if (threadsIndex != -1) + { + numberOfThreads = Math.Max(1, Convert.ToInt32(args[threadsIndex + 1])); + } + } + + if (graphicsIndex != -1) + { + switch (args[graphicsIndex + 1].ToLower()) + { + case "opengl": + graphicsMode = (int)GraphicsBackend.OpenGL; + break; + case "metal": + graphicsMode = (int)GraphicsBackend.Metal; + break; + case "d3d11": + graphicsMode = (int)GraphicsBackend.Direct3D11; + break; + case "vulkan": + default: + graphicsMode = (int)GraphicsBackend.Vulkan; + break; + } + } + + int i = 0; + bool done = false; + while (!done && (i < args.Length)) + { + // Extract XML file. + try + { + string[] tokens = args[i].Split(new char[] { '.' }); + string extension = tokens[tokens.Length - 1]; + if ((extension.ToUpper() == "VARIANCE") || (extension.ToUpper() == "XML")) + { + xmlFile = args[i]; + done = true; + } + } + catch (Exception) + { + } + i++; + } + + // File validation + if (xmlFile != "" && (!System.IO.File.Exists(xmlFile))) + { + Error.ErrorReporter.showMessage_OK("Unable to find project file: " + xmlFile, "ERROR"); + xmlFile = ""; + } + } + + GraphicsBackend backend = VeldridSurface.PreferredBackend; + + if (graphicsMode != -1) + { + try + { + backend = (GraphicsBackend)graphicsMode; + } + catch (Exception) + { + // avoid changing the backend from the preferred case. + } + } + + Int32 HTCount = Environment.ProcessorCount; + + var platform = new Eto.GtkSharp.Platform(); + platform.Add(() => new GtkVeldridSurfaceHandler()); + + VarianceContextGUI varianceContext = new VarianceContextGUI(false, xmlFile, numberOfThreads, + HTCount, backend); + // run application with our main form + VarianceApplication va = new VarianceApplication(platform, varianceContext); + va.Run(); + } + } +} diff --git a/Eto/Variance.Gtk/Variance.Gtk.csproj b/Eto/Variance.Gtk/Variance.Gtk.csproj new file mode 100644 index 0000000..dc4e5f7 --- /dev/null +++ b/Eto/Variance.Gtk/Variance.Gtk.csproj @@ -0,0 +1,36 @@ + + + + WinExe + netcoreapp3.1 + Debug;Release;Release_obf + + + + true + + + + TRACE + + + + TRACE; + + + + TRACE + + + + + + + + + + + + + + diff --git a/Eto/Variance.Gtk2/Monte_Carlo_2550495b_ico.ico b/Eto/Variance.Gtk2/Monte_Carlo_2550495b_ico.ico new file mode 100644 index 0000000..5751add Binary files /dev/null and b/Eto/Variance.Gtk2/Monte_Carlo_2550495b_ico.ico differ diff --git a/Eto/Variance.Gtk2/Program.cs b/Eto/Variance.Gtk2/Program.cs new file mode 100644 index 0000000..4c0f8f7 --- /dev/null +++ b/Eto/Variance.Gtk2/Program.cs @@ -0,0 +1,118 @@ +using Eto.Forms; +using Eto.Veldrid; +using Eto.Veldrid.Gtk; +using OpenTK; +using System; +using Veldrid; + +namespace Variance.Gtk2 +{ + public static class MainClass + { + [STAThread] + public static void Main(string[] args) + { + string xmlFile = ""; + int numberOfThreads = -1; // -1 corresponds to using all threads that are detected. + int graphicsMode = -1; + + if (args.Length > 0) + { + int oneThreadIndex = Array.IndexOf(args, "--1thread"); + int threadsIndex = Array.IndexOf(args, "--threads"); + int graphicsIndex = Array.IndexOf(args, "--graphicsMode"); + + if (oneThreadIndex != -1) + { + numberOfThreads = -1; + } + else + { + if (threadsIndex != -1) + { + numberOfThreads = Math.Max(1, Convert.ToInt32(args[threadsIndex + 1])); + } + } + + if (graphicsIndex != -1) + { + switch (args[graphicsIndex + 1].ToLower()) + { + case "opengl": + graphicsMode = (int)GraphicsBackend.OpenGL; + break; + case "metal": + graphicsMode = (int)GraphicsBackend.Metal; + break; + case "d3d11": + graphicsMode = (int)GraphicsBackend.Direct3D11; + break; + case "vulkan": + default: + graphicsMode = (int)GraphicsBackend.Vulkan; + break; + } + } + + int i = 0; + bool done = false; + while (!done && (i < args.Length)) + { + // Extract XML file. + try + { + string[] tokens = args[i].Split(new char[] { '.' }); + string extension = tokens[tokens.Length - 1]; + if ((extension.ToUpper() == "VARIANCE") || (extension.ToUpper() == "XML")) + { + xmlFile = args[i]; + done = true; + } + } + catch (Exception) + { + } + i++; + } + + // File validation + if (xmlFile != "" && (!System.IO.File.Exists(xmlFile))) + { + Error.ErrorReporter.showMessage_OK("Unable to find project file: " + xmlFile, "ERROR"); + xmlFile = ""; + } + } + + GraphicsBackend backend = VeldridSurface.PreferredBackend; + + if (graphicsMode != -1) + { + try + { + backend = (GraphicsBackend)graphicsMode; + } + catch (Exception) + { + // avoid changing the backend from the preferred case. + } + } + + if (backend == GraphicsBackend.OpenGL) + { + Toolkit.Init(new ToolkitOptions { Backend = PlatformBackend.PreferNative }); + } + + var platform = new Eto.GtkSharp.Platform(); + platform.Add(() => new GtkVeldridSurfaceHandler()); + + + Int32 HTCount = Environment.ProcessorCount; + + VarianceContextGUI varianceContext = new VarianceContextGUI(false, xmlFile, numberOfThreads, + HTCount, backend); + // run application with our main form + VarianceApplication va = new VarianceApplication(platform, varianceContext); + va.Run(); + } + } +} diff --git a/Eto/Variance.Gtk2/Variance.Gtk2.csproj b/Eto/Variance.Gtk2/Variance.Gtk2.csproj new file mode 100644 index 0000000..3534133 --- /dev/null +++ b/Eto/Variance.Gtk2/Variance.Gtk2.csproj @@ -0,0 +1,58 @@ + + + + WinExe + netcoreapp3.1 + + $(AssemblySearchPaths);{GAC} + Debug;Release;Release_obf + + + + true + + + + Project + false + + + + AnyCPU + + + + AnyCPU + + + + + + + + + + + + + + + + gtk-sharp-2.0 + + + gtk-sharp-2.0 + + + glib-sharp-2.0 + + + gtk-sharp-2.0 + + + gtk-sharp-2.0 + + + + diff --git a/Eto/Variance.Mac/App.config b/Eto/Variance.Mac/App.config new file mode 100644 index 0000000..ec01dfb --- /dev/null +++ b/Eto/Variance.Mac/App.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/Eto/Variance.Mac/Icon.icns b/Eto/Variance.Mac/Icon.icns new file mode 100644 index 0000000..8f385bb Binary files /dev/null and b/Eto/Variance.Mac/Icon.icns differ diff --git a/Eto/Variance.Mac/Info.plist b/Eto/Variance.Mac/Info.plist new file mode 100644 index 0000000..8d29819 --- /dev/null +++ b/Eto/Variance.Mac/Info.plist @@ -0,0 +1,36 @@ + + + + + CFBundleIdentifier + com.philstopford.variance + NSHumanReadableCopyright + Copyright © 2015-2019 + CFBundleShortVersionString + 3.6 + CFBundleVersion + 1 + CFBundleDevelopmentRegion + en + CFBundleIconFile + mc_image.icns + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + NSPrincipalClass + NSApplication + CFBundleName + Variance.Mac + CFBundleExecutable + Variance.Mac + LSMinimumSystemVersion + 10.7 + MonoMinimumVersion + 5.10 + NSRequiresAquaSystemAppearance + False + + diff --git a/Eto/Variance.Mac/Program.cs b/Eto/Variance.Mac/Program.cs new file mode 100644 index 0000000..882d42d --- /dev/null +++ b/Eto/Variance.Mac/Program.cs @@ -0,0 +1,119 @@ +using Eto.Forms; +using Eto.Veldrid; +using Eto.Veldrid.Mac; +using OpenTK; +using System; +using System.Diagnostics; +using System.IO; +using Veldrid; + +namespace Variance.Mac +{ + public static class MainClass + { + [STAThread] + public static void Main(string[] args) + { + string xmlFile = ""; + int numberOfThreads = -1; // -1 corresponds to using all threads that are detected. + int graphicsMode = -1; + + if (args.Length > 0) + { + int oneThreadIndex = Array.IndexOf(args, "--1thread"); + int threadsIndex = Array.IndexOf(args, "--threads"); + int graphicsIndex = Array.IndexOf(args, "--graphicsMode"); + + if (oneThreadIndex != -1) + { + numberOfThreads = -1; + } + else + { + if (threadsIndex != -1) + { + numberOfThreads = Math.Max(1, Convert.ToInt32(args[threadsIndex + 1])); + } + } + + if (graphicsIndex != -1) + { + switch (args[graphicsIndex + 1].ToLower()) + { + case "opengl": + graphicsMode = (int)GraphicsBackend.OpenGL; + break; + case "metal": + graphicsMode = (int)GraphicsBackend.Metal; + break; + case "d3d11": + graphicsMode = (int)GraphicsBackend.Direct3D11; + break; + case "vulkan": + default: + graphicsMode = (int)GraphicsBackend.Vulkan; + break; + } + } + + int i = 0; + bool done = false; + while (!done && (i < args.Length)) + { + // Extract XML file. + try + { + string[] tokens = args[i].Split(new char[] { '.' }); + string extension = tokens[tokens.Length - 1]; + if ((extension.ToUpper() == "VARIANCE") || (extension.ToUpper() == "XML")) + { + xmlFile = args[i]; + done = true; + } + } + catch (Exception) + { + } + i++; + } + + // File validation + if (xmlFile != "" && (!System.IO.File.Exists(xmlFile))) + { + Error.ErrorReporter.showMessage_OK("Unable to find project file: " + xmlFile, "ERROR"); + xmlFile = ""; + } + } + + GraphicsBackend backend = VeldridSurface.PreferredBackend; + + if (graphicsMode != -1) + { + try + { + backend = (GraphicsBackend)graphicsMode; + } + catch (Exception) + { + // avoid changing the backend from the preferred case. + } + } + + if (backend == GraphicsBackend.OpenGL) + { + Toolkit.Init(new ToolkitOptions { Backend = PlatformBackend.PreferNative }); + } + + var platform = new Eto.Mac.Platform(); + platform.Add(() => new MacVeldridSurfaceHandler()); + + Int32 HTCount = Environment.ProcessorCount; + + VarianceContextGUI varianceContext = new VarianceContextGUI(false, xmlFile, numberOfThreads, + HTCount, backend); + // run application with our main form + VarianceApplication va = new VarianceApplication(platform, varianceContext); + va.Run(); + } + } +} diff --git a/Eto/Variance.Mac/Variance.Mac.csproj b/Eto/Variance.Mac/Variance.Mac.csproj new file mode 100644 index 0000000..a00a8d8 --- /dev/null +++ b/Eto/Variance.Mac/Variance.Mac.csproj @@ -0,0 +1,50 @@ + + + + WinExe + netcoreapp3.1 + Debug;Release;Release_obf + + osx-x64 + + + + true + + + + AnyCPU + + + + AnyCPU + + + + + + + + + + + + + + + + + + + + + + + + --simple --library "$(OutputPath)$(VeldridSpirvNativeName)" + + + + diff --git a/Eto/Variance.Mac/mc_image.icns b/Eto/Variance.Mac/mc_image.icns new file mode 100644 index 0000000..0ad1a91 Binary files /dev/null and b/Eto/Variance.Mac/mc_image.icns differ diff --git a/Eto/Variance.WPF/Monte_Carlo_2550495b_ico.ico b/Eto/Variance.WPF/Monte_Carlo_2550495b_ico.ico new file mode 100644 index 0000000..5751add Binary files /dev/null and b/Eto/Variance.WPF/Monte_Carlo_2550495b_ico.ico differ diff --git a/Eto/Variance.WPF/Program.cs b/Eto/Variance.WPF/Program.cs new file mode 100644 index 0000000..a256fff --- /dev/null +++ b/Eto/Variance.WPF/Program.cs @@ -0,0 +1,121 @@ +using Eto.Forms; +using Eto.Veldrid; +using Eto.Veldrid.Wpf; +using OpenTK; +using System; +using Veldrid; + +namespace Variance.WPF +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + string xmlFile = ""; + int numberOfThreads = -1; // -1 corresponds to using all threads that are detected. + int graphicsMode = -1; + + if (args.Length > 0) + { + int oneThreadIndex = Array.IndexOf(args, "--1thread"); + int threadsIndex = Array.IndexOf(args, "--threads"); + int graphicsIndex = Array.IndexOf(args, "--graphicsMode"); + + if (oneThreadIndex != -1) + { + numberOfThreads = -1; + } + else + { + if (threadsIndex != -1) + { + numberOfThreads = Math.Max(1, Convert.ToInt32(args[threadsIndex + 1])); + } + } + + if (graphicsIndex != -1) + { + switch (args[graphicsIndex + 1].ToLower()) + { + case "opengl": + graphicsMode = (int)GraphicsBackend.OpenGL; + break; + case "metal": + graphicsMode = (int)GraphicsBackend.Metal; + break; + case "d3d11": + graphicsMode = (int)GraphicsBackend.Direct3D11; + break; + case "vulkan": + default: + graphicsMode = (int)GraphicsBackend.Vulkan; + break; + } + } + + int i = 0; + bool done = false; + while (!done && (i < args.Length)) + { + // Extract XML file. + try + { + string[] tokens = args[i].Split(new char[] { '.' }); + string extension = tokens[tokens.Length - 1]; + if ((extension.ToUpper() == "VARIANCE") || (extension.ToUpper() == "XML")) + { + xmlFile = args[i]; + done = true; + } + } + catch (Exception) + { + } + i++; + } + + // File validation + if (xmlFile != "" && (!System.IO.File.Exists(xmlFile))) + { + Error.ErrorReporter.showMessage_OK("Unable to find project file: " + xmlFile, "ERROR"); + xmlFile = ""; + } + } + + GraphicsBackend backend = VeldridSurface.PreferredBackend; + + if (graphicsMode != -1) + { + try + { + backend = (GraphicsBackend)graphicsMode; + } + catch (Exception) + { + // avoid changing the backend from the preferred case. + } + } + + if (backend == GraphicsBackend.OpenGL) + { + Toolkit.Init(new ToolkitOptions { Backend = PlatformBackend.PreferNative }); + } + + var platform = new Eto.Wpf.Platform(); + platform.Add(() => new WpfVeldridSurfaceHandler()); + + + Int32 HTCount = Environment.ProcessorCount; + + VarianceContextGUI varianceContext = new VarianceContextGUI(false, xmlFile, numberOfThreads, + HTCount, backend); + // run application with our main form + VarianceApplication va = new VarianceApplication(platform, varianceContext); + va.Run(); + } + } +} diff --git a/Eto/Variance.WPF/Variance.WPF.csproj b/Eto/Variance.WPF/Variance.WPF.csproj new file mode 100644 index 0000000..c744706 --- /dev/null +++ b/Eto/Variance.WPF/Variance.WPF.csproj @@ -0,0 +1,39 @@ + + + + WinExe + netcoreapp3.1 + app1.manifest + Monte_Carlo_2550495b_ico.ico + Debug;Release;Release_obf + True + true + + + + + + + + + + + TRACE + + + + + + + + + + + + + + + + + + diff --git a/Eto/Variance.WPF/app1.manifest b/Eto/Variance.WPF/app1.manifest new file mode 100644 index 0000000..2b5548c --- /dev/null +++ b/Eto/Variance.WPF/app1.manifest @@ -0,0 +1,20 @@ + + + + + + + + PerMonitorV2,PerMonitor + + + true/PM + + + diff --git a/Headless/Program.cs b/Headless/Program.cs new file mode 100644 index 0000000..7bddda3 --- /dev/null +++ b/Headless/Program.cs @@ -0,0 +1,153 @@ +using System; + +namespace Variance +{ + class VHeadless + { + static void Main(string[] args) + { + bool implantMode = false; + string xmlFile = ""; + int numberOfThreads = -1; + bool emailSettingsOK = false; + string emailAddress = ""; + string emailPwd = ""; + string emailServer = ""; + string emailPort = ""; + bool emailOnCompletion = false; + bool emailPerJob = false; + bool emailSSL = false; + if (args.Length > 0) + { + int implantIndex = Array.IndexOf(args, "--implant"); + int oneThreadIndex = Array.IndexOf(args, "--1thread"); + int threadsIndex = Array.IndexOf(args, "--threads"); + int emailIndex = Array.IndexOf(args, "--email"); + int emailPerJobIndex = Array.IndexOf(args, "--emailPerJob"); + int emailOnCompletionIndex = Array.IndexOf(args, "--emailOnCompletion"); + + implantMode = (implantIndex != -1); + if (oneThreadIndex != -1) + { + numberOfThreads = -1; + } + else + { + if (threadsIndex != -1) + { + numberOfThreads = Math.Max(1, Convert.ToInt32(args[threadsIndex + 1])); + } + } + + emailPerJob = (emailPerJobIndex != -1); + emailOnCompletion = (emailOnCompletionIndex != -1); + + if (emailIndex != -1) + { + string emailFile = args[emailIndex + 1]; + // Validate that this is actually a file + if (System.IO.File.Exists(emailFile)) + { + bool addressOK, pwdOK, serverOK, portOK; + addressOK = pwdOK = serverOK = portOK = false; + // Set our flags to ensure we have a valid email configuration + + char[] splitArray = new char[] { ' ' }; + System.IO.StreamReader emailSettings = new System.IO.StreamReader(emailFile); + while (!emailSettings.EndOfStream) + { + string line = emailSettings.ReadLine(); + string[] tokens = line.Split(splitArray); + if (line.ToUpper().StartsWith("ADDRESS")) + { + // email address should be here. + emailAddress = tokens[1]; // spaces are illegal in email addresses. + addressOK = true; + } + + if (line.ToUpper().StartsWith("PASSWORD")) + { + emailPwd = tokens[1]; + for (int token = 2; token < tokens.Length; token++) + { + // spaces are legal in passwords so we need to merge tokens. + emailPwd += " " + tokens[token]; + } + pwdOK = true; + } + + if (line.ToUpper().StartsWith("SERVER")) + { + emailServer = tokens[1]; // spaces are illegal in server addresses. + serverOK = true; + } + + if (line.ToUpper().StartsWith("PORT")) + { + emailPort = tokens[1]; // spaces are illegal in server addresses. + portOK = true; + } + + if (line.ToUpper().StartsWith("SSL")) + { + emailSSL = true; + } + } + emailSettingsOK = addressOK && pwdOK && portOK && serverOK; + } + } + + int i = 0; + bool done = false; + while (!done && (i < args.Length)) + { + // Extract XML file. + try + { + string[] tokens = args[i].Split(new char[] { '.' }); + string extension = tokens[tokens.Length - 1]; + if ((extension.ToUpper() == "VARIANCE") || (extension.ToUpper() == "XML")) + { + xmlFile = args[i]; + done = true; + } + } + catch (Exception) + { + } + i++; + } + } + + // File validation + if (!System.IO.File.Exists(xmlFile)) + { + Error.ErrorReporter.showMessage_OK("Unable to find project file: " + xmlFile, "ERROR"); + } + else + { + // Email validation + if (!emailSettingsOK) + { + emailOnCompletion = false; + emailPerJob = false; + } + + Int32 HTCount = Environment.ProcessorCount; + VarianceContext varianceContext = new VarianceContext(implantMode, xmlFile, numberOfThreads, + HTCount, "Variance_hl"); + varianceContext.emailAddress = emailAddress; + varianceContext.emailPwd = emailPwd; + varianceContext.ssl = emailSSL; + varianceContext.host = emailServer; + varianceContext.port = emailPort; + varianceContext.completion = emailOnCompletion; + varianceContext.perJob = emailPerJob; + Headless hl = new Headless(varianceContext); + + Console.CancelKeyPress += hl.cancelHandler; + hl.doStuff(); + } + } + } +} diff --git a/Headless/Variance_Headless.csproj b/Headless/Variance_Headless.csproj new file mode 100644 index 0000000..c65cf6d --- /dev/null +++ b/Headless/Variance_Headless.csproj @@ -0,0 +1,30 @@ + + + + Exe + netcoreapp3.1 + + + Debug;Release;Release_obf + + + + true + + + + AnyCPU + + + + AnyCPU + + + + + + + + + + diff --git a/Monte_Carlo_2550495b_ico.ico b/Monte_Carlo_2550495b_ico.ico new file mode 100644 index 0000000..5751add Binary files /dev/null and b/Monte_Carlo_2550495b_ico.ico differ diff --git a/Series 4.txt b/Series 4.txt new file mode 100644 index 0000000..c1a4d75 --- /dev/null +++ b/Series 4.txt @@ -0,0 +1,126 @@ +Changelog for Variance + +4.2 + + - Performance enhancements through extended use of multithreading. + - Runtime improvements range from 10 to 30%, depending on the situation. + - Aligned Veldrid code with upstream. + - Moved email handling to MailKit. + - Moved to .NET Core 3.1 based on Eto updates. + - Allow independent alignment of flipped shape in X and Y. + +4.1.1 + + - Added graphicsMode switch in launch args. + - d3d11 : D3D 11 + - vulkan : Vulkan + - opengl : OpenGL + - metal : Metal + +4.1 + + - Viewport optimization. + - Eto Veldrid updates. + +4.1a2 + + - GTK3 prototype port added. + - Further performance work on the viewport. + - Re-enabled obfuscation. + - Fixed packaging issues lingering from changes. + +4.1a1 + + - Prototyping new viewport code (Veldrid-based). + - Improved panning code. + - Moving libraries to .NET standard 2.0. + - Refactored some internals. + - Squashed a bug in the U-shape second subshape horizontal length clamping. + +4.0.1 + + - Add an option for the 'friendly' numeric output. + - Fixed 'update' label jumping around. + - Histograms (10 buckets) provided in summary output for each result. + +4.0 + + - Docs for ILB, showing overview of capabilities. + +4.0b1 + + - Beta shake-down. + - Fix for rare crash on project load. + - Revised the keyholer to iterate cuts, rather than use a single pass. This resolves multiple issues, at the cost of runtime. + - Fixed an issue where internal tracking data for the viewport got out-of-sync with the geometry state. + - Found a legacy re-order method in the core that can be served by GeoWrangler. + - Fixed geometry artifacts arising from too-aggressive gap removal in the keyholer. + - Fixed issue where keyhole edge extension may not cut through geometry, leading to geometry issues. + - Fixed issue where the keyholer could fail (now union all cutters before running the Boolean). + - Varous clean-ups and optimizations. + - Refragment merged-overlap geometry. + - Tweaked ClipperLib to experiment with preserving vertices whilst sorting out overlaps. + +4.0a5 + + - Moved to Eto.OpenTK for the etoViewport infrastructure. + - Extensively reworked various parts of the geometry systems arising from keyhole/ILB research. + - Sliver/gap removal has been overhauled. + - Keyholing has been improved. + - Overlap processing (self-intersections) has been addressed. + - Boolean systems now clean up slivers/gaps. + - Extensive test bed used to review behavior. + - GeoWrangler can decompose arbitrary geometry now. + - Background layers are now re-evaluated with updates to the foreground. + - Increases computation from previous approach, but more useful for ILB set-up. + +4.0a4 + + - Fixed contouring of negated holes. + - Root cause was fail of orthogonality check due to colinear points and inconsistent polygon termination based on upstream source. + - ShapeLibrary now ensures incoming geometry meets certain critera prior to review. + - Duplicate terminators are stripped; shape is terminated prior to colinear vertex strip. Next is orthogonality check, and then the terminator is removed to meet downstream expectations. + - GeoWrangler now owns the orthogonality checks and also now has methods to strip terminator and colinear points from geometry. + - Any orthogonal geometry can now be contoured! + - Fix up UI irritations when loading a project file. + - Geometry pipeline auto-decimates geometry if calculation strategy permits. + - Spacing/enclosure calculation is excluded from this system. + - Patched ClipperLib to retain colinear vertices (if desired) during offsetting. This isn't enabled in the upstream code. + - Further work on the sliver/gap removal code to ensure output geometry is correctly oriented and terminated. + - Added optimizations to avoid sliver/gap unless ILB is in use (A/B groups), avoiding runtime impact unless really needed. + - Verified sliver removal for simulations where keyhole geometry is inverted. + +4.0a3 + + - Apply sliver/gap removal to geometry inputs in calculation pipeline. + - Avoids impact from internal walls / artifacts; displayed input geometry will still have keyholes to avoid display issues. + - Friendly value reporting in progress read-outs. + - Multi-threaded CSV export implemented. + - Much faster compared to old approach. + - Implemented write-during-run for external files. + - Significant memory saving, testing impact on runtime. + ! Runtime impact is severe : runs nearly at the same rate as single-threaded mode. + - Might be acceptable given that replay mode exists and that the contents of the viewport can be written to layout files now. + - Restore tessellation optimization that was disabled in a3 for debug work. + - Sampling engine implemented. + - Pre-samples the space (except in PA search mode). + - Currently for standard Monte Carlo, but may offer alternative sampling strategies in future. + - Removed single-threaded operation from GUI. + - Enabled export of viewport contents to GDS/Oasis, alongside the SVG feature. + - Initial work on multi-target export from simulations. + - SVG remains available, but GDSII and Oasis are now available as targets. + - Bug fix for layer name export in Oasis. + +4.0a2 + + - Layout loads now set the active cell according to the top cell definition. + - Staging work for viewport export to layout files. + - Tracking element source for layer creation. + - Viewport work. + - Decoupled the tessellated geometry from the boundaries. + - Optimizations through multithreading. + +4.0a1 + + - ILB pipeline refinements. + - Keyholes are much more robustly generated. diff --git a/Variance.sln b/Variance.sln new file mode 100644 index 0000000..63c7648 --- /dev/null +++ b/Variance.sln @@ -0,0 +1,464 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29102.190 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "geoLib", "..\DesignLibs_GPL\Common\geoLib\geoLib.csproj", "{87C2783D-AC80-4684-875C-F06237E9CC3F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mersenneTwister", "..\DesignLibs_GPL\Common\MersenneTwister\mersenneTwister.csproj", "{9B35CB06-05BD-468C-9D9B-41876B793EF5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "noise", "..\DesignLibs_GPL\Common\Noise\noise.csproj", "{FF8EDE08-8236-49A0-A82E-3B6208B81431}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "errorReporter", "..\DesignLibs_GPL\Eto\errorReporter\errorReporter.csproj", "{6270531D-FCD0-44B8-95BA-4C4CED998179}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibTessDotNet", "..\DesignLibs_GPL\Common\LibTessDotNet\LibTessDotNet.csproj", "{5EE39029-873A-45A0-9259-2198BF8729F4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "geoWrangler", "..\DesignLibs_GPL\Common\geoWrangler\geoWrangler.csproj", "{1D7842B4-12C0-4E11-A6A9-77CEB55F156C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "utility", "..\DesignLibs_GPL\Common\utility\utility.csproj", "{C3255560-6437-4EFF-8948-971A76C6E9AB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "color", "..\DesignLibs_GPL\Common\Color\color.csproj", "{576CBA59-F35E-4F45-905C-26927E2E441A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "entropyRNG", "..\DesignLibs_GPL\Common\entropyRNG\entropyRNG.csproj", "{663A7D25-5255-4B85-B94D-53C431426339}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Variance", "Common\Variance\Variance.csproj", "{DE11C249-FEF2-41C4-AE0C-BAA039788DA8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Variance_hl", "Common\Variance_hl\Variance_hl.csproj", "{FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "geoCore", "..\DesignLibs_GPL\Common\geoCore\geoCore.csproj", "{7B4E57E2-739D-40B7-894A-2EA467C6DE18}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "info.lundin.math", "..\DesignLibs_GPL\Common\info.lundin.math\info.lundin.math.csproj", "{13D15F17-7EC0-48E8-A13E-A0760DB70999}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KDTree", "..\DesignLibs_GPL\Common\KDTree\KDTree.csproj", "{B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "clipper", "..\DesignLibs_GPL\Common\clipper\clipper.csproj", "{150BF729-EDBE-4557-927C-0EB3844794F6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiscUtil", "..\DesignLibs_GPL\Common\MiscUtil\MiscUtil.csproj", "{ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "resources", "Eto\Resources\resources.csproj", "{DAFA7EA7-4087-4943-8FBC-ED5156721409}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eto.VeldridSurface", "..\DesignLibs_GPL\Eto\Eto.VeldridSurface\Eto.VeldridSurface.csproj", "{9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Variance.Gtk2", "Eto\Variance.Gtk2\Variance.Gtk2.csproj", "{9D14949A-93D4-4796-88BF-8B059FA921BA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Variance_Headless", "Headless\Variance_Headless.csproj", "{F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Folder", "Solution Folder", "{9C0B29AE-1364-455B-BC6A-672F626A56C6}" + ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + nuget.config = nuget.config + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Variance.Gtk", "Eto\Variance.Gtk\Variance.Gtk.csproj", "{D89C0EB9-8758-4352-85EC-151C0FFB69A7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Variance.Mac", "Eto\Variance.Mac\Variance.Mac.csproj", "{19A4A36B-C946-4BB6-81AE-285E19272E2A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eto.Veldrid.Gtk", "..\DesignLibs_GPL\Eto\Eto.Veldrid.Gtk\Eto.Veldrid.Gtk.csproj", "{34FED725-6E87-46C7-BA26-AD8F5C32AA4A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eto.Veldrid.Gtk2", "..\DesignLibs_GPL\Eto\Eto.Veldrid.Gtk2\Eto.Veldrid.Gtk2.csproj", "{1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eto.Veldrid.Mac64", "..\DesignLibs_GPL\Eto\Eto.Veldrid.Mac\Eto.Veldrid.Mac64.csproj", "{E37655B8-B033-46DE-BB06-8911C845E8BC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eto.Veldrid.WinForms", "..\DesignLibs_GPL\Eto\Eto.Veldrid.WinForms\Eto.Veldrid.WinForms.csproj", "{1BD5A0FA-CC97-4A53-9609-52944FB30462}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eto.Veldrid.Wpf", "..\DesignLibs_GPL\Eto\Eto.Veldrid.Wpf\Eto.Veldrid.Wpf.csproj", "{F5393816-68AA-4E41-A38C-6DA9BF6C2916}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Variance.WPF", "Eto\Variance.WPF\Variance.WPF.csproj", "{A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DesignLibs_GPL", "DesignLibs_GPL", "{737F4D86-2E7A-48E5-89B9-7DEB6EFC2443}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Eto", "Eto", "{B440F290-1E0F-45F1-ADB7-415AEA8B04CA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{59912BF0-0AF4-41FA-B82B-B9FAD59296CD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Debug|x64.ActiveCfg = Debug|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Debug|x64.Build.0 = Debug|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Debug|x86.ActiveCfg = Debug|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Debug|x86.Build.0 = Debug|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Release|Any CPU.Build.0 = Release|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Release|x64.ActiveCfg = Release|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Release|x64.Build.0 = Release|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Release|x86.ActiveCfg = Release|Any CPU + {87C2783D-AC80-4684-875C-F06237E9CC3F}.Release|x86.Build.0 = Release|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Debug|x64.ActiveCfg = Debug|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Debug|x64.Build.0 = Debug|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Debug|x86.ActiveCfg = Debug|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Debug|x86.Build.0 = Debug|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Release|Any CPU.Build.0 = Release|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Release|x64.ActiveCfg = Release|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Release|x64.Build.0 = Release|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Release|x86.ActiveCfg = Release|Any CPU + {9B35CB06-05BD-468C-9D9B-41876B793EF5}.Release|x86.Build.0 = Release|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Debug|x64.ActiveCfg = Debug|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Debug|x64.Build.0 = Debug|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Debug|x86.ActiveCfg = Debug|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Debug|x86.Build.0 = Debug|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Release|Any CPU.Build.0 = Release|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Release|x64.ActiveCfg = Release|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Release|x64.Build.0 = Release|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Release|x86.ActiveCfg = Release|Any CPU + {FF8EDE08-8236-49A0-A82E-3B6208B81431}.Release|x86.Build.0 = Release|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Debug|x64.ActiveCfg = Debug|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Debug|x64.Build.0 = Debug|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Debug|x86.ActiveCfg = Debug|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Debug|x86.Build.0 = Debug|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Release|Any CPU.Build.0 = Release|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Release|x64.ActiveCfg = Release|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Release|x64.Build.0 = Release|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Release|x86.ActiveCfg = Release|Any CPU + {6270531D-FCD0-44B8-95BA-4C4CED998179}.Release|x86.Build.0 = Release|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Debug|x64.ActiveCfg = Debug|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Debug|x64.Build.0 = Debug|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Debug|x86.ActiveCfg = Debug|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Debug|x86.Build.0 = Debug|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Release|Any CPU.Build.0 = Release|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Release|x64.ActiveCfg = Release|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Release|x64.Build.0 = Release|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Release|x86.ActiveCfg = Release|Any CPU + {5EE39029-873A-45A0-9259-2198BF8729F4}.Release|x86.Build.0 = Release|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Debug|x64.ActiveCfg = Debug|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Debug|x64.Build.0 = Debug|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Debug|x86.ActiveCfg = Debug|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Debug|x86.Build.0 = Debug|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Release|Any CPU.Build.0 = Release|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Release|x64.ActiveCfg = Release|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Release|x64.Build.0 = Release|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Release|x86.ActiveCfg = Release|Any CPU + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C}.Release|x86.Build.0 = Release|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Debug|x64.ActiveCfg = Debug|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Debug|x64.Build.0 = Debug|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Debug|x86.ActiveCfg = Debug|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Debug|x86.Build.0 = Debug|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Release|Any CPU.Build.0 = Release|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Release|x64.ActiveCfg = Release|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Release|x64.Build.0 = Release|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Release|x86.ActiveCfg = Release|Any CPU + {C3255560-6437-4EFF-8948-971A76C6E9AB}.Release|x86.Build.0 = Release|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Debug|x64.ActiveCfg = Debug|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Debug|x64.Build.0 = Debug|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Debug|x86.ActiveCfg = Debug|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Debug|x86.Build.0 = Debug|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Release|Any CPU.Build.0 = Release|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Release|x64.ActiveCfg = Release|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Release|x64.Build.0 = Release|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Release|x86.ActiveCfg = Release|Any CPU + {576CBA59-F35E-4F45-905C-26927E2E441A}.Release|x86.Build.0 = Release|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Debug|Any CPU.Build.0 = Debug|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Debug|x64.ActiveCfg = Debug|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Debug|x64.Build.0 = Debug|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Debug|x86.ActiveCfg = Debug|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Debug|x86.Build.0 = Debug|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Release|Any CPU.ActiveCfg = Release|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Release|Any CPU.Build.0 = Release|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Release|x64.ActiveCfg = Release|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Release|x64.Build.0 = Release|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Release|x86.ActiveCfg = Release|Any CPU + {663A7D25-5255-4B85-B94D-53C431426339}.Release|x86.Build.0 = Release|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Debug|x64.ActiveCfg = Debug|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Debug|x64.Build.0 = Debug|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Debug|x86.ActiveCfg = Debug|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Debug|x86.Build.0 = Debug|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Release|Any CPU.Build.0 = Release|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Release|x64.ActiveCfg = Release|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Release|x64.Build.0 = Release|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Release|x86.ActiveCfg = Release|Any CPU + {DE11C249-FEF2-41C4-AE0C-BAA039788DA8}.Release|x86.Build.0 = Release|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Debug|x64.ActiveCfg = Debug|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Debug|x64.Build.0 = Debug|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Debug|x86.ActiveCfg = Debug|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Debug|x86.Build.0 = Debug|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Release|Any CPU.Build.0 = Release|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Release|x64.ActiveCfg = Release|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Release|x64.Build.0 = Release|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Release|x86.ActiveCfg = Release|Any CPU + {FFC02E18-22CD-4F8D-9DF1-E87FE58C4821}.Release|x86.Build.0 = Release|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Debug|x64.ActiveCfg = Debug|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Debug|x64.Build.0 = Debug|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Debug|x86.ActiveCfg = Debug|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Debug|x86.Build.0 = Debug|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Release|Any CPU.Build.0 = Release|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Release|x64.ActiveCfg = Release|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Release|x64.Build.0 = Release|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Release|x86.ActiveCfg = Release|Any CPU + {7B4E57E2-739D-40B7-894A-2EA467C6DE18}.Release|x86.Build.0 = Release|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Debug|x64.ActiveCfg = Debug|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Debug|x64.Build.0 = Debug|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Debug|x86.ActiveCfg = Debug|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Debug|x86.Build.0 = Debug|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Release|Any CPU.ActiveCfg = Release|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Release|Any CPU.Build.0 = Release|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Release|x64.ActiveCfg = Release|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Release|x64.Build.0 = Release|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Release|x86.ActiveCfg = Release|Any CPU + {13D15F17-7EC0-48E8-A13E-A0760DB70999}.Release|x86.Build.0 = Release|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Debug|x64.ActiveCfg = Debug|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Debug|x64.Build.0 = Debug|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Debug|x86.ActiveCfg = Debug|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Debug|x86.Build.0 = Debug|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Release|Any CPU.Build.0 = Release|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Release|x64.ActiveCfg = Release|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Release|x64.Build.0 = Release|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Release|x86.ActiveCfg = Release|Any CPU + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF}.Release|x86.Build.0 = Release|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Debug|x64.ActiveCfg = Debug|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Debug|x64.Build.0 = Debug|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Debug|x86.ActiveCfg = Debug|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Debug|x86.Build.0 = Debug|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Release|Any CPU.Build.0 = Release|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Release|x64.ActiveCfg = Release|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Release|x64.Build.0 = Release|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Release|x86.ActiveCfg = Release|Any CPU + {150BF729-EDBE-4557-927C-0EB3844794F6}.Release|x86.Build.0 = Release|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Debug|x64.ActiveCfg = Debug|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Debug|x64.Build.0 = Debug|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Debug|x86.ActiveCfg = Debug|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Debug|x86.Build.0 = Debug|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Release|Any CPU.Build.0 = Release|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Release|x64.ActiveCfg = Release|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Release|x64.Build.0 = Release|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Release|x86.ActiveCfg = Release|Any CPU + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D}.Release|x86.Build.0 = Release|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Debug|x64.ActiveCfg = Debug|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Debug|x64.Build.0 = Debug|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Debug|x86.ActiveCfg = Debug|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Debug|x86.Build.0 = Debug|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Release|Any CPU.Build.0 = Release|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Release|x64.ActiveCfg = Release|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Release|x64.Build.0 = Release|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Release|x86.ActiveCfg = Release|Any CPU + {DAFA7EA7-4087-4943-8FBC-ED5156721409}.Release|x86.Build.0 = Release|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Debug|x64.ActiveCfg = Debug|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Debug|x64.Build.0 = Debug|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Debug|x86.ActiveCfg = Debug|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Debug|x86.Build.0 = Debug|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Release|Any CPU.Build.0 = Release|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Release|x64.ActiveCfg = Release|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Release|x64.Build.0 = Release|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Release|x86.ActiveCfg = Release|Any CPU + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F}.Release|x86.Build.0 = Release|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Debug|x64.Build.0 = Debug|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Debug|x86.Build.0 = Debug|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Release|Any CPU.Build.0 = Release|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Release|x64.ActiveCfg = Release|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Release|x64.Build.0 = Release|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Release|x86.ActiveCfg = Release|Any CPU + {9D14949A-93D4-4796-88BF-8B059FA921BA}.Release|x86.Build.0 = Release|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Debug|x64.ActiveCfg = Debug|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Debug|x64.Build.0 = Debug|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Debug|x86.Build.0 = Debug|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Release|Any CPU.Build.0 = Release|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Release|x64.ActiveCfg = Release|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Release|x64.Build.0 = Release|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Release|x86.ActiveCfg = Release|Any CPU + {F3EEFD6A-23CD-410A-8BEC-CA2B7E29553D}.Release|x86.Build.0 = Release|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Debug|x64.ActiveCfg = Debug|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Debug|x64.Build.0 = Debug|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Debug|x86.ActiveCfg = Debug|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Debug|x86.Build.0 = Debug|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Release|Any CPU.Build.0 = Release|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Release|x64.ActiveCfg = Release|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Release|x64.Build.0 = Release|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Release|x86.ActiveCfg = Release|Any CPU + {D89C0EB9-8758-4352-85EC-151C0FFB69A7}.Release|x86.Build.0 = Release|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Debug|x64.ActiveCfg = Debug|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Debug|x64.Build.0 = Debug|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Debug|x86.ActiveCfg = Debug|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Debug|x86.Build.0 = Debug|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Release|Any CPU.Build.0 = Release|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Release|x64.ActiveCfg = Release|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Release|x64.Build.0 = Release|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Release|x86.ActiveCfg = Release|Any CPU + {19A4A36B-C946-4BB6-81AE-285E19272E2A}.Release|x86.Build.0 = Release|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Debug|x64.ActiveCfg = Debug|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Debug|x64.Build.0 = Debug|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Debug|x86.ActiveCfg = Debug|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Debug|x86.Build.0 = Debug|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Release|Any CPU.Build.0 = Release|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Release|x64.ActiveCfg = Release|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Release|x64.Build.0 = Release|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Release|x86.ActiveCfg = Release|Any CPU + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A}.Release|x86.Build.0 = Release|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Debug|x64.ActiveCfg = Debug|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Debug|x64.Build.0 = Debug|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Debug|x86.ActiveCfg = Debug|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Debug|x86.Build.0 = Debug|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Release|Any CPU.Build.0 = Release|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Release|x64.ActiveCfg = Release|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Release|x64.Build.0 = Release|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Release|x86.ActiveCfg = Release|Any CPU + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7}.Release|x86.Build.0 = Release|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Debug|x64.ActiveCfg = Debug|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Debug|x64.Build.0 = Debug|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Debug|x86.ActiveCfg = Debug|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Debug|x86.Build.0 = Debug|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Release|Any CPU.Build.0 = Release|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Release|x64.ActiveCfg = Release|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Release|x64.Build.0 = Release|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Release|x86.ActiveCfg = Release|Any CPU + {E37655B8-B033-46DE-BB06-8911C845E8BC}.Release|x86.Build.0 = Release|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Debug|x64.ActiveCfg = Debug|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Debug|x64.Build.0 = Debug|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Debug|x86.ActiveCfg = Debug|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Debug|x86.Build.0 = Debug|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Release|Any CPU.Build.0 = Release|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Release|x64.ActiveCfg = Release|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Release|x64.Build.0 = Release|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Release|x86.ActiveCfg = Release|Any CPU + {1BD5A0FA-CC97-4A53-9609-52944FB30462}.Release|x86.Build.0 = Release|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Debug|x64.ActiveCfg = Debug|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Debug|x64.Build.0 = Debug|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Debug|x86.ActiveCfg = Debug|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Debug|x86.Build.0 = Debug|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Release|Any CPU.Build.0 = Release|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Release|x64.ActiveCfg = Release|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Release|x64.Build.0 = Release|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Release|x86.ActiveCfg = Release|Any CPU + {F5393816-68AA-4E41-A38C-6DA9BF6C2916}.Release|x86.Build.0 = Release|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Debug|x64.ActiveCfg = Debug|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Debug|x64.Build.0 = Debug|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Debug|x86.ActiveCfg = Debug|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Debug|x86.Build.0 = Debug|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Release|Any CPU.Build.0 = Release|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Release|x64.ActiveCfg = Release|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Release|x64.Build.0 = Release|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Release|x86.ActiveCfg = Release|Any CPU + {A50E044D-3E14-40C0-95F7-54FCBD6BD0D3}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {87C2783D-AC80-4684-875C-F06237E9CC3F} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {9B35CB06-05BD-468C-9D9B-41876B793EF5} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {FF8EDE08-8236-49A0-A82E-3B6208B81431} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {6270531D-FCD0-44B8-95BA-4C4CED998179} = {B440F290-1E0F-45F1-ADB7-415AEA8B04CA} + {5EE39029-873A-45A0-9259-2198BF8729F4} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {1D7842B4-12C0-4E11-A6A9-77CEB55F156C} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {C3255560-6437-4EFF-8948-971A76C6E9AB} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {576CBA59-F35E-4F45-905C-26927E2E441A} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {663A7D25-5255-4B85-B94D-53C431426339} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {7B4E57E2-739D-40B7-894A-2EA467C6DE18} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {13D15F17-7EC0-48E8-A13E-A0760DB70999} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {B72FF9C0-FE72-47B2-B4ED-D11575B2D1DF} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {150BF729-EDBE-4557-927C-0EB3844794F6} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {ADB1092A-6BD2-4FAB-BC39-91BB49F0AD2D} = {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} + {9B4D03BB-9C3F-4D1C-B6AF-F3647EB6106F} = {B440F290-1E0F-45F1-ADB7-415AEA8B04CA} + {34FED725-6E87-46C7-BA26-AD8F5C32AA4A} = {B440F290-1E0F-45F1-ADB7-415AEA8B04CA} + {1F3A4CC0-B582-4600-BD28-34CE0D16BFB7} = {B440F290-1E0F-45F1-ADB7-415AEA8B04CA} + {E37655B8-B033-46DE-BB06-8911C845E8BC} = {B440F290-1E0F-45F1-ADB7-415AEA8B04CA} + {1BD5A0FA-CC97-4A53-9609-52944FB30462} = {B440F290-1E0F-45F1-ADB7-415AEA8B04CA} + {F5393816-68AA-4E41-A38C-6DA9BF6C2916} = {B440F290-1E0F-45F1-ADB7-415AEA8B04CA} + {B440F290-1E0F-45F1-ADB7-415AEA8B04CA} = {737F4D86-2E7A-48E5-89B9-7DEB6EFC2443} + {59912BF0-0AF4-41FA-B82B-B9FAD59296CD} = {737F4D86-2E7A-48E5-89B9-7DEB6EFC2443} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B6266959-173B-4E69-92E6-CEF36DE419C8} + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + Policies = $0 + $0.TextStylePolicy = $1 + version = 0.24 + StartupItem = SharpFlame.Gui.Linux\SharpFlame.Gui.Linux.csproj + EndGlobalSection +EndGlobal diff --git a/nuget.config b/nuget.config new file mode 100644 index 0000000..5ee6a0c --- /dev/null +++ b/nuget.config @@ -0,0 +1,7 @@ + + + + + + +