├── Demo ├── App.config ├── Demo.csproj ├── Demo.sln ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── clDB.cs ├── clJobFileLib.cs └── clSliceDataLib.cs ├── LICENSE ├── README.md ├── c#-sli-library ├── absSliceDataSource.cs ├── clSliceData.cs └── slicefiles │ ├── clCliFileReader.cs │ ├── clSliFileReader.cs │ ├── clSliceDataList.cs │ └── clSliceJobFile.cs ├── cli_format.html ├── eos-format.vcxproj ├── eos-format.vcxproj.filters ├── eos-formats.sln ├── examples ├── Box.sli ├── Demo.exe ├── _info_.txt ├── box_job.job └── eos-format.dll ├── images ├── db_connect.png ├── db_jobs.png ├── db_log.png ├── db_parts_config.png ├── jobfile_viewer.png └── slifile_viewer.png └── source ├── abstractSliceFile.h ├── clError.cpp ├── clError.h ├── clFile.cpp ├── clFile.h ├── clJobFile.cpp ├── clJobFile.h ├── clJobFileInterpreter.cpp ├── clJobFileInterpreter.h ├── clJobSliceFile.cpp ├── clJobSliceFile.h ├── clSliFile.cpp ├── clSliFile.h ├── clSliceData.cpp ├── clSliceData.h ├── export_lib_job.cpp ├── export_lib_job.h ├── export_lib_sli.cpp ├── export_lib_sli.h ├── main.cpp └── main.h /Demo/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Demo/Demo.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {253AC784-5591-42B7-A520-CB7B051392C1} 8 | WinExe 9 | Properties 10 | Demo 11 | Demo 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | x86 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | x86 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Form 53 | 54 | 55 | Form1.cs 56 | 57 | 58 | 59 | 60 | Form1.cs 61 | 62 | 63 | ResXFileCodeGenerator 64 | Resources.Designer.cs 65 | Designer 66 | 67 | 68 | True 69 | Resources.resx 70 | True 71 | 72 | 73 | SettingsSingleFileGenerator 74 | Settings.Designer.cs 75 | 76 | 77 | True 78 | Settings.settings 79 | True 80 | 81 | 82 | 83 | 84 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /Demo/Demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Demo.csproj", "{253AC784-5591-42B7-A520-CB7B051392C1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {253AC784-5591-42B7-A520-CB7B051392C1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {253AC784-5591-42B7-A520-CB7B051392C1}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Demo/Form1.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /Demo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Forms; 4 | 5 | namespace Demo 6 | { 7 | static class Program 8 | { 9 | /// 10 | /// Der Haupteinstiegspunkt für die Anwendung. 11 | /// 12 | [STAThread] 13 | static void Main() 14 | { 15 | Application.EnableVisualStyles(); 16 | Application.SetCompatibleTextRenderingDefault(false); 17 | Application.Run(new Form1()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Demo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die mit einer Assembly verknüpft sind. 8 | [assembly: AssemblyTitle("Demo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Demo")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 18 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("c3fe3401-d535-4d7e-a7e5-a7001294d966")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 33 | // übernehmen, indem Sie "*" eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Demo/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Dieser Code wurde von einem Tool generiert. 4 | // Laufzeitversion:4.0.30319.18444 5 | // 6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn 7 | // der Code erneut generiert wird. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Demo.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. 17 | /// 18 | // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert 19 | // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. 20 | // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen 21 | // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Demo.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle 51 | /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Demo/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Demo/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Dieser Code wurde von einem Tool generiert. 4 | // Laufzeitversion:4.0.30319.18444 5 | // 6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn 7 | // der Code erneut generiert wird. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Demo.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Demo/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/clDB.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Odbc; 3 | using System.Collections; 4 | 5 | namespace Demo 6 | { 7 | public class clDB 8 | { 9 | public enum ENUM_DB_TYPE 10 | { 11 | DB_MYSQL, 12 | DB_DB2 13 | } 14 | 15 | private OdbcConnection m_con; 16 | private OdbcDataReader m_rec; 17 | private Hashtable m_fieldNames; 18 | public bool eof; 19 | private ENUM_DB_TYPE m_db_type; 20 | 21 | //---------------------------------------------------// 22 | public clDB(String connectionString, ENUM_DB_TYPE DBType) 23 | { 24 | m_con = null; 25 | m_rec = null; 26 | eof = true; 27 | m_db_type = DBType; 28 | 29 | try 30 | { 31 | m_con = new OdbcConnection(connectionString); 32 | m_con.Open(); 33 | } 34 | catch(Exception e) 35 | { 36 | m_con = null; 37 | Form1.addError(e.Message); 38 | } 39 | } 40 | 41 | //---------------------------------------------------// 42 | private bool execute_query(out OdbcDataReader rec, out bool set_eof, out Hashtable fieldNames, string query, int RecordLimit = -1) 43 | { 44 | rec = null; 45 | set_eof = true; 46 | fieldNames = new Hashtable(0); 47 | 48 | if (m_con==null) return false; 49 | 50 | OdbcCommand cmd; 51 | 52 | if (RecordLimit >= 0) 53 | { 54 | query += SQL_LIMIT_FORMAT(RecordLimit); 55 | } 56 | 57 | try 58 | { 59 | cmd = new OdbcCommand(query, m_con); 60 | } 61 | catch (Exception e) 62 | { 63 | Form1.addError(e.Message); 64 | Form1.addError(query); 65 | return false; 66 | } 67 | 68 | //-- execute --/ 69 | try 70 | { 71 | rec = cmd.ExecuteReader(); 72 | } 73 | catch (Exception e) 74 | { 75 | Form1.addError(e.Message); 76 | Form1.addError(query); 77 | return false; 78 | } 79 | 80 | 81 | try 82 | { 83 | set_eof = !rec.Read(); 84 | } 85 | catch (Exception e) 86 | { 87 | Form1.addError(e.Message); 88 | Form1.addError(query); 89 | set_eof = true; 90 | return false; 91 | } 92 | 93 | //-- read Fieldnames --// 94 | int l = rec.FieldCount; 95 | fieldNames = new Hashtable(l); 96 | 97 | for (int i = 0; i < l; i++) 98 | { 99 | fieldNames.Add(rec.GetName(i).ToLower(), i); 100 | } 101 | 102 | return true; 103 | } 104 | 105 | 106 | //---------------------------------------------------// 107 | public bool execute(string query, int RecordLimit = -1) 108 | { 109 | return execute_query(out m_rec, out eof, out m_fieldNames, query, RecordLimit); 110 | } 111 | 112 | 113 | 114 | //---------------------------------------------------// 115 | public void setListViewHeader(System.Windows.Forms.ListView listView, string keyField, int[] ColumnWidth) 116 | { 117 | if (m_rec == null) return; 118 | //if (eof) return; 119 | 120 | int count = m_rec.FieldCount; 121 | int countOut = count; 122 | 123 | if (count < 1) return; 124 | 125 | listView.Columns.Clear(); 126 | 127 | //- find field-Index for key 128 | string key = keyField.ToLower(); 129 | int keyFieldIndex = -1; 130 | if (m_fieldNames.ContainsKey(key)) 131 | { 132 | keyFieldIndex = (int)m_fieldNames[key]; 133 | countOut = count - 1; 134 | } 135 | 136 | //- read row 137 | string[] items = new string[countOut]; 138 | int j = 0; 139 | int currentColumnWidth = 200; 140 | 141 | for (int i = 0; i < count; i++) 142 | { 143 | if (i != keyFieldIndex) 144 | { 145 | if (j < ColumnWidth.Length) currentColumnWidth = ColumnWidth[j]; 146 | 147 | listView.Columns.Add(m_rec.GetName(i), currentColumnWidth); 148 | j++; 149 | } 150 | } 151 | 152 | } 153 | 154 | public static string Hex2String(string hex) 155 | { 156 | string result = ""; 157 | int count = hex.Length / 2; 158 | int s; 159 | 160 | for (s = 0; s < count; s++) 161 | { 162 | string zeichen = hex.Substring(s * 2, 2); 163 | result += (char)Convert.ToUInt16(zeichen, 16); 164 | } 165 | 166 | return result; 167 | } 168 | //---------------------------------------------------// 169 | public System.Windows.Forms.ListViewItem getListViewRow(string keyField) 170 | { 171 | if (m_rec == null) return new System.Windows.Forms.ListViewItem(""); 172 | if (eof) return new System.Windows.Forms.ListViewItem(""); 173 | 174 | int count = m_rec.FieldCount; 175 | int countOut = count; 176 | 177 | if (count<1) return new System.Windows.Forms.ListViewItem(""); 178 | 179 | //- find field-Index for key 180 | string key = keyField.ToLower(); 181 | int keyFieldIndex = -1; 182 | if (m_fieldNames.ContainsKey(key)) 183 | { 184 | keyFieldIndex = (int)m_fieldNames[key]; 185 | countOut = count - 1; 186 | } 187 | 188 | //- read row 189 | string[] items = new string[countOut]; 190 | int j = 0; 191 | for (int i = 0; i < count; i++) 192 | { 193 | if (i != keyFieldIndex) 194 | { 195 | if (m_rec.GetDataTypeName(i).ToUpper() != "BLOB") 196 | { 197 | try 198 | { 199 | items[j] = m_rec.GetValue(i).ToString(); 200 | } 201 | catch (Exception) { } 202 | } 203 | else 204 | { 205 | try 206 | { 207 | items[j] = Hex2String(m_rec.GetString(i)); 208 | } 209 | catch (Exception) { } 210 | } 211 | 212 | j++; 213 | } 214 | } 215 | 216 | //- create new intem 217 | System.Windows.Forms.ListViewItem Item = new System.Windows.Forms.ListViewItem(items); 218 | 219 | //- add key-Value to item 220 | if (keyFieldIndex >= 0) Item.Name = m_rec.GetValue(keyFieldIndex).ToString(); 221 | 222 | return Item; 223 | } 224 | 225 | 226 | //---------------------------------------------------// 227 | public bool MoveNext() 228 | { 229 | if (m_rec == null) return false; 230 | 231 | try 232 | { 233 | eof = !m_rec.Read(); 234 | } 235 | catch (Exception e) 236 | { 237 | Form1.addError(e.Message); 238 | eof = true; 239 | return false; 240 | } 241 | 242 | 243 | return !eof; 244 | } 245 | 246 | 247 | 248 | //---------------------------------------------------// 249 | public string FieldName(int index) 250 | { 251 | if (m_rec == null) return ""; 252 | if (eof) return ""; 253 | if ((index < 0) && (index >= m_rec.FieldCount)) return ""; 254 | 255 | return m_rec.GetName(index); 256 | } 257 | 258 | //---------------------------------------------------// 259 | public int FieldCount() 260 | { 261 | if (m_rec == null) return 0; 262 | return m_rec.FieldCount; 263 | } 264 | 265 | 266 | //---------------------------------------------------// 267 | public string FieldStr(string fieldName, string defaultReturn="") 268 | { 269 | if (m_rec == null) return defaultReturn; 270 | if (eof) return defaultReturn; 271 | 272 | string key = fieldName.ToLower(); 273 | 274 | if (!m_fieldNames.ContainsKey(key)) return defaultReturn; 275 | 276 | try 277 | { 278 | return m_rec.GetValue((int)m_fieldNames[key]).ToString(); 279 | } 280 | catch (Exception) 281 | { 282 | return defaultReturn; 283 | } 284 | } 285 | 286 | 287 | //---------------------------------------------------// 288 | public int FieldInt(string fieldName, int defaultReturn = 0) 289 | { 290 | if (m_rec == null) return defaultReturn; 291 | if (eof) return defaultReturn; 292 | 293 | try 294 | { 295 | return Convert.ToInt32(FieldStr(fieldName, defaultReturn.ToString())); 296 | } 297 | catch 298 | { 299 | return defaultReturn; 300 | } 301 | } 302 | 303 | //---------------------------------------------------// 304 | public double FieldDouble(string fieldName, double defaultReturn = 0) 305 | { 306 | if (m_rec == null) return defaultReturn; 307 | if (eof) return defaultReturn; 308 | 309 | try 310 | { 311 | return Convert.ToDouble(FieldStr(fieldName, defaultReturn.ToString())); 312 | } 313 | catch 314 | { 315 | return defaultReturn; 316 | } 317 | } 318 | //---------------------------------------------------// 319 | public Record[] execute_to_array(string query, string keyField, string valueField) 320 | { 321 | OdbcDataReader my_rec; 322 | Hashtable my_fieldNames; 323 | bool my_eof; 324 | Record [] outRec = new Record[0]; 325 | 326 | if (!execute_query(out my_rec, out my_eof, out my_fieldNames, query)) return outRec; 327 | 328 | string key_v = keyField.ToLower(); 329 | string value_v = valueField.ToLower(); 330 | 331 | if (!my_fieldNames.ContainsKey(key_v)) return outRec; 332 | if (!my_fieldNames.ContainsKey(value_v)) return outRec; 333 | 334 | int key_i = (int)my_fieldNames[key_v]; 335 | int value_i = (int)my_fieldNames[value_v]; 336 | 337 | int RecCount = 0; 338 | outRec = new Record[10]; 339 | 340 | while (!my_eof) 341 | { 342 | try 343 | { 344 | outRec[RecCount] = new Record(my_rec.GetValue(key_i).ToString(), my_rec.GetValue(value_i).ToString()); 345 | RecCount++; 346 | 347 | my_eof = !my_rec.Read(); 348 | } 349 | catch (Exception e) 350 | { 351 | Form1.addError(e.Message); 352 | my_eof = true; 353 | return outRec; 354 | } 355 | 356 | 357 | 358 | if (my_eof) break; 359 | 360 | if (RecCount >= outRec.Length) 361 | { 362 | Array.Resize(ref outRec, outRec.Length + 20); 363 | } 364 | } 365 | 366 | //- remove empty elements at the end! 367 | Array.Resize(ref outRec, RecCount); 368 | 369 | return outRec; 370 | 371 | } 372 | 373 | //---------------------------------------------------// 374 | public string SQL_LIMIT_FORMAT(int count) 375 | { 376 | switch(m_db_type) 377 | { 378 | case ENUM_DB_TYPE.DB_DB2: 379 | return " FETCH FIRST " + count + " ROWS ONLY "; 380 | case ENUM_DB_TYPE.DB_MYSQL: 381 | return " LIMIT 0," + count + " "; 382 | } 383 | return ""; 384 | } 385 | 386 | 387 | //---------------------------------------------------// 388 | public string ToEscapeStr(string value2Escape) 389 | { 390 | try 391 | { 392 | return "'" + System.Text.RegularExpressions.Regex.Replace(value2Escape, @"[\000\010\011\012\015\032\042\047\134\140]", "\\$0") + "'"; 393 | } 394 | catch 395 | { 396 | return "''"; 397 | } 398 | 399 | } 400 | 401 | 402 | //---------------------------------------------------// 403 | //---------------------------------------------------// 404 | //---------------------------------------------------// 405 | public class Record 406 | { 407 | public string value; 408 | public string key; 409 | 410 | 411 | public Record(string new_key, string new_value) 412 | { 413 | value = new_value; 414 | key = new_key; 415 | } 416 | 417 | public override string ToString() 418 | { 419 | return value; 420 | } 421 | } 422 | } 423 | } 424 | -------------------------------------------------------------------------------- /Demo/clJobFileLib.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System; 3 | 4 | namespace Demo 5 | { 6 | 7 | class clJobFileLib 8 | { 9 | private const string LIB_DLL_NAME = "eos-format.dll"; 10 | 11 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 12 | private static extern Int32 jf_initLib(); 13 | 14 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 15 | private static extern void jf_freeLib(int jobI); 16 | 17 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 18 | private static extern Int32 jf_readFromFile(int jobI, byte [] fileName); 19 | 20 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 21 | private static extern Int32 jf_printXML(int jobI); 22 | 23 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 24 | private static extern IntPtr jf_getKeyName(int jobI, int keyIndex); 25 | 26 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 27 | private static extern Int32 jf_getFirstKeyChild(int jobI, int keyIndex); 28 | 29 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 30 | private static extern Int32 jf_getNextKeyChild(int jobI, int keyIndex); 31 | 32 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 33 | private static extern Int32 jf_getFirstProperty(int jobI, int propertyIndex); 34 | 35 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 36 | private static extern Int32 jf_getNextProperty(int jobI, int propertyIndex); 37 | 38 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 39 | private static extern IntPtr jf_getPropertyName(int jobI, int propertyIndex); 40 | 41 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 42 | private static extern IntPtr jf_getPropertyValue(int jobI, int propertyIndex); 43 | 44 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 45 | private static extern IntPtr jf_getPropertyComment(int jobI, int propertyIndex); 46 | 47 | 48 | private int m_lib = 0; 49 | 50 | //---------------------------------------------------// 51 | public clJobFileLib() 52 | { 53 | try 54 | { 55 | m_lib = jf_initLib(); 56 | } 57 | catch (Exception e) 58 | { 59 | System.Windows.Forms.MessageBox.Show("jf_initLib Error: " + e.Message); 60 | } 61 | } 62 | 63 | //---------------------------------------------------// 64 | ~clJobFileLib() 65 | { 66 | try 67 | { 68 | jf_freeLib(m_lib); 69 | } 70 | catch (Exception e) 71 | { 72 | System.Windows.Forms.MessageBox.Show("jf_initLib Error: " + e.Message); 73 | } 74 | } 75 | 76 | //---------------------------------------------------// 77 | public bool readFromFile(string filename) 78 | { 79 | try 80 | { 81 | int ret = jf_readFromFile(m_lib, Str2CChr(filename)); 82 | if (ret > 0) return true; 83 | 84 | System.Windows.Forms.MessageBox.Show("jf_readFromFile Error: " + ret); 85 | } 86 | catch (Exception e) 87 | { 88 | System.Windows.Forms.MessageBox.Show("jf_initLib Error: " + e.Message); 89 | } 90 | return false; 91 | } 92 | 93 | //---------------------------------------------------// 94 | public int getFirstKeyChild(int KeyID = 0) 95 | { 96 | try 97 | { 98 | return jf_getFirstKeyChild(m_lib, KeyID); 99 | } 100 | catch (Exception e) 101 | { 102 | System.Diagnostics.Debug.WriteLine(e.Message); 103 | return 0; 104 | } 105 | } 106 | 107 | 108 | //---------------------------------------------------// 109 | public int getNextKeyChild(int KeyID = 0) 110 | { 111 | try 112 | { 113 | return jf_getNextKeyChild(m_lib, KeyID); 114 | } 115 | catch (Exception e) 116 | { 117 | System.Diagnostics.Debug.WriteLine(e.Message); 118 | return 0; 119 | } 120 | } 121 | 122 | //---------------------------------------------------// 123 | public int getFirstProperty(int KeyID = 0) 124 | { 125 | try 126 | { 127 | return jf_getFirstProperty(m_lib, KeyID); 128 | } 129 | catch (Exception e) 130 | { 131 | System.Diagnostics.Debug.WriteLine(e.Message); 132 | return 0; 133 | } 134 | } 135 | 136 | 137 | //---------------------------------------------------// 138 | public int getNextProperty(int PropID = 0) 139 | { 140 | try 141 | { 142 | return jf_getNextProperty(m_lib, PropID); 143 | } 144 | catch (Exception e) 145 | { 146 | System.Diagnostics.Debug.WriteLine(e.Message); 147 | return 0; 148 | } 149 | } 150 | 151 | 152 | //---------------------------------------------------// 153 | public string getKeyName(int KeyID = 0) 154 | { 155 | IntPtr ptr = jf_getKeyName(m_lib, KeyID); 156 | 157 | if (ptr == IntPtr.Zero) return ""; 158 | 159 | return ptr2String(ptr); 160 | } 161 | 162 | //---------------------------------------------------// 163 | public string getPropertyName(int PropID = 0) 164 | { 165 | IntPtr ptr = jf_getPropertyName(m_lib, PropID); 166 | 167 | if (ptr == IntPtr.Zero) return ""; 168 | 169 | return ptr2String(ptr); 170 | } 171 | 172 | //---------------------------------------------------// 173 | public string getPropertyValue(int PropID = 0) 174 | { 175 | IntPtr ptr = jf_getPropertyValue(m_lib, PropID); 176 | 177 | if (ptr == IntPtr.Zero) return ""; 178 | 179 | return ptr2String(ptr); 180 | } 181 | 182 | //---------------------------------------------------// 183 | public string getPropertyComment(int PropID = 0) 184 | { 185 | IntPtr ptr = jf_getPropertyComment(m_lib, PropID); 186 | 187 | if (ptr == IntPtr.Zero) return ""; 188 | 189 | return ptr2String(ptr); 190 | } 191 | 192 | //---------------------------------------------------// 193 | private string ptr2String(IntPtr ptr) 194 | { 195 | int len=0; 196 | 197 | while (System.Runtime.InteropServices.Marshal.ReadByte(ptr, len) != 0) len++; 198 | 199 | if (len == 0) return ""; 200 | 201 | byte[] array = new byte[len]; 202 | 203 | System.Runtime.InteropServices.Marshal.Copy(ptr, array, 0, len); 204 | 205 | return System.Text.Encoding.Default.GetString(array); 206 | } 207 | 208 | 209 | //---------------------------------------------------// 210 | private byte[] Str2CChr(string strData="") 211 | { 212 | //- C# uses UNICODE for char-type so 2Byte! 213 | byte[] bytes = System.Text.Encoding.ASCII.GetBytes(strData); 214 | Array.Resize(ref bytes, bytes.Length + 1); 215 | bytes[bytes.Length - 1] = 0; 216 | return bytes; 217 | } 218 | 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /Demo/clSliceDataLib.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System; 3 | 4 | 5 | namespace Demo 6 | { 7 | public class clSliceDataLib 8 | { 9 | 10 | private const string LIB_DLL_NAME = "eos-format.dll"; 11 | 12 | 13 | /// 14 | /// Homogeneous coordinates Matrix - used for DLL-Libary call. 15 | /// 16 | public class clMatrix3x2 17 | { 18 | //-------------------------------------------------------// 19 | public struct ty_Matrix 20 | { 21 | //- do not change! used for dll-libary-call 22 | public float m11, m12, m13; 23 | public float m21, m22, m23; 24 | } 25 | 26 | public ty_Matrix m; 27 | 28 | 29 | //-------------------------------------------------------// 30 | public clMatrix3x2() 31 | { 32 | //- load Identity matrix 33 | m.m11 = 1; m.m12 = 0; m.m13 = 0; 34 | m.m21 = 0; m.m22 = 1; m.m23 = 0; 35 | } 36 | 37 | 38 | //-------------------------------------------------------// 39 | public static clMatrix3x2 MatrixMult(clMatrix3x2 A, clMatrix3x2 B) 40 | { 41 | clMatrix3x2 C = new clMatrix3x2(); 42 | 43 | C.m.m11 = A.m.m11 * B.m.m11 + A.m.m12 * B.m.m21 + A.m.m13 * 0; 44 | C.m.m12 = A.m.m11 * B.m.m12 + A.m.m12 * B.m.m22 + A.m.m13 * 0; 45 | C.m.m13 = A.m.m11 * B.m.m13 + A.m.m12 * B.m.m23 + A.m.m13 * 1; 46 | 47 | C.m.m21 = A.m.m21 * B.m.m11 + A.m.m22 * B.m.m21 + A.m.m23 * 0; 48 | C.m.m22 = A.m.m21 * B.m.m12 + A.m.m22 * B.m.m22 + A.m.m23 * 0; 49 | C.m.m23 = A.m.m21 * B.m.m13 + A.m.m22 * B.m.m23 + A.m.m23 * 1; 50 | 51 | return C; 52 | } 53 | } 54 | 55 | 56 | 57 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 58 | private static extern Int32 sf_initLib(); 59 | 60 | 61 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 62 | private static extern Int32 sf_getPartCount(int sliI); 63 | 64 | 65 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 66 | private static extern float sf_getLayerThickness(int sliI); 67 | 68 | 69 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 70 | private static extern Int32 sf_getLayerCount(int sliI, int partIndex); 71 | 72 | 73 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 74 | private static extern float sf_getMaxLayerPos(int sliI, int partIndex); 75 | 76 | 77 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 78 | private static extern float sf_getLayerPos(int sliI, int partIndex, int layerIndex); 79 | 80 | 81 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 82 | private static extern int sf_getLayerIndexByPos(int sliI, int partIndex, float layerPos); 83 | 84 | 85 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 86 | private static extern Int32 sf_freeLib(int sliI); 87 | 88 | 89 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 90 | private static extern Int32 sf_addRasterObject(int sliI, int [,] outFilledPicture, int [,] outLinePicture, int partIndex, clMatrix3x2.ty_Matrix matrix, int color, int width, int height); 91 | 92 | 93 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 94 | private static extern Int32 sf_readFromFile(int sliI, byte [] fileName); 95 | 96 | 97 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 98 | private static extern Int32 sf_readSliceData(int sliI, int partIndex, int LayerIndex); 99 | 100 | 101 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 102 | private static extern IntPtr sf_getPartName(int sliI, int partIndex); 103 | 104 | 105 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 106 | private static extern IntPtr sf_getPartProperty(int sliI, int partIndex); 107 | 108 | 109 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 110 | private static extern IntPtr sf_getLastError(); 111 | 112 | 113 | [DllImport(LIB_DLL_NAME, CallingConvention = CallingConvention.Cdecl)] 114 | private static extern IntPtr sf_getLastDebug(); 115 | 116 | 117 | private int m_SLI_lib = 0; 118 | 119 | 120 | 121 | //---------------------------------------------------// 122 | public clSliceDataLib() 123 | { 124 | m_SLI_lib = sf_initLib(); 125 | } 126 | 127 | 128 | //---------------------------------------------------// 129 | public void readFromFile(string fileName) 130 | { 131 | int i = sf_readFromFile(m_SLI_lib, Str2CChr(fileName)); 132 | checkForErros(); 133 | } 134 | 135 | 136 | //---------------------------------------------------// 137 | private void checkForErros() 138 | { 139 | Form1.addError( getLastError(), false); 140 | Form1.addError( getLastDebug(), true); 141 | } 142 | 143 | 144 | //---------------------------------------------------// 145 | public void readSliceData(int layer, int partIndex) 146 | { 147 | int i = sf_readSliceData(m_SLI_lib, partIndex, layer); 148 | checkForErros(); 149 | } 150 | 151 | 152 | //---------------------------------------------------// 153 | /// 154 | /// randers the polyline to [outAreaPicture] and [outLinePicture]. [outAreaPicture] will be filled with [RGBColor]. [outLinePicture] will only be outlined with [RGBColor]. 155 | /// 156 | /// Picture-Buffer.
No [RGBColor] values are allowed within the buffer-data!
Can be NULL. 157 | /// Picture-Buffer.
Can be NULL. 158 | /// Index of the Part to draw 159 | /// Homogeneous coordinates to transform the point data 160 | /// RGB color to draw with 161 | public void addRasterObject(int[,] outAreaPicture, int[,] outLinePicture, int partIndex, clMatrix3x2 matrix, int RGBColor) 162 | { 163 | int w=0; 164 | int h=0; 165 | if (outLinePicture != null) 166 | { 167 | w=outLinePicture.GetLength(0); 168 | h=outLinePicture.GetLength(1); 169 | } 170 | else if (outAreaPicture != null) 171 | { 172 | w=outAreaPicture.GetLength(0); 173 | h=outAreaPicture.GetLength(1); 174 | } 175 | else 176 | { 177 | return; 178 | } 179 | 180 | 181 | int i = sf_addRasterObject(m_SLI_lib, outAreaPicture, outLinePicture, partIndex, matrix.m, RGBColor, w, h); 182 | checkForErros(); 183 | 184 | //System.Diagnostics.Debug.WriteLine("addRasterObject() return = " + i); 185 | } 186 | 187 | 188 | //---------------------------------------------------// 189 | public int getLayerCount(int partIndex=-1) 190 | { 191 | if (partIndex>=0) return sf_getLayerCount(m_SLI_lib, partIndex); 192 | 193 | //- find maximum of index 194 | int max_index = 0; 195 | int partCount = getPartCount(); 196 | 197 | for (int i = 0; i < partCount; i++ ) 198 | { 199 | max_index = System.Math.Max(max_index, sf_getLayerCount(m_SLI_lib, i)); 200 | } 201 | 202 | 203 | return max_index; 204 | } 205 | 206 | 207 | //---------------------------------------------------// 208 | public float getLayerThickness() 209 | { 210 | return sf_getLayerThickness(m_SLI_lib); 211 | } 212 | 213 | 214 | //---------------------------------------------------// 215 | public float getMaxLayerPos(int partIndex = -1) 216 | { 217 | if (partIndex >= 0) return sf_getMaxLayerPos(m_SLI_lib, partIndex); 218 | 219 | //- find maximum layer position 220 | float max_pos = 0; 221 | int partCount = getPartCount(); 222 | 223 | for (int i = 0; i < partCount; i++) 224 | { 225 | max_pos = System.Math.Max(max_pos, sf_getMaxLayerPos(m_SLI_lib, i)); 226 | } 227 | 228 | 229 | return max_pos; 230 | } 231 | 232 | 233 | //---------------------------------------------------// 234 | public float getLayerPos(int partIndex, int LayerIndex) 235 | { 236 | return sf_getLayerPos(m_SLI_lib, partIndex, LayerIndex); 237 | } 238 | 239 | 240 | //---------------------------------------------------// 241 | public int getLayerIndexByPos(int partIndex, float layerPos) 242 | { 243 | return sf_getLayerIndexByPos(m_SLI_lib, partIndex, layerPos); 244 | } 245 | 246 | 247 | 248 | //---------------------------------------------------// 249 | public string getPartName(int partIndex) 250 | { 251 | IntPtr ptr = sf_getPartName(m_SLI_lib, partIndex); 252 | 253 | if (ptr == IntPtr.Zero) return ""; 254 | 255 | return ptr2String(ptr); 256 | } 257 | 258 | 259 | //---------------------------------------------------// 260 | public string getPartProperty(int partIndex) 261 | { 262 | IntPtr ptr = sf_getPartProperty(m_SLI_lib, partIndex); 263 | 264 | if (ptr == IntPtr.Zero) return ""; 265 | 266 | return ptr2String(ptr); 267 | } 268 | 269 | //---------------------------------------------------// 270 | public int getPartCount() 271 | { 272 | return sf_getPartCount(m_SLI_lib); 273 | } 274 | 275 | 276 | //---------------------------------------------------// 277 | private byte[] Str2CChr(string strData = "") 278 | { 279 | //- C# uses UNICODE for char-type so 2Byte! 280 | byte[] bytes = System.Text.Encoding.ASCII.GetBytes(strData); 281 | Array.Resize(ref bytes, bytes.Length + 1); 282 | bytes[bytes.Length - 1] = 0; 283 | return bytes; 284 | } 285 | 286 | 287 | //---------------------------------------------------// 288 | private string ptr2String(IntPtr ptr) 289 | { 290 | int len=0; 291 | 292 | while (System.Runtime.InteropServices.Marshal.ReadByte(ptr, len) != 0) len++; 293 | 294 | if (len == 0) return ""; 295 | 296 | byte[] array = new byte[len]; 297 | 298 | System.Runtime.InteropServices.Marshal.Copy(ptr, array, 0, len); 299 | 300 | return System.Text.Encoding.Default.GetString(array); 301 | } 302 | 303 | 304 | //---------------------------------------------------// 305 | public string getLastError() 306 | { 307 | IntPtr ptr = sf_getLastError(); 308 | 309 | if (ptr == IntPtr.Zero) return ""; 310 | 311 | return ptr2String(ptr); 312 | } 313 | 314 | 315 | //---------------------------------------------------// 316 | public string getLastDebug() 317 | { 318 | IntPtr ptr = sf_getLastDebug(); 319 | 320 | if (ptr == IntPtr.Zero) return ""; 321 | 322 | return ptr2String(ptr); 323 | } 324 | 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Thomas Zeugner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | EOS-Formats 2 | =========== 3 | 4 | job-format 5 | ---------- 6 | * read .job files of the Process-controlling-Software (create with PSW Software) of 3D Printers from EOS GmbH(c) 7 | * C++ Library (visual Studio 2015) 8 | * or use as commad line tool to convert eos .job files to .xml.
9 | 10 | 11 | sli-format 12 | ---------- 13 | * read .sli "Slice Layer Interface" (Proprietary form of the "Common Layer Interface" format) 14 | * [Magic number](https://en.wikipedia.org/wiki/File_format#Magic_number) of the File format: : `EOS 1993 SLI FILE` 15 | * C++ Library (visual Studio 2015) 16 | 17 | Demo 18 | ---- 19 | * Demonstration application for job-format-library to view .job files in a treeview 20 | * open and view/render EOS-sli files 21 | * Query EOS-DB to get information about current build process and finished jobs 22 | * C# (visual Studio 2013)
23 | /examples/Demo.exe 24 | 25 | 26 | c#-sli-library (additional stuff) 27 | ---- 28 | in the directory `c#-sli-library` you can find a c# library to access the .sli and .cli format with the following drawbacks: 29 | * no visual studio project 30 | * you need to replace the error handling 31 | * code comments in German 32 | > to any body: feel free to clean up this and send a pull request :-) - I do not have time for this at the moment! 33 | 34 | 35 | Status 36 | ------ 37 | 2014-12-11 38 | ![example1](images/jobfile_viewer.png) 39 | ![example2](images/slifile_viewer.png) 40 | ![example2](images/db_connect.png) 41 | ![example2](images/db_jobs.png) 42 | ![example2](images/db_log.png) 43 | ![example2](images/db_parts_config.png) 44 | 45 | --- 46 | EOS is a registered trademark of EOS GmbH and not involved in this project 47 | -------------------------------------------------------------------------------- /c#-sli-library/absSliceDataSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ThermoBox.slicedata 7 | { 8 | 9 | public class ty_Matrix3x2 10 | { 11 | public double m00 = 1; public double m10 = 0; public double m20 = 0; 12 | public double m01 = 0; public double m11 = 1; public double m21 = 0; 13 | 14 | 15 | //-------------------------------------------------------// 16 | public static ty_Matrix3x2 MatrixMult(ty_Matrix3x2 A, ty_Matrix3x2 B) 17 | { 18 | ty_Matrix3x2 C = new ty_Matrix3x2(); 19 | 20 | C.m00 = A.m00 * B.m00 + A.m10 * B.m01 + A.m20 * 0; 21 | C.m10 = A.m00 * B.m10 + A.m10 * B.m11 + A.m20 * 0; 22 | C.m20 = A.m00 * B.m20 + A.m10 * B.m21 + A.m20 * 1; 23 | 24 | C.m01 = A.m01 * B.m00 + A.m11 * B.m01 + A.m21 * 0; 25 | C.m11 = A.m01 * B.m10 + A.m11 * B.m11 + A.m21 * 0; 26 | C.m21 = A.m01 * B.m20 + A.m11 * B.m21 + A.m21 * 1; 27 | 28 | return C; 29 | } 30 | } 31 | 32 | public interface absSliceDataSource 33 | { 34 | //------------------------------------------// 35 | void setFileName(System.String filename); 36 | 37 | //------------------------------------------// 38 | System.String getFileName(); 39 | 40 | //------------------------------------------// 41 | int getLayerCount(); 42 | 43 | //------------------------------------------// 44 | float getLayerThickness(); 45 | 46 | //------------------ 47 | float getLayerUpPosition(int LayerIndex); 48 | 49 | 50 | //------------------------------------------// 51 | int getObjectCount(); 52 | 53 | //-------------------------------------------// 54 | System.String getObjectName(int ObjectIndex); 55 | System.String getObjectInfo(int ObjectIndex); 56 | 57 | bool getObjectEnabled(int ObjectIndex); 58 | void setObjectEnabled(int ObjectIndex, bool enable); 59 | 60 | 61 | 62 | 63 | //------------------------------------------// 64 | clSliceData getSliceData(int ObjectIndex, int LayerIndex, float JobLayerThickness_mm); 65 | ty_Matrix3x2 getSliceTransformMatrix(int ObjectIndex, int LayerIndex); 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /c#-sli-library/clSliceData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace ThermoBox.slicedata 5 | { 6 | public class clSliceData 7 | { 8 | private struct tyPolygon 9 | { 10 | public float[,] coords; 11 | public bool isHatch; 12 | public int coords_length; 13 | 14 | } 15 | 16 | private System.Collections.Generic.List m_polygons = new System.Collections.Generic.List(); 17 | 18 | //-------------------------------------------// 19 | public clSliceData() 20 | { 21 | } 22 | 23 | //-------------------------------------------// 24 | public void addPolygon(float [,] polygon_coordinates, int pointCount) 25 | { 26 | tyPolygon p = new tyPolygon(); 27 | p.coords = polygon_coordinates; 28 | p.isHatch = false; 29 | p.coords_length = pointCount; 30 | 31 | m_polygons.Add (p); 32 | } 33 | 34 | //-------------------------------------------// 35 | public void addHatch(float[,] polygon_coordinates, int pointCount) 36 | { 37 | tyPolygon p = new tyPolygon(); 38 | p.coords = polygon_coordinates; 39 | p.isHatch = true; 40 | p.coords_length = pointCount; 41 | 42 | m_polygons.Add (p); 43 | } 44 | 45 | //-------------------------------------------// 46 | public bool isHatch(int polygonIndex) 47 | { 48 | return m_polygons[polygonIndex].isHatch; 49 | } 50 | 51 | //-------------------------------------------// 52 | public int getPolygonCount() 53 | { 54 | return m_polygons.Count; 55 | } 56 | 57 | //-------------------------------------------// 58 | public int getPointCount(int polygonIndex) 59 | { 60 | return m_polygons[polygonIndex].coords_length; 61 | } 62 | 63 | //-------------------------------------------// 64 | public float getPointX(int polygonIndex, int PointIndex) 65 | { 66 | return m_polygons[polygonIndex].coords[0, PointIndex]; 67 | } 68 | 69 | //-------------------------------------------// 70 | public float getPointY(int polygonIndex, int PointIndex) 71 | { 72 | return m_polygons[polygonIndex].coords[1, PointIndex]; 73 | } 74 | 75 | //-------------------------------------------// 76 | public float[,] getPolygon(int polygonIndex) 77 | { 78 | return m_polygons[polygonIndex].coords; 79 | } 80 | 81 | 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /c#-sli-library/slicefiles/clSliFileReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using ThermoBox.tools; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace ThermoBox.slicedata 7 | { 8 | public class clSliFileReader : absSliceDataSource 9 | { 10 | //- für die Umwandlung von Int->Float verhält sich wie ein Union 11 | [StructLayout(LayoutKind.Explicit)] 12 | public struct BinaryConvertIntToFloat 13 | { 14 | [FieldOffset(0)] 15 | public float toFloat; 16 | [FieldOffset(0)] 17 | public int toInt; 18 | } 19 | private BinaryConvertIntToFloat converterIntFloat; 20 | 21 | 22 | 23 | private struct tyFileHead 24 | { 25 | public System.String magic; 26 | public int int01; //- Header länge ? 27 | public int int02; //- Header anzahl ? 28 | public int FileDataOffset; //- Header offset 29 | 30 | public int int05; 31 | 32 | public int int07; 33 | public int FileSliceDataOffset; 34 | public int FileIndexPos ; 35 | public System.String String2 ; 36 | public int LayerCount1 ; 37 | public int LayerCount2; 38 | 39 | public int int14; 40 | 41 | public float scaleFactor; 42 | }; 43 | 44 | 45 | private struct tyIndexTable 46 | { 47 | public int FileOffset; 48 | public float layerPos; //- Syntax : $$LAYER/z - Start of a layer with upper surface at height z (z*units [mm]). 49 | } 50 | 51 | private int m_IndexTable_count; 52 | private tyIndexTable[] m_IndexTable; 53 | 54 | private tyFileHead m_FileHead; 55 | private String m_filename; 56 | private BinaryReader m_reader; 57 | private bool m_eof; 58 | private int m_blocklen; 59 | private clError m_error; 60 | private int m_offset; 61 | private System.String m_objectName; 62 | private bool m_is_enabeld = true; 63 | 64 | //------------------------------------------// 65 | public clSliFileReader(System.String filename=null) 66 | { 67 | m_error = new clError("SliFileReader"); 68 | 69 | if (filename != null) this.setFileName(filename); 70 | 71 | } 72 | 73 | //------------------------------------------// 74 | public void setFileName(System.String filename) 75 | { 76 | this.m_filename = filename; 77 | 78 | m_objectName = Path.GetFileName(m_filename); 79 | 80 | if (openStream(filename)) 81 | { 82 | readHead(); 83 | } 84 | } 85 | 86 | //------------------------------------------// 87 | public System.String getFileName() 88 | { 89 | return m_filename; 90 | } 91 | 92 | 93 | //------------------------------------------// 94 | public System.String getObjectName(int ObjectIndex) 95 | { 96 | if (ObjectIndex != 0) return ""; 97 | return m_objectName; 98 | } 99 | 100 | //------------------------------------------// 101 | public bool getObjectEnabled(int ObjectIndex) 102 | { 103 | if (ObjectIndex != 0) return false; 104 | return m_is_enabeld; 105 | } 106 | 107 | //------------------------------------------// 108 | public void setObjectEnabled(int ObjectIndex, bool enable) 109 | { 110 | if (ObjectIndex == 0) m_is_enabeld = enable; 111 | } 112 | 113 | 114 | 115 | //------------------------------------------// 116 | public System.String getObjectInfo(int ObjectIndex) 117 | { 118 | if (ObjectIndex != 0) return ""; 119 | return ""; 120 | } 121 | 122 | 123 | //------------------------------------------// 124 | public int getLayerCount() 125 | { 126 | return m_IndexTable_count; 127 | } 128 | 129 | //------------------------------------------// 130 | public float getLayerThickness() //- in [mm] 131 | { 132 | if (m_IndexTable.Length > 2) 133 | return (m_IndexTable[1].layerPos - m_IndexTable[0].layerPos); 134 | else 135 | return 0; 136 | 137 | } 138 | 139 | 140 | //------------------------------------------// 141 | public int getObjectCount() 142 | { 143 | return 1; 144 | } 145 | 146 | 147 | //------------------------------------------// 148 | //- gibt die Position der Oberseite des Layers zurück 149 | public float getLayerUpPosition(int LayerIndex) //- in [mm] 150 | { 151 | if ((LayerIndex >= 0) && (LayerIndex < m_IndexTable_count)) 152 | { 153 | return m_IndexTable[LayerIndex].layerPos; 154 | } 155 | else 156 | { 157 | return -1; 158 | } 159 | } 160 | 161 | 162 | //-------------------------------------// 163 | public ty_Matrix3x2 getSliceTransformMatrix(int ObjectIndex, int LayerIndex) 164 | { 165 | ty_Matrix3x2 tmp = new ty_Matrix3x2(); ; // ist Einheitsmatrix 166 | return tmp; 167 | } 168 | 169 | 170 | //------------------------------------------// 171 | public clSliceData getSliceData(int ObjectIndex, int LayerIndex, float jobLayerThickness) 172 | { 173 | clSliceData sd = new clSliceData(); 174 | int n = 0; 175 | 176 | if (ObjectIndex != 0) return sd; 177 | 178 | 179 | float scaleFactor = m_FileHead.scaleFactor; 180 | 181 | //m_error.addInfo(System.IO.Path.GetFileName( m_filename) +" : factor: " + scaleFactor + "; "); 182 | 183 | 184 | int convertedLayerindex = LayerIndex - (int)(m_IndexTable[0].layerPos / jobLayerThickness); // Min z 185 | 186 | 187 | 188 | 189 | if ((convertedLayerindex >= 0) && (convertedLayerindex < m_IndexTable_count)) 190 | { 191 | 192 | 193 | 194 | 195 | setOffset(m_IndexTable[convertedLayerindex].FileOffset); 196 | 197 | int OType =0; 198 | while (OType!=2) 199 | { 200 | //- Befehl/Operator Byte 201 | OType = readIntBE(1); 202 | 203 | switch (OType) 204 | { 205 | case 1: 206 | //- ersten 2 Byte sind ca. die Höhe??!!! 207 | readByte(11); //- Header überspringen 208 | //- Header... lesen???!!! 209 | break; 210 | 211 | case 2: 212 | //- Ende 213 | break; 214 | 215 | case 3: 216 | //Command : start polyline 217 | //Syntax : $$POLYLINE/id,dir,n,p1x,p1y,...pnx,pny 218 | //Parameters: 219 | // 220 | // id : INTEGER 221 | // dir,n : INTEGER 222 | // p1x..pny : REAL 223 | // 224 | // 225 | //id : identifier to allow more than one model information in one file. 226 | //id refers to the parameter id of command $$LABEL (HEADER-section). 227 | //dir : Orientation of the line when viewing in the negative z-direction 228 | //0 : clockwise (internal) 229 | //1 : counter-clockwise (external) 230 | //2 : open line (no solid) 231 | //n : number of points 232 | //p1x..pny : coordinates of the points 1..n 233 | 234 | if (readIntBE(1) != 0) //- vielleicht "dir"? 235 | { 236 | m_error.addWarning("unbekanntes Byte [dir?] @ " + m_offset); 237 | } 238 | 239 | n = readIntBE(2); 240 | 241 | 242 | if (n > 0) 243 | { 244 | //int n2 = n*2; //- x+y 245 | float[,] points = new float[n,2]; 246 | 247 | //- Punkte lesen 248 | for (int i=0;i 0) 287 | { 288 | //- hier gibt es 2 Punkt pro Linie 289 | int m = n * 2; 290 | 291 | float[,] points = new float[m, 2]; 292 | 293 | //- Punkte lesen: es werden 2*n Punkte eingelesen da jede Linie einen Start und ein Ende-Punkt hat 294 | for (int i = 0; i < m; i++) 295 | { 296 | points[i, 0] = scaleFactor * readIntBE(2);//- start/ende-x 297 | points[i, 1] = scaleFactor * readIntBE(2);//- start/ende-y 298 | } 299 | 300 | sd.addHatch(points, m); 301 | } 302 | 303 | break; 304 | 305 | default: 306 | m_error.addWarning("Data-Stream-Error??? Unknow Data Type: " + OType + " @ " + m_offset); 307 | break; 308 | 309 | } 310 | } 311 | 312 | } 313 | 314 | return sd; 315 | } 316 | 317 | 318 | 319 | //------------------------------------------// 320 | private bool readHead() 321 | { 322 | //- los gehts bei position 0 323 | setOffset(0); 324 | 325 | //- Datei Magic lesen und prüfen 326 | m_FileHead.magic = readStr(40); 327 | 328 | if (m_FileHead.magic.CompareTo("EOS 1993 SLI FILE ") != 0) //- Achtung Leerzeichen! 329 | { 330 | m_error.addError("file header magic is wrong? soll: >EOS 1993 SLI FILE < ist >"+ m_FileHead.magic +"<"); 331 | return false; 332 | } 333 | 334 | 335 | m_FileHead.int01 = readIntBE(2);; 336 | 337 | m_FileHead.int02 = readIntBE(2); 338 | 339 | m_FileHead.FileDataOffset = readIntBE(4); 340 | 341 | m_FileHead.int05 = readIntBE(4); 342 | 343 | m_FileHead.int07 = readIntBE(4); 344 | 345 | m_FileHead.FileSliceDataOffset = readIntBE(4); 346 | 347 | m_FileHead.FileIndexPos = readIntBE(4); 348 | 349 | m_FileHead.String2 = readStr(40); 350 | 351 | m_FileHead.LayerCount1 = readIntBE(4); 352 | 353 | m_FileHead.LayerCount2 = readIntBE(4); 354 | 355 | m_FileHead.int14 = readIntBE(4); 356 | 357 | 358 | //- 8 DWords überspringen 359 | setOffset(m_offset + 4 * 8); 360 | 361 | m_FileHead.scaleFactor = readFloatBE(4); 362 | 363 | 364 | /* 365 | Debug.Print "------------------------------" 366 | Debug.Print "Header:" 367 | Debug.Print "magic: " & FileHead.magic 368 | Debug.Print "int 1: " & FileHead.int01 369 | Debug.Print "int 2: " & FileHead.int02 370 | Debug.Print "DataOffset: " & FileHead.FileDataOffset 371 | Debug.Print "int 5: " & FileHead.int05 372 | Debug.Print "int 7: " & FileHead.int07 373 | Debug.Print "FileSliceDataOffset: " & FileHead.FileSliceDataOffset 374 | Debug.Print "FileIndexPos: " & FileHead.FileIndexPos 375 | Debug.Print "string2: " & FileHead.String2 376 | Debug.Print "LayerCount1: " & FileHead.LayerCount1 377 | Debug.Print "LayerCount2: " & FileHead.LayerCount2 378 | Debug.Print "int14: " & FileHead.int14 379 | Debug.Print "------------------------------" 380 | */ 381 | 382 | 383 | return readIndex(m_FileHead.FileIndexPos, m_FileHead.FileDataOffset, m_FileHead.LayerCount1); 384 | } 385 | 386 | 387 | 388 | //-------------------------------------// 389 | private bool readIndex(int FilePos, int FileOffset , int LayerCount) 390 | { 391 | setOffset( FilePos + FileOffset ); 392 | 393 | m_IndexTable_count = 0; 394 | 395 | if (m_IndexTable == null) m_IndexTable = new tyIndexTable[LayerCount]; 396 | if (m_IndexTable.Length < LayerCount) System.Array.Resize(ref m_IndexTable, LayerCount); 397 | 398 | 399 | while ((!m_eof) && (m_IndexTable_count < LayerCount)) 400 | { 401 | //- Start of a layer with upper surface at height z (z*units [mm]). All layers must be sorted in ascending order with respect to z. The thickness of the layer is given by the difference between the z values of the current and previous layers. A thickness for the first (lowest) layer can be specified by including a "zero-layer" with a given z value but with no polyline. 402 | m_IndexTable[m_IndexTable_count].layerPos = readIntBE(2) * m_FileHead.scaleFactor; 403 | 404 | m_IndexTable[m_IndexTable_count].FileOffset = readIntBE(4) + FileOffset; 405 | 406 | 407 | m_IndexTable_count++; 408 | } 409 | 410 | //Debug.Print "Layer Count " & IndexTable_count 411 | return true; 412 | } 413 | 414 | 415 | 416 | //-------------------------------------// 417 | private String readStr(int lenght, int offset=-1) 418 | { 419 | String outVal=""; 420 | 421 | byte[] tmpData = this.readByte(lenght, offset); 422 | 423 | if (tmpData!=null) 424 | { 425 | outVal = System.Text.Encoding.Default.GetString(tmpData); 426 | } 427 | 428 | return outVal; 429 | } 430 | 431 | //-----------------------------------------------// 432 | private bool openStream(String filename) 433 | { 434 | 435 | this.m_eof = true; 436 | this.m_blocklen = 0; 437 | this.m_offset = 0; 438 | 439 | try 440 | { 441 | m_reader = new System.IO.BinaryReader(System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)); 442 | 443 | this.m_eof = false; 444 | m_blocklen = (int)m_reader.BaseStream.Length; //- Beschränkung auf max 2GB Dateigröße 445 | } 446 | catch (System.Exception ex) 447 | { 448 | this.m_error.addError("IO.BinaryReader fail", ex.Message, filename); 449 | return false; 450 | } 451 | 452 | return true; 453 | } 454 | 455 | //-------------------------------------// 456 | private void setOffset(int offset) 457 | { 458 | if (offset > -1) 459 | { 460 | m_reader.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin); 461 | m_offset = offset; 462 | } 463 | } 464 | 465 | //-------------------------------------// 466 | private float readFloatBE(int lenght = 4, int offset = -1) 467 | { 468 | converterIntFloat.toInt = readIntBE(lenght, offset); 469 | return converterIntFloat.toFloat; 470 | } 471 | 472 | //-------------------------------------// 473 | private byte[] readByte(int lenght, int offset=-1) 474 | { 475 | if (lenght < 0) lenght = 0; 476 | setOffset(offset); 477 | 478 | byte[] dataArray = null; 479 | 480 | 481 | if (m_offset < m_blocklen) 482 | { 483 | if ((m_offset + lenght) > m_blocklen) 484 | { 485 | m_eof = true; 486 | lenght = m_blocklen - m_offset; 487 | } 488 | 489 | dataArray = new byte[lenght]; 490 | 491 | 492 | try 493 | { 494 | lenght = m_reader.Read(dataArray, 0, lenght); 495 | } 496 | catch 497 | { 498 | lenght = 0; 499 | m_eof = true; 500 | } 501 | 502 | if (lenght != dataArray.Length) System.Array.Resize(ref dataArray, lenght); 503 | } 504 | else 505 | { 506 | if (lenght > 0) 507 | { 508 | m_error.addWarning("ReadStr:EOF!"); 509 | lenght = 0; 510 | } 511 | 512 | m_eof = true; 513 | } 514 | 515 | 516 | if (lenght > 0) m_offset = m_offset + lenght; 517 | 518 | return dataArray; 519 | } 520 | 521 | 522 | 523 | 524 | //-------------------------------------// 525 | private int readIntBE(int lenght, int offset = -1) 526 | { 527 | int outVal = 0; 528 | if (lenght > 4) lenght = 4; 529 | 530 | byte[] tmpData = this.readByte(lenght, offset); 531 | 532 | if (tmpData != null) 533 | { 534 | lenght = tmpData.Length; 535 | 536 | if (lenght == 4) 537 | { 538 | outVal = (int)tmpData[0] + (tmpData[1] << 8) + (tmpData[2] << 16) + (tmpData[3] << 24); 539 | } 540 | else if (lenght == 2) 541 | { 542 | outVal = (int)tmpData[0] + (tmpData[1] << 8); 543 | } 544 | else if (lenght == 1) 545 | { 546 | outVal = (int)tmpData[0]; 547 | } 548 | else if (lenght == 3) 549 | { 550 | outVal = (int)tmpData[0] + (tmpData[1] << 8) + (tmpData[2] << 16); 551 | } 552 | } 553 | 554 | return outVal; 555 | } 556 | 557 | 558 | 559 | } 560 | } 561 | -------------------------------------------------------------------------------- /c#-sli-library/slicefiles/clSliceDataList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ThermoBox.tools; 3 | 4 | namespace ThermoBox.slicedata 5 | { 6 | public class clSliceDataList : absSliceDataSource 7 | { 8 | private System.Collections.Generic.List m_List = new System.Collections.Generic.List(); 9 | 10 | private String m_filename; 11 | private String m_filePath; 12 | 13 | private int m_max_Layers; 14 | private float m_layerthickness; 15 | private clError m_error; 16 | private bool m_is_enabeld = true; 17 | 18 | //------------------------------------------// 19 | public clSliceDataList(string filename="") 20 | { 21 | m_max_Layers = 0; 22 | m_layerthickness = 0; 23 | 24 | m_error = new clError("SliceDataList"); 25 | 26 | setFileName(filename); 27 | } 28 | 29 | //------------------------------------------// 30 | public void addSlice(string filename) 31 | { 32 | if (filename != "") 33 | { 34 | if (System.IO.File.Exists(filename)) 35 | { 36 | addSlice(clHelper.OpenSliceFile(filename)); 37 | } 38 | else 39 | { 40 | addSlice(clHelper.OpenSliceFile(m_filePath + filename)); 41 | } 42 | } 43 | } 44 | 45 | 46 | //------------------------------------------// 47 | public void addSlice(absSliceDataSource sliceData) 48 | { 49 | if (m_max_Layers < sliceData.getLayerCount()) m_max_Layers = sliceData.getLayerCount(); 50 | if (m_layerthickness != sliceData.getLayerThickness()) m_layerthickness = sliceData.getLayerThickness(); 51 | 52 | 53 | m_List.Add(sliceData); 54 | } 55 | 56 | 57 | //------------------------------------------// 58 | public void setFileName(System.String filename) 59 | { 60 | m_filename = filename; 61 | m_filePath = System.IO.Path.GetDirectoryName(filename); 62 | if (m_filePath[m_filePath.Length - 1] != System.IO.Path.DirectorySeparatorChar) m_filePath = m_filePath + System.IO.Path.DirectorySeparatorChar.ToString(); 63 | 64 | String[] files; 65 | 66 | try 67 | { 68 | 69 | files = System.IO.File.ReadAllLines(filename); 70 | } 71 | catch 72 | { 73 | files = new string[0]; 74 | } 75 | 76 | 77 | for (int i = 0; i < files.Length; i++) 78 | { 79 | addSlice(files[i]); 80 | } 81 | 82 | } 83 | 84 | //------------------------------------------// 85 | public System.String getFileName() 86 | { 87 | return m_filename; 88 | } 89 | 90 | //------------------------------------------// 91 | public System.String getObjectName(int ObjectIndex) 92 | { 93 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return ""; 94 | return m_List[ObjectIndex].getObjectName(0); 95 | } 96 | 97 | 98 | //------------------------------------------// 99 | public System.String getObjectInfo(int ObjectIndex) 100 | { 101 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return ""; 102 | return m_List[ObjectIndex].getObjectInfo(0); 103 | } 104 | 105 | //------------------------------------------// 106 | public bool getObjectEnabled(int ObjectIndex) 107 | { 108 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return false; 109 | return m_List[ObjectIndex].getObjectEnabled(0); 110 | } 111 | 112 | //------------------------------------------// 113 | public void setObjectEnabled(int ObjectIndex, bool enable) 114 | { 115 | if (ObjectIndex == 0) m_is_enabeld = enable; 116 | } 117 | 118 | //------------------------------------------// 119 | public int getLayerCount() 120 | { 121 | return m_max_Layers; 122 | } 123 | 124 | 125 | //------------------------------------------// 126 | public float getLayerThickness() 127 | { 128 | return m_layerthickness; 129 | 130 | } 131 | 132 | //------------------------------------------// 133 | //- gibt die Position der Oberseite des Layers zurück 134 | public float getLayerUpPosition(int LayerIndex) 135 | { 136 | 137 | return -1; 138 | 139 | } 140 | 141 | //------------------------------------------// 142 | public int getObjectCount() 143 | { 144 | return m_List.Count; 145 | } 146 | 147 | 148 | //------------------------------------------// 149 | public clSliceData getSliceData(int ObjectIndex, int LayerIndex, float jobLayerThickness) 150 | { 151 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return new clSliceData(); 152 | 153 | return m_List[ObjectIndex].getSliceData(0, LayerIndex, jobLayerThickness); 154 | } 155 | 156 | 157 | //-------------------------------------// 158 | public ty_Matrix3x2 getSliceTransformMatrix(int ObjectIndex, int LayerIndex) 159 | { 160 | ty_Matrix3x2 tmp = new ty_Matrix3x2(); ; 161 | return tmp; 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /c#-sli-library/slicefiles/clSliceJobFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ThermoBox.tools; 3 | using ThermoBox.config; 4 | 5 | 6 | namespace ThermoBox.slicedata 7 | { 8 | public class clSliceJobFile : absSliceDataSource 9 | { 10 | 11 | private class ty_part 12 | { 13 | public double zs; 14 | public double z; 15 | public double ys; 16 | public double y; 17 | public double xs; 18 | public double x; 19 | public double rotation; 20 | public string filename; 21 | public string ExpParName; 22 | public bool isEnabled; 23 | public float layerthikness; 24 | 25 | public absSliceDataSource sliceClass; 26 | } 27 | 28 | private System.Collections.Generic.List m_List = new System.Collections.Generic.List(); 29 | 30 | private String m_filename; 31 | private String m_filePath; 32 | 33 | private int m_max_Layers; 34 | private float m_layerthickness; 35 | private ty_part m_partZMax; 36 | private clError m_error; 37 | private clEosJobFileReader m_eosJob; 38 | 39 | 40 | 41 | //------------------------------------------// 42 | public clSliceJobFile(string filename = "") 43 | { 44 | m_max_Layers = 0; 45 | m_layerthickness = 0; 46 | m_error = new clError("clSliceJobFile"); 47 | 48 | setFileName(filename); 49 | } 50 | 51 | 52 | 53 | //------------------------------------------// 54 | private void addSlice(ty_part partInfo) 55 | { 56 | if (partInfo.filename != "") 57 | { 58 | string tmp = ""; 59 | 60 | try 61 | { 62 | tmp = System.IO.Path.GetFileName(partInfo.filename); 63 | } 64 | catch (System.Exception e) 65 | { 66 | m_error.addError("addSlice"+ e.Message); 67 | return; 68 | } 69 | 70 | string filename = ""; 71 | 72 | 73 | if (System.IO.File.Exists(m_filePath + partInfo.filename)) 74 | { 75 | filename = m_filePath + partInfo.filename; 76 | } 77 | else if (System.IO.File.Exists(m_filePath + tmp)) 78 | { 79 | filename = m_filePath + tmp; 80 | } 81 | else if (System.IO.File.Exists(partInfo.filename)) 82 | { 83 | filename = partInfo.filename; 84 | } 85 | 86 | 87 | 88 | if (filename != "") 89 | { 90 | //- open slice file 91 | absSliceDataSource sliceClass = clHelper.OpenSliceFile(filename); 92 | 93 | partInfo.sliceClass = sliceClass; 94 | 95 | //int test = ((clSliFileReader)sliceClass).getLayerUpPosition(1); 96 | 97 | 98 | if (m_max_Layers < sliceClass.getLayerCount()) 99 | { 100 | m_max_Layers = sliceClass.getLayerCount(); 101 | m_partZMax = partInfo; // Speichern des höchsten Bauteils für 102 | } 103 | 104 | partInfo.layerthikness = sliceClass.getLayerThickness(); 105 | 106 | //- diese klasse hat als Layer-Stärke die minimale Slise-Stärke aller Teile 107 | m_layerthickness = Math.Min(m_layerthickness, partInfo.layerthikness); 108 | 109 | 110 | 111 | m_List.Add(partInfo); 112 | } 113 | else 114 | { 115 | m_error.addError("Can't find file: [" + partInfo.filename + "]"); 116 | } 117 | } 118 | } 119 | 120 | 121 | 122 | //------------------------------------------// 123 | public void setFileName(System.String filename) 124 | { 125 | m_filename = filename; 126 | m_filePath = System.IO.Path.GetDirectoryName(filename); 127 | if (m_filePath.Substring(m_filePath.Length-1,1)!="\\") m_filePath = m_filePath + "\\"; 128 | 129 | 130 | m_eosJob = new clEosJobFileReader(filename); 131 | 132 | int partsID = m_eosJob.getOpenTreeElement("Parts"); 133 | int partsCount = m_eosJob.getElementChildCount(partsID); 134 | 135 | for (int i = 0; i < partsCount; i++) 136 | { 137 | int part = m_eosJob.getElementChild(partsID, i); 138 | int property = m_eosJob.getSubElement(part, "FileName"); 139 | 140 | if (property > 0) 141 | { 142 | 143 | ty_part newPart = new ty_part(); 144 | newPart.x = m_eosJob.getSubElementValueDouble(part,"x"); 145 | newPart.xs = m_eosJob.getSubElementValueDouble(part,"xs"); 146 | 147 | newPart.y = m_eosJob.getSubElementValueDouble(part,"y"); 148 | newPart.ys = m_eosJob.getSubElementValueDouble(part,"ys"); 149 | 150 | newPart.z = m_eosJob.getSubElementValueDouble(part,"z"); 151 | newPart.zs = m_eosJob.getSubElementValueDouble(part,"zs"); 152 | 153 | newPart.rotation = m_eosJob.getSubElementValueDouble(part, "Rotation"); 154 | 155 | newPart.filename = m_eosJob.getSubElementValueString(part,"FileName"); 156 | newPart.ExpParName = m_eosJob.getSubElementValueString(part, "ExpParName").Trim(); 157 | 158 | newPart.isEnabled = true; 159 | newPart.layerthikness = 0; 160 | 161 | if (String.Equals(newPart.ExpParName, "No_Exposure", StringComparison.OrdinalIgnoreCase)) newPart.isEnabled = false; 162 | if (String.Equals(newPart.ExpParName, "_ExternalSupport", StringComparison.OrdinalIgnoreCase)) newPart.isEnabled = false; 163 | 164 | addSlice(newPart); 165 | 166 | } 167 | } 168 | 169 | //- debug out File! 170 | //System.Diagnostics.Debug.WriteLine(m_eosJob.getXML()); 171 | } 172 | 173 | //------------------------------------------// 174 | public System.String getFileName() 175 | { 176 | return m_filename; 177 | } 178 | 179 | //------------------------------------------// 180 | public System.String getObjectName(int ObjectIndex) 181 | { 182 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return ""; 183 | return m_List[ObjectIndex].sliceClass.getObjectName(0); 184 | } 185 | 186 | //------------------------------------------// 187 | public System.String getObjectInfo(int ObjectIndex) 188 | { 189 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return ""; 190 | return m_List[ObjectIndex].ExpParName; 191 | } 192 | 193 | //------------------------------------------// 194 | public bool getObjectEnabled(int ObjectIndex) 195 | { 196 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return false; 197 | return m_List[ObjectIndex].isEnabled; 198 | } 199 | 200 | //------------------------------------------// 201 | public void setObjectEnabled(int ObjectIndex, bool enable) 202 | { 203 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return; 204 | m_List[ObjectIndex].isEnabled = enable; 205 | } 206 | 207 | 208 | //------------------------------------------// 209 | public int getLayerCount() 210 | { 211 | return m_max_Layers; 212 | } 213 | 214 | 215 | //------------------------------------------// 216 | public float getLayerThickness() 217 | { 218 | return m_layerthickness; 219 | 220 | } 221 | 222 | //- gibt die Position der Oberseite des Layers zurück 223 | public float getLayerUpPosition(int LayerIndex) 224 | { 225 | 226 | return -1; 227 | //return m_partZMax.sliceClass.getLayerUpPosition(LayerIndex); 228 | 229 | } 230 | 231 | 232 | //------------------------------------------// 233 | public int getObjectCount() 234 | { 235 | return m_List.Count; 236 | } 237 | 238 | 239 | //------------------------------------------// 240 | public clSliceData getSliceData(int ObjectIndex, int LayerIndex, float jobLayerThickness) 241 | { 242 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return new clSliceData(); 243 | 244 | double zshift = m_List[ObjectIndex].z; 245 | 246 | return m_List[ObjectIndex].sliceClass.getSliceData(0, (int)(LayerIndex * jobLayerThickness / m_List[ObjectIndex].layerthikness), jobLayerThickness); 247 | } 248 | 249 | 250 | 251 | //-------------------------------------// 252 | public ty_Matrix3x2 getSliceTransformMatrix(int ObjectIndex, int LayerIndex) 253 | { 254 | ty_Matrix3x2 tmpA = new ty_Matrix3x2(); 255 | ty_Matrix3x2 tmpB = new ty_Matrix3x2(); 256 | 257 | if ((ObjectIndex < 0) || (ObjectIndex >= m_List.Count)) return tmpA; 258 | 259 | ty_part tmpPart = m_List[ObjectIndex]; 260 | 261 | float a = (float)(tmpPart.rotation * 2 * Math.PI/360.0); 262 | 263 | //- toDo : rotation und skalierung! 264 | tmpA.m00 = Math.Cos(a); tmpA.m10 = -Math.Sin(a); 265 | tmpA.m01 = Math.Sin(a); tmpA.m11 = Math.Cos(a); 266 | 267 | tmpA.m20 = 0; 268 | tmpA.m21 = 0; 269 | 270 | 271 | 272 | tmpB.m00 = 1; tmpB.m10 = 0; 273 | tmpB.m01 = 0; tmpB.m11 = 1; 274 | 275 | tmpB.m20 = (float)tmpPart.x; 276 | tmpB.m21 = (float)tmpPart.y; 277 | 278 | 279 | ty_Matrix3x2 resultMat = ty_Matrix3x2.MatrixMult(tmpB, tmpA); 280 | 281 | 282 | return resultMat; 283 | } 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /eos-format.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug [dll] 6 | Win32 7 | 8 | 9 | Debug 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | 18 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9} 19 | Win32Proj 20 | sliformat 21 | 8.1 22 | eos-format 23 | 24 | 25 | 26 | DynamicLibrary 27 | true 28 | v140 29 | Unicode 30 | 31 | 32 | DynamicLibrary 33 | true 34 | v140 35 | Unicode 36 | 37 | 38 | DynamicLibrary 39 | false 40 | true 41 | Unicode 42 | v140_xp 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | true 59 | 60 | 61 | true 62 | 63 | 64 | false 65 | 66 | 67 | 68 | 69 | 70 | Level3 71 | Disabled 72 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 73 | true 74 | 75 | 76 | Console 77 | true 78 | 79 | 80 | 81 | 82 | 83 | 84 | Level3 85 | Disabled 86 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 87 | true 88 | 89 | 90 | Console 91 | true 92 | 93 | 94 | 95 | 96 | Level3 97 | 98 | 99 | MaxSpeed 100 | true 101 | true 102 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 103 | true 104 | 105 | 106 | Console 107 | true 108 | true 109 | true 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /eos-format.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {bbb61d48-c221-4afa-b3de-818eca12e842} 18 | 19 | 20 | {9a1d7601-f068-4cbb-9701-33db27c8a260} 21 | 22 | 23 | {2151c8f7-faa9-4ada-a150-f315dec4d0b7} 24 | 25 | 26 | {e66bbf32-92d9-4b54-a84b-f22c110826ce} 27 | 28 | 29 | {8915c864-49ae-4c24-af2b-252a75a9f48d} 30 | 31 | 32 | {b46c9838-2c29-4ac5-8e16-34467c9e75a5} 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Quelldateien 41 | 42 | 43 | Quelldateien 44 | 45 | 46 | Quelldateien 47 | 48 | 49 | Quelldateien\helper 50 | 51 | 52 | Quelldateien\helper 53 | 54 | 55 | Quelldateien\jobSlice 56 | 57 | 58 | Quelldateien\sliSlice 59 | 60 | 61 | Quelldateien\sliSlice 62 | 63 | 64 | Quelldateien\sliSlice 65 | 66 | 67 | Quelldateien\jobSlice 68 | 69 | 70 | 71 | 72 | Headerdateien 73 | 74 | 75 | Headerdateien 76 | 77 | 78 | Headerdateien 79 | 80 | 81 | Headerdateien\helper 82 | 83 | 84 | Headerdateien\helper 85 | 86 | 87 | Headerdateien\jobSlice 88 | 89 | 90 | Headerdateien\jobSlice 91 | 92 | 93 | Headerdateien\sliSlice 94 | 95 | 96 | Headerdateien\sliSlice 97 | 98 | 99 | Headerdateien\sliSlice 100 | 101 | 102 | Headerdateien\sliSlice 103 | 104 | 105 | -------------------------------------------------------------------------------- /eos-formats.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Demo\Demo.csproj", "{253AC784-5591-42B7-A520-CB7B051392C1}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eos-format", "eos-format.vcxproj", "{8C4563C6-8AC6-47CF-A910-B441D4FC30A9}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug [dll]|Any CPU = Debug [dll]|Any CPU 13 | Debug [dll]|Mixed Platforms = Debug [dll]|Mixed Platforms 14 | Debug [dll]|Win32 = Debug [dll]|Win32 15 | Debug|Any CPU = Debug|Any CPU 16 | Debug|Mixed Platforms = Debug|Mixed Platforms 17 | Debug|Win32 = Debug|Win32 18 | Release|Any CPU = Release|Any CPU 19 | Release|Mixed Platforms = Release|Mixed Platforms 20 | Release|Win32 = Release|Win32 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug [dll]|Any CPU.ActiveCfg = Debug|Any CPU 24 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug [dll]|Any CPU.Build.0 = Debug|Any CPU 25 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug [dll]|Mixed Platforms.ActiveCfg = Debug|Any CPU 26 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug [dll]|Mixed Platforms.Build.0 = Debug|Any CPU 27 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug [dll]|Win32.ActiveCfg = Debug|Any CPU 28 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 31 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 32 | {253AC784-5591-42B7-A520-CB7B051392C1}.Debug|Win32.ActiveCfg = Debug|Any CPU 33 | {253AC784-5591-42B7-A520-CB7B051392C1}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {253AC784-5591-42B7-A520-CB7B051392C1}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {253AC784-5591-42B7-A520-CB7B051392C1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 36 | {253AC784-5591-42B7-A520-CB7B051392C1}.Release|Mixed Platforms.Build.0 = Release|Any CPU 37 | {253AC784-5591-42B7-A520-CB7B051392C1}.Release|Win32.ActiveCfg = Release|Any CPU 38 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug [dll]|Any CPU.ActiveCfg = Debug [dll]|Win32 39 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug [dll]|Mixed Platforms.ActiveCfg = Debug [dll]|Win32 40 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug [dll]|Mixed Platforms.Build.0 = Debug [dll]|Win32 41 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug [dll]|Win32.ActiveCfg = Debug [dll]|Win32 42 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug [dll]|Win32.Build.0 = Debug [dll]|Win32 43 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug|Any CPU.ActiveCfg = Debug|Win32 44 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 45 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug|Mixed Platforms.Build.0 = Debug|Win32 46 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug|Win32.ActiveCfg = Debug|Win32 47 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Debug|Win32.Build.0 = Debug|Win32 48 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Release|Any CPU.ActiveCfg = Release|Win32 49 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Release|Mixed Platforms.ActiveCfg = Release|Win32 50 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Release|Mixed Platforms.Build.0 = Release|Win32 51 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Release|Win32.ActiveCfg = Release|Win32 52 | {8C4563C6-8AC6-47CF-A910-B441D4FC30A9}.Release|Win32.Build.0 = Release|Win32 53 | EndGlobalSection 54 | GlobalSection(SolutionProperties) = preSolution 55 | HideSolutionNode = FALSE 56 | EndGlobalSection 57 | EndGlobal 58 | -------------------------------------------------------------------------------- /examples/Box.sli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/examples/Box.sli -------------------------------------------------------------------------------- /examples/Demo.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/examples/Demo.exe -------------------------------------------------------------------------------- /examples/_info_.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/examples/_info_.txt -------------------------------------------------------------------------------- /examples/box_job.job: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/examples/box_job.job -------------------------------------------------------------------------------- /examples/eos-format.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/examples/eos-format.dll -------------------------------------------------------------------------------- /images/db_connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/images/db_connect.png -------------------------------------------------------------------------------- /images/db_jobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/images/db_jobs.png -------------------------------------------------------------------------------- /images/db_log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/images/db_log.png -------------------------------------------------------------------------------- /images/db_parts_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/images/db_parts_config.png -------------------------------------------------------------------------------- /images/jobfile_viewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/images/jobfile_viewer.png -------------------------------------------------------------------------------- /images/slifile_viewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/images/slifile_viewer.png -------------------------------------------------------------------------------- /source/abstractSliceFile.h: -------------------------------------------------------------------------------- 1 | #ifndef ABSTRACT_SLICE_FILE_H 2 | #define ABSTRACT_SLICE_FILE_H 3 | 4 | #include "abstractSliceFile.h" 5 | 6 | class abstractSliceFile 7 | { 8 | public: 9 | 10 | /// Read and interpret slice-data from File 11 | /// Filename to read from 12 | /// true on success; false on not 13 | virtual bool readFromFile(const char * filename) = 0; 14 | 15 | /// Read the slice data and add it to the sliceData class to the PartIndex index 16 | /// sliceData class 17 | /// index of the Part to read 18 | /// index of the layer to read 19 | /// [optional] Index in [sliceData] to store the data in, use -1 for same as PartIndex 20 | /// true on success; false on not 21 | virtual bool readSliceData(clSliceData * sliceData, int PartIndex, int LayerIndex, int storeAsPartIndex = -1) = 0; 22 | 23 | /// returns the Layer Count of the file 24 | /// index of the Part 25 | virtual int getLayerCount(int PartIndex) = 0; 26 | 27 | /// returns the Layer position in [mm] of the sellected part 28 | /// index of the Part 29 | /// index of the Layer 30 | virtual float getLayerPos(int PartIndex, int layerIndex) = 0; 31 | 32 | /// returns the name of the part 33 | /// index of the Part 34 | virtual char * getPartName(int PartIndex) = 0; 35 | 36 | 37 | /// returns a string with special propertys to use for this part 38 | /// index of the Part 39 | virtual char * getPartProperty(int PartIndex) = 0; 40 | 41 | 42 | /// finds and returns the Layer-Index for a layer position (in [mm]) 43 | /// index of the Part 44 | /// position of the layer in [mm] 45 | virtual int getLayerIndexByPos(int PartIndex, float LayerPos) = 0; 46 | 47 | /// returns the top Layer position in [mm] 48 | /// index of the Part 49 | virtual float getMaxLayerPos(int PartIndex) = 0; 50 | 51 | /// returns the number of parts in this file 52 | virtual int getPartCount() = 0; 53 | 54 | 55 | /// returns the LayerThickness in [mm] 56 | virtual float getLayerThickness() = 0; 57 | 58 | }; 59 | 60 | 61 | #endif -------------------------------------------------------------------------------- /source/clError.cpp: -------------------------------------------------------------------------------- 1 | #include "clError.h" 2 | #include 3 | 4 | #pragma warning (push) 5 | #pragma warning(disable : 4996) 6 | 7 | 8 | bool clError::s_hasLastError = false; 9 | char clError::s_lastError[2048]; 10 | bool clError::s_hasLastDebug = false; 11 | char clError::s_lastDebug[2048]; 12 | 13 | 14 | clError::clError(const char * className) 15 | { 16 | m_ClassName = className; 17 | } 18 | 19 | //-------------------------------------// 20 | void clError::AddError(const char * errorString, ...) 21 | { 22 | va_list args; 23 | va_start(args, errorString); 24 | 25 | char * infoStr = formatError(s_lastError, sizeof(s_lastError), "!Error", m_ClassName, errorString, args); 26 | 27 | printf("%s\n", infoStr); 28 | 29 | s_hasLastError = true; 30 | 31 | va_end(args); 32 | } 33 | 34 | 35 | 36 | //-------------------------------------// 37 | void clError::AddDebug(const char * debugString, ...) 38 | { 39 | va_list args; 40 | va_start(args, debugString); 41 | 42 | char * infoStr = formatError(s_lastDebug, sizeof(s_lastDebug), " Debug", m_ClassName, debugString, args); 43 | 44 | printf("%s\n", infoStr); 45 | 46 | s_hasLastDebug = true; 47 | 48 | va_end(args); 49 | } 50 | 51 | 52 | //-------------------------------------// 53 | char * clError::formatError(char * dest, int destSize, const char* ErrorType, const char* className, const char* outputString, va_list args) 54 | { 55 | int startsize = strlen(dest); 56 | int sizeofprefix = strlen(ErrorType) + strlen(className) + 20; 57 | 58 | if ((startsize + sizeofprefix) >= destSize) 59 | { 60 | //- on overflow restart! 61 | dest[0] = '\0'; 62 | startsize = 0; 63 | } 64 | 65 | if (clError::s_hasLastError) 66 | { 67 | dest[startsize] = '\n'; 68 | startsize++; 69 | } 70 | else 71 | { 72 | startsize = 0; 73 | } 74 | 75 | sprintf(&dest[startsize], "%s: [%s] ", ErrorType, className); 76 | int size = strlen(&dest[startsize]) + startsize; 77 | 78 | vsnprintf(&dest[size], destSize - size, outputString, args); 79 | 80 | clError::s_hasLastError = true; 81 | 82 | return &dest[startsize]; 83 | } 84 | 85 | 86 | //-------------------------------------// 87 | clError::~clError() 88 | { 89 | } 90 | 91 | 92 | //-------------------------------------// 93 | char * clError::getLastError() 94 | { 95 | if (!clError::s_hasLastError) return NULL; 96 | clError::s_hasLastError = false; 97 | return clError::s_lastError; 98 | } 99 | 100 | //-------------------------------------// 101 | char * clError::getLastDebug() 102 | { 103 | if (!clError::s_hasLastDebug) return NULL; 104 | clError::s_hasLastDebug = false; 105 | return clError::s_lastDebug; 106 | } 107 | 108 | 109 | 110 | #pragma warning (pop) -------------------------------------------------------------------------------- /source/clError.h: -------------------------------------------------------------------------------- 1 | #ifndef CLERROR_H 2 | #define CLERROR_H 3 | 4 | #include 5 | #include 6 | 7 | class clError 8 | { 9 | private: 10 | const char * m_ClassName; 11 | static char s_lastError[2048]; 12 | static bool s_hasLastError; 13 | static char s_lastDebug[2048]; 14 | static bool s_hasLastDebug; 15 | 16 | char * formatError(char * dest, int destSize, const char* ErrorType, const char* className, const char* outputString, va_list ap); 17 | public: 18 | 19 | clError(const char * className); 20 | ~clError(); 21 | void AddError(const char * errorString, ...); 22 | void AddDebug(const char * debugString, ...); 23 | static char * getLastError(); 24 | static char * getLastDebug(); 25 | }; 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /source/clFile.cpp: -------------------------------------------------------------------------------- 1 | #include "clFile.h" 2 | 3 | 4 | clFile::clFile(const char * FilePath, const char * FileName): 5 | m_error("clFile"), 6 | m_eof(false) 7 | { 8 | m_buffer = NULL; 9 | m_filesize = 0; 10 | m_bufferLen = 0; 11 | m_filePos = 0; 12 | m_eof = true; 13 | 14 | openFile(FilePath, FileName); 15 | 16 | } 17 | 18 | 19 | //---------------------------------------------------// 20 | clFile::~clFile() 21 | { 22 | //- close file 23 | closeFile(); 24 | } 25 | 26 | 27 | //---------------------------------------------------// 28 | void clFile::closeFile() 29 | { 30 | //- delete buffer if already used 31 | if (m_buffer != NULL) delete m_buffer; 32 | 33 | m_buffer = NULL; 34 | m_filesize = 0; 35 | m_bufferLen = 0; 36 | m_filePos = 0; 37 | m_eof = true; 38 | 39 | m_File.close(); 40 | m_File.clear(); 41 | } 42 | 43 | //---------------------------------------------------// 44 | bool clFile::openFile(const char * FileName) 45 | { 46 | return openFile(NULL, FileName); 47 | } 48 | 49 | 50 | //---------------------------------------------------// 51 | bool clFile::fileExist(const char * Filename) 52 | { 53 | struct stat buffer; 54 | return (stat(Filename, &buffer) == 0); 55 | } 56 | 57 | //---------------------------------------------------// 58 | bool clFile::openFile(const char * FilePath, const char * FileName) 59 | { 60 | if (FileName == NULL) return false; 61 | 62 | if (FilePath != NULL) FileName = std::string(FilePath).append(FileName).c_str(); 63 | 64 | m_buffer = NULL; 65 | m_bufferLen = 0; 66 | m_filesize = 0; 67 | m_filePos = 0; 68 | m_eof = true; 69 | m_fileReadPos = 0; 70 | 71 | m_File.open(FileName, ios::in | ios::binary); 72 | if (m_File) 73 | { 74 | m_error.AddDebug("Open file %s", FileName); 75 | 76 | //- get stream size 77 | m_File.seekg(0, m_File.end); 78 | m_filesize = (unsigned int) m_File.tellg(); 79 | m_File.seekg(0, m_File.beg); 80 | 81 | m_eof = false; 82 | } 83 | else 84 | { 85 | m_error.AddError("Unable to open file: %s", FileName); 86 | return false; 87 | } 88 | 89 | return true; 90 | 91 | 92 | } 93 | 94 | 95 | 96 | //---------------------------------------------------// 97 | bool clFile::readFilePart(unsigned int offset, int size) 98 | { 99 | if (m_File) 100 | { 101 | //- move to file pos 102 | if (offset >= 0) 103 | { 104 | if (offset > m_filesize) 105 | { 106 | m_filePos = m_filesize; 107 | m_error.AddError("readFile(): file seek(EOF)!"); 108 | m_eof = true; 109 | return false; 110 | } 111 | m_File.seekg(offset, m_File.beg); 112 | m_filePos = offset; 113 | } 114 | else 115 | { 116 | offset = m_fileReadPos; //- use the end-pos of the last read 117 | } 118 | 119 | 120 | if (size < 0) 121 | { 122 | //- read everything left 123 | size = m_filesize - offset; 124 | } 125 | 126 | 127 | //- create buffer 128 | if (m_bufferLen < size) 129 | { 130 | //- delete buffer if already used 131 | if (m_buffer != NULL) delete m_buffer; 132 | 133 | m_bufferLen = size; 134 | 135 | //- create buffer 136 | m_buffer = new char[m_bufferLen]; 137 | 138 | if (m_buffer == NULL) 139 | { 140 | m_error.AddError("readFile(): Out of memory"); 141 | return false; 142 | } 143 | } 144 | 145 | 146 | //- read over EOF? 147 | if (size + offset > m_filesize) 148 | { 149 | size = m_filesize - offset; 150 | } 151 | 152 | //- read data from file to buffer 153 | m_File.read(m_buffer, size); 154 | m_bufferLen = size; 155 | m_fileReadPos = offset + size; 156 | m_bufferPos = offset; 157 | } 158 | else 159 | { 160 | m_error.AddError("file is not open"); 161 | } 162 | 163 | return true; 164 | } 165 | 166 | 167 | //---------------------------------------------------// 168 | int clFile::readString(char * destBuffer, int size, int offset) 169 | { 170 | int readCount = 0; 171 | const char * buffer; 172 | char * pOut = destBuffer; 173 | 174 | buffer = readString(&readCount, size, offset); 175 | 176 | for (int i = readCount; i > 0; i--) 177 | { 178 | *pOut = *buffer; 179 | pOut++; 180 | buffer++; 181 | } 182 | 183 | for (int i = size - readCount; i > 0; i--) 184 | { 185 | *pOut = '\0'; 186 | pOut++; 187 | } 188 | 189 | return readCount; 190 | } 191 | 192 | 193 | //---------------------------------------------------// 194 | const char * clFile::readString(int * outSize, int size, int offset) 195 | { 196 | const char * out; 197 | 198 | if (offset>-1) 199 | { 200 | m_bufferPos = offset - m_filePos; 201 | m_eof = false; //- we do check this later... 202 | } 203 | 204 | //- if no size given then return to the end of buffer 205 | if (size == -1) size = m_bufferLen - m_bufferPos; 206 | if (size < 0) size = 0; 207 | 208 | 209 | int ofs = m_bufferPos - m_filePos; 210 | 211 | //- not EOF? 212 | if (ofs < m_bufferLen) 213 | { 214 | //- requestet size is available? 215 | if (ofs + size > m_bufferLen) 216 | { 217 | m_eof = true; 218 | 219 | if (outSize == NULL) 220 | { 221 | m_error.AddError("Out of filesize! Available size: %i / requestet size: %i", m_bufferLen, size); 222 | return NULL; //- the required Buffer size can't be returned 223 | } 224 | 225 | m_eof = true; 226 | size = m_bufferLen - m_bufferPos; 227 | } 228 | 229 | 230 | out = &m_buffer[ofs]; 231 | } 232 | else 233 | { 234 | m_error.AddError("EOF!"); 235 | m_eof = true; 236 | size = 0; 237 | out = NULL; 238 | } 239 | m_bufferPos += size; 240 | 241 | if (outSize != NULL) *outSize = size; 242 | 243 | return out; 244 | } 245 | 246 | 247 | //---------------------------------------------------// 248 | unsigned int clFile::readIntBE(int size, int offset) 249 | { 250 | int retSize = 0; 251 | const char * tmp = readString(&retSize, size, offset); 252 | 253 | if (tmp == NULL) return 0; 254 | if (retSize == 4) return *((int*) tmp); 255 | if (retSize == 2) return ((*((int*) tmp)) & 0x0000FFFF); 256 | if (retSize == 1) return ((*((int*) tmp)) & 0x000000FF); 257 | if (retSize == 3) return ((*((int*) tmp)) & 0x00FFFFFF); 258 | 259 | return 0; 260 | } 261 | 262 | 263 | //---------------------------------------------------// 264 | int clFile::readSignedWordBE(int offset) 265 | { 266 | int retSize = 0; 267 | const char * tmp = readString(&retSize, 2, offset); 268 | 269 | if (retSize != 2) return 0; 270 | 271 | return (*((short*) tmp)); 272 | } 273 | 274 | //---------------------------------------------------// 275 | float clFile::readFloat(int offset) 276 | { 277 | UNION_FLOAT_2_CHAR destF; 278 | 279 | if (readString((char*) destF.ch, 4, offset) == 4) return destF.f; 280 | 281 | return 0.0f; 282 | } 283 | 284 | //---------------------------------------------------// 285 | int clFile::getOffset() 286 | { 287 | return m_bufferPos; 288 | } 289 | 290 | //---------------------------------------------------// 291 | bool clFile::setOffset(int newOffset) 292 | { 293 | int tmpOffset = newOffset - m_filePos; 294 | 295 | if ((tmpOffset >= 0) && (tmpOffset < m_bufferLen)) 296 | { 297 | m_bufferPos = tmpOffset; 298 | return true; 299 | } 300 | else 301 | { 302 | m_error.AddError("setOffset(%i) out of buffered File [%i - %i]", newOffset, m_filePos, m_filePos + m_bufferLen); 303 | return false; 304 | } 305 | } 306 | 307 | //---------------------------------------------------// 308 | bool clFile::eof() 309 | { 310 | return m_eof; 311 | } -------------------------------------------------------------------------------- /source/clFile.h: -------------------------------------------------------------------------------- 1 | #ifndef CLFILE_H 2 | #define CLFILE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | #include "clError.h" 10 | 11 | using namespace std; 12 | 13 | class clFile 14 | { 15 | private: 16 | union BinaryConvertIntToFloat 17 | { 18 | float toFloat; 19 | int toInt; 20 | }; 21 | 22 | 23 | char * m_buffer; 24 | int m_bufferLen; 25 | //- offset in buffer 26 | int m_bufferPos; 27 | 28 | int m_filePos; 29 | int m_fileReadPos; 30 | 31 | 32 | bool m_eof; 33 | 34 | 35 | clError m_error; 36 | unsigned int m_filesize; 37 | 38 | std::ifstream m_File; 39 | 40 | union UNION_FLOAT_2_CHAR 41 | { 42 | float f; 43 | char ch[4]; 44 | }; 45 | 46 | 47 | public: 48 | //clFile(); 49 | clFile::clFile(const char * FilePath = NULL, const char * FileName = NULL); 50 | ~clFile(); 51 | 52 | 53 | 54 | 55 | 56 | /// open a File 57 | /// Path of File to read from 58 | /// Filename of File to read from 59 | /// true on success 60 | bool openFile(const char * FilePath, const char * FileName); 61 | bool openFile(const char * FileName); 62 | 63 | 64 | /// close the file 65 | void closeFile(); 66 | 67 | 68 | 69 | /// reads from opened File 70 | /// offset in file; values smaler 0 read from current position 71 | /// count of bytes to to read 72 | /// true on success 73 | bool readFilePart(unsigned int offset, int size); 74 | bool readFilePart(int size); 75 | 76 | /// return the next [size] byte. 77 | /// count of bytes read. 78 | /// count of bytes to read. 79 | /// offset to start reading. 80 | /// pointer to binary char buffer 81 | const char * readString(int * outSize, int size, int offset= -1); 82 | 83 | /// copy [size] byte from file buffer to dest buffer. 84 | /// 85 | /// count of bytes to read. 86 | /// offset to start reading. 87 | /// count of bytes read 88 | int readString(char * destBuffer, int size, int offset = -1); 89 | 90 | /// return the next [size] byte and convert them to a BigEnding Integer. 91 | /// count of bytes to read. 92 | /// offset to start reading. 93 | unsigned int readIntBE(int size = 4, int offset = -1); 94 | 95 | int readSignedWordBE(int offset); 96 | 97 | /// return the next 4 byte and convert them to a float. 98 | /// offset to start reading. 99 | float readFloat(int offset = -1); 100 | 101 | /// return the current offset in the file 102 | /// file offset 103 | int getOffset(); 104 | 105 | /// set the current offset in the file 106 | /// true on success 107 | bool setOffset(int newOffset); 108 | 109 | 110 | /// Check if File [Filename] exists 111 | /// Filename to test. 112 | /// true on success 113 | static bool fileExist(const char * Filename); 114 | 115 | bool eof(); 116 | 117 | }; 118 | 119 | #endif -------------------------------------------------------------------------------- /source/clJobFile.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/source/clJobFile.cpp -------------------------------------------------------------------------------- /source/clJobFile.h: -------------------------------------------------------------------------------- 1 | #ifndef CL_JOBFILE_H 2 | #define CL_JOBFILE_H 3 | 4 | #include 5 | #include "clError.h" 6 | #include 7 | #include 8 | 9 | class clJobFile 10 | { 11 | public: 12 | clJobFile(); 13 | ~clJobFile(); 14 | 15 | static const int ROOT_ELEMENT = 0; 16 | 17 | /// Read and interpret job-data from File 18 | /// Filename of File to read 19 | /// uncoded buffer on success; NULL on error 20 | char * readFromFile(const char * filename); 21 | 22 | /// Interpret job-data from char buffer 23 | /// char Buffer to interpre 24 | /// lenght of [buffer] 25 | /// uncoded buffer on success; NULL on error 26 | char * readFromBuffer(const char * buffer, int bufferLength); 27 | 28 | 29 | /// returns the lenght of the uncrypted buffer/data 30 | /// the lenght of the uncrypted data 31 | int getBufferLenght(); 32 | 33 | /// returns the uncrypted buffer/data 34 | /// the uncrypted data 35 | char * getBuffer(); 36 | 37 | 38 | private: 39 | 40 | 41 | clError m_error; 42 | 43 | /// Counting not empty lines in file 44 | int countBufferLines(const char * buffer, int bufferLen); 45 | 46 | /// uncodes a cryptet text-line (with crypting header) of [lineLen] characters from [pInBuffer] to [pOutBuffer]. Returns the new end of [pOutBuffer] 47 | char * uncryptLine(char * pOutBuffer, const char * pInBuffer, int lineLen); 48 | 49 | /// uncrypt [lineLen] characters from [pInBuffer] to [pOutBuffer]. Returns the new end of [pOutBuffer] 50 | char * uncryptString(char * pOutBuffer, const char * pInBuffer, int lineLen); 51 | 52 | 53 | /// find the position of the first appearance of a byte 54 | int findByte(const char * pInBuffer, int lineLen, char Byte2Find); 55 | 56 | 57 | char * m_filebuffer; 58 | int m_filebuffer_lenght; 59 | int m_filebuffer_used_len; 60 | }; 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /source/clJobFileInterpreter.cpp: -------------------------------------------------------------------------------- 1 | #include "clJobFileInterpreter.h" 2 | 3 | 4 | clJobFileInterpreter::clJobFileInterpreter() 5 | : m_error("clJobFileInterpreter") 6 | { 7 | m_values = NULL; 8 | m_values_length = 0; 9 | m_values_count = 0; 10 | 11 | m_keys = NULL; 12 | m_keys_length = 0; 13 | m_keys_count = 0; 14 | } 15 | 16 | //---------------------------------------------------// 17 | clJobFileInterpreter::~clJobFileInterpreter() 18 | { 19 | if (m_keys != NULL) 20 | { 21 | delete[] m_keys; 22 | m_keys = NULL; 23 | } 24 | m_keys_length = 0; 25 | 26 | 27 | if (m_values != NULL) 28 | { 29 | delete[] m_values; 30 | m_values = NULL; 31 | } 32 | m_values_length = 0; 33 | } 34 | 35 | 36 | //---------------------------------------------------// 37 | bool clJobFileInterpreter::readFromFile(const char * filename) 38 | { 39 | if (m_JobFile.readFromFile(filename) == NULL) 40 | { 41 | m_error.AddError("readFromFile() failed"); 42 | return false; 43 | } 44 | 45 | return interpret(); 46 | } 47 | 48 | 49 | //---------------------------------------------------// 50 | bool clJobFileInterpreter::readFromBuffer(const char * buffer, int bufferLength) 51 | { 52 | 53 | if (m_JobFile.readFromBuffer(buffer, bufferLength) == NULL) 54 | { 55 | m_error.AddError("readFromBuffer() failed"); 56 | return false; 57 | } 58 | 59 | return interpret(); 60 | } 61 | 62 | 63 | //---------------------------------------------------// 64 | bool clJobFileInterpreter::interpret() 65 | { 66 | char * pBuffer = m_JobFile.getBuffer(); 67 | int bufferLen = m_JobFile.getBufferLenght(); 68 | 69 | if (pBuffer == NULL) 70 | { 71 | m_error.AddError("interpret() no data"); 72 | return false; 73 | } 74 | 75 | 76 | //- first count keys and propertys and create buffers 77 | createBuffers(pBuffer, bufferLen); 78 | 79 | 80 | //- add root item 81 | m_keys_count = 1; 82 | m_keys[0].name = (char *)"_root_"; 83 | m_keys[0].first_client = NULL; 84 | m_keys[0].last_client = NULL; 85 | m_keys[0].first_property = NULL; 86 | m_keys[0].last_property = NULL; 87 | m_keys[0].next_item = NULL; 88 | m_keys[0].parent = NULL; 89 | m_keys[0].index = 0; 90 | 91 | //- add dummy item for index 0 92 | m_values_count = 1; 93 | m_values[0].comment = NULL; 94 | m_values[0].name = NULL; 95 | m_values[0].type = '\0'; 96 | m_values[0].value = NULL; 97 | m_values[0].next_property = NULL; 98 | m_values[0].index = 0; 99 | 100 | 101 | char * pLineStart = pBuffer; 102 | bool isFirstChar = true; 103 | int lineLen = 0; 104 | 105 | int parents[100]; //- lookup tabel for parrents 106 | //- set lookup-table to root element 107 | for (int i = 0; i<100; i++) parents[i] = 0; 108 | 109 | int currentLeafe = 0; 110 | 111 | 112 | for (int i = bufferLen; i > 0; i--) 113 | { 114 | char value = *pBuffer; 115 | if ((value == '\n') || (value == '\r')) //- is this a "\n" or "\r" or "\r\n" 116 | { 117 | if (lineLen > 1) 118 | { 119 | if (*pLineStart == '[') 120 | { 121 | //------------------------- 122 | //-- this is a KEY-Element 123 | 124 | int pos = findByte(pLineStart, lineLen, ']'); 125 | if (pos < 1) 126 | { 127 | m_error.AddError("Syntax-Error. Missing ']'"); 128 | } 129 | else 130 | { 131 | int newDeep = std::atoi(pLineStart + 1); 132 | if (newDeep > 99) newDeep = 99; 133 | 134 | if (newDeep > 0) //- every element has to be in the root-element 135 | { 136 | //- close the "m_keys[newKey].name" string 137 | *pBuffer = '\0'; 138 | 139 | int newKey = m_keys_count; 140 | m_keys_count++; 141 | 142 | //- set values for this key 143 | m_keys[newKey].index = newKey; 144 | m_keys[newKey].parent = &m_keys[parents[newDeep - 1]]; 145 | m_keys[newKey].name = Trim(pLineStart + pos + 1); 146 | m_keys[newKey].first_client = NULL; 147 | m_keys[newKey].last_client = NULL; 148 | m_keys[newKey].next_item = NULL; 149 | m_keys[newKey].first_property = NULL; 150 | m_keys[newKey].last_property = NULL; 151 | 152 | 153 | //- update parrent 154 | if (m_keys[newKey].parent->first_client == NULL) m_keys[newKey].parent->first_client = &m_keys[newKey]; 155 | 156 | if (m_keys[newKey].parent->last_client == NULL) 157 | { 158 | m_keys[newKey].parent->last_client = &m_keys[newKey]; 159 | } 160 | else 161 | { 162 | //- update the next-item property of the last item on this level 163 | m_keys[newKey].parent->last_client->next_item = &m_keys[newKey]; 164 | m_keys[newKey].parent->last_client = &m_keys[newKey]; 165 | } 166 | 167 | //- save state 168 | parents[newDeep] = newKey; 169 | currentLeafe = newKey; 170 | } 171 | else 172 | { 173 | currentLeafe = 0; 174 | } 175 | } 176 | } 177 | else 178 | { 179 | //------------------------- 180 | //-- this is a Property 181 | 182 | int pos = findByte(pLineStart, lineLen, '='); 183 | if (pos < 1) 184 | { 185 | m_error.AddError("Syntax-Error. Missing '='"); 186 | } 187 | else 188 | { 189 | //- close the property-name string: "m_value[newValue].name" 190 | *(pLineStart + pos) = '\0'; 191 | //- close the property-value string: "m_value[newValue].value" 192 | *pBuffer = '\0'; 193 | 194 | 195 | int newValue = m_values_count; 196 | m_values_count++; 197 | 198 | char * value = LTrim(pLineStart + pos + 1); 199 | char * comment = NULL; 200 | 201 | int c_pos = findByte(value, lineLen, '#'); 202 | if (c_pos > 0) 203 | { 204 | *(value + c_pos) = '\0'; 205 | comment = value + c_pos + 1; 206 | 207 | RTrim(value); //- remove all spaces at the end of value 208 | } 209 | 210 | m_values[newValue].index = newValue; 211 | m_values[newValue].name = Trim(pLineStart); 212 | m_values[newValue].value = value + 1; 213 | m_values[newValue].type = *value; //- the type is in the first char 214 | m_values[newValue].comment = LTrim(comment); 215 | m_values[newValue].next_property = NULL; 216 | 217 | //- update parrent 218 | if (m_keys[currentLeafe].first_property == NULL) 219 | { 220 | m_keys[currentLeafe].first_property = &m_values[newValue]; 221 | } 222 | else 223 | { 224 | //- update last property in this key 225 | m_keys[currentLeafe].last_property->next_property = &m_values[newValue]; 226 | } 227 | 228 | m_keys[currentLeafe].last_property = &m_values[newValue]; 229 | 230 | } 231 | } 232 | //- this is a valid line 233 | } 234 | 235 | 236 | //- is this a "\r\n" ? 237 | if ((value == '\r') && (*pBuffer == '\n')) pBuffer++; 238 | 239 | //- next start pos 240 | isFirstChar = true; 241 | pLineStart = pBuffer + 1; 242 | lineLen = 0; 243 | } 244 | else 245 | { 246 | if (isFirstChar) 247 | { 248 | //- jump over spaces on the right 249 | if ((value != ' ') && (value != '\t')) 250 | { 251 | isFirstChar = false; 252 | pLineStart = pBuffer; 253 | lineLen = 0; 254 | } 255 | } 256 | lineLen++; 257 | } 258 | 259 | 260 | pBuffer++; 261 | } 262 | 263 | 264 | return true; 265 | } 266 | 267 | 268 | //---------------------------------------------------// 269 | bool clJobFileInterpreter::printXML() 270 | { 271 | if (m_JobFile.getBuffer() == NULL) 272 | { 273 | m_error.AddError("job-file is not open"); 274 | return false; 275 | } 276 | 277 | if (m_keys == NULL) 278 | { 279 | m_error.AddError("no data in file"); 280 | return false; 281 | } 282 | printXMLout(0, m_keys); 283 | 284 | return true; 285 | } 286 | 287 | 288 | //---------------------------------------------------// 289 | void clJobFileInterpreter::printXMLout(int deep, tyConfigKey * key) 290 | { 291 | char padding[100]; 292 | 293 | for (int i = 0; i < deep; i++) padding[i] = '\t'; 294 | padding[deep] = '\0'; 295 | 296 | printf("%s<%s>\n", padding, key->name); 297 | 298 | //- print propertys 299 | tyConfigValue * value = key->first_property; 300 | while (value != NULL) 301 | { 302 | printf("%s\tname, value->type, value->value); 303 | 304 | if (value->comment != NULL) printf("comment=\"%s\" ", value->comment); 305 | 306 | printf("/>\n"); 307 | 308 | value = value->next_property; 309 | } 310 | 311 | //- print childs 312 | tyConfigKey * child = key->first_client; 313 | while (child != NULL) 314 | { 315 | printXMLout(deep+1, child); 316 | child = child->next_item; 317 | } 318 | 319 | printf("%s\n", padding, key->name); 320 | } 321 | 322 | 323 | //---------------------------------------------------// 324 | bool clJobFileInterpreter::createBuffers(const char * pBuffer, int bufferLen) 325 | { 326 | //------------------- 327 | //- count keys and propertys 328 | int keys_c = 0; 329 | int prop_c = 0; 330 | int lineLen = 0; 331 | bool doneFirstChar = false; 332 | 333 | //- free old buffers 334 | if (m_values != NULL) delete[] m_values; 335 | m_values = NULL; 336 | 337 | if (m_keys != NULL) delete[] m_keys; 338 | m_keys = NULL; 339 | 340 | //- count 341 | for (int i = bufferLen; i > 0; i--) 342 | { 343 | char value = *pBuffer; 344 | if ((value == '\n') || (value == '\r')) //- is this a "\n" or "\r" or "\r\n" 345 | { 346 | doneFirstChar = false; 347 | 348 | //- is this a "\r\n" ? 349 | if ((value == '\r') && (*pBuffer == '\n')) pBuffer++; 350 | } 351 | else if (!doneFirstChar) 352 | { 353 | //- ignore left free-spaces 354 | if ((value != ' ') && (value != '\t')) 355 | { 356 | doneFirstChar = true; 357 | 358 | if (value == '[') 359 | { 360 | keys_c++; 361 | } 362 | else 363 | { 364 | prop_c++; 365 | } 366 | 367 | } 368 | } 369 | 370 | pBuffer++; 371 | } 372 | 373 | //- create buffers 374 | m_values_length = prop_c + 2; //- +1 for 0 item 375 | m_values = new tyConfigValue[m_values_length]; 376 | m_values_count = 0; 377 | 378 | m_keys_length = keys_c + 2; //- +1 for root item 379 | m_keys = new tyConfigKey[m_keys_length]; 380 | m_keys_count = 0; 381 | 382 | 383 | 384 | return true; 385 | } 386 | 387 | 388 | 389 | //---------------------------------------------------// 390 | int clJobFileInterpreter::findByte(const char * pInBuffer, int lineLen, char Byte2Find) 391 | { 392 | const char * pIn = pInBuffer; 393 | 394 | for (int i = 0; i < lineLen; i++) 395 | { 396 | char v = *pIn; 397 | 398 | if (v == Byte2Find) return i; 399 | if (v == '\0') return -1; 400 | 401 | pIn++; 402 | } 403 | return -1; 404 | } 405 | 406 | 407 | //---------------------------------------------------// 408 | char * clJobFileInterpreter::LTrim(char * buffer) 409 | { 410 | char * pIn = buffer; 411 | if (pIn == NULL) return NULL; 412 | 413 | while (*pIn != '\0') 414 | { 415 | char v = *pIn; 416 | if ((v != ' ') && (v != '\t')) return pIn; 417 | pIn++; 418 | } 419 | return pIn; 420 | } 421 | 422 | //---------------------------------------------------// 423 | char * clJobFileInterpreter::RTrim(char * buffer) 424 | { 425 | char * pIn = buffer; 426 | if (pIn == NULL) return NULL; 427 | 428 | char * lastChar = pIn; 429 | 430 | while (*pIn != '\0') 431 | { 432 | char v = *pIn; 433 | if ((v != ' ') && (v != '\t')) lastChar = pIn; 434 | pIn++; 435 | } 436 | 437 | *(lastChar + 1) = '\0'; 438 | 439 | return pIn; 440 | } 441 | 442 | 443 | 444 | //---------------------------------------------------// 445 | char * clJobFileInterpreter::Trim(char * buffer) 446 | { 447 | char * pIn = buffer; 448 | if (pIn == NULL) return NULL; 449 | 450 | //- find first non space 451 | while (*pIn != '\0') 452 | { 453 | char v = *pIn; 454 | 455 | if ((v != ' ') && (v != '\t')) 456 | { 457 | buffer = pIn; 458 | break; 459 | } 460 | pIn++; 461 | } 462 | 463 | 464 | //- stripe last emptys 465 | char * lastChar = pIn; 466 | 467 | while (*pIn != '\0') 468 | { 469 | char v = *pIn; 470 | if ((v != ' ') && (v != '\t')) lastChar = pIn; 471 | pIn++; 472 | } 473 | 474 | *(lastChar + 1) = '\0'; 475 | 476 | return buffer; 477 | } 478 | 479 | //---------------------------------------------------// 480 | char * clJobFileInterpreter::getKeyName(int id) 481 | { 482 | if ((id < 0) || (id >= m_keys_count)) return NULL; 483 | return m_keys[id].name; 484 | } 485 | 486 | //---------------------------------------------------// 487 | int clJobFileInterpreter::getFirstChild(int id) 488 | { 489 | if ((id < 0) || (id >= m_keys_count)) return -1; 490 | if (m_keys[id].first_client == NULL) return -1; 491 | 492 | return m_keys[id].first_client->index; 493 | } 494 | 495 | //---------------------------------------------------// 496 | int clJobFileInterpreter::getNextChild(int id) 497 | { 498 | if ((id < 0) || (id >= m_keys_count)) return -1; 499 | if (m_keys[id].next_item == NULL) return -1; 500 | 501 | return m_keys[id].next_item->index; 502 | } 503 | 504 | //---------------------------------------------------// 505 | int clJobFileInterpreter::getChild(int id, const char * keyName) 506 | { 507 | if ((id < 0) || (id >= m_keys_count)) return -1; 508 | if (m_keys[id].first_client == NULL) return -1; 509 | 510 | 511 | int key = m_keys[id].first_client->index; 512 | 513 | while (key > 0) 514 | { 515 | if (_strcmpi(keyName, m_keys[key].name) == 0) return key; 516 | 517 | if (m_keys[key].next_item <= 0) return -1; 518 | key = m_keys[key].next_item->index; 519 | } 520 | 521 | return -1; 522 | } 523 | 524 | 525 | //---------------------------------------------------// 526 | int clJobFileInterpreter::getChildCount(int id) 527 | { 528 | if ((id < 0) || (id >= m_keys_count)) return 0; 529 | if (m_keys[id].first_client == NULL) return 0; 530 | 531 | int count = 0; 532 | 533 | int key = m_keys[id].first_client->index; 534 | 535 | while (key > 0) 536 | { 537 | count++; 538 | if (m_keys[key].next_item <= 0) return count; 539 | key = m_keys[key].next_item->index; 540 | } 541 | 542 | return count; 543 | } 544 | 545 | //---------------------------------------------------// 546 | int clJobFileInterpreter::getProperty(int id, const char * propertyName) 547 | { 548 | if ((id < 0) || (id >= m_keys_count)) return -1; 549 | if (m_keys[id].first_property == NULL) return -1; 550 | 551 | int prop = m_keys[id].first_property->index; 552 | 553 | while (prop > 0) 554 | { 555 | if (_strcmpi(propertyName, m_values[prop].name) == 0) return prop; 556 | 557 | if (m_values[prop].next_property == NULL) return -1; 558 | prop = m_values[prop].next_property->index; 559 | } 560 | 561 | 562 | return -1; 563 | } 564 | 565 | 566 | //---------------------------------------------------// 567 | int clJobFileInterpreter::getFirstProperty(int id) 568 | { 569 | if ((id < 0) || (id >= m_keys_count)) return -1; 570 | if (m_keys[id].first_property == NULL) return -1; 571 | 572 | return m_keys[id].first_property->index; 573 | } 574 | 575 | 576 | //---------------------------------------------------// 577 | int clJobFileInterpreter::getNextProperty(int id) 578 | { 579 | if ((id < 0) || (id >= m_values_count)) return -1; 580 | if (m_values[id].next_property == NULL) return -1; 581 | 582 | return m_values[id].next_property->index; 583 | } 584 | 585 | //---------------------------------------------------// 586 | char * clJobFileInterpreter::getPropertyName(int id) 587 | { 588 | if ((id < 0) || (id >= m_values_count)) return NULL; 589 | return m_values[id].name; 590 | } 591 | 592 | //---------------------------------------------------// 593 | char * clJobFileInterpreter::getPropertyValue(int id) 594 | { 595 | if ((id < 0) || (id >= m_values_count)) return NULL; 596 | return m_values[id].value; 597 | } 598 | 599 | //---------------------------------------------------// 600 | float clJobFileInterpreter::getPropertyValue(int id, float defaultValue) 601 | { 602 | char * val = getPropertyValue(id); 603 | if (val == NULL) return defaultValue; 604 | 605 | 606 | char * e; 607 | errno = 0; 608 | float x = (float)std::strtod(val, &e); 609 | 610 | if (*e != '\0' || // error, we didn't consume the entire string 611 | errno != 0) // error, overflow or underflow 612 | { 613 | return defaultValue; 614 | } 615 | 616 | 617 | return x; 618 | } 619 | 620 | 621 | //---------------------------------------------------// 622 | char * clJobFileInterpreter::getPropertyComment(int id) 623 | { 624 | if ((id < 0) || (id >= m_values_count)) return NULL; 625 | return m_values[id].comment; 626 | } 627 | -------------------------------------------------------------------------------- /source/clJobFileInterpreter.h: -------------------------------------------------------------------------------- 1 | #ifndef CL_JOBFILEINTERPRETER_H 2 | #define CL_JOBFILEINTERPRETER_H 3 | 4 | #include "clJobFile.h" 5 | 6 | //- for atoi 7 | #include 8 | 9 | class clJobFileInterpreter 10 | { 11 | public: 12 | clJobFileInterpreter(); 13 | ~clJobFileInterpreter(); 14 | 15 | /// Read and interpret job-data from File 16 | /// Filename of File to read 17 | /// true on sucess 18 | bool readFromFile(const char * filename); 19 | 20 | /// Interpret job-data from char buffer 21 | /// char Buffer to interpre 22 | /// lenght of [buffer] 23 | /// true on sucess 24 | bool readFromBuffer(const char * buffer, int bufferLength); 25 | 26 | /// Print out the job-file in XML-Format 27 | bool printXML(); 28 | 29 | 30 | //---------------------------------------------------// 31 | char * getKeyName(int keyIndex); 32 | int getFirstChild(int keyIndex=clJobFile::ROOT_ELEMENT); 33 | int getChild(int keyIndex, const char * KeyName); 34 | int getNextChild(int keyIndex); 35 | int getProperty(int id, const char * propertyName); 36 | int getFirstProperty(int keyIndex); 37 | int getNextProperty(int propertyIndex); 38 | char * getPropertyName(int propertyIndex); 39 | char * getPropertyValue(int propertyIndex); 40 | float getPropertyValue(int propertyIndex, float defaultValue); 41 | char * getPropertyComment(int propertyIndex); 42 | int getChildCount(int id); 43 | 44 | private: 45 | clJobFile m_JobFile; 46 | clError m_error; 47 | 48 | 49 | struct tyConfigValue 50 | { 51 | int index; 52 | char * name; 53 | char * value; 54 | char type; 55 | char * comment; 56 | tyConfigValue * next_property; 57 | }; 58 | 59 | 60 | struct tyConfigKey 61 | { 62 | int index; 63 | tyConfigKey * parent; //- root of this item 64 | tyConfigKey * first_client; //- first leave on this item 65 | tyConfigKey * last_client; //- last leave on this item 66 | tyConfigKey * next_item; //- next item in this branch 67 | tyConfigValue * first_property; // => tyConfigValue 68 | tyConfigValue * last_property; // => tyConfigValue 69 | char * name; 70 | }; 71 | 72 | 73 | tyConfigValue * m_values; 74 | int m_values_length; 75 | int m_values_count; 76 | 77 | tyConfigKey * m_keys; 78 | int m_keys_length; 79 | int m_keys_count; 80 | 81 | /// Interpret the job-data from [m_Buffer] 82 | bool interpret(); 83 | 84 | /// creates the [m_values] and [m_keys] 85 | bool createBuffers(const char * pBuffer, int bufferLen); 86 | 87 | /// find the position of the first appearance of a byte 88 | int findByte(const char * pInBuffer, int lineLen, char Byte2Find); 89 | 90 | /// retunes first byte not ' ' and '\t' 91 | char * LTrim(char * buffer); 92 | 93 | /// set all ' ' and '\t' at the end to '\0' 94 | char * RTrim(char * buffer); 95 | 96 | /// set all ' ' and '\t' at the end to '\0' and returns the first char-pos 97 | char * Trim(char * buffer); 98 | 99 | /// helper for recursion output 100 | void printXMLout(int deep, tyConfigKey * key); 101 | }; 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /source/clJobSliceFile.cpp: -------------------------------------------------------------------------------- 1 | #include "clJobSliceFile.h" 2 | 3 | 4 | clJobSliceFile::clJobSliceFile() 5 | :m_error("clJobSliceFile") 6 | { 7 | 8 | m_SliFiles = NULL; 9 | m_SliFilesCount = 0; 10 | } 11 | 12 | //---------------------------------------------------// 13 | clJobSliceFile::~clJobSliceFile() 14 | { 15 | if (m_SliFiles != NULL) delete[] m_SliFiles; 16 | m_SliFilesCount = 0; 17 | } 18 | 19 | 20 | //------------------------------------------------------------// 21 | bool clJobSliceFile::readFromFile(const char * filename) 22 | { 23 | clJobFileInterpreter job; 24 | 25 | if (!job.readFromFile(filename)) return false; 26 | 27 | 28 | int GeneralKey = job.getChild(clJobFile::ROOT_ELEMENT, "General"); 29 | if (GeneralKey > 0) 30 | { 31 | int prop_LayerThickness = job.getProperty(GeneralKey, "LayerThickness"); 32 | m_LayerThickness = job.getPropertyValue(prop_LayerThickness, 0.00f); 33 | } 34 | else 35 | { 36 | m_LayerThickness = 0.0f; 37 | m_error.AddError("No [General] Element found in .job file : Layer-Thickness may wrong!"); 38 | } 39 | 40 | 41 | int PartsKey = job.getChild(clJobFile::ROOT_ELEMENT, "Parts"); 42 | if (PartsKey <= 0) 43 | { 44 | m_error.AddError("No [Parts] Element found in .job file"); 45 | return false; 46 | } 47 | 48 | //- chreate buffer for sli-files 49 | m_SliFilesCount = job.getChildCount(PartsKey); 50 | 51 | if (m_SliFiles != NULL) delete [] m_SliFiles; 52 | m_SliFiles = new tySliFile[m_SliFilesCount]; 53 | 54 | 55 | int child = job.getFirstChild(PartsKey); 56 | int partID = 0; 57 | 58 | while (child>0) 59 | { 60 | //- get keys to propertys 61 | int prop_ExpParName = job.getProperty(child, "ExpParName"); 62 | int prop_FileName = job.getProperty(child, "FileName"); 63 | int prop_x = job.getProperty(child, "x"); 64 | int prop_y = job.getProperty(child, "y"); 65 | int prop_rotation = job.getProperty(child, "Rotation"); 66 | 67 | //- check if propertys available 68 | if ((prop_ExpParName > 0) && (prop_FileName > 0)) 69 | { 70 | tySliFile * part = &m_SliFiles[partID]; 71 | 72 | //- reset all 73 | part->exposureProfile[0] = '\0'; 74 | memset(&part->matrix, 0, sizeof(part->matrix)); 75 | strCopy(part->fileName, job.getPropertyValue(prop_FileName), sizeof(part->fileName)); 76 | part->sliFile.reset(); 77 | 78 | //- read .sli file 79 | if (openPartFile(part, filename)) 80 | { 81 | //- copy propertys 82 | strCopy(part->partName, job.getKeyName(child), sizeof(part->partName)); 83 | 84 | 85 | strCopy(part->exposureProfile, job.getPropertyValue(prop_ExpParName), sizeof(part->exposureProfile)); 86 | 87 | 88 | float a = (float) (job.getPropertyValue(prop_rotation, 0.f) * 2 * PI / 360.0); 89 | 90 | 91 | part->matrix.m11 = cos(a); 92 | part->matrix.m12 = -sin(a); 93 | part->matrix.m13 = job.getPropertyValue(prop_x, 0.f); 94 | part->matrix.m21 = sin(a);; 95 | part->matrix.m22 = cos(a); 96 | part->matrix.m23 = job.getPropertyValue(prop_y, 0.f); 97 | 98 | 99 | //- move to next part 100 | partID++; 101 | } 102 | else 103 | { 104 | m_error.AddError("File for Part [%s] not found [%s]", job.getKeyName(child), part->fileName); 105 | } 106 | } 107 | else 108 | { 109 | m_error.AddError("Missing information for Part [%s]", job.getKeyName(child)); 110 | } 111 | 112 | m_error.AddDebug("%s", job.getKeyName(child)); 113 | 114 | //- read next key in .job-file 115 | child = job.getNextChild(child); 116 | 117 | 118 | } 119 | 120 | m_SliFilesCount = partID; 121 | 122 | return true; 123 | } 124 | 125 | //---------------------------------------------------// 126 | int clJobSliceFile::getPartCount() 127 | { 128 | return m_SliFilesCount; 129 | } 130 | 131 | 132 | //------------------------------------------------------------// 133 | bool clJobSliceFile::openPartFile(tySliFile * part, const char * jobFileName) 134 | { 135 | if ((part == NULL)) return false; 136 | if (part->fileName == NULL) return false; 137 | 138 | 139 | if (clFile::fileExist(part->fileName)) 140 | { 141 | return part->sliFile.readFromFile(part->fileName); 142 | } 143 | 144 | int lastBack = strIndexOfLast(jobFileName, '\\', 1024); 145 | if (lastBack > 0) 146 | { 147 | char buffer[255]; 148 | lastBack+=2; //- copy also the '\\' 149 | 150 | lastBack = (sizeof(buffer) < lastBack) ? sizeof(buffer) : lastBack; 151 | strCopy(buffer, &jobFileName[0], lastBack); 152 | 153 | //- Path + Filename 154 | std::string newFileName = std::string(buffer).append(part->fileName); 155 | 156 | if (clFile::fileExist(newFileName.c_str())) 157 | { 158 | return part->sliFile.readFromFile(newFileName.c_str()); 159 | } 160 | } 161 | 162 | 163 | lastBack = strIndexOfLast(jobFileName, '/', 1024); 164 | if (lastBack > 0) 165 | { 166 | char buffer[255]; 167 | lastBack += 2; //- copy also the '/' 168 | 169 | lastBack = (sizeof(buffer) < lastBack) ? sizeof(buffer) : lastBack; 170 | strCopy(buffer, &jobFileName[0], lastBack); 171 | 172 | //- Path + Filename 173 | std::string newFileName = std::string(buffer).append(part->fileName); 174 | 175 | if (clFile::fileExist(newFileName.c_str())) 176 | { 177 | return part->sliFile.readFromFile(newFileName.c_str()); 178 | } 179 | } 180 | 181 | m_error.AddError("File [%s] not found.", part->fileName); 182 | return false; 183 | } 184 | 185 | 186 | //------------------------------------------------------------// 187 | int clJobSliceFile::getLayerIndexByPos(int PartIndex, float LayerPos) 188 | { 189 | if (m_SliFiles == NULL) return false; 190 | if ((PartIndex < 0) && (PartIndex >= m_SliFilesCount)) return false; 191 | 192 | tySliFile * part = &m_SliFiles[PartIndex]; 193 | 194 | return part->sliFile.getLayerIndexByPos(0, LayerPos); 195 | } 196 | 197 | 198 | //------------------------------------------------------------// 199 | bool clJobSliceFile::readSliceData(clSliceData * sliceData, int PartIndex, int LayerIndex, int storeAsPartIndex) 200 | { 201 | if (m_SliFiles == NULL) return false; 202 | if ((PartIndex < 0) && (PartIndex >= m_SliFilesCount)) return false; 203 | if (storeAsPartIndex == -1) storeAsPartIndex = PartIndex; 204 | 205 | tySliFile * part = &m_SliFiles[PartIndex]; 206 | 207 | bool ret = part->sliFile.readSliceData(sliceData, 0, LayerIndex, storeAsPartIndex); 208 | 209 | sliceData->PartMatrixMult(storeAsPartIndex, part->matrix); 210 | 211 | return ret; 212 | } 213 | 214 | 215 | //------------------------------------------------------------// 216 | char * clJobSliceFile::strCopy(char *dest, const char * src, int maxCount) 217 | { 218 | if (dest == NULL) return ""; 219 | *dest = 0; 220 | if (src == NULL) return dest; 221 | 222 | char * destP = dest; 223 | const char * srcP = src; 224 | 225 | for (int i = maxCount - 1; i > 0; i--) 226 | { 227 | char s = *srcP++; 228 | if (s == 0) break; 229 | 230 | *destP = s; 231 | destP++; 232 | } 233 | *destP = 0; 234 | return dest; 235 | 236 | } 237 | 238 | //------------------------------------------------------------// 239 | int clJobSliceFile::strIndexOfLast(const char * src, char findChar, int maxScanCount) 240 | { 241 | if (src == NULL) return -1; 242 | 243 | const char * srcP = src; 244 | 245 | int pos = -1; 246 | 247 | for (int i = 0; i= m_SliFilesCount)) return 0; 261 | 262 | tySliFile * part = &m_SliFiles[PartIndex]; 263 | 264 | return part->sliFile.getLayerCount(0); 265 | } 266 | 267 | 268 | //------------------------------------------------------------// 269 | float clJobSliceFile::getMaxLayerPos(int PartIndex) 270 | { 271 | if (m_SliFiles == NULL) return 0; 272 | if ((PartIndex < 0) && (PartIndex >= m_SliFilesCount)) return 0; 273 | 274 | tySliFile * part = &m_SliFiles[PartIndex]; 275 | 276 | return part->sliFile.getMaxLayerPos(0); 277 | } 278 | 279 | 280 | //------------------------------------------------------------// 281 | float clJobSliceFile::getLayerThickness() 282 | { 283 | return m_LayerThickness; 284 | } 285 | 286 | 287 | //------------------------------------------------------------// 288 | float clJobSliceFile::getLayerPos(int PartIndex, int layerIndex) 289 | { 290 | if (m_SliFiles == NULL) return 0.f; 291 | if ((PartIndex < 0) && (PartIndex >= m_SliFilesCount)) return 0.f; 292 | 293 | tySliFile * part = &m_SliFiles[PartIndex]; 294 | 295 | return part->sliFile.getLayerPos(0, layerIndex); 296 | } 297 | 298 | //------------------------------------------------------------// 299 | char * clJobSliceFile::getPartName(int PartIndex) 300 | { 301 | if (m_SliFiles == NULL) return NULL; 302 | if ((PartIndex < 0) && (PartIndex >= m_SliFilesCount)) return NULL; 303 | 304 | tySliFile * part = &m_SliFiles[PartIndex]; 305 | 306 | return part->partName; 307 | } 308 | 309 | //---------------------------------------------------// 310 | char * clJobSliceFile::getPartProperty(int PartIndex) 311 | { 312 | if (m_SliFiles == NULL) return NULL; 313 | if ((PartIndex < 0) && (PartIndex >= m_SliFilesCount)) return NULL; 314 | 315 | tySliFile * part = &m_SliFiles[PartIndex]; 316 | 317 | return part->exposureProfile; 318 | } 319 | -------------------------------------------------------------------------------- /source/clJobSliceFile.h: -------------------------------------------------------------------------------- 1 | #ifndef CLJOBSLICEFILE_H 2 | #define CLJOBSLICEFILE_H 3 | 4 | #include "clSliceData.h" 5 | #include "abstractSliceFile.h" 6 | #include "clSliFile.h" 7 | #include "clJobFileInterpreter.h" 8 | #include "clFile.h" 9 | #include // cos, sin 10 | 11 | #define PI 3.14159265 12 | 13 | class clJobSliceFile : public abstractSliceFile 14 | { 15 | 16 | public: 17 | clJobSliceFile(); 18 | ~clJobSliceFile(); 19 | 20 | /// Read and interpret job-data from File 21 | /// Filename of File to read 22 | /// true on success; false on not 23 | bool readFromFile(const char * filename); 24 | 25 | /// Read the slice data and add it to the sliceData class 26 | /// sliceData class 27 | /// index of the Part 28 | /// index of the layer 29 | /// [optional] Index in [sliceData] to store the data in, use -1 for same as PartIndex 30 | /// true on success; false on not 31 | virtual bool readSliceData(clSliceData * sliceData, int PartIndex, int LayerIndex, int storeAsPartIndex=-1); 32 | 33 | /// returns the Layer Count of the file 34 | /// index of the Part 35 | int getLayerCount(int PartIndex); 36 | 37 | /// returns the Layer position in [mm] of the sellected part 38 | /// index of the Part 39 | /// index of the Layer 40 | float getLayerPos(int PartIndex, int layerIndex); 41 | 42 | 43 | /// returns the name of the part 44 | /// index of the Part 45 | char * getPartName(int PartIndex); 46 | 47 | /// returns a string with special propertys to use for this part 48 | /// index of the Part 49 | char * getPartProperty(int PartIndex); 50 | 51 | /// returns the number of parts in this file 52 | int getPartCount(); 53 | 54 | 55 | /// returns the top Layer position in [mm] 56 | /// index of the Part 57 | float getMaxLayerPos(int PartIndex); 58 | 59 | /// finds and returns the Layer-Index for a layer position (in [mm]) 60 | /// index of the Part 61 | /// position of the layer in [mm] 62 | int getLayerIndexByPos(int PartIndex, float LayerPos); 63 | 64 | 65 | /// returns the LayerThickness in [mm] 66 | float getLayerThickness(); 67 | 68 | private: 69 | 70 | struct tySliFile 71 | { 72 | char fileName[255]; 73 | char partName[40]; 74 | char exposureProfile[40]; 75 | clSliceData::tyMatrix matrix; 76 | clSliFile sliFile; 77 | }; 78 | 79 | tySliFile * m_SliFiles; 80 | int m_SliFilesCount; 81 | float m_LayerThickness; 82 | 83 | clError m_error; 84 | 85 | bool openPartFile(tySliFile * part, const char * jobFileName); 86 | char * strCopy(char * dest, const char * src, int maxCopyCount); 87 | int strIndexOfLast(const char * src, char findChar, int maxScanCount); 88 | }; 89 | 90 | 91 | 92 | #endif -------------------------------------------------------------------------------- /source/clSliFile.cpp: -------------------------------------------------------------------------------- 1 | #include "clSliFile.h" 2 | 3 | //- Math macros -// 4 | #define ABS(a) (((a)>=0)?(a):(-(a))) 5 | #define MIN(a,b) (((a)<(b))?(a):(b)) 6 | #define MAX(a,b) (((a)>(b))?(a):(b)) 7 | 8 | //---------------------------------------------------// 9 | clSliFile::clSliFile() 10 | :m_error("clSliFile") 11 | { 12 | m_IndexTable = NULL; 13 | m_IndexTable_lenght = 0; 14 | 15 | reset(); 16 | } 17 | 18 | 19 | 20 | //---------------------------------------------------// 21 | clSliFile::~clSliFile() 22 | { 23 | m_file.closeFile(); 24 | 25 | reset(); 26 | } 27 | 28 | 29 | //---------------------------------------------------// 30 | void clSliFile::reset() 31 | { 32 | if (m_IndexTable != NULL) delete[] m_IndexTable; 33 | m_IndexTable = NULL; 34 | 35 | m_IndexTable_lenght = 0; 36 | 37 | m_currentLayerIndex = 0; 38 | 39 | m_LayerThickness = 0.0f; 40 | 41 | m_partName[0] = '\0'; 42 | 43 | 44 | memset(&m_FileHead, 0, sizeof(m_FileHead)); 45 | 46 | } 47 | 48 | 49 | //---------------------------------------------------// 50 | bool clSliFile::readFromFile(const char * filename) 51 | { 52 | 53 | reset(); 54 | 55 | if (!m_file.openFile(filename)) 56 | { 57 | m_error.AddError("readFromFile(): Unable to open file: %s", filename); 58 | return false; 59 | } 60 | 61 | m_file.readFilePart(0, 160); 62 | 63 | 64 | m_file.readString(m_FileHead.magic, 40); 65 | 66 | if (strncmp("EOS 1993 SLI FILE ", m_FileHead.magic, 40) != 0) 67 | { 68 | m_error.AddError("Wrong File-magic. Not a SLI file?"); 69 | m_file.closeFile(); 70 | return false; 71 | } 72 | 73 | int posName = -1; 74 | posName = MAX(posName, strIndexOfLast(filename, '\\', 1024)); 75 | posName = MAX(posName, strIndexOfLast(filename, '/', 1024)); 76 | 77 | #pragma warning(disable : 4996) 78 | strncpy(m_partName, &filename[posName + 1], sizeof(m_partName)); 79 | 80 | m_FileHead.version = m_file.readIntBE(2); 81 | m_FileHead.int02 = m_file.readIntBE(2); 82 | m_FileHead.HeaderSize = m_file.readIntBE(4); 83 | m_FileHead.int05 = m_file.readIntBE(4); 84 | m_FileHead.int07 = m_file.readIntBE(4); 85 | m_FileHead.FileSliceDataOffset = m_file.readIntBE(4); 86 | m_FileHead.FileIndexPos = m_file.readIntBE(4); 87 | m_file.readString(m_FileHead.creator, 40); 88 | m_FileHead.LayerCount = m_file.readIntBE(4); 89 | m_FileHead.PolylineCount = m_file.readIntBE(4); 90 | m_FileHead.int14 = m_file.readIntBE(4); 91 | 92 | //- jump over 8 unknown DWords 93 | m_file.setOffset(m_file.getOffset() + 4 * 8); 94 | 95 | m_FileHead.scaleFactor = m_file.readFloat(); 96 | 97 | m_FileHead.Dimension_x0 = m_file.readFloat(4); 98 | m_FileHead.Dimension_x1 = m_file.readFloat(4); 99 | m_FileHead.Dimension_y0 = m_file.readFloat(4); 100 | m_FileHead.Dimension_y1 = m_file.readFloat(4); 101 | m_FileHead.Dimension_z0 = m_file.readFloat(4); 102 | m_FileHead.Dimension_z1 = m_file.readFloat(4); 103 | 104 | 105 | 106 | //- read Index table 107 | return readIndexTable(m_FileHead.FileIndexPos, m_FileHead.HeaderSize, m_FileHead.LayerCount); 108 | } 109 | 110 | 111 | 112 | //---------------------------------------------------// 113 | bool clSliFile::readIndexTable(int FilePos, int FileOffset, int LayerCount) 114 | { 115 | m_file.readFilePart(FilePos + FileOffset, LayerCount * 6); 116 | 117 | m_IndexTable_lenght = 0; 118 | if (m_IndexTable != NULL) delete []m_IndexTable; 119 | 120 | m_IndexTable = new tyIndexTable[LayerCount]; 121 | 122 | float last_LayerPos = -1.0f; 123 | m_LayerThickness = 999999; 124 | 125 | while ((!m_file.eof()) && (m_IndexTable_lenght < LayerCount)) 126 | { 127 | //- Start of a layer with upper surface at height z (z*units [mm]). All layers must be sorted in ascending order with respect to z. The thickness of the layer is given by the difference between the z values of the current and previous layers. A thickness for the first (lowest) layer can be specified by including a "zero-layer" with a given z value but with no polyline. 128 | float this_LayerPos = m_file.readIntBE(2) * m_FileHead.scaleFactor; 129 | m_IndexTable[m_IndexTable_lenght].layerPos = this_LayerPos; 130 | 131 | m_IndexTable[m_IndexTable_lenght].FileOffset = m_file.readIntBE(4) + FileOffset; 132 | 133 | //m_error.AddDebug("[%i] %f @ %i", m_IndexTable_lenght, m_IndexTable[m_IndexTable_lenght].layerPos, m_IndexTable[m_IndexTable_lenght].FileOffset); 134 | 135 | m_IndexTable_lenght++; 136 | 137 | 138 | //- find LayerThickness 139 | if (last_LayerPos > 0) 140 | { 141 | float delta = (this_LayerPos - last_LayerPos); 142 | if (delta > 0) 143 | { 144 | m_LayerThickness = MIN(m_LayerThickness, delta); 145 | } 146 | else 147 | { 148 | m_error.AddError("readIndexTable() : File layer position is not ordered or has a wrong value! This may cause an error if calling [ getLayerIndexByPos() ]"); 149 | } 150 | 151 | } 152 | last_LayerPos = this_LayerPos; 153 | 154 | } 155 | 156 | m_error.AddDebug("Layer count: %i", m_IndexTable_lenght); 157 | return true; 158 | } 159 | 160 | 161 | //---------------------------------------------------// 162 | int clSliFile::getLayerCount(int PartIndex) 163 | { 164 | if (PartIndex != 0) return 0; 165 | return m_FileHead.LayerCount; 166 | } 167 | 168 | //------------------------------------------------------------// 169 | float clSliFile::getMaxLayerPos(int PartIndex) 170 | { 171 | if (PartIndex != 0) return 0; 172 | if (m_FileHead.LayerCount < 1) return 0; 173 | 174 | return m_IndexTable[m_FileHead.LayerCount-1].layerPos; 175 | } 176 | 177 | 178 | //---------------------------------------------------// 179 | int clSliFile::getPartCount() 180 | { 181 | return 1; 182 | } 183 | 184 | //------------------------------------------------------------// 185 | float clSliFile::getLayerThickness() 186 | { 187 | return m_LayerThickness; 188 | } 189 | 190 | 191 | //---------------------------------------------------// 192 | float clSliFile::getLayerPos(int PartIndex, int LayerIndex) 193 | { 194 | if (PartIndex != 0) return -1; 195 | if ((LayerIndex < 0) || (LayerIndex >= m_FileHead.LayerCount)) return - 1; 196 | 197 | return m_IndexTable[LayerIndex].layerPos; 198 | } 199 | 200 | //---------------------------------------------------// 201 | char * clSliFile::getPartName(int PartIndex) 202 | { 203 | if (PartIndex != 0) return NULL; 204 | return m_partName; 205 | } 206 | 207 | //---------------------------------------------------// 208 | char * clSliFile::getPartProperty(int PartIndex) 209 | { 210 | if (PartIndex != 0) return NULL; 211 | return ""; 212 | } 213 | 214 | 215 | //---------------------------------------------------// 216 | inline int clSliFile::checkLayerPos(int * minIndex, int * maxIndex, int index2Check, float LayerPos) 217 | { 218 | if (index2Check < *minIndex) return -1; 219 | if (index2Check > *maxIndex) return +1; 220 | 221 | 222 | float delta = LayerPos - m_IndexTable[index2Check].layerPos; 223 | 224 | if (delta > m_LayerThickness * 0.5f) 225 | { 226 | *minIndex = index2Check + 1; 227 | return +1; 228 | } 229 | else if (delta < -m_LayerThickness * 0.5f) 230 | { 231 | *maxIndex = index2Check - 1; 232 | return -1; 233 | } 234 | else //- -0.0001f < delta < 0.0001f 235 | { 236 | return 0; 237 | } 238 | 239 | } 240 | 241 | 242 | // Returns the Layer-Index for a given Layer-Postion. 243 | // 244 | //@param PartIndex: Index of the Part 245 | //@param LayerPos: Layer Position in [mm] 246 | //@return an Index >=0 ; On error this function returns -1 247 | // 248 | int clSliFile::getLayerIndexByPos(int PartIndex, float LayerPos) 249 | { 250 | if (PartIndex != 0) return -1; 251 | 252 | int minIndex = 0; 253 | int maxIndex = m_FileHead.LayerCount-1; 254 | 255 | if (LayerPos < m_IndexTable[minIndex].layerPos) return -1; 256 | if (LayerPos > m_IndexTable[maxIndex].layerPos) return -1; 257 | 258 | int chIndex = m_currentLayerIndex; 259 | 260 | //- may the current didn't change? 261 | if (checkLayerPos(&minIndex, &maxIndex, m_currentLayerIndex + 0, LayerPos) == 0) { m_currentLayerIndex += 0; return m_currentLayerIndex; } 262 | if (checkLayerPos(&minIndex, &maxIndex, m_currentLayerIndex + 1, LayerPos) == 0) { m_currentLayerIndex += 1; return m_currentLayerIndex; } 263 | if (checkLayerPos(&minIndex, &maxIndex, m_currentLayerIndex - 1, LayerPos) == 0) { m_currentLayerIndex -= 1; return m_currentLayerIndex; } 264 | if (checkLayerPos(&minIndex, &maxIndex, m_currentLayerIndex + 2, LayerPos) == 0) { m_currentLayerIndex += 2; return m_currentLayerIndex; } 265 | if (checkLayerPos(&minIndex, &maxIndex, m_currentLayerIndex - 2, LayerPos) == 0) { m_currentLayerIndex -= 2; return m_currentLayerIndex; } 266 | 267 | 268 | //- Binary search of position/index 269 | int pos = 0; 270 | 271 | while (minIndex <= maxIndex) 272 | { 273 | pos = (maxIndex + minIndex) / 2; 274 | 275 | if (checkLayerPos(&minIndex, &maxIndex, pos, LayerPos) == 0) 276 | { 277 | m_currentLayerIndex = pos; 278 | return pos; 279 | } 280 | } 281 | 282 | //- not found. 283 | return -1; 284 | } 285 | 286 | 287 | 288 | //---------------------------------------------------// 289 | bool clSliFile::readSliceData(clSliceData * sliceData, int PartIndex, int LayerIndex, int storeAsPartIndex) 290 | { 291 | if (PartIndex != 0) return false; 292 | 293 | int n = 0; 294 | float scaleFactor = m_FileHead.scaleFactor; 295 | 296 | if (storeAsPartIndex == -1) storeAsPartIndex = PartIndex; 297 | 298 | //- clear old data or define new empty part 299 | int newObject = sliceData->createPart(storeAsPartIndex, scaleFactor, 0, 0, 0, scaleFactor, 0); 300 | 301 | if ((LayerIndex < 0) || (LayerIndex >= m_FileHead.LayerCount)) return false; 302 | 303 | m_file.readFilePart(m_IndexTable[LayerIndex].FileOffset, 32); 304 | 305 | 306 | int OType = 0; 307 | 308 | while (OType != 2) 309 | { 310 | //- command 311 | OType = m_file.readIntBE(1); 312 | 313 | switch (OType) 314 | { 315 | case 1: 316 | { 317 | //- header of layer 318 | int unknownLayerPos = m_file.readIntBE(2); //- LayerPos as int 319 | 320 | //- unknownLayerThickness1 == unknownLayerThickness2 ! 321 | float unknownLayerThickness1 = m_file.readFloat(); 322 | float unknownLayerThickness2 = m_file.readFloat(); 323 | 324 | //m_error.AddDebug("pos %i, float1 %f, float2 %f", unknownLayerPos, unknownLayerThickness1, unknownLayerThickness2); 325 | } 326 | 327 | //- padding 328 | if (m_file.readIntBE(1) != 0) 329 | { 330 | m_error.AddError("unknown Byte @ %i", m_file.getOffset() - 1); 331 | } 332 | 333 | break; 334 | 335 | case 2: 336 | //- end of layer 337 | break; 338 | 339 | case 3: 340 | //Command : start polyline 341 | //Syntax : $$POLYLINE/id,dir,n,p1x,p1y,...pnx,pny 342 | //Parameters: 343 | // 344 | // id : INTEGER 345 | // dir,n : INTEGER 346 | // p1x..pny : REAL 347 | // 348 | // 349 | //id : identifier to allow more than one model information in one file. 350 | //id refers to the parameter id of command $$LABEL (HEADER-section). 351 | //dir : Orientation of the line when viewing in the negative z-direction 352 | //0 : clockwise (internal) 353 | //1 : counter-clockwise (external) 354 | //2 : open line (no solid) 355 | //n : number of points 356 | //p1x..pny : coordinates of the points 1..n 357 | 358 | if (m_file.readIntBE(1) != 0) //- dir or padding? 359 | { 360 | m_error.AddError("unknown Byte @ %i " + m_file.getOffset() - 1); 361 | return false; 362 | } 363 | 364 | 365 | n = m_file.readIntBE(2); 366 | if (n > 0) 367 | { 368 | float * points = sliceData->createPolygon(storeAsPartIndex, n); 369 | 370 | //- read file 371 | m_file.readFilePart(m_file.getOffset(), n * 4 * 2 + 32); 372 | 373 | //- read points - every Hatch has 4 points 374 | for (int i = n * 2; i > 0; i--) 375 | { 376 | *points = (float)m_file.readIntBE(2); 377 | points++; 378 | } 379 | 380 | } 381 | 382 | break; 383 | case 4: 384 | //- support 385 | //m_error.addWarning("Support is not supported!"); 386 | 387 | //Command : start hatches 388 | //Syntax : $$HATCHES/id,n,p1sx,p1sy,p1ex,p1ey,...pnex,pney 389 | //Parameters: 390 | // 391 | // id : INTEGER 392 | // n : INTEGER 393 | // p1sx..pney : REAL 394 | // 395 | //id : identifier to allow more than one model information in one file. 396 | //id refers to the parameter id of command $$LABEL (HEADER-section). 397 | //n : number of hatches (n*4 =number of coordinates) 398 | //p1sx..pney : coordinates of the hatches 1..n 399 | //4 parameters for every hatch (startx,starty,endx,endy) 400 | 401 | //- padding 402 | if (m_file.readIntBE(1) != 0) 403 | { 404 | m_error.AddError("unknown Byte @ %i " + m_file.getOffset() - 1); 405 | return false; 406 | } 407 | 408 | n = m_file.readIntBE(2); 409 | 410 | if (n > 0) 411 | { 412 | float * points = sliceData->createHatch(storeAsPartIndex, n); 413 | 414 | //- read file 415 | m_file.readFilePart(m_file.getOffset(), n * 4 * 4 + 32); 416 | 417 | //- read points - every Hatch has 4 points 418 | for (int i = n * 4; i > 0; i--) 419 | { 420 | *points = (float)m_file.readIntBE(2); 421 | points++; 422 | } 423 | 424 | } 425 | 426 | break; 427 | 428 | default: 429 | m_error.AddError("Unknow opcode %i at %i ", OType, m_file.getOffset() - 1); 430 | return false; 431 | 432 | } 433 | } 434 | 435 | return true; 436 | } 437 | 438 | 439 | //------------------------------------------------------------// 440 | int clSliFile::strIndexOfLast(const char * src, char findChar, int maxScanCount) 441 | { 442 | if (src == NULL) return -1; 443 | 444 | const char * srcP = src; 445 | 446 | int pos = -1; 447 | 448 | for (int i = 0; iRead and interpret sli-data from File 17 | /// Filename of File to read 18 | /// true on success; false on not 19 | bool readFromFile(const char * filename); 20 | 21 | /// Read the slice data and add it to the sliceData class 22 | /// sliceData class 23 | /// index of the Part 24 | /// index of the layer 25 | /// [optional] Index in [sliceData] to store the data in, use -1 for same as PartIndex 26 | /// true on success; false on not 27 | virtual bool readSliceData(clSliceData * sliceData, int PartIndex, int LayerIndex, int storeAsPartIndex = -1); 28 | 29 | /// returns the Layer Count of the file 30 | /// index of the Part 31 | int getLayerCount(int PartIndex); 32 | 33 | /// returns the Layer position in [mm] of the sellected part 34 | /// index of the Part 35 | /// index of the Layer 36 | float getLayerPos(int PartIndex, int layerIndex); 37 | 38 | /// returns the number of parts in this file 39 | int getPartCount(); 40 | 41 | /// returns the name of the part 42 | /// index of the Part 43 | char * getPartName(int PartIndex); 44 | 45 | 46 | /// returns a string with special propertys to use for this part 47 | /// index of the Part 48 | char * getPartProperty(int PartIndex); 49 | 50 | 51 | /// finds and returns the Layer-Index for a layer position (in [mm]) 52 | /// index of the Part 53 | /// position of the layer in [mm] 54 | int getLayerIndexByPos(int PartIndex, float LayerPos); 55 | 56 | 57 | /// returns the top Layer position in [mm] 58 | /// index of the Part 59 | float getMaxLayerPos(int PartIndex); 60 | 61 | 62 | /// returns the LayerThickness in [mm] 63 | float getLayerThickness(); 64 | 65 | /// reset 66 | void reset(); 67 | 68 | private: 69 | struct tyFileHead 70 | { 71 | char magic[40]; 72 | int version; //- version? "v divided by 100 gives the version number. " 73 | int int02; //- Head count ? 74 | int HeaderSize; //- Header offset 75 | int int05; //- unknown 76 | int int07; //- unknown 77 | int FileSliceDataOffset; 78 | int FileIndexPos; 79 | char creator[40]; 80 | int LayerCount; 81 | int PolylineCount; 82 | int int14; //- unknown 83 | float scaleFactor; 84 | 85 | float Dimension_x0; //- Bounding Box 86 | float Dimension_x1; 87 | float Dimension_y0; 88 | float Dimension_y1; 89 | float Dimension_z0; 90 | float Dimension_z1; 91 | }; 92 | 93 | tyFileHead m_FileHead; 94 | 95 | clError m_error; 96 | 97 | char m_partName[255]; 98 | 99 | clFile m_file; 100 | 101 | struct tyIndexTable 102 | { 103 | int FileOffset; 104 | float layerPos; //- Syntax : $$LAYER/z - Start of a layer with upper surface at height z (z*units [mm]). 105 | }; 106 | 107 | tyIndexTable * m_IndexTable; 108 | int m_IndexTable_lenght; 109 | int m_currentLayerIndex; 110 | 111 | bool readIndexTable(int FilePos, int FileOffset, int LayerCount); 112 | inline int checkLayerPos(int * minIndex, int * maxIndex, int index2Check, float LayerPos); 113 | 114 | float m_LayerThickness; 115 | int strIndexOfLast(const char * src, char findChar, int maxScanCount); 116 | }; 117 | 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /source/clSliceData.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomsoftware/EOS-Formats/520b9e64f0a394362264343245b8f09b04d270e7/source/clSliceData.cpp -------------------------------------------------------------------------------- /source/clSliceData.h: -------------------------------------------------------------------------------- 1 | #ifndef CL_SLICEDATA_H 2 | #define CL_SLICEDATA_H 3 | 4 | #include "clError.h" 5 | #include 6 | 7 | 8 | 9 | 10 | 11 | /// Container Object for polygons and hatches 12 | /// [Part]->[Object]->[Polygon or Hatch] 13 | class clSliceData 14 | { 15 | public: 16 | struct tyMatrix 17 | { 18 | float m11, m12, m13; 19 | float m21, m22, m23; 20 | }; 21 | 22 | 23 | private: 24 | 25 | struct tyObject 26 | { 27 | float * points; 28 | int pointCount; 29 | int pointLenght; 30 | bool isHatch; 31 | }; 32 | 33 | struct tyPart 34 | { 35 | tyObject * objects; 36 | int objectCount; 37 | int objectLenght; 38 | tyMatrix transformMatrix; 39 | }; 40 | 41 | 42 | tyPart * m_parts; 43 | int m_partCount; 44 | int m_partLenght; 45 | 46 | tyObject * createNewObject(int partCount, int coordinatesCount); 47 | 48 | float * m_TransformedPoints; 49 | int m_TransformedPointsLenght; 50 | 51 | public: 52 | clSliceData(); 53 | ~clSliceData(); 54 | 55 | /// reset the internal structure for part [partIndex] 56 | /// [optional] Number of Parts to define 57 | bool clearParts(int AllocatePartCount=0); 58 | 59 | /// create a new part with the index [partIndex] 60 | /// index of the Part 61 | /// transformations matrix [m11] [m12] [m13] 62 | /// transformations matrix [m21] [m22] [m23] 63 | bool createPart(int partIndex, float m11, float m12, float m13, float m21, float m22, float m23); 64 | 65 | /// define a new polygon/polyline with for the part [partIndex] 66 | /// index of the Part 67 | /// number of points (2 floats per point) 68 | /// pointer to buffer to store data in (size: 2*[PointCount]*sizeof(float)) 69 | float * createPolygon(int partIndex, int PointCount); 70 | 71 | /// define a new hatch with for the part [partIndex] 72 | /// index of the Part 73 | /// number of Lines (4 floats per line) 74 | /// pointer to buffer to store data in (size: 4*[LineCount]*sizeof(float)) 75 | float * createHatch(int partIndex, int LineCount); 76 | 77 | /// is this object of a Part a Polygon/Polyline (2 Floats per Point) 78 | /// index of the Part 79 | /// index of the polyline or Hatch of the part 80 | bool isPolygon(int partIndex, int objectIndex); 81 | 82 | 83 | /// is this object of a Part a Hatch (4 Floats per Line) 84 | /// index of the Part 85 | /// index of the polyline or Hatch of the part 86 | bool isHatch(int partIndex, int objectIndex); 87 | 88 | /// returnes the number of parts 89 | int getPartCount(); 90 | 91 | /// returnes the number of objects of a part 92 | /// index of the Part 93 | int getObjectCount(int partIndex); 94 | 95 | /// returnes the coordinates of the part object [objectIndex] 96 | /// index of the Part 97 | /// index of the polyline or Hatch of the part 98 | float * getObjectPoints(int partIndex, int objectIndex); 99 | 100 | 101 | /// returnes the transformed coordinates for the part object [objectIndex] 102 | /// index of the Part 103 | /// index of the polyline or Hatch of the part 104 | /// transfrom matrix to apply to the part 105 | float * getObjectPointsTransformed(int partIndex, int objectIndex, tyMatrix matrix); 106 | 107 | /// rasters/renders a part layer to a INT Array 108 | /// INT Array to render the part filled with [color] - can be NULL 109 | /// INT Array to render the part conture with [color] - can be NULL 110 | /// index of the Part 111 | /// transfrom matrix to apply to the part 112 | /// Value to use for rendering 113 | /// width of [outFilledPicture] and [outLinePicture] 114 | /// height of [outFilledPicture] and [outLinePicture] 115 | bool drawRasteredObject(int * outFilledPicture, int * outLinePicture, int partIndex, tyMatrix matrix, int color, int widht, int height); 116 | 117 | 118 | /// applys a matrix to the current transfrom matrix of the part 119 | /// index of the Part 120 | /// matrix to apply 121 | void PartMatrixMult(int partIndex, tyMatrix matrix); 122 | 123 | 124 | static void IdentityMatrix(tyMatrix * dest); 125 | static void MatrixMult(tyMatrix * dest, tyMatrix A, tyMatrix B); 126 | 127 | 128 | static int fillEdgePoly(int * DataDest, int width, int height, int color); 129 | static int fillEdgePolyROI(int * DataDest, int width, int height, int min_x, int min_y, int max_x, int max_y, int color); 130 | static int addEdgeflag(int * DataDest, int width, int height, int x1, int y1, int x2, int y2, int color); 131 | static int drawLine(int * DataDest, int width, int height, int x1, int y1, int x2, int y2, int color); 132 | }; 133 | 134 | 135 | 136 | #endif -------------------------------------------------------------------------------- /source/export_lib_job.cpp: -------------------------------------------------------------------------------- 1 | #include "export_lib_job.h" 2 | 3 | //---------------------------------------------------// 4 | //-- library interface--// 5 | //---------------------------------------------------// 6 | int jf_initLib() 7 | { 8 | 9 | tyLibraryInterface *libInt = new tyLibraryInterface; 10 | 11 | libInt->magic = MAGIC_JOB; 12 | libInt->jobFile = new clJobFileInterpreter(); 13 | 14 | return (int) libInt; 15 | } 16 | 17 | //---------------------------------------------------// 18 | void jf_freeLib(int jobI) 19 | { 20 | if (jobI != NULL) 21 | { 22 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 23 | if (libInt->magic == MAGIC_JOB) 24 | { 25 | if (libInt->jobFile != NULL) delete libInt->jobFile; 26 | 27 | libInt->magic = 0; 28 | libInt->jobFile = NULL; 29 | } 30 | } 31 | } 32 | 33 | //---------------------------------------------------// 34 | int jf_readFromFile(int jobI, char * fileName) 35 | { 36 | if (jobI == NULL) return -1; 37 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 38 | if (libInt->magic != MAGIC_JOB) return -2; 39 | if (libInt->jobFile == NULL) return -3; 40 | 41 | if (libInt->jobFile->readFromFile(fileName)) return 1; 42 | return 0; 43 | 44 | 45 | } 46 | 47 | //---------------------------------------------------// 48 | int jf_printXML(int jobI) 49 | { 50 | if (jobI == NULL) return -1; 51 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 52 | if (libInt->magic != MAGIC_JOB) return -2; 53 | if (libInt->jobFile == NULL) return -3; 54 | 55 | if (libInt->jobFile->printXML()) return 1; 56 | return 0; 57 | } 58 | 59 | 60 | //---------------------------------------------------// 61 | char * jf_getKeyName(int jobI, int keyIndex) 62 | { 63 | if (jobI == NULL) return NULL; 64 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 65 | if (libInt->magic != MAGIC_JOB) return NULL; 66 | if (libInt->jobFile == NULL) return NULL; 67 | 68 | return libInt->jobFile->getKeyName(keyIndex); 69 | } 70 | 71 | //---------------------------------------------------// 72 | int jf_getFirstKeyChild(int jobI, int keyIndex) 73 | { 74 | if (jobI == NULL) return -1; 75 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 76 | if (libInt->magic != MAGIC_JOB) return -2; 77 | if (libInt->jobFile == NULL) return -3; 78 | 79 | return libInt->jobFile->getFirstChild(keyIndex); 80 | } 81 | 82 | //---------------------------------------------------// 83 | int jf_getNextKeyChild(int jobI, int keyIndex) 84 | { 85 | if (jobI == NULL) return -1; 86 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 87 | if (libInt->magic != MAGIC_JOB) return -2; 88 | if (libInt->jobFile == NULL) return -3; 89 | 90 | return libInt->jobFile->getNextChild(keyIndex); 91 | } 92 | 93 | //---------------------------------------------------// 94 | int jf_getFirstProperty(int jobI, int propertyIndex) 95 | { 96 | if (jobI == NULL) return -1; 97 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 98 | if (libInt->magic != MAGIC_JOB) return -2; 99 | if (libInt->jobFile == NULL) return -3; 100 | 101 | return libInt->jobFile->getFirstProperty(propertyIndex); 102 | } 103 | 104 | //---------------------------------------------------// 105 | int jf_getNextProperty(int jobI, int propertyIndex) 106 | { 107 | if (jobI == NULL) return -1; 108 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 109 | if (libInt->magic != MAGIC_JOB) return -2; 110 | if (libInt->jobFile == NULL) return -3; 111 | 112 | return libInt->jobFile->getNextProperty(propertyIndex); 113 | } 114 | 115 | //---------------------------------------------------// 116 | char * jf_getPropertyName(int jobI, int propertyIndex) 117 | { 118 | if (jobI == NULL) return NULL; 119 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 120 | if (libInt->magic != MAGIC_JOB) return NULL; 121 | if (libInt->jobFile == NULL) return NULL; 122 | 123 | return libInt->jobFile->getPropertyName(propertyIndex); 124 | } 125 | 126 | //---------------------------------------------------// 127 | char * jf_getPropertyValue(int jobI, int propertyIndex) 128 | { 129 | if (jobI == NULL) return NULL; 130 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 131 | if (libInt->magic != MAGIC_JOB) return NULL; 132 | if (libInt->jobFile == NULL) return NULL; 133 | 134 | return libInt->jobFile->getPropertyValue(propertyIndex); 135 | } 136 | 137 | //---------------------------------------------------// 138 | char * jf_getPropertyComment(int jobI, int propertyIndex) 139 | { 140 | if (jobI == NULL) return NULL; 141 | tyLibraryInterface * libInt = (tyLibraryInterface *) jobI; 142 | if (libInt->magic != MAGIC_JOB) return NULL; 143 | if (libInt->jobFile == NULL) return NULL; 144 | 145 | return libInt->jobFile->getPropertyComment(propertyIndex); 146 | } 147 | 148 | -------------------------------------------------------------------------------- /source/export_lib_job.h: -------------------------------------------------------------------------------- 1 | #ifndef EXPORT_LIB_JOB_H 2 | #define EXPORT_LIB_JOB_H 3 | 4 | #include "clJobFileInterpreter.h" 5 | 6 | #define MAGIC_JOB ('J' | ('o'<<8) | ('B'<<16) | (255<24)) 7 | 8 | struct tyLibraryInterface 9 | { 10 | int magic; 11 | clJobFileInterpreter * jobFile; 12 | }; 13 | 14 | 15 | //---- DLL EXPORTS ------// 16 | #define DllExport extern "C" __declspec(dllexport) 17 | 18 | DllExport int jf_initLib(); 19 | DllExport void jf_freeLib(int jobI); 20 | DllExport int jf_readFromFile(int jobI, char * fileName); 21 | DllExport int jf_printXML(int jobI); 22 | DllExport char * jf_getKeyName(int jobI, int keyIndex); 23 | DllExport int jf_getFirstKeyChild(int jobI, int keyIndex); 24 | DllExport int jf_getNextKeyChild(int jobI, int keyIndex); 25 | DllExport int jf_getFirstProperty(int jobI, int propertyIndex); 26 | DllExport int jf_getNextProperty(int jobI, int propertyIndex); 27 | DllExport char * jf_getPropertyName(int jobI, int propertyIndex); 28 | DllExport char * jf_getPropertyValue(int jobI, int propertyIndex); 29 | DllExport char * jf_getPropertyComment(int jobI, int propertyIndex); 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /source/export_lib_sli.cpp: -------------------------------------------------------------------------------- 1 | #include "export_lib_sli.h" 2 | 3 | 4 | //------------------------------------------------------------// 5 | int strIndexOfLast(const char * src, char findChar, int maxScanCount) 6 | { 7 | if (src == NULL) return -1; 8 | 9 | const char * srcP = src; 10 | 11 | int pos = -1; 12 | 13 | for (int i = 0; imagic = MAGIC_SLI; 33 | libInt->sliFile = NULL; 34 | libInt->sliceData = new clSliceData(); 35 | 36 | return (int) libInt; 37 | } 38 | 39 | //---------------------------------------------------// 40 | void sf_freeLib(int sliI) 41 | { 42 | if (sliI != NULL) 43 | { 44 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 45 | if (libInt->magic == MAGIC_SLI) 46 | { 47 | if (libInt->sliFile != NULL) delete libInt->sliFile; 48 | if (libInt->sliceData != NULL) delete libInt->sliceData; 49 | 50 | libInt->magic = 0; 51 | libInt->sliFile = NULL; 52 | libInt->sliceData = NULL; 53 | } 54 | } 55 | } 56 | 57 | //---------------------------------------------------// 58 | int sf_readFromFile(int sliI, char * fileName) 59 | { 60 | if (sliI == NULL) return -1; 61 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 62 | if (libInt->magic != MAGIC_SLI) return -2; 63 | 64 | if (libInt->sliFile != NULL) delete libInt->sliFile; 65 | libInt->sliFile = NULL; 66 | 67 | int pos = strIndexOfLast(fileName, '.', 1024); 68 | if (pos < 1) return -3; 69 | 70 | //- select the right format by file extention 71 | if (_stricmp(&fileName[pos + 1], "sli") == 0) 72 | { 73 | libInt->sliFile = new clSliFile(); 74 | } 75 | else if (_stricmp(&fileName[pos + 1], "job") == 0) 76 | { 77 | libInt->sliFile = new clJobSliceFile(); 78 | } 79 | else 80 | { 81 | return -4; 82 | } 83 | 84 | if (libInt->sliFile == NULL) return -3; 85 | 86 | if (libInt->sliFile->readFromFile(fileName)) return 1; 87 | 88 | return -5; 89 | } 90 | 91 | //---------------------------------------------------// 92 | int sf_getLayerCount(int sliI, int partIndex) 93 | { 94 | if (sliI == NULL) return -1; 95 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 96 | if (libInt->magic != MAGIC_SLI) return -2; 97 | if (libInt->sliFile == NULL) return -3; 98 | 99 | return libInt->sliFile->getLayerCount(partIndex); 100 | } 101 | 102 | 103 | //---------------------------------------------------// 104 | float sf_getMaxLayerPos(int sliI, int partIndex) 105 | { 106 | if (sliI == NULL) return -1; 107 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 108 | if (libInt->magic != MAGIC_SLI) return -2; 109 | if (libInt->sliFile == NULL) return -3; 110 | 111 | return libInt->sliFile->getMaxLayerPos(partIndex); 112 | } 113 | 114 | 115 | //---------------------------------------------------// 116 | float sf_getLayerThickness(int sliI) 117 | { 118 | if (sliI == NULL) return -1; 119 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 120 | if (libInt->magic != MAGIC_SLI) return -2; 121 | if (libInt->sliFile == NULL) return -3; 122 | 123 | return libInt->sliFile->getLayerThickness(); 124 | } 125 | 126 | 127 | //---------------------------------------------------// 128 | float sf_getLayerPos(int sliI, int partIndex, int layerIndex) 129 | { 130 | if (sliI == NULL) return -1; 131 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 132 | if (libInt->magic != MAGIC_SLI) return -2; 133 | if (libInt->sliFile == NULL) return -3; 134 | 135 | return libInt->sliFile->getLayerPos(partIndex, layerIndex); 136 | } 137 | 138 | 139 | //---------------------------------------------------// 140 | int sf_getLayerIndexByPos(int sliI, int partIndex, float layerPos) 141 | { 142 | if (sliI == NULL) return -1; 143 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 144 | if (libInt->magic != MAGIC_SLI) return -2; 145 | if (libInt->sliFile == NULL) return -3; 146 | 147 | return libInt->sliFile->getLayerIndexByPos(partIndex, layerPos); 148 | } 149 | 150 | 151 | //---------------------------------------------------// 152 | char * sf_getPartName(int sliI, int partIndex) 153 | { 154 | if (sliI == NULL) return NULL; 155 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 156 | if (libInt->magic != MAGIC_SLI) return NULL; 157 | if (libInt->sliFile == NULL) return NULL; 158 | 159 | return libInt->sliFile->getPartName(partIndex); 160 | } 161 | 162 | //---------------------------------------------------// 163 | char * sf_getPartProperty(int sliI, int partIndex) 164 | { 165 | if (sliI == NULL) return NULL; 166 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 167 | if (libInt->magic != MAGIC_SLI) return NULL; 168 | if (libInt->sliFile == NULL) return NULL; 169 | 170 | return libInt->sliFile->getPartProperty(partIndex); 171 | } 172 | 173 | 174 | //---------------------------------------------------// 175 | int sf_readSliceData(int sliI, int partIndex, int layerIndex) 176 | { 177 | if (sliI == NULL) return -1; 178 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 179 | if (libInt->magic != MAGIC_SLI) return -2; 180 | if (libInt->sliFile == NULL) return -3; 181 | if (libInt->sliceData == NULL) return -4; 182 | 183 | return libInt->sliFile->readSliceData(libInt->sliceData, partIndex, layerIndex); 184 | } 185 | 186 | 187 | //---------------------------------------------------// 188 | int sf_addRasterObject(int sliI, int * outFilledPicture, int * outLinePicture, int partIndex, clSliceData::tyMatrix matrix, int color, int width, int height) 189 | { 190 | if (sliI == NULL) return -1; 191 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 192 | if (libInt->magic != MAGIC_SLI) return -2; 193 | if (libInt->sliceData == NULL) return -4; 194 | 195 | return libInt->sliceData->drawRasteredObject(outFilledPicture, outLinePicture, partIndex, matrix, color, width, height); 196 | 197 | } 198 | 199 | //---------------------------------------------------// 200 | int sf_getPartCount(int sliI) 201 | { 202 | if (sliI == NULL) return -1; 203 | tyLibraryInterface * libInt = (tyLibraryInterface *) sliI; 204 | if (libInt->magic != MAGIC_SLI) return -2; 205 | if (libInt->sliFile == NULL) return -3; 206 | 207 | return libInt->sliFile->getPartCount(); 208 | } 209 | 210 | 211 | //---------------------------------------------------// 212 | char * sf_getLastError() 213 | { 214 | return clError::getLastError(); 215 | } 216 | 217 | //---------------------------------------------------// 218 | char * sf_getLastDebug() 219 | { 220 | return clError::getLastDebug(); 221 | } 222 | -------------------------------------------------------------------------------- /source/export_lib_sli.h: -------------------------------------------------------------------------------- 1 | #ifndef EXPORT_LIB_SLI 2 | #define EXPORT_LIB_SLI 3 | 4 | #include "clSliFile.h" 5 | #include "clSliceData.h" 6 | #include "clJobSliceFile.h" 7 | 8 | #define MAGIC_SLI ('S' | ('l'<<8) | ('i'<<16) | (254<24)) 9 | 10 | struct tyLibraryInterface 11 | { 12 | int magic; 13 | abstractSliceFile * sliFile; 14 | clSliceData * sliceData; 15 | }; 16 | 17 | 18 | //---- DLL EXPORTS ------// 19 | #define DllExport extern "C" __declspec(dllexport) 20 | 21 | DllExport int sf_initLib(); 22 | DllExport void sf_freeLib(int sliI); 23 | DllExport int sf_readFromFile(int sliI, char * fileName); 24 | DllExport int sf_getLayerCount(int sliI, int partIndex); 25 | DllExport int sf_readSliceData(int sliI, int partIndex, int layerIndex); 26 | DllExport int sf_addRasterObject(int sliI, int * outFilledPicture, int * outLinePicture, int partIndex, clSliceData::tyMatrix matrix, int color, int width, int height); 27 | DllExport int sf_getPartCount(int sliI); 28 | DllExport char * sf_getPartName(int sliI, int partIndex); 29 | DllExport char * sf_getPartProperty(int sliI, int partIndex); 30 | DllExport float sf_getLayerPos(int sliI, int partIndex, int layerIndex); 31 | DllExport int sf_getLayerIndexByPos(int sliI, int partIndex, float layerPos); 32 | DllExport char * sf_getLastError(); 33 | DllExport char * sf_getLastDebug(); 34 | DllExport float sf_getMaxLayerPos(int sliI, int partIndex); 35 | DllExport float sf_getLayerThickness(int sliI); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /source/main.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | 4 | 5 | int main(int argc, char* argv []) 6 | { 7 | 8 | clJobSliceFile sliFile; 9 | clSliceData sliceData; 10 | 11 | 12 | if (argc > 1) 13 | { 14 | sliFile.readFromFile(argv[1]); 15 | } 16 | else 17 | { 18 | sliFile.readFromFile("D:\\Entwicklung\\VC\\ThermoBoxEmgu\\_test_files_\\ScanV_Micro.Job"); 19 | } 20 | 21 | 22 | 23 | sliFile.readSliceData(&sliceData, 0, 0); 24 | 25 | clSliceData::tyMatrix TransMatrix; 26 | clSliceData::IdentityMatrix(&TransMatrix); 27 | 28 | int partCount = sliceData.getPartCount(); 29 | for (int part = 0; part < partCount; part++) 30 | { 31 | int objectCount = sliceData.getObjectCount(part); 32 | for (int object = 0; object < objectCount; object++) 33 | { 34 | //float * points = sliceData.getObjectPointsTransformed(part, object, TransMatrix); 35 | 36 | 37 | //sliceData.drawRasteredObject(&imgFilled, &imgPolyLine, part, object, TransMatrix, object, w, h); 38 | } 39 | } 40 | 41 | system("pause"); 42 | } 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /source/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include "clJobFileInterpreter.h" 5 | #include "clJobSliceFile.h" 6 | 7 | #endif 8 | --------------------------------------------------------------------------------