Files
Integration/IntegrationEgaltech/BTL.cs
T
Dario Sassi 4b85e596da Integration :
- aggiunta gestione file dati ausiliari btm (per ora contiene solo LOAD90).
2019-12-20 15:08:14 +00:00

299 lines
15 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ib.essetre.integration.egaltech
{
// La classe BTL rappresenta un singolo file BTL e come esso può contenere una o più Part (ovvero le travi di legno)
// ed ogni Part può contenere una o più Feature (ovvero i tagli da effettuare)
public class BTL
{
public string projectNumber ;
public string barLength ;
public string barLoad90 ;
public List<Part> parts ;
// I seguenti Id servono per il nome del file BTL
public int productionId ;
public int patternId ;
public int projectId ;
public int elementId ;
public string fileName ;
// Contatore entità di contorno libero
private int _FcEnt ;
public BTL()
{}
public bool WriteIntoFile( string BtlPath, bool IsFromProject)
{
// Se un file txt (contenente messaggio di errore) con lo stesso nome esiste già viene cancellato
if ( File.Exists( Path.ChangeExtension( BtlPath, ".txt")))
File.Delete( Path.ChangeExtension( BtlPath, ".txt")) ;
// Se non esistono pezzi, non faccio alcunché
if ( parts == null)
return false ;
// Reset entità di contorno libero
_FcEnt = Constants.FcBaseId ;
// Il seguente blocco 'using' si occupa della scrittura del file di testo, poi salvato in .btl
using ( var tw = new StreamWriter( BtlPath, false)) {
tw.WriteLine( Constants.VERSION) ;
tw.WriteLine( Constants.BUILD) ;
tw.WriteLine( Constants.GENERAL) ;
tw.WriteLine( Constants.PROJECT_NUMBER + this.projectNumber) ;
tw.WriteLine( Constants.SCALE_UNIT + Constants.scaleUnit.ToString()) ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"PRODID\":" + "\"" + ( IsFromProject ? 0 : productionId) + "\"") ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"PATTID\":" + "\"" + ( IsFromProject ? 0 : patternId) + "\"") ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"BARLEN\":" + "\"" + barLength + "\"") ;
foreach ( Part singlePart in parts) {
tw.WriteLine( Constants.PART) ;
tw.WriteLine( Constants.SINGLE_MEMBER_NUMBER + singlePart.singleMemberNumber) ;
tw.WriteLine( Constants.COUNT + singlePart.count) ;
double len = Convert.ToDouble( singlePart.length) * Math.Pow( 10, Constants.scaleUnit) ;
int intLen = Convert.ToInt32( len) ;
tw.WriteLine( Constants.LENGTH + intLen.ToString( "D8")) ;
double hei = Convert.ToDouble( singlePart.height) * Math.Pow( 10, Constants.scaleUnit) ;
int intHei = Convert.ToInt32( hei) ;
tw.WriteLine( Constants.HEIGHT + intHei.ToString( "D8")) ;
double wid = Convert.ToDouble( singlePart.width) * Math.Pow( 10, Constants.scaleUnit) ;
int intWid = Convert.ToInt32( wid) ;
tw.WriteLine( Constants.WIDTH + intWid.ToString( "D8")) ;
string posX = singlePart.x.ToString( "0.00", System.Globalization.CultureInfo.InvariantCulture) ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"POSX\":" + "\"" + posX + "\"") ;
string inv = singlePart.inverted.ToString() ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"INVERTED\":" + "\"" + inv + "\"") ;
string rot = singlePart.rotated.ToString() ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"ROTATED\":" + "\"" + rot + "\"") ;
string CutId = ( IsFromProject ? singlePart.elementId : singlePart.cutId).ToString() ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"CUTID\":" + "\"" + CutId + "\"") ;
foreach ( Feature singleFeature in singlePart.features) {
// Assegno identificativo del processo
string TaskId = ( IsFromProject ? singleFeature.processId : singleFeature.taskId).ToString() ;
// Se Contorno Libero (processo "250") elaborazione speciale
if ( singleFeature.processKey.Contains( "250")) {
FreeContourAnalyzer( singleFeature, TaskId, tw) ;
}
else {
// Tipo di Process
tw.WriteLine( Constants.PROCESS_KEY + singleFeature.processKey + " " + singleFeature.designation) ;
// Parametri standard del Process ( 1 .. 26)
tw.Write( Constants.PROCESS_PARAMETERS) ;
for ( int i = 1 ; i <= 26 ; ++ i) {
string singleParameter = singleFeature.processParameters[i-1] ;
if ( i != 15 || ! ( singleFeature.processKey.Contains( "060") || singleFeature.processKey.Contains( "061")))
tw.Write( "P" + i.ToString( "D2") + ":" + MultAndConvertTo8( singleParameter) + " ") ;
else
tw.Write( "P" + i.ToString( "D2") + ":" + "\"" + singleParameter + "\" ") ;
}
tw.WriteLine( "") ;
// Parametri speciali Q diversi da 0, preceduti da "USERATTRIBUTE:"
for ( int i = 1 ; i <= 20 ; ++ i) {
string singleParameter = singleFeature.processParameters[i+25] ;
if ( ! singleParameter.Equals( "0")) {
singleParameter = singleParameter.Replace( ",", ".") ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"Q" + i.ToString( "D2") + "\":\"" + singleParameter + "\" ") ;
}
}
tw.WriteLine( Constants.PROCESS_IDENT + singleFeature.processIdent) ;
tw.WriteLine( Constants.PROCESS + singleFeature.process) ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"TASKID\":" + "\"" + TaskId + "\"") ;
}
}
}
}
// Scrittura file ausiliario con dati che non fanno ricalcolare le lavorazioni
using ( var tw = new StreamWriter( Path.ChangeExtension( BtlPath, ".btm"), false)) {
tw.WriteLine( "[AuxData]") ;
tw.WriteLine( "LOAD90=" + barLoad90) ;
}
return true ;
}
// Il seguente metodo analizza il campo sag1 della singleFeature passata: se non è vuoto allora la stringa
// viene splittata nei parametri P di POLY ed analizzata
public void FreeContourAnalyzer( Feature singleFeature, String TaskId, StreamWriter tw)
{
// Se non ci sono dati, esco
if ( singleFeature.sag1 == "")
return ;
// Divido i dati in record punti
string[] arrParam = singleFeature.sag1.Split( new string[] { "POLY([", "),", ")]" }, StringSplitOptions.RemoveEmptyEntries) ;
// Se curva chiusa, copio il primo punto nell'ultimo elemento
if ( arrParam[arrParam.Length-1] == ",'P','C')")
arrParam[arrParam.Length-1] = arrParam[0] ;
// altrimenti aperta, quindi elimino l'ultimo elemento
else
Array.Resize( ref arrParam, arrParam.Length-1) ;
// Se il parametro Q10 è 1, l'ordine dell'array viene invertito
if ( singleFeature.processParameters[35] == "1")
Array.Reverse( arrParam) ;
// Ciclo sugli elementi
Boolean flagArco = false ;
for (int i = 0; i < arrParam.Length; i++) {
char[] separators = { ',', '(' } ;
string[] parts = arrParam[i].Split( separators) ; // ogni parametro P di POLY viene splittato in più parti
// il primo elemento di parts[] indica se ci troviamo all'inizio di un Arco o no
switch ( parts[0]) {
case "P":
default :
// Se StartPoint
if ( i == 0) {
++ _FcEnt ;
tw.WriteLine(Constants.PROCESS_KEY + singleFeature.processKey + " " + singleFeature.designation);
tw.Write(Constants.PROCESS_PARAMETERS);
tw.Write("P01:" + MultAndConvertTo8(parts[1]) + " "); // x
tw.Write("P02:" + MultAndConvertTo8(parts[2]) + " "); // y
tw.Write("P03:" + MultAndConvertTo8(parts[3]) + " "); // z
tw.Write("P05:" + MultAndConvertTo8(singleFeature.processParameters[4]) + " ");
tw.Write("P06:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P07:" + MultAndConvertTo8(singleFeature.processParameters[6]) + " ");
tw.Write("P08:" + Constants.EIGHT_ZEROS + " ");
if ( i == arrParam.Length - 1) // Verifica se ci troviamo all'ultimo parametro di POLY
tw.Write("P09:" + Constants.EIGHT_ZEROS + " "); // L'ultimo elemento di POLY deve avere "P09: 00000000"
else
tw.Write("P09:" + MultAndConvertTo8( (_FcEnt + 1).ToString()) + " ");
tw.Write("P10:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P11:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P12:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P13:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P14:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P15:" + Constants.EIGHT_ZEROS + " ");
tw.WriteLine(" ");
tw.WriteLine(Constants.PROCESS_IDENT + _FcEnt.ToString());
tw.WriteLine(Constants.PROCESS + singleFeature.process);
// Parametri speciali Q diversi da 0, preceduti da "USERATTRIBUTE:"
for ( int j = 1 ; j <= 20 ; ++ j) {
string singleParameter = singleFeature.processParameters[j+25] ;
if ( ! singleParameter.Equals( "0")) {
singleParameter = singleParameter.Replace( ",", ".") ;
tw.WriteLine( Constants.USERATTRIBUTE + "\"Q" + j.ToString( "D2") + "\":\"" + singleParameter + "\" ") ;
}
}
// TaskId
tw.WriteLine( Constants.USERATTRIBUTE + "\"TASKID\":" + "\"" + TaskId + "\"") ;
}
// se altrimenti FineArco
else if ( flagArco) {
++ _FcEnt ;
tw.WriteLine(Constants.PROCESS_KEY + singleFeature.processKey + " " + singleFeature.designation);
tw.Write(Constants.PROCESS_PARAMETERS);
tw.Write("P01:" + MultAndConvertTo8(parts[1]) + " "); // x (EndPoint Arc)
tw.Write("P02:" + MultAndConvertTo8(parts[2]) + " "); // y (EndPoint Arc)
tw.Write("P03:" + MultAndConvertTo8(parts[3]) + " "); // z (Endpoint Arc)
tw.Write("P05:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P06:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P07:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P08:" + "00000200" + " ");
if ( i == arrParam.Length - 1)
tw.Write("P09:" + Constants.EIGHT_ZEROS + " ");
else
tw.Write("P09:" + MultAndConvertTo8( (_FcEnt + 1).ToString()) + " ");
string[] PrevParts = arrParam[i - 1].Split(separators);
tw.Write("P10:" + MultAndConvertTo8(PrevParts[1]) + " "); // x (Point on Arc)
tw.Write("P11:" + MultAndConvertTo8(PrevParts[2]) + " "); // y (Point on Arc)
tw.Write("P12:" + MultAndConvertTo8(PrevParts[3]) + " "); // z (Point on Arc)
tw.Write("P13:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P14:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P15:" + Constants.EIGHT_ZEROS + " ");
tw.WriteLine(" ");
tw.WriteLine(Constants.PROCESS_IDENT + _FcEnt.ToString());
tw.WriteLine(Constants.PROCESS + singleFeature.process);
flagArco = false ;
}
// altrimenti FineSegmento
else {
++ _FcEnt ;
tw.WriteLine(Constants.PROCESS_KEY + singleFeature.processKey + " " + singleFeature.designation);
tw.Write(Constants.PROCESS_PARAMETERS);
tw.Write("P01:" + MultAndConvertTo8(parts[1]) + " "); // x
tw.Write("P02:" + MultAndConvertTo8(parts[2]) + " "); // y
tw.Write("P03:" + MultAndConvertTo8(parts[3]) + " "); // z
tw.Write("P05:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P06:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P07:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P08:" + "00000100" + " ");
if ( i == arrParam.Length - 1)
tw.Write("P09:" + Constants.EIGHT_ZEROS + " ");
else
tw.Write("P09:" + MultAndConvertTo8( (_FcEnt + 1).ToString()) + " ");
tw.Write("P10:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P11:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P12:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P13:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P14:" + Constants.EIGHT_ZEROS + " ");
tw.Write("P15:" + Constants.EIGHT_ZEROS + " ");
tw.WriteLine(" ");
tw.WriteLine(Constants.PROCESS_IDENT + _FcEnt.ToString());
tw.WriteLine(Constants.PROCESS + singleFeature.process);
}
break;
case "A": // InizioArco
flagArco = true;
break;
}
}
}
// Il seguente metodo prende il valore di un Process Parameter, lo moltiplica per 10^scaleUnit
// e lo converte in una stringa di 8 caratteri (i caratteri mancanti sono degli 0)
public string MultAndConvertTo8( string processParameter)
{
string rp = processParameter.Replace( ",", ".") ;
double sp = Convert.ToDouble( rp, CultureInfo.InvariantCulture) * Math.Pow( 10, Constants.scaleUnit) ;
int intSp = Convert.ToInt32( sp) ;
string s8 = intSp.ToString( "D8") ;
return s8 ;
}
// Le 2 seguenti struct dichiarano i campi necessari alla costruzione di una Part e di una Feature
public struct Part
{
public string singleMemberNumber ;
public string count ;
public string length ;
public string height ;
public string width ;
public List<Feature> features ;
public double x ;
public string inverted ;
public string rotated ;
public int elementId ;
public int cutId ;
}
public struct Feature
{
public string taskId ;
public string processKey ;
public string designation ;
public List<string> processParameters ;
public string processIdent ;
public string process ;
public string sag1 ;
public string processId ;
}
}
}