/// <summary> /// Draws NPlot.ImagePlot (heatmap). /// Does Clear(), axis are hidden. /// Can be used for icons as well. /// </summary> /// <param name="plotSurface2D"> /// A <see cref="IPlotSurface2D"/> /// </param> /// <param name="table"> /// A <see cref="Table3D"/> /// </param> public static void Draw(IPlotSurface2D plotSurface2D, Table3D table) { float[] valuesZ = table.GetValuesZasFloats(); // NPlot ImagePlot, needs 2D-array of type double int cyi = table.CountY - 1; int cx = table.CountX; double[,] data = new double[table.CountY, cx]; for (int i = 0; i < valuesZ.Length; i++) { // [row, col], include y-reordering, same effect as plotSurface.YAxis1.Reversed // not using using YAxis1.Reversed seems to avoid a display bug (white row sometimes included) data[cyi - i / cx, i % cx] = valuesZ[i]; } var ip = new ImagePlot(data); ip.Gradient = gradient; plotSurface2D.Clear(); plotSurface2D.Add(ip); plotSurface2D.XAxis1.Hidden = true; plotSurface2D.YAxis1.Hidden = true; }
protected override void OnTableTypeChanged(TreeIter iter, TableType newTableType) { Table3D table3D = (Table3D)treeModel.GetValue(iter, (int)ColumnNr3D.Obj); viewModel.ChangeTableType(table3D, newTableType); viewModel.SetNodeContentTypeChanged(iter, table3D); }
public void SetNodeContent(TreeIter iter, Table3D table3D) { // TODO optimize when columns are final store.SetValue(iter, (int)ColumnNr3D.Obj, table3D); store.SetValue(iter, (int)ColumnNr3D.Category, table3D.Category); store.SetValue(iter, (int)ColumnNr3D.Toggle, false); store.SetValue(iter, (int)ColumnNr3D.Title, table3D.Title); store.SetValue(iter, (int)ColumnNr3D.UnitZ, table3D.UnitZ); store.SetValue(iter, (int)ColumnNr3D.NameX, table3D.NameX); store.SetValue(iter, (int)ColumnNr3D.NameY, table3D.NameY); store.SetValue(iter, (int)ColumnNr3D.UnitX, table3D.UnitX); store.SetValue(iter, (int)ColumnNr3D.UnitY, table3D.UnitY); store.SetValue(iter, (int)ColumnNr3D.CountX, table3D.CountX); store.SetValue(iter, (int)ColumnNr3D.CountY, table3D.CountY); store.SetValue(iter, (int)ColumnNr3D.CountZ, table3D.CountZ); store.SetValue(iter, (int)ColumnNr3D.Xmin, table3D.Xmin); store.SetValue(iter, (int)ColumnNr3D.Xmax, table3D.Xmax); store.SetValue(iter, (int)ColumnNr3D.Ymin, table3D.Ymin); store.SetValue(iter, (int)ColumnNr3D.Ymax, table3D.Ymax); store.SetValue(iter, (int)ColumnNr3D.ZPos, table3D.RangeZ.Pos); store.SetValue(iter, (int)ColumnNr3D.Location, table3D.Location); store.SetValue(iter, (int)ColumnNr3D.Description, table3D.Description); SetNodeContentTypeChanged(iter, table3D); }
// create or close gnuplot window void OnPlotActionActivated(object sender, System.EventArgs e) { try { // gnuplot process itself can be slow to startup // so this does not prevent closing it immediatly when pressed twice //plotExternalAction.Sensitive = false; switch (CurrentUI) { case ActiveUI.View2D: Table2D table2D = dataView2DGtk.Selected; if (table2D != null) { GnuPlot.ToggleGnuPlot(table2D); } break; case ActiveUI.View3D: Table3D table3D = dataView3DGtk.Selected; if (table3D != null) { GnuPlot.ToggleGnuPlot(table3D); } break; } } catch (GnuPlotProcessException ex) { Console.Error.WriteLine(ex); ErrorMsg("Error launching gnuplot!", ex.Message + "\n\nHave you installed gnuplot?" + "\nYou also may need to edit file '" + appName + ".exe.config'." + "\nCurrent platform-ID is '" + System.Environment.OSVersion.Platform.ToString() + "'." + "\nSee 'README.txt' for details."); } catch (GnuPlotException ex) { Console.Error.WriteLine(ex); ErrorMsg("Error launching gnuplot!", ex.Message); } }
public Gdk.Pixbuf CreateIcon3D(Table3D table) { if (table.Zmin == table.Zmax) { return(GetNoDataPixBuf); } Plot3D.Draw(plotSurface, table); // Things like Padding needs to be set each time after Clear() plotSurface.Padding = padding; using (System.Drawing.Graphics g = Graphics.FromImage(bitmap_cache)) { plotSurface.Draw(g, bounds); } if (memoryStream == null) { memoryStream = new System.IO.MemoryStream(MemoryStreamCapacity); } memoryStream.Position = 0; bitmap_cache.Save(memoryStream, imageFormat); memoryStream.Position = 0; // TODO create Pixbuf directly from bitmap if possible, avoiding MemoryStream return(new Gdk.Pixbuf(memoryStream)); }
// static string AnnotationStr (Table2D table2D) // { // return string.Format ("Min: {0} Max: {1} Avg: {2}", table2D.Ymin.ToString (), table2D.Ymax.ToString (), table2D.Yavg.ToString ()); // } // TODO investigate piping binary data via standard input, avoiding temp file // However temp file might be useful for manual gnuplot experiments. static void WriteGnuPlotBinary(BinaryWriter bw, Table3D table3D) { /* from gnuplot help PDF page 157, "matrix binary": * * Single precision floats are stored in a binary file as follows: * <N+1> <y0> <y1> <y2> ... <yN> * <x0> <z0,0> <z0,1> <z0,2> ... <z0,N> * <x1> <z1,0> <z1,1> <z1,2> ... <z1,N> */ // x <-> y designation from above (manual) seems wrong as xlabel etc. matches code below! float[] valuesX = table3D.ValuesX; // write first float: <N+1> bw.Write((float)(valuesX.Length)); // x axis foreach (var x in valuesX) { bw.Write(x); } float[] valuesY = table3D.ValuesY; float[] valuesZ = table3D.GetValuesZasFloats(); for (int iy = 0; iy < valuesY.Length; iy++) { bw.Write(valuesY [iy]); for (int ix = 0; ix < valuesX.Length; ix++) { bw.Write(valuesZ [ix + iy * valuesX.Length]); } } }
void Merge(Table3D original, Table3D newTable) { MergeCommon(original, newTable); original.NameY = UpdateString(original.NameY, newTable.NameY); original.UnitZ = UpdateString(original.UnitZ, newTable.UnitZ); }
/// <summary> /// Constructor /// </summary> /// <param name="symbol">Symbol of variable</param> /// <param name="measure">Measure</param> /// <param name="detector">Detector of variables</param> internal VariableMeasurement(string symbol, IMeasurement measure, IVariableDetector detector) { this.symbol = symbol; this.measurement = measure; this.detector = detector; object par = measure.Type; if (par is IOneVariableFunction) { func = par as IOneVariableFunction; operationDetector = new OneVariableFunctionDetector(detector); funcwrapper = new OneVariableFunctionDetector(func); } else if (par is Table2D) { table2D = par as Table2D; } else if (par is Table3D) { table3D = par as Table3D; } /*!!! else if (par is FuncReturn) * { * funcReturn = par as FuncReturn; * //operationDetector = new FormulaEditor.Func.FuncDetector(detector, ) * }*/ else { acceptor = this; } tree = new ObjectFormulaTree(this, new List <ObjectFormulaTree>()); }
public void TableTooSmallNotValid() { Assert.Throws <ArgumentException>(() => { var table = new Table3D(x, y, z, new[] { f[0] }); table.Validate(); }); }
/// <summary> /// Constructor /// </summary> /// <param name="label">Label of object</param> public FormTable3D(IObjectLabel label) : this() { this.LoadResources(); this.label = label; table = label.Object as Table3D; UpdateFormUI(); }
void HandleTreeViewRowActivated(object o, RowActivatedArgs args) { Table3D table3D = Selected; if (table3D != null && Activated != null) { Activated(this, new ActionEventArgs(table3D)); } }
public void FindMaps(int startPos, int lastPos, out IList <Table2D> list2D, out IList <Table3D> list3D) { this.startPos = startPos; // smallest 2D table record size is 12 bytes lastPos = Math.Min(lastPos, Size - 1 - 12); this.lastPos = lastPos; // Restricting pointers to a realistic range improves detection accuracy. // Using conservative settings here: // In Subaru ROMs at least first 8 KiB usually contain low level stuff, no maps. Table.PosMin = 8 * KiB; Table.PosMax = Size - 1; // default capacities suitable for current (MY2015 2MiB) diesel ROMs list2D = new List <Table2D> (1500); list3D = new List <Table3D> (1300); OnProgressChanged(0); this.percentDoneLastReport = 0; // records need to be 4-byte-aligned anyway // --> much faster than just ++pos, also skips a few false positives for (long pos = startPos; pos <= lastPos; pos = NextAlignedPos(pos, 4)) { stream.Position = pos; CheckProgress(pos); // try Table3D first as it contains more struct info; more info to validate = better detection Table3D info3D = Table3D.TryParseValid(this.stream); if (info3D != null) { list3D.Add(info3D); // this is often a valid next pos, already aligned pos = stream.Position; } else { // must back off stream.Position = pos; // not 3D, try 2D Table2D info2D = Table2D.TryParseValid(this.stream); if (info2D != null) { list2D.Add(info2D); // this is often a valid next pos, already aligned pos = stream.Position; } else { // nothing valid, try at next possible location pos++; } } } OnProgressChanged(100); }
/* * public IList<Table3D> FindMaps3D () * { * return FindMaps3D (0); * } * * public IList<Table3D> FindMaps3D (int startPos) * { * // should stop at EOF * return FindMaps3D (startPos, (int)fs.Length); * } * * public IList<Table3D> FindMaps3D (int startPos, int lastPos) * { * this.startPos = startPos; * lastPos = Math.Min (lastPos, (int)fs.Length); * this.lastPos = lastPos; * OnProgressChanged (0); * this.percentDoneLastReport = 0; * List<Table3D> list3D = new List<Table3D> (800); * * for (long pos = startPos; pos <= lastPos;) { * // check for end of file * if (pos >= fs.Length) * break; * fs.Position = pos; * CheckProgress (pos); * * Table3D info3D = Table3D.TryParseValid (this.fs); * if (info3D != null) { * list3D.Add (info3D); * pos = fs.Position; * } else { * // not valid, try at next possible location * pos++; * } * } * OnProgressChanged (100); * return list3D; * } */ public void FindMaps(int startPos, int lastPos, out IList <Table2D> list2D, out IList <Table3D> list3D) { this.startPos = startPos; lastPos = Math.Min(lastPos, (int)fs.Length); this.lastPos = lastPos; // Restricting pointers to a range can improve detection accuracy. // Using conservative settings here: Table.PosMin = 8 * 1024; Table.PosMax = (int)fs.Length - 1; // default capacities suitable for SH7059 diesel ROMs list2D = new List <Table2D> (800); list3D = new List <Table3D> (1000); OnProgressChanged(0); this.percentDoneLastReport = 0; for (long pos = startPos; pos <= lastPos;) { // check for end of file if (pos >= fs.Length) { break; } fs.Position = pos; CheckProgress(pos); // try Table3D first as it contains more struct info; more info to validate = better detection Table3D info3D = Table3D.TryParseValid(this.fs); if (info3D != null) { list3D.Add(info3D); pos = fs.Position; } else { // must back off fs.Position = pos; // not 3D, try 2D Table2D info2D = Table2D.TryParseValid(this.fs); if (info2D != null) { list2D.Add(info2D); pos = fs.Position; } else { // nothing valid, try at next possible location pos++; } } } OnProgressChanged(100); }
static Table3D ParseTable3D(XElement el) { Table3D table3D = new Table3D(); ParseCommon(el, table3D); int? address; string name, unit; XElement subEl; subEl = el.Element(X_axisX); if (subEl != null) { ParseAxis(subEl, out address, out name, out unit); table3D.NameX = name; table3D.UnitX = unit; if (address.HasValue) { table3D.RangeX = new Util.Range(address.Value, 0); } } subEl = el.Element(X_axisY); if (subEl != null) { ParseAxis(subEl, out address, out name, out unit); table3D.NameY = name; table3D.UnitY = unit; if (address.HasValue) { table3D.RangeY = new Util.Range(address.Value, 0); } } subEl = el.Element(X_values); if (subEl != null) { TableType?tableType; ParseValues(subEl, out address, out unit, out tableType); table3D.UnitZ = unit; if (address.HasValue) { table3D.RangeZ = new Util.Range(address.Value, 0); } if (tableType.HasValue) { table3D.TableType = tableType.Value; } } table3D.Description = (string)el.Element(X_description); return(table3D); }
public void SetNodeContentTypeChanged(TreeIter iter, Table3D table3D) { store.SetValue(iter, (int)ColumnNr3D.Type, (int)table3D.TableType); store.SetValue(iter, (int)ColumnNr3D.Zmin, table3D.Zmin); store.SetValue(iter, (int)ColumnNr3D.Zavg, table3D.Zavg); store.SetValue(iter, (int)ColumnNr3D.Zmax, table3D.Zmax); if (iconsCached) { CreateSetNewIcon(iter, table3D); } }
static void ScriptGnuplot3D(TextWriter tw, Table3D table3D) { tw.WriteLine(SetLabel("xlabel", table3D.NameX, true, table3D.UnitX)); tw.WriteLine(SetLabel("ylabel", table3D.NameY, true, table3D.UnitY)); // use title instead of zlabel as it would need extra space tw.WriteLine(SetLabel("title", table3D.Title, false, table3D.UnitZ)); tw.WriteLine("set label 1 \"" + AnnotationStr(table3D) + "\" at screen 0.01,0.95 front left textcolor rgb \"blue\""); //set label 1 "Annotation Label" at screen 0.01,0.95 front left textcolor rgb "blue" tw.WriteLine("load \"" + TemplateFile3D + "\""); }
public MainWindow(string[] args) : base(Gtk.WindowType.Toplevel) { // Execute Gtk# visual designer generated code (MonoDevelop http://monodevelop.com/ ) // Obviously, Visual Studio doesn't have a Gtk# designer, you'll have to code all UI stuff by yourself. // Compiling existing generated UI code within Visual Studio does work however. Build(); this.Icon = MainClass.AppIcon; dataView3DModelGtk = new DataView3DModelGtk(this.data); dataView3DGtk = new DataView3DGtk(dataView3DModelGtk, treeview3D); dataView3DGtk.Activated += delegate(object sender, ActionEventArgs e) { Table3D table3D = (Table3D)e.Tag; if (table3D != null) { this.Show3D(table3D); } }; dataView2DModelGtk = new DataView2DModelGtk(this.data); dataView2DGtk = new DataView2DGtk(dataView2DModelGtk, treeview2D); dataView2DGtk.Activated += delegate(object sender, ActionEventArgs e) { Table2D table2D = (Table2D)e.Tag; if (table2D != null) { this.Show2D(table2D); } }; plot2D = new Plot2D(plotSurface); this.vpaned2D.Add2(plotSurface); global::Gtk.Paned.PanedChild pc = ((global::Gtk.Paned.PanedChild)(this.vpaned2D[plotSurface])); // to resize both panes proportionally when parent (main window) resizes pc.Resize = false; // pc.Shrink = false; this.vpaned2D.ShowAll(); this.notebook1.Page = 1; if (Config.IconsOnByDefault) { iconsAction.Active = true; dataView2DGtk.ShowIcons = true; dataView3DGtk.ShowIcons = true; } // program arguments: first argument is ROM path to auto-load if (args != null && args.Length > 0 && !string.IsNullOrEmpty(args[0])) { OpenRom(args[0]); } }
static XElement GetXElement(Table3D table3D) { return(new XElement(X_table3D, new XAttribute(X_category, table3D.Category), new XAttribute(X_name, table3D.Title), new XAttribute(X_address, HexNum(table3D.Location)), Table.CommentValuesStats(table3D.Xmin, table3D.Xmax), GetAxisXElement(X_axisX, table3D.RangeX.Pos, table3D.NameX, table3D.UnitX), Table.CommentValuesStats(table3D.Ymin, table3D.Ymax), GetAxisXElement(X_axisY, table3D.RangeY.Pos, table3D.NameY, table3D.UnitY), Table.CommentValuesStats(table3D.Zmin, table3D.Zmax, table3D.Zavg), GetValuesElement(table3D.RangeZ.Pos, table3D.UnitZ, table3D.TableType), new XElement(X_description, table3D.Description))); }
public IntensityProvider2D(string file, string[] filterSeq) { this.filterSeq = filterSeq; Table3D tabInt = new Table3D(file); this.teffArray = tabInt.YMas; this.loggArray = tabInt.XMas; this.spliner2d = new Spline32D[filterSeq.Length]; for (int q = 0; q < filterSeq.Length; q++) { this.spliner2d[q] = new Spline32D(tabInt.YMas, tabInt.XMas, tabInt.FMas[q]); } }
static void ScriptGnuplot3D(StreamWriter sw, Table3D table3D) { WriteLine(sw, SetLabel("xlabel", table3D.NameX, true, table3D.UnitX)); WriteLine(sw, SetLabel("ylabel", table3D.NameY, true, table3D.UnitY)); // use title instead of zlabel as it would need extra space WriteLine(sw, SetLabel("title", table3D.Title, false, table3D.UnitZ)); WriteLine(sw, "set label 1 \"" + AnnotationStr(table3D) + "\" at screen 0.01,0.95 front left textcolor rgb \"blue\""); //set label 1 "Annotation Label" at screen 0.01,0.95 front left textcolor rgb "blue" // call gnuplot script, also pass argument to it (path to temporary binary data file) // Windows: do not use double quotes - does not recognize paths containing "\" then sw.WriteLine("call '{0}' '{1}'", FindFileInCurrentOrAppFolder(TemplateFile3D), BinaryFile); }
void StartProcess(Table table) { if (string.IsNullOrEmpty(exePath)) { throw new GnuPlotProcessException("gnuplot executable path is empty!"); } process = new Process(); process.StartInfo.FileName = exePath; process.StartInfo.WorkingDirectory = System.Environment.CurrentDirectory; // StartInfo.UseShellExecute must be false in order to use stream redirection process.StartInfo.UseShellExecute = false; // Could write temp script file but using standard input is more elegant and allows more functionality.. process.StartInfo.RedirectStandardInput = true; // --persist without stdinput method didn't work on Windows - gnuplot window closes immediatly!? // --persist + using stdinput prints gnuplot commands into terminal text // process.StartInfo.Arguments = "--persist"; //process.StartInfo.StandardInputEncoding = System.Text.Encoding.UTF8; // hide additional cmd window on Windows, useful for debugging (printing gnuplot vars etc.) process.StartInfo.CreateNoWindow = true; process.EnableRaisingEvents = true; process.Exited += HandleProcessExited; process.Start(); stdInputStream = process.StandardInput; ScriptGnuplotCommon(stdInputStream, table); Table3D t = table as Table3D; if (t != null) { ScriptGnuplot3D(stdInputStream, t); } else { ScriptGnuplot2D(stdInputStream, (Table2D)table); } stdInputStream.Flush(); }
void UpdateModel(TreeIter iter) { Table3D table = store.GetValue(iter, (int)ColumnNr3D.Obj) as Table3D; if (table == null) { return; } table.Category = (string)store.GetValue(iter, (int)ColumnNr3D.Category); table.Title = (string)store.GetValue(iter, (int)ColumnNr3D.Title); table.UnitZ = (string)store.GetValue(iter, (int)ColumnNr3D.UnitZ); table.NameX = (string)store.GetValue(iter, (int)ColumnNr3D.NameX); table.UnitX = (string)store.GetValue(iter, (int)ColumnNr3D.UnitX); table.NameY = (string)store.GetValue(iter, (int)ColumnNr3D.NameY); table.UnitY = (string)store.GetValue(iter, (int)ColumnNr3D.UnitY); table.Description = (string)store.GetValue(iter, (int)ColumnNr3D.Description); }
void Show3D(Table3D table) { if (table == null) { return; } var valuesZ = table.GetValuesZasFloats(); var tableUI = new GtkWidgets.TableWidget(coloring, table.ValuesX, table.ValuesY, valuesZ, table.Zmin, table.Zmax); tableUI.TitleMarkup = GtkWidgets.TableWidget.MakeTitleMarkup(table.Title, table.UnitZ); tableUI.AxisMarkupX = GtkWidgets.TableWidget.MakeMarkup(table.NameX, table.UnitX); tableUI.AxisMarkupY = GtkWidgets.TableWidget.MakeMarkup(table.NameY, table.UnitY); // HACK FormatValues, no good digits algorithm yet int digits = ScoobyRom.Data.AutomaticMinDigits(valuesZ); if (digits <= 3) { tableUI.FormatValues = ScoobyRom.Data.ValueFormat(digits); } else { tableUI.FormatValues = table.Zmax < 30 ? "0.00" : "0.0"; if (table.Zmax < 10) { tableUI.FormatValues = "0.000"; } } // Viewport needed for ScrolledWindow to work as generated table widget has no scroll support var viewPort = new Gtk.Viewport(); viewPort.Add(tableUI.Create()); Gtk.Widget previous = this.scrolledwindowTable3D.Child; if (previous != null) { this.scrolledwindowTable3D.Remove(previous); } // previous.Dispose () or previous.Destroy () cause NullReferenceException! this.scrolledwindowTable3D.Add(viewPort); this.scrolledwindowTable3D.ShowAll(); }
public int TryMergeWith(IList <Table3D> toUpdate) { Console.WriteLine("Merging " + this.xml3D.Count.ToString() + " 3D XML items"); int count = 0; foreach (Table3D table in xml3D) { Table3D found = null; int v; v = table.Location; if (v > 0) { found = toUpdate.Where(t => t.Location == v).FirstOrDefault(); } else { v = table.RangeZ.Pos; found = toUpdate.Where(t => t.RangeZ.Pos == v).FirstOrDefault(); if (found == null) { v = table.RangeX.Pos; found = toUpdate.Where(t => t.RangeX.Pos == v).FirstOrDefault(); if (found == null) { v = table.RangeY.Pos; found = toUpdate.Where(t => t.RangeY.Pos == v).FirstOrDefault(); } } } // TODO add further match checking and conflict resolving if (found != null) { Merge(found, table); ++count; } else { Console.Error.WriteLine("Could not find this Table3D from XML: " + table.ToString()); } } return(count); }
void CreateAllIcons() { TreeIter iter; if (!store.GetIterFirst(out iter)) { return; } do { Table3D table3D = (Table3D)store.GetValue(iter, (int)ColumnNr3D.Obj); Gdk.Pixbuf pixbuf = plotIcon.CreateIcon3D(table3D); // copy needed to work properly, closure does not recognize and copy updated ref var ? TreeIter iterCopy = iter; // update model reference in GUI Thread to make sure UI display is ok Application.Invoke(delegate { store.SetValue(iterCopy, (int)ColumnNr3D.Icon, pixbuf); }); } while (store.IterNext(ref iter)); plotIcon.CleanupTemp(); }
// use static factory methods! private GnuPlot(Table table) { try { using (FileStream fs = new FileStream(BinaryFile, FileMode.Create, FileAccess.Write)) using (BinaryWriter bw = new BinaryWriter(fs)) { Table3D t3D = table as Table3D; if (t3D != null) { WriteGnuPlotBinary(bw, t3D); } else { WriteGnuPlotBinary(bw, (Table2D)table); } } } catch (Exception ex) { throw new GnuPlotException("Could not create temporary binary data file for GnuPlot:\n" + BinaryFile + "\n\n" + ex.Message); } try { StartProcess(table); } catch (System.ComponentModel.Win32Exception ex) { // from MSDN // These are the Win32 error code for file not found or access denied. const int ERROR_FILE_NOT_FOUND = 2; const int ERROR_ACCESS_DENIED = 5; switch (ex.NativeErrorCode) { case ERROR_FILE_NOT_FOUND: throw new GnuPlotProcessException("Could not find gnuplot executable path:\n" + exePath + "\n\n" + ex.Message); case ERROR_ACCESS_DENIED: throw new GnuPlotProcessException("Access denied, no permission to start gnuplot process!\n" + ex.Message); default: throw new GnuPlotProcessException("Unknown error. Could not start gnuplot process.\n" + ex.Message); } } }
public void ChangeTableType(Table3D table3D, TableType newType) { table3D.ChangeTypeToAndReload(newType, rom.Stream); }
void CreateSetNewIcon(TreeIter iter, Table3D table3D) { store.SetValue(iter, (int)ColumnNr3D.Icon, plotIcon.CreateIcon3D(table3D)); }
public void ValidateTest() { var table = new Table3D(x, y, z, f); table.Validate(); }
public void ChangeTableType(Table3D table3D, TableType newType) { data.ChangeTableType(table3D, newType); }