Skip to content

Commit 0c2034a

Browse files
Merge pull request #39 from Digital-Production-Aachen/computeMetaData
added new extension to compute and store geometric meta data of a vec…
2 parents 538ec04 + 5067270 commit 0c2034a

File tree

12 files changed

+236
-25
lines changed

12 files changed

+236
-25
lines changed

ReaderWriter/3rdPartyFormatAdapters/ASP/ASPFileReaderWriter/ASPFileWriter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ private void _writeGo(float[] pt)
312312
}
313313

314314
/// <inheritdoc/>
315-
public override void SimpleJobWrite(Job job, string filename, IFileReaderWriterProgress progress)
315+
public override void SimpleJobWrite(Job job, string filename, IFileReaderWriterProgress progress = null)
316316
{
317317
CheckConsistence(job.NumWorkPlanes, job.WorkPlanes.Count);
318318
for (int i = 0; i < job.NumWorkPlanes; i++)
@@ -333,7 +333,7 @@ public override void SimpleJobWrite(Job job, string filename, IFileReaderWriterP
333333
}
334334

335335
/// <inheritdoc/>
336-
public override void StartWritePartial(Job jobShell, string filename, IFileReaderWriterProgress progress)
336+
public override void StartWritePartial(Job jobShell, string filename, IFileReaderWriterProgress progress = null)
337337
{
338338
_jobShell = jobShell;
339339
_fileOperationInProgress = FileWriteOperation.PartialWrite;

ReaderWriter/3rdPartyFormatAdapters/CLI_ILT/ILTFileReaderAdapter/ILTFileReaderAdapter.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public override Job JobShell
9494

9595
public override CacheState CacheState => _cacheState;
9696

97-
public override void OpenJob(string filename, IFileReaderWriterProgress progress)
97+
public override void OpenJob(string filename, IFileReaderWriterProgress progress = null)
9898
{
9999
this.progress = progress;
100100
this.filename = filename;
@@ -290,7 +290,7 @@ private void AddVectorBlocksToWorkPlane(WorkPlane buildJobWorkPlane, ILayer sect
290290
/// <summary>
291291
/// Scans the ILT file and converts the structural data to a target
292292
/// </summary>
293-
private void ConvertILTStructure(IFileReaderWriterProgress progress)
293+
private void ConvertILTStructure(IFileReaderWriterProgress progress = null)
294294
{
295295
// ilt file is handled
296296
SetJobData(buildJob);
@@ -321,7 +321,7 @@ they don't provide any information*/
321321

322322
if (i % 100 == 0)
323323
{
324-
progress.Update(section.ModelsectionName + " layer " + i + @"/" + section.Geometry.Layers.Count,
324+
progress?.Update(section.ModelsectionName + " layer " + i + @"/" + section.Geometry.Layers.Count,
325325
(int)((sectionProgress / buildJob.ModelSections.Count) * 100.0
326326
+ ((i / (double)section.Geometry.Layers.Count) * 100.0 / buildJob.ModelSections.Count)));
327327
}
@@ -339,7 +339,7 @@ they don't provide any information*/
339339
job.NumWorkPlanes = job.WorkPlanes.Count;
340340
}
341341

342-
private void ConvertCLIStructure(IFileReaderWriterProgress progress)
342+
private void ConvertCLIStructure(IFileReaderWriterProgress progress = null)
343343
{
344344
job.JobMetaData = TranslateMetaData(cliFile);
345345
job.JobMetaData.JobName = this.jobfilename;
@@ -358,7 +358,7 @@ private void ConvertCLIStructure(IFileReaderWriterProgress progress)
358358
newWorkPlane.NumBlocks = workPlane.VectorBlocks.Count;
359359
if (i % 100 == 0)
360360
{
361-
progress.Update("workPlane " + i + @"/" + cliFile.Geometry.Layers.Count,
361+
progress?.Update("workPlane " + i + @"/" + cliFile.Geometry.Layers.Count,
362362
(int)((i / (double)cliFile.Geometry.Layers.Count) * 100.0));
363363
}
364364
}

ReaderWriter/AbstractReaderWriter/FileReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public Task OpenJobAsync(string filename, IFileReaderWriterProgress progress)
7373
/// </summary>
7474
/// <param name="filename">name of the file to open</param>
7575
/// <param name="progress">status update interface to be called</param>
76-
public abstract void OpenJob(string filename, IFileReaderWriterProgress progress);
76+
public abstract void OpenJob(string filename, IFileReaderWriterProgress progress = null);
7777

7878
/// <summary>
7979
/// Retrieves the complete job with all workplane data.

ReaderWriter/AbstractReaderWriter/FileWriter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public abstract class FileWriter : IWriter, IDisposable
5151
/// <param name="jobShell">OVF Job Object to write to file</param>
5252
/// <param name="filename">Path and name for savefile</param>
5353
/// <param name="progress">status update interface to be called</param>
54-
public abstract void StartWritePartial(Job jobShell, string filename, IFileReaderWriterProgress progress);
54+
public abstract void StartWritePartial(Job jobShell, string filename, IFileReaderWriterProgress progress = null);
5555

5656
/// <summary>
5757
/// Writes a complete <see cref="Job"/>. Needs to contain all <see cref="WorkPlane"/>s and <see cref="VectorBlock"/>s already.
@@ -67,7 +67,7 @@ public virtual Task SimpleJobWriteAsync(Job job, string filename, IFileReaderWri
6767
return Task.CompletedTask;
6868
}
6969

70-
public abstract void SimpleJobWrite(Job job, string filename, IFileReaderWriterProgress progress);
70+
public abstract void SimpleJobWrite(Job job, string filename, IFileReaderWriterProgress progress = null);
7171

7272
/// <summary>Disposes the FileWriter, finishing the partial write (if initiated).</summary>
7373
public abstract void Dispose();

ReaderWriter/FileReaderWriterFactory/FileConverter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public static async Task ConvertAsync(FileInfo file, FileInfo targetFile, IFileR
9999
/// <param name="file">a file to load in a supported format</param>
100100
/// <param name="targetFile">the target file. extension decides which writer will be used</param>
101101
/// <param name="progress">progress interface to call for updates</param>
102-
public static void Convert(FileInfo file, FileInfo targetFile, IFileReaderWriterProgress progress)
102+
public static void Convert(FileInfo file, FileInfo targetFile, IFileReaderWriterProgress progress = null)
103103
{
104104
CheckExtensions(file.Extension, targetFile.Extension);
105105
using (var reader = FileReaderFactory.CreateNewReader(file.Extension))
@@ -135,7 +135,7 @@ public async System.Threading.Tasks.Task ConvertAsyncAddParams(FileInfo file, Fi
135135
/// <param name="targetFile">the target file. extension decides which writer will be used</param>
136136
/// <param name="progress">progress interface to call for updates</param>
137137
/// <returns></returns>
138-
public void ConvertAddParams(FileInfo file, FileInfo targetFile, IFileReaderWriterProgress progress)
138+
public void ConvertAddParams(FileInfo file, FileInfo targetFile, IFileReaderWriterProgress progress = null)
139139
{
140140
CheckExtensions(file.Extension, targetFile.Extension);
141141
using (var reader = FileReaderFactory.CreateNewReader(file.Extension))
@@ -171,7 +171,7 @@ public Job ConvertAsyncAddParams(FileInfo file, IFileReaderWriterProgress progre
171171
/// <param name="file">file to read from</param>
172172
/// <param name="progress">progress interface to call for updates</param>
173173
/// <returns></returns>
174-
public Job ConvertAddParams(FileInfo file, IFileReaderWriterProgress progress)
174+
public Job ConvertAddParams(FileInfo file, IFileReaderWriterProgress progress = null)
175175
{
176176
CheckExtensions(file.Extension, ".ovf");
177177
using (var reader = FileReaderFactory.CreateNewReader(file.Extension))

ReaderWriter/OVFDefinition/VectorBlockExtensions.cs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,132 @@ public static void StoreVectorBlockBoundsInMetaData(this VectorBlock vectorBlock
340340
vectorBlock.MetaData.Bounds = vectorBlock.Bounds2D();
341341
}
342342

343+
/// <summary>
344+
/// Computes and stores the vector blocks meta data (bounds and scan/jump distances).
345+
/// </summary>
346+
/// <param name="vectorBlock"></param>
347+
public static VectorBlock.Types.VectorBlockMetaData ComputeAndStoreMetaData(this VectorBlock vectorBlock)
348+
{
349+
if (vectorBlock.MetaData == null) vectorBlock.MetaData = new VectorBlock.Types.VectorBlockMetaData();
350+
ComputeDistances(vectorBlock);
351+
vectorBlock.MetaData.Bounds = vectorBlock.Bounds2D();
352+
return vectorBlock.MetaData;
353+
}
354+
355+
private static void ComputeDistances(VectorBlock vectorBlock)
356+
{
357+
if (vectorBlock.VectorCount() < 1)
358+
return;
359+
360+
switch (vectorBlock.VectorDataCase)
361+
{
362+
case VectorBlock.VectorDataOneofCase.LineSequence:
363+
DistanceLineSeq2d(vectorBlock);
364+
break;
365+
case VectorBlock.VectorDataOneofCase.LineSequence3D:
366+
DistanceLineSeq3d(vectorBlock, ignoreZ: false);
367+
break;
368+
case VectorBlock.VectorDataOneofCase.LineSequenceParaAdapt:
369+
DistanceLineSeq3d(vectorBlock, ignoreZ: true);
370+
break;
371+
case VectorBlock.VectorDataOneofCase.Hatches:
372+
DistanceHatches2d(vectorBlock);
373+
break;
374+
case VectorBlock.VectorDataOneofCase.Hatches3D:
375+
DistanceHatches3d(vectorBlock, ignoreZ: false);
376+
break;
377+
case VectorBlock.VectorDataOneofCase.HatchParaAdapt:
378+
DistanceHatches3d(vectorBlock, ignoreZ: true);
379+
break;
380+
case VectorBlock.VectorDataOneofCase.Ellipses:
381+
throw new NotImplementedException("ToDo");
382+
case VectorBlock.VectorDataOneofCase.Arcs:
383+
case VectorBlock.VectorDataOneofCase.Arcs3D:
384+
throw new NotImplementedException("ToDo");
385+
case VectorBlock.VectorDataOneofCase.PointSequence:
386+
case VectorBlock.VectorDataOneofCase.PointSequence3D:
387+
case VectorBlock.VectorDataOneofCase.ExposurePause:
388+
case VectorBlock.VectorDataOneofCase.None:
389+
// no vector lengths
390+
break;
391+
default:
392+
throw new NotImplementedException($"unknown VectorDataCase: {vectorBlock.VectorDataCase}");
393+
}
394+
}
395+
396+
private static void DistanceLineSeq2d(VectorBlock vectorBlock)
397+
{
398+
var coordsSpan = vectorBlock.RawCoordinates().AsSpan();
399+
var vecSpan = System.Runtime.InteropServices.MemoryMarshal.Cast<float, Vector2>(coordsSpan);
400+
double scanDistance = 0;
401+
Vector2 curVec;
402+
for (int i = 1; i < vecSpan.Length; i++)
403+
{
404+
curVec = vecSpan[i] - vecSpan[i - 1];
405+
scanDistance += curVec.Length();
406+
}
407+
vectorBlock.MetaData.TotalJumpDistanceInMm = 0; // no jumps in a polyline
408+
vectorBlock.MetaData.TotalScanDistanceInMm = scanDistance;
409+
}
410+
411+
private static void DistanceLineSeq3d(VectorBlock vectorBlock, bool ignoreZ)
412+
{
413+
var coordsSpan = vectorBlock.RawCoordinates().AsSpan();
414+
var vecSpan = System.Runtime.InteropServices.MemoryMarshal.Cast<float, Vector3>(coordsSpan);
415+
double scanDistance = 0;
416+
Vector3 curVec;
417+
for (int i = 1; i < vecSpan.Length; i++)
418+
{
419+
curVec = vecSpan[i] - vecSpan[i - 1];
420+
if(ignoreZ) curVec.Z = 0;
421+
scanDistance += curVec.Length();
422+
}
423+
vectorBlock.MetaData.TotalJumpDistanceInMm = 0; // no jumps in a polyline
424+
vectorBlock.MetaData.TotalScanDistanceInMm = scanDistance;
425+
}
426+
427+
private static void DistanceHatches2d(VectorBlock vectorBlock)
428+
{
429+
var coordsSpan = vectorBlock.RawCoordinates().AsSpan();
430+
var vecSpan = System.Runtime.InteropServices.MemoryMarshal.Cast<float, Vector2>(coordsSpan);
431+
double jumpDistance = 0, scanDistance = 0;
432+
Vector2 curVec;
433+
for (int i = 1; i < vecSpan.Length - 1; i += 2)
434+
{
435+
curVec = vecSpan[i] - vecSpan[i - 1];
436+
scanDistance += curVec.Length();
437+
curVec = vecSpan[i + 1] - vecSpan[i];
438+
jumpDistance += curVec.Length();
439+
}
440+
// do last vec without jump
441+
curVec = vecSpan[vecSpan.Length - 1] - vecSpan[vecSpan.Length - 2];
442+
scanDistance += curVec.Length();
443+
vectorBlock.MetaData.TotalJumpDistanceInMm = jumpDistance;
444+
vectorBlock.MetaData.TotalScanDistanceInMm = scanDistance;
445+
}
446+
447+
private static void DistanceHatches3d(VectorBlock vectorBlock, bool ignoreZ)
448+
{
449+
var coordsSpan = vectorBlock.RawCoordinates().AsSpan();
450+
var vecSpan = System.Runtime.InteropServices.MemoryMarshal.Cast<float, Vector3>(coordsSpan);
451+
double jumpDistance = 0, scanDistance = 0;
452+
Vector3 curVec;
453+
for (int i = 1; i < vecSpan.Length - 1; i += 2)
454+
{
455+
curVec = vecSpan[i] - vecSpan[i - 1];
456+
if (ignoreZ) curVec.Z = 0;
457+
scanDistance += curVec.Length();
458+
curVec = vecSpan[i + 1] - vecSpan[i];
459+
if (ignoreZ) curVec.Z = 0;
460+
jumpDistance += curVec.Length();
461+
}
462+
// do last vec without jump
463+
curVec = vecSpan[vecSpan.Length - 1] - vecSpan[vecSpan.Length - 2];
464+
scanDistance += curVec.Length();
465+
vectorBlock.MetaData.TotalJumpDistanceInMm = jumpDistance;
466+
vectorBlock.MetaData.TotalScanDistanceInMm = scanDistance;
467+
}
468+
343469
public static void SetDisplayColor(this VectorBlock.Types.VectorBlockMetaData metaData, Color color)
344470
{
345471
metaData.DisplayColor = ColorConversions.ColorToInt(color);

ReaderWriter/UnitTests/TestAbstractVectorFileHandler.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,20 @@ public void SimpleWriteAndRead(FileInfo testFile)
7171

7272
[DynamicData("TestFiles")]
7373
[DataTestMethod]
74-
public async Task TestConvertAndCompareAsync(FileInfo testFile)
74+
public void TestConvertAndCompare(FileInfo testFile)
7575
{
7676
Console.WriteLine("TestConvertAndCompare");
7777

78-
IFileReaderWriterProgress progress = new FileReaderWriterProgress();
7978
foreach (string extension in FileWriterFactory.SupportedFileFormats)
8079
{
8180
FileInfo target = new FileInfo(Path.GetTempFileName() + extension);
8281
Console.WriteLine("Converting from {0} to {1}", testFile.Extension, target.Extension);
8382

84-
FileConverter.Convert(testFile, target, progress);
83+
FileConverter.Convert(testFile, target);
8584
FileReader originalReader = FileReaderFactory.CreateNewReader(testFile.Extension);
8685
FileReader convertedReader = FileReaderFactory.CreateNewReader(target.Extension);
87-
originalReader.OpenJob(testFile.FullName, progress);
88-
convertedReader.OpenJob(target.FullName, progress);
86+
originalReader.OpenJob(testFile.FullName);
87+
convertedReader.OpenJob(target.FullName);
8988

9089
Job originalJob = originalReader.CacheJobToMemory();
9190
Job convertedJob = convertedReader.CacheJobToMemory();
@@ -101,10 +100,14 @@ public async Task TestConvertAndCompareAsync(FileInfo testFile)
101100
convertedJob = ASPHelperUtils.HandleJobCompareWithASPTarget(originalJob, convertedJob);
102101
}
103102

104-
convertedJob.JobMetaData.Bounds = null;
105-
foreach (var workplane in convertedJob.WorkPlanes)
103+
if (target.Extension != testFile.Extension)
106104
{
107-
workplane.MetaData = null;
105+
// all formats except ovf are unable to store meta data
106+
convertedJob.JobMetaData.Bounds = null;
107+
foreach (var workplane in convertedJob.WorkPlanes)
108+
{
109+
workplane.MetaData = null;
110+
}
108111
}
109112

110113
Assert.AreEqual(originalJob, convertedJob);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
---- Copyright Start ----
3+
4+
This file is part of the OpenVectorFormatTools collection. This collection provides tools to facilitate the usage of the OpenVectorFormat.
5+
6+
Copyright (C) 2024 Digital-Production-Aachen
7+
8+
This library is free software; you can redistribute it and/or
9+
modify it under the terms of the GNU Lesser General Public
10+
License as published by the Free Software Foundation; either
11+
version 2.1 of the License, or (at your option) any later version.
12+
13+
This library is distributed in the hope that it will be useful,
14+
but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
Lesser General Public License for more details.
17+
18+
You should have received a copy of the GNU Lesser General Public
19+
License along with this library; if not, write to the Free Software
20+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
22+
---- Copyright End ----
23+
*/
24+
25+
using FluentAssertions;
26+
using Microsoft.VisualStudio.TestTools.UnitTesting;
27+
using OpenVectorFormat;
28+
using OpenVectorFormat.FileReaderWriterFactory;
29+
using System;
30+
using System.Collections.Generic;
31+
using System.IO;
32+
using System.Linq;
33+
using System.Numerics;
34+
using System.Text;
35+
using System.Threading.Tasks;
36+
37+
namespace UnitTests
38+
{
39+
[TestClass]
40+
public class TestComputeMetaData
41+
{
42+
private static DirectoryInfo dir = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "TestFiles"));
43+
44+
[TestMethod]
45+
public void TestComputeMetaDataBunny()
46+
{
47+
var testFileName = Path.Combine(dir.FullName, "bunny.ovf");
48+
using var reader = FileReaderFactory.CreateNewReader(Path.GetExtension(testFileName));
49+
reader.OpenJob(testFileName);
50+
var jobShell = reader.JobShell;
51+
52+
int numLayers = jobShell.NumWorkPlanes;
53+
double jumpLength = 0, markLength = 0;
54+
for(int i = 0; i < numLayers; i++)
55+
{
56+
var wp = reader.GetWorkPlane(i);
57+
if (wp.VectorBlocks.Count == 0) continue;
58+
foreach(var vectorBlock in wp.VectorBlocks)
59+
{
60+
var metaData = vectorBlock.ComputeAndStoreMetaData();
61+
jumpLength += metaData.TotalJumpDistanceInMm;
62+
markLength += metaData.TotalScanDistanceInMm;
63+
}
64+
}
65+
66+
const double precision = 0.1;
67+
markLength.Should().BeApproximately(831978.62, precision);
68+
//jumpLength.Should().BeApproximately(928193.66, precision);//ups this jump distance includes jumps between blocks and skywriting jumps
69+
jumpLength.Should().BeApproximately(821578.01, precision);
70+
}
71+
}
72+
}
5.12 KB
Binary file not shown.
20.4 KB
Binary file not shown.

0 commit comments

Comments
 (0)