Add required layer cascade to slice preset tests
This commit is contained in:
parent
b064b9db64
commit
e0c4bbd011
1 changed files with 76 additions and 72 deletions
|
|
@ -22,6 +22,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
static ConfigIniTests()
|
||||
{
|
||||
allPrinters = (from configIni in new DirectoryInfo(printerSettingsDirectory).GetFiles("config.ini", System.IO.SearchOption.AllDirectories)
|
||||
let oemProfile = new OemProfile(SettingsLayer.LoadFromIni(configIni.FullName))
|
||||
select new PrinterConfig
|
||||
{
|
||||
PrinterName = configIni.Directory.Name,
|
||||
|
|
@ -29,21 +30,24 @@ namespace MatterControl.Tests.MatterControl
|
|||
ConfigPath = configIni.FullName,
|
||||
ConfigIni = new LayerInfo()
|
||||
{
|
||||
RelativePath = configIni.FullName.Substring(printerSettingsDirectory.Length + 1),
|
||||
Settings = SettingsLayer.LoadFromIni(configIni.FullName),
|
||||
RelativeFilePath = configIni.FullName.Substring(printerSettingsDirectory.Length + 1),
|
||||
|
||||
// The config.ini layer cascade contains only itself
|
||||
LayerCascade = new LayeredProfile(oemProfile, new SettingsLayer()),
|
||||
},
|
||||
MatterialLayers = LoadLayers(Path.Combine(configIni.Directory.FullName, "material")),
|
||||
QualityLayers = LoadLayers(Path.Combine(configIni.Directory.FullName, "quality"))
|
||||
MatterialLayers = LoadLayers(Path.Combine(configIni.Directory.FullName, "material"), oemProfile),
|
||||
QualityLayers = LoadLayers(Path.Combine(configIni.Directory.FullName, "quality"), oemProfile)
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
private static List<LayerInfo> LoadLayers(string layersDirectory)
|
||||
private static List<LayerInfo> LoadLayers(string layersDirectory, OemProfile oemProfile)
|
||||
{
|
||||
// The slice presets layer cascade contains the preset layer, with config.ini data as a parent
|
||||
return Directory.Exists(layersDirectory) ?
|
||||
Directory.GetFiles(layersDirectory, "*.slice").Select(file => new LayerInfo()
|
||||
{
|
||||
RelativePath = file.Substring(printerSettingsDirectory.Length + 1),
|
||||
Settings = SettingsLayer.LoadFromIni(file)
|
||||
RelativeFilePath = file.Substring(printerSettingsDirectory.Length + 1),
|
||||
LayerCascade = new LayeredProfile(new OemProfile(SettingsLayer.LoadFromIni(file)), oemProfile.OemLayer)
|
||||
}).ToList()
|
||||
: new List<LayerInfo>();
|
||||
}
|
||||
|
|
@ -51,64 +55,64 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void CsvBedSizeExistsAndHasTwoValues()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
// Bed size is not required in slice files
|
||||
if (layer.RelativePath.IndexOf(".slice", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
if (settings.RelativeFilePath.IndexOf(".slice", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string bedSize = layer.Settings.ValueOrDefault("bed_size");
|
||||
string bedSize = settings.LayerCascade.GetValue("bed_size");
|
||||
|
||||
// Must exist in all configs
|
||||
Assert.IsNotNullOrEmpty(bedSize, "[bed_size] must exist: " + layer.RelativePath);
|
||||
Assert.IsNotNullOrEmpty(bedSize, "[bed_size] must exist: " + settings.RelativeFilePath);
|
||||
|
||||
string[] segments = bedSize.Trim().Split(',');
|
||||
|
||||
// Must be a CSV and have two values
|
||||
Assert.AreEqual(2, segments.Length, "[bed_size] should have two values separated by a comma: " + layer.RelativePath);
|
||||
Assert.AreEqual(2, segments.Length, "[bed_size] should have two values separated by a comma: " + settings.RelativeFilePath);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CsvPrintCenterExistsAndHasTwoValues()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
// Printer center is not required in slice files
|
||||
if (layer.RelativePath.IndexOf(".slice", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
if (settings.RelativeFilePath.IndexOf(".slice", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string printCenter = layer.Settings.ValueOrDefault("print_center");
|
||||
string printCenter = settings.LayerCascade.GetValue("print_center");
|
||||
|
||||
// Must exist in all configs
|
||||
Assert.IsNotNullOrEmpty(printCenter, "[print_center] must exist: " + layer.RelativePath);
|
||||
Assert.IsNotNullOrEmpty(printCenter, "[print_center] must exist: " + settings.RelativeFilePath);
|
||||
|
||||
string[] segments = printCenter.Trim().Split(',');
|
||||
|
||||
// Must be a CSV and have only two values
|
||||
Assert.AreEqual(2, segments.Length, "[print_center] should have two values separated by a comma: " + layer.RelativePath);
|
||||
Assert.AreEqual(2, segments.Length, "[print_center] should have two values separated by a comma: " + settings.RelativeFilePath);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RetractLengthIsLessThanTwenty()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string retractLengthString = layer.Settings.ValueOrDefault("retract_length");
|
||||
string retractLengthString = settings.LayerCascade.GetValue("retract_length");
|
||||
if (!string.IsNullOrEmpty(retractLengthString))
|
||||
{
|
||||
float retractLength;
|
||||
if (!float.TryParse(retractLengthString, out retractLength))
|
||||
{
|
||||
Assert.Fail("Invalid [retract_length] value (float parse failed): " + layer.RelativePath);
|
||||
Assert.Fail("Invalid [retract_length] value (float parse failed): " + settings.RelativeFilePath);
|
||||
}
|
||||
|
||||
Assert.Less(retractLength, 20, "[retract_length]: " + layer.RelativePath);
|
||||
Assert.Less(retractLength, 20, "[retract_length]: " + settings.RelativeFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -116,19 +120,19 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void ExtruderCountIsGreaterThanZero()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string extruderCountString = layer.Settings.ValueOrDefault("extruder_count");
|
||||
string extruderCountString = settings.LayerCascade.GetValue("extruder_count");
|
||||
if (!string.IsNullOrEmpty(extruderCountString))
|
||||
{
|
||||
int extruderCount;
|
||||
if (!int.TryParse(extruderCountString, out extruderCount))
|
||||
{
|
||||
Assert.Fail("Invalid [extruder_count] value (int parse failed): " + layer.RelativePath);
|
||||
Assert.Fail("Invalid [extruder_count] value (int parse failed): " + settings.RelativeFilePath);
|
||||
}
|
||||
|
||||
// Must be greater than zero
|
||||
Assert.Greater(extruderCount, 0, "[extruder_count]: " + layer.RelativePath);
|
||||
Assert.Greater(extruderCount, 0, "[extruder_count]: " + settings.RelativeFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -136,20 +140,20 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void MinFanSpeedOneHundredOrLess()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string fanSpeedString = layer.Settings.ValueOrDefault("min_fan_speed");
|
||||
string fanSpeedString = settings.LayerCascade.GetValue("min_fan_speed");
|
||||
if (!string.IsNullOrEmpty(fanSpeedString))
|
||||
{
|
||||
// Must be valid int data
|
||||
int minFanSpeed;
|
||||
if (!int.TryParse(fanSpeedString, out minFanSpeed))
|
||||
{
|
||||
Assert.Fail("Invalid [min_fan_speed] value (int parse failed): " + layer.RelativePath);
|
||||
Assert.Fail("Invalid [min_fan_speed] value (int parse failed): " + settings.RelativeFilePath);
|
||||
}
|
||||
|
||||
// Must be less than or equal to 100
|
||||
Assert.LessOrEqual(minFanSpeed, 100, "[min_fan_speed]: " + layer.RelativePath);
|
||||
Assert.LessOrEqual(minFanSpeed, 100, "[min_fan_speed]: " + settings.RelativeFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -157,20 +161,20 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void MaxFanSpeedOneHundredOrLess()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string fanSpeedString = layer.Settings.ValueOrDefault("max_fan_speed");
|
||||
string fanSpeedString = settings.LayerCascade.GetValue("max_fan_speed");
|
||||
if (!string.IsNullOrEmpty(fanSpeedString))
|
||||
{
|
||||
// Must be valid int data
|
||||
int maxFanSpeed;
|
||||
if (!int.TryParse(fanSpeedString, out maxFanSpeed))
|
||||
{
|
||||
Assert.Fail("Invalid [max_fan_speed] value (int parse failed): " + layer.RelativePath);
|
||||
Assert.Fail("Invalid [max_fan_speed] value (int parse failed): " + settings.RelativeFilePath);
|
||||
}
|
||||
|
||||
// Must be less than or equal to 100
|
||||
Assert.LessOrEqual(maxFanSpeed, 100, "[max_fan_speed]: " + layer.RelativePath);
|
||||
Assert.LessOrEqual(maxFanSpeed, 100, "[max_fan_speed]: " + settings.RelativeFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -178,16 +182,16 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void NoCurlyBracketsInGcode()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
// TODO: Why aren't we testing all gcode sections?
|
||||
string[] keysToTest = { "start_gcode", "end_gcode" };
|
||||
foreach (string gcodeKey in keysToTest)
|
||||
{
|
||||
string gcode = layer.Settings.ValueOrDefault(gcodeKey);
|
||||
string gcode = settings.LayerCascade.GetValue(gcodeKey);
|
||||
if (gcode.Contains("{") || gcode.Contains("}") )
|
||||
{
|
||||
Assert.Fail(string.Format("[{0}] Curly brackets not allowed: {1}", gcodeKey, layer.RelativePath));
|
||||
Assert.Fail(string.Format("[{0}] Curly brackets not allowed: {1}", gcodeKey, settings.RelativeFilePath));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -196,9 +200,9 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void BottomSolidLayersEqualsOneMM()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string bottomSolidLayers = layer.Settings.ValueOrDefault("bottom_solid_layers");
|
||||
string bottomSolidLayers = settings.LayerCascade.GetValue("bottom_solid_layers");
|
||||
if (!string.IsNullOrEmpty(bottomSolidLayers))
|
||||
{
|
||||
if (bottomSolidLayers != "1mm")
|
||||
|
|
@ -207,7 +211,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
return;
|
||||
}
|
||||
|
||||
Assert.AreEqual("1mm", bottomSolidLayers, "[bottom_solid_layers] must be 1mm: " + layer.RelativePath);
|
||||
Assert.AreEqual("1mm", bottomSolidLayers, "[bottom_solid_layers] must be 1mm: " + settings.RelativeFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -215,40 +219,40 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void NoFirstLayerTempInStartGcode()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string startGcode = layer.Settings.ValueOrDefault("start_gcode");
|
||||
Assert.False(startGcode.Contains("first_layer_temperature"), "[start_gcode] should not contain [first_layer_temperature]" + layer.RelativePath);
|
||||
string startGcode = settings.LayerCascade.GetValue("start_gcode");
|
||||
Assert.False(startGcode.Contains("first_layer_temperature"), "[start_gcode] should not contain [first_layer_temperature]" + settings.RelativeFilePath);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NoFirstLayerBedTempInStartGcode()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string startGcode = layer.Settings.ValueOrDefault("start_gcode");
|
||||
Assert.False(startGcode.Contains("first_layer_bed_temperature"), "[start_gcode] should not contain [first_layer_bed_temperature]" + layer.RelativePath);
|
||||
string startGcode = settings.LayerCascade.GetValue("start_gcode");
|
||||
Assert.False(startGcode.Contains("first_layer_bed_temperature"), "[start_gcode] should not contain [first_layer_bed_temperature]" + settings.RelativeFilePath);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FirstLayerHeightLessThanNozzleDiameterXExtrusionMultiplier()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
if (layer.Settings.ValueOrDefault("output_only_first_layer") == "1")
|
||||
if (settings.LayerCascade.GetValue("output_only_first_layer") == "1")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float nozzleDiameter = float.Parse(layer.Settings.ValueOrDefault("nozzle_diameter"));
|
||||
float layerHeight = float.Parse(layer.Settings.ValueOrDefault("layer_height"));
|
||||
float nozzleDiameter = float.Parse(settings.LayerCascade.GetValue("nozzle_diameter"));
|
||||
float layerHeight = float.Parse(settings.LayerCascade.GetValue("layer_height"));
|
||||
|
||||
|
||||
float firstLayerExtrusionWidth;
|
||||
|
||||
string firstLayerExtrusionWidthString = layer.Settings.ValueOrDefault("first_layer_extrusion_width");
|
||||
string firstLayerExtrusionWidthString = settings.LayerCascade.GetValue("first_layer_extrusion_width");
|
||||
if (!string.IsNullOrEmpty(firstLayerExtrusionWidthString) && firstLayerExtrusionWidthString.Trim() != "0")
|
||||
{
|
||||
firstLayerExtrusionWidth = ValueOrPercentageOf(firstLayerExtrusionWidthString, nozzleDiameter);
|
||||
|
|
@ -258,7 +262,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
firstLayerExtrusionWidth = nozzleDiameter;
|
||||
}
|
||||
|
||||
string firstLayerHeightString = layer.Settings.ValueOrDefault("first_layer_height");
|
||||
string firstLayerHeightString = settings.LayerCascade.GetValue("first_layer_height");
|
||||
if (!string.IsNullOrEmpty(firstLayerHeightString))
|
||||
{
|
||||
float firstLayerHeight = ValueOrPercentageOf(firstLayerHeightString, layerHeight);
|
||||
|
|
@ -272,7 +276,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
return;
|
||||
}
|
||||
|
||||
Assert.Less(firstLayerHeight, minimumLayerHeight, "[first_layer_height] must be less than [firstLayerExtrusionWidth]: " + layer.RelativePath);
|
||||
Assert.Less(firstLayerHeight, minimumLayerHeight, "[first_layer_height] must be less than [firstLayerExtrusionWidth]: " + settings.RelativeFilePath);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -281,15 +285,15 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void LayerHeightLessThanNozzleDiameter()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
if (layer.Settings.ValueOrDefault("output_only_first_layer") == "1")
|
||||
if (settings.LayerCascade.GetValue("output_only_first_layer") == "1")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float nozzleDiameter = float.Parse(layer.Settings.ValueOrDefault("nozzle_diameter"));
|
||||
float layerHeight = float.Parse(layer.Settings.ValueOrDefault("layer_height"));
|
||||
float nozzleDiameter = float.Parse(settings.LayerCascade.GetValue("nozzle_diameter"));
|
||||
float layerHeight = float.Parse(settings.LayerCascade.GetValue("layer_height"));
|
||||
|
||||
double minimumLayerHeight = nozzleDiameter * 0.85;
|
||||
|
||||
|
|
@ -300,18 +304,18 @@ namespace MatterControl.Tests.MatterControl
|
|||
return;
|
||||
}
|
||||
|
||||
Assert.Less(layerHeight, minimumLayerHeight, "[layer_height] must be less than [minimumLayerHeight]: " + layer.RelativePath);
|
||||
Assert.Less(layerHeight, minimumLayerHeight, "[layer_height] must be less than [minimumLayerHeight]: " + settings.RelativeFilePath);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FirstLayerExtrusionWidthGreaterThanNozzleDiameterIfSet()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
float nozzleDiameter = float.Parse(layer.Settings.ValueOrDefault("nozzle_diameter"));
|
||||
float nozzleDiameter = float.Parse(settings.LayerCascade.GetValue("nozzle_diameter"));
|
||||
|
||||
string firstLayerExtrusionWidthString = layer.Settings.ValueOrDefault("first_layer_extrusion_width");
|
||||
string firstLayerExtrusionWidthString = settings.LayerCascade.GetValue("first_layer_extrusion_width");
|
||||
if (!string.IsNullOrEmpty(firstLayerExtrusionWidthString))
|
||||
{
|
||||
float firstLayerExtrusionWidth = ValueOrPercentageOf(firstLayerExtrusionWidthString, nozzleDiameter);
|
||||
|
|
@ -321,7 +325,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
return;
|
||||
}
|
||||
|
||||
Assert.GreaterOrEqual(firstLayerExtrusionWidth, nozzleDiameter, "[first_layer_extrusion_width] must be nozzle diameter or greater: " + layer.RelativePath);
|
||||
Assert.GreaterOrEqual(firstLayerExtrusionWidth, nozzleDiameter, "[first_layer_extrusion_width] must be nozzle diameter or greater: " + settings.RelativeFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -329,12 +333,12 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void SupportMaterialAssignedToExtruderOne()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string supportMaterialExtruder = layer.Settings.ValueOrDefault("support_material_extruder");
|
||||
string supportMaterialExtruder = settings.LayerCascade.GetValue("support_material_extruder");
|
||||
if (!string.IsNullOrEmpty(supportMaterialExtruder) && printer.Oem != "Esagono")
|
||||
{
|
||||
Assert.AreEqual("1", supportMaterialExtruder, "[support_material_extruder] must be assigned to extruder 1: " + layer.RelativePath);
|
||||
Assert.AreEqual("1", supportMaterialExtruder, "[support_material_extruder] must be assigned to extruder 1: " + settings.RelativeFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -342,12 +346,12 @@ namespace MatterControl.Tests.MatterControl
|
|||
[Test]
|
||||
public void SupportInterfaceMaterialAssignedToExtruderOne()
|
||||
{
|
||||
ValidateOnAllPrinters((printer, layer) =>
|
||||
ValidateOnAllPrinters((printer, settings) =>
|
||||
{
|
||||
string supportMaterialInterfaceExtruder = layer.Settings.ValueOrDefault("support_material_interface_extruder");
|
||||
string supportMaterialInterfaceExtruder = settings.LayerCascade.GetValue("support_material_interface_extruder");
|
||||
if (!string.IsNullOrEmpty(supportMaterialInterfaceExtruder) && printer.Oem != "Esagono")
|
||||
{
|
||||
Assert.AreEqual("1", supportMaterialInterfaceExtruder, "[support_material_interface_extruder] must be assigned to extruder 1: " + layer.RelativePath);
|
||||
Assert.AreEqual("1", supportMaterialInterfaceExtruder, "[support_material_interface_extruder] must be assigned to extruder 1: " + settings.RelativeFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -382,7 +386,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
|
||||
if (printer.RuleViolated)
|
||||
{
|
||||
ruleViolations.Add(printer.ConfigIni.RelativePath);
|
||||
ruleViolations.Add(printer.ConfigIni.RelativeFilePath);
|
||||
}
|
||||
|
||||
foreach (var layer in printer.MatterialLayers)
|
||||
|
|
@ -393,7 +397,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
|
||||
if (printer.RuleViolated)
|
||||
{
|
||||
ruleViolations.Add(layer.RelativePath);
|
||||
ruleViolations.Add(layer.RelativeFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -405,7 +409,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
|
||||
if (printer.RuleViolated)
|
||||
{
|
||||
ruleViolations.Add(layer.RelativePath);
|
||||
ruleViolations.Add(layer.RelativeFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -433,8 +437,8 @@ namespace MatterControl.Tests.MatterControl
|
|||
|
||||
private class LayerInfo
|
||||
{
|
||||
public string RelativePath { get; set; }
|
||||
public SettingsLayer Settings { get; set; }
|
||||
public string RelativeFilePath { get; set; }
|
||||
public LayeredProfile LayerCascade { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue