-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathopen_vector_format.proto
More file actions
763 lines (678 loc) · 33.3 KB
/
open_vector_format.proto
File metadata and controls
763 lines (678 loc) · 33.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
// MIT License
//
// Copyright (c) 2025 Digital-Production-Aachen
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
syntax = "proto3";
package open_vector_format;
option go_package = "github.com/digital-production-aachen/openvectorformat/proto";
//all coordinate units are millimeters
//all fields are optional
//Represents one single production job. May be used as a central (very) large object containing
//all information, or as a "shell" with no or incomplete WorkPlane information to break down object size.
message Job {
repeated WorkPlane work_planes = 1;
JobMetaData job_meta_data = 2;
map<int32,MarkingParams> marking_params_map = 3;
map<int32,Part> parts_map = 4;
JobParameters job_parameters = 5;
//Number of Layer (LPBF) /3DPatches (Structuring)
int32 num_work_planes = 6;
//Metadata: Represents metadata related to the job object itself
message JobMetaData {
//jobCreationTime in UNIX time (number of seconds since January 1, 1970 12:00am UTC)
int64 job_creation_time = 1;
uint64 version = 2;
string job_name = 3;
string author = 4;
string description = 5;
//2D axis aligned bounding box of all workplanes vector block coordinates
AxisAlignedBox2D bounds = 6;
}
}
//Process parameters applying to the job as a whole
message JobParameters {
//setpoint temperature of a globally effective heating system (e.g. build chamber/substrate plate)
double preheating_temperatur_in_dg_c = 1;
//vector of main direction of a shielding gas flow (xy or xyz)
repeated double shielding_gas_directions = 2;
//vector of main direction of a material feed (e.g. powder coater, powder feed, extrusion nozzle) (xy or xyz)
repeated double material_feed_directions = 3;
//bounds of the scan fields associated with the respective laser_index found in vector blocks data
repeated AxisAlignedBox2D scan_field_bounds = 5;
//map of additional proprietary parameters
map<string,Part.ProcessStrategy.ProprietaryParam> additional_parameters = 4;
}
//Parameters controlling the tool (e.g. laser beam) behaviour
message MarkingParams {
float laser_power_in_w = 1;
float laser_speed_in_mm_per_s = 2;
float laser_focus_shift_in_mm = 3;
float point_exposure_time_in_us = 4;
float jump_speed_in_mm_s = 5;
//gives the number of exposure cycles executed
//applies for points only, for movement distance and speed implicitly define this
float point_exposure_repetitions = 6;
//repition rate of the exposure cycle, e.g. pulses/bursts etc. per second
//0 Hz is defined as continous wave (cw)
uint64 repetition_rate_in_hz = 7;
//for burst mode, number of pulses per burst
//0 is defined as no burst mode
//pulses in the burst are reapeated with oscillator frequency, pulseDurationInFemtoseconds applies to each pulse
uint64 laser_pulses_per_burst = 8;
//length of one pulse, defines the duty cycle together with repetitionRateInHz and laserPowerInW
uint64 pulseDurationInFemtoseconds = 9;
//marking mode switches between normal marking and skywriting modes
MarkingMode marking_mode = 10;
CornerBlendMode blend_mode = 28;
//Parameters for marking without Skywriting
float jump_delay_in_us = 11;
float laser_off_delay_in_us = 12;
float laser_on_delay_in_us = 13;
float mark_delay_in_us = 14;
float polygon_delay_in_us = 15;
//Parameters for marking with Skywriting
float time_lag_in_us = 16;
float laser_on_shift_in_us = 17;
//limit angle to switch from polygon delay to skywriting [degrees]
float limit = 18;
float n_prev_in_us = 19;
float n_post_in_us = 20;
//maximum allowed deviation from the setpoint mark path to optimize scanner dynamics by "cutting corners"
//Only applies in CornerBlendMode.SWIFT_BLENDING_MAXIMIZE_SPEED and
//Synonyms: radial tolerance
float corner_tolerance = 29;
//minimum mark speed to guaranty by scanner dynamics
//mark speed may be reduced down between laser_speed_in_mm_per_s and minimum_mark_speed when "cutting corners"
float minimum_mark_speed = 30;
//Parameters for marking with Wobble
float wob_frequency_in_hz = 21;
float wob_amp_long_in_mm = 22;
float wob_amp_trans_in_mm = 23;
WobbleMode wobble_mode = 24;
PowerGradientParams powerGradient = 25;
//meta data: custom, human readable name of this marking parameter set
string name = 26;
//discrete beam shape profile number
//used to control beam shaping devices (e.g. nLight AFX) to switch between different beam shape profiles (e.g. from Gauss-shaped to donut-shaped)
int32 beam_shape_profile_nr = 27;
enum MarkingMode {
NO_SKY = 0;
//Skywriting modes 1-3
SKY_1 = 1;
SKY_2 = 2;
SKY_3 = 3;
//Controls Sky Writing jerk-limited based on a lookahead simulation of scanner dynamics.
//manual skywriting params (n_prev_in_us, n_post_in_us, time_lag_in_us, laser_on_shift_in_us, limit, polygon_delay_in_us) are ignored
//Synonyms: BlendMode (ScanLab), ScanPack (Novanta)
SKYWRITING_LOOKAHEAD = 4;
}
enum CornerBlendMode {
//Uses the angle given by "limit" to choose between executing polygon delay or skywriting.
//When skywriting is not performed, a delay of length polygon_delay_in_us is inserted.
LIMIT_ANGLE_POLYGON_DELAY = 0;
//Keeps the marking speed constant to the speed defined in laser_speed_in_mm_per_s.
//Then optimizes the accuracy to be as close to the setpoint geometry as scanner dynamics allow.
//If the corner_tolerance cannot be fulfilled, the behaviour depends on the skywriting mode.
//If skywriting is DYNAMIC_LOOKAHEAD, a skywriting motion is inserted. If skywriting mode is NO_SKY, a dynamics violation is triggered.
SWIFT_BLENDING_CONSTANT_SPEED = 1;
//Utilizes scanner dynamics lookahead to maximize the speed of the scanning process.
//Guaranties that the corner_tolerance is fulfilled.
//Maximizes the scanning speed possibly beyond the limits of minimum_mark_speed and laser_speed_in_mm_per_s.
//Does not insert sky writing-like motions, instead decelerates as needed on the trajectory. Ignores marking_mode.
SWIFT_BLENDING_MAXIMIZE_SPEED = 2;
//Utilizes scanner dynamics lookahead to maximize the accuracy of the scanning process.
//Guaranties that the minimum_mark_speed is fulfilled.
//If the corner_tolerance cannot be fulfilled, the behaviour depends on the skywriting mode.
//If skywriting is DYNAMIC_LOOKAHEAD, a skywriting motion is inserted. If skywriting mode is NO_SKY, a dynamics violation is triggered.
BEST_ACCURACY_MIN_MARK_SPEED = 3;
}
enum WobbleMode {
NO_WOBBLE = 0;
//ellipse-shape wobble movement perpendicular to the current movement direction
ELLIPSE_WOBBLE = 1;
//8-shape wobble movement perpendicular to the current movement direction
STANDING_EIGHT_WOBBLE = 2;
//8-shape wobble movement parallel to the current movement direction
LYING_EIGHT_WOBBLE = 3;
}
//reserved tag range to allow for OVF varaiations without conflicts, e.g. adding proprietary parameters
reserved 128 to 164;
}
message PowerGradientParams
{
float minPowerInW = 1;
float gradientInWPerS = 2;
}
//Part is a reference to a CAD 3D model instance in this Job.
//Instances in a job may differ in their position, orientation, process strategy, marking parameters or support structures,
//even if they are derived from the same parent part.
//Common parent parts of instances can be identified using the parent_part_name, if set.
message Part {
string name = 1;
GeometryInfo geometry_info = 2;
Material material = 3;
//process strategy used for the in skin (volume) of the part
ProcessStrategy process_strategy = 4;
//process strategy used for the down skin of the part, if differing
ProcessStrategy up_skin_process_strategy = 5;
//process strategy used for the up skin of the part, if differing
ProcessStrategy down_skin_process_strategy = 6;
//meta data defining the exposure order that was used to order the vector blocks of this part
//the first item gets exposed first, e.g. exposure starts with downskin hatches, followed by inskin hatches
//two LPBFMetadata objects are added with PartArea set to VOLUME in both, SkinType set to DOWN_SKIN in first and IN_SKIN in second
repeated VectorBlock.LPBFMetadata exposure_order = 7;
//reference to the original CAD 3D model this instance was created from
string parent_part_name = 8;
//Metadata related to the geometry of the part
message GeometryInfo {
//part volume in cubic millimeters
double volume_in_mm3 = 1;
//support volume in cubic millimeters
double support_volume_in_mm3 = 2;
//height (layer) of the top slice in millimeters
double build_height_in_mm = 3;
//surface area of the 3D model in square millimeters
double surface_area_in_mm2 = 4;
//surface area projected on the biuld plate in square millimeters
double projected_surface_in_mm2 = 5;
}
message Material {
uint64 id = 1;
string name = 2;
}
//Metadata: parameters the job preprocessing program (e.g. Slicer, CAM) used to create the vector data
message ProcessStrategy {
//universal, vendor independent parameters
//start rotation angle of scan patches or layers
float rot_angle_in_deg = 1;
//Angle increment of scan patches from layer to layer
float increment_angle_in_deg = 2;
//Shift of patches in the pattern from layer to layer
float shift_in_mm = 3;
//Extension of patches in to each other. Synonym: overlap distance
float extend_into_in_mm = 4;
//maximum length of hatches when applying a pattern. Values <= 0 result in no limitation.
//for stripes and checkerboard this controls the size of the groups/patches
//for single tracks (uni- or bidirectional) this does not apply
float pattern_hatch_length_in_mm = 13;
//pattern type of the hatches that fill the contours
HatchingPattern hatching_pattern = 12;
//thickness of a layer/workplane
float layer_thickness_in_mm = 5;
//distance between single material tracks
float hatch_distance_in_mm = 6;
//distance between contour and filling
float hatch_contour_distance_in_mm = 7;
//critical angle that is considered as overhang
float overhang_angle_in_deg = 8;
//offset of the first contour relative to the computed contour of the geometry.
//often reffered to as "beam compensation" as well
float contour_offset_in_mm = 9;
//number of generated contours. If <= 0, there will only be hatches.
int32 number_of_contours = 10;
//distance inbetween multiple contour lines. Only takes effect if number_of_contours > 1.
float contour_distance_in_mm = 11;
//meta data: custom, human readable name of this process strategy
string name = 90;
//proprietary parameters, vendor specific
repeated ProprietaryParam additional_parameters = 100;
//generic definition of proprietary parameters descriptor
message ProprietaryParam{
string param_name = 1;
oneof parameter_value{
double param_value = 2;
string param_string = 4;
bytes param_blob = 5;
}
string param_description = 3;
}
enum HatchingPattern{
//single hatch lines that follow the same direction. Long jumps are executed back to the start after each line.
UNIDIRECTIONAL = 0;
//single hatch lines that alternate directions with short jumps in between
BIDIRECTIONAL = 1;
//hatches are seperated into patches with perpendicular direction following a checkerboard pattern
//size of each patch is quadratic pattern_hatch_length_in_mm times pattern_hatch_length_in_mm
//patch overlap (size of area with two patches) is of size extend_into_in_mm
CHECKERBOARD = 2;
//hatches are seperated into patches ("stripes"), but opposed to checkerboard only in one direction perpendicular to the marking direction
//size of each patch is pattern_hatch_length_in_mm in marking direction, unrestricted perpendicular to the marking direction
//patch overlap (size of area with two patches) is of size extend_into_in_mm
STRIPES = 3;
//hatches are seperated into patches ("hexagon")
//size of each sidelength is pattern_hatch_length_in_mm and the long and short diagonal is calculated from it
//patch overlap (size of area with two patches) is of size extend_into_in_mm
HEXAGON = 4;
}
}
}
//A WorkingPlane is a 2D working plane of the tool (e.g. laser scanfield, electron beam scan field)
//in the global 3D coordinate system that is set by moving one or more physical axis relative to the workpiece.
//It follows the same concept as a sketch plane in CAD applications.
//Any axis movement that changes the work plane position will require a new WorkingPlane message.
//synonyms: Layer (LPBF) / 3DPatches (Structuring) / Scanfields (MultiBeam)
message WorkPlane {
repeated VectorBlock vector_blocks = 1;
// Axis positions - can be used for tiling
float x_pos_in_mm = 2;
float y_pos_in_mm = 3;
// for PBF processes bed position
float z_pos_in_mm = 4;
float x_rot_in_deg = 5;
float y_rot_in_deg = 6;
float z_rot_in_deg = 7;
int32 num_blocks = 8;
//how many times the WorkPlane will be executed
//this will execute all vector blocks in order once, then repeat [repeats] times starting with the first block again etc.
uint32 repeats = 9;
//reference for syncing or asynchronious execution (keeping correct order)
int32 work_plane_number = 10;
//machine specific information for directly controlling additional axis
//that don't work in the main coordinate system
//the exact machine type has to be known for this during job preparation
//identifier of the machine to prevent type mismatch, has to be verified by the machine controller
string machine_type = 11;
//goal positions of the axis in order of machine axis number
repeated float additional_axis_positions = 12;
WorkPlaneMetaData meta_data = 13;
//optional metadata of this work plane
message WorkPlaneMetaData {
//total scan distance of this WorkPlane in mm
double total_scan_distance_in_mm = 1;
//total scan distance of this WorkPlane in mm
double total_jump_distance_in_mm = 2;
//map containing all patches in this workplane
map<int32,Patch> patches_map = 3;
//actually applied max laser power after dynamic parameter allocation in this workPlane
float maxPower = 4;
//actually applied min laser power after dynamic parameter allocation in this workPlane
float minPower = 5;
//all closed contours present in this workplane
repeated closedContour contours = 6;
message closedContour {
//indices of the vector blocks in vector_blocks repeated field that represent different sections of one closed contour
//sections are necessary to indicate parameter set changes along the contour
//with this meta data reconstruction of original contours is possible
repeated int32 contour_section_vector_block_indices = 1;
//this closed contours area in square millimeters
float area_in_mm_2 = 2;
//this closed contours total length in millimeters
float length_in_mm = 3;
//index of the parent (containing) contour in this workplanes' repeated contours field
//if the parent index points to the contour itself, it is one outermost contour
int32 parent_index = 5;
//defines the winding number of the contour around the contours centroid
//also indicateing its direction: negative = clockwise / positive = counterclockwise
int32 winding_number = 6;
//indicates the ContourType of this contour
ContourType type = 7;
enum ContourType {
//an outer contour of the unprocessed part slice
//for non overlapping contour groups, outer an inner contours always alternate
//the hierarchy of the contours is stored in parent_index instead
PART_OUTER_CONTOUR = 0;
//an inner contour of the unprocessed part slice
//for non overlapping contour groups, outer an inner contours always alternate
//the hierarchy of the contours is stored in parent_index instead
PART_INNER_CONTOUR = 1;
//an additional contour that has been offset from a contour of the unprocessed part slice
//e.g. because number_of_contours > 1 in the part process strategy
//these contours are not part of the unprocessed part slices contour hierarchy
//they instead are offset to their parent contour indicated by parent_index
//and typically are used to weld the parent contour to the hatches
OFFSET_CONTOUR = 2;
}
}
//2D axis aligned bounding box of all the workplanes vector block coordinates
AxisAlignedBox2D Bounds = 7;
}
//A patch is a subdivision in a workPlane with an own local coordinate system.
//The local transformation is given by the 2D origin (u/v)
//Coordinates in the workplane may be tranformed by the machine depending on the patch
message Patch {
//optional 2D polygon that forms the outer contour (not marked) of this patch
//if the contour should get executed a separate vector block is used.
VectorBlock.LineSequence outer_contour = 1;
//local transformation of workpiece coordinate x
float u = 2;
//local transformation of workpiece coordinate y
float v = 3;
//identifier of actual workpiece layer / stack
//for single patch processes like powder bed this equals the workPlane number
int32 layer_id = 4;
}
}
message VectorBlock {
oneof vector_data {
LineSequence line_sequence = 1;
Hatches _hatches = 2;
PointSequence point_sequence = 3;
Arcs _arcs = 4;
Ellipses ellipses = 5;
LineSequence3D line_sequence_3d = 6;
Hatches3D hatches_3d = 7;
PointSequence3D point_sequence_3d = 8;
Arcs3D arcs_3d = 9;
ExposurePause exposure_pause = 10;
LineSequenceParaAdapt line_sequence_para_adapt = 11;
HatchesParaAdapt _hatchParaAdapt = 12;
CubicBezierHatches cubic_bezier_hatches = 13;
QuadraticBezierHatches quadratic_bezier_hatches = 14;
CubicBezierSpline cubic_bezier_spline = 15;
QuadraticBezierSpline quadratic_bezier_spline = 16;
CubicBezierHatches3D cubic_bezier_hatches_3d = 17;
QuadraticBezierHatches3D quadratic_bezier_hatches_3d = 18;
CubicBezierSpline3D cubic_bezier_spline_3d = 19;
QuadraticBezierSpline3D quadratic_bezier_spline_3d = 20;
SynchronizationBlock sync_block = 21;
}
//key used in Job/markingParamsMap
int32 marking_params_key = 50;
//LaserIndex is used for assigning vectorBlocks to different actors, e.g. in multi scanner systems
int32 laser_index = 53;
//vetor blocks are executed in order once by default (repeats = 0),
//then repeated [repeats] times starting with the first vector again etc.
uint64 repeats = 54;
VectorBlockMetaData meta_data = 100;
oneof process_meta_data {
LPBFMetadata lpbf_metadata = 101;
MicroStructuringMetadata micro_structuring_metadata = 102;
PolishingMetadata polishing_metadata = 103;
}
message VectorBlockMetaData{
//total scan distance of this vector block in mm
double total_scan_distance_in_mm = 1;
//total scan distance of this vector block in mm
double total_jump_distance_in_mm = 2;
//key used in Job/partsMap
int32 part_key = 3;
//key used in Job/Workplane/patchesMap
int32 patch_key = 4;
//Index of the closedContour in the workplane/Metadata/contours field this vector block is contained in.
//Contours shall be enumerated ascending in each workplane to identifiy physical contours
//consisting of multiple vector blocks (e.g. when parameters change) as one.
//If this parameter is set to any value smaller than 0, this explicitly indicates that none of the vectors
//of the block are contained in any contour (this is the case for e.g. single vector/line supports).
//If contour_index is set to a valid contour index, all of the blocks vectors are contained in the contour.
//The case of a vector block that partly overlaps a contour is excluded on purpose. Overlapping blocks cause
//a reexposure that should be handled by the machine controller. If containing contour meta data is calculated,
//overlapping vector blocks should be split and properly indicate the reexposure in the meta data.
int32 contour_index = 5;
//2D axis aligned bounding box of the vector block coordinates
AxisAlignedBox2D bounds = 6;
//Optional metadata defining a preferred 32bit RGBA color to render the vector data of this vector block in a viewer.
//int32 is interpreted as byte[4] with byte[0] = red, byte[1] = green, byte[2] = blue, byte[3] = alpha
int32 display_color = 7;
//---these fields can be used by simulation software to write detailed exposure times into the OVF structure---
//internal execution time of the vector block, including block internal delays and skywriting
//this time stays constant when the vector block is translated/rotated, excludes jump_to_time_in_s
//the full execution time is the sum of exposure_time_in_s and jump_to_time_in_s
double exposure_time_in_s = 8;
//jump time from the end position of the previous vector block to the start position of this vector block
//this time changes when the vector block is translated/rotated
//the full execution time is the sum of exposure_time_in_s and jump_to_time_in_s
double jump_to_time_in_s = 9;
//time the laser power was on
//can be used to calculate productive time percentage and theoretical energy input (multiply with laser_power_in_w)
double laser_on_time_in_s = 10;
}
// ProcessMetaData for LPBF
message LPBFMetadata {
PartArea part_area = 1;
SkinType skin_type = 2;
SkinCoreStrategyArea skin_core_strategy_area = 3;
StructureType structure_type = 4;
//states if this vector block is a reexposure of the area (true) or the first exposure (false)
bool reexposure = 5;
//SkinType defines if the vectors of this block belong to the parts surface in vertical direction
//InSkin (default), vectors are found on this position on previous and next layer
//DownSkin, no vectors in previous layer, exposure in powder bed
//Upskin, no vectors in next layer
enum SkinType {
IN_SKIN = 0;
DOWN_SKIN = 1;
UP_SKIN = 2;
}
//Skin Core strategy uses two laser spots with different sizes for core (bigger spot)
//and outer hull (smaller spot) to increase productivity. Default value
//(also for not using the strategy) is OuterHull, using the small spot for the whole part.
enum SkinCoreStrategyArea {
OUTER_HULL = 0;
CORE = 1;
INBETWEEN_HULL = 2;
}
}
//ProcessMetaData for MicroStructuring
message MicroStructuringMetadata {
PartArea part_area = 1;
StructureType structure_type = 2;
}
//ProcessMetaData for Polishing
message PolishingMetadata {
// Todo: Define
}
//PartArea defines if the vectors belong to a part surface in horizontal direction (in layer).
//Contours are borders of the part in the layer, volume (or core) is the area inbetween.
//Transition contours are special additional contour lines connecting volume and contour.
enum PartArea {
//also called core or hatches
VOLUME = 0;
CONTOUR = 1;
TRANSITION_CONTOUR = 2;
}
//StructureType defines the type of structure model the vectors belong to.
//PART is default, usually refering to a tesselated model, e.g. STL models.
//Support structures don't belong to any part, but are needed for the process.
//Wirestructures can be tesselated. But it is more efficient to treat them seperatly in a
//parametrized format. They are similar to supports, but are not removed after the process.
//Points use is very limited. They may form a support or wirestructure.
enum StructureType {
PART = 0;
SUPPORT = 1;
WIRESTRUCTURE = 2;
POINTS = 3;
}
//--- Vetor Block Type Definitions ---
//--- OVF performance: why use unstructured repeated float in vector block type definitions? ---
//The choice of using unstructured repeated float in OVF is very deliberate and the reasoning is performance.
//Approx. 99% of the data volume in OVF is the coordinate data.
//Using repeated float enables reinterpreting the float data as an array of structs using equivalents of "memcast" in the target programming languages.
//This enables using different definitions of point structs without allocating again or copying the data.
//Example use cases are struct definitions for different domain models or libraries,
//or Single Input Multipe Data (SIMD) vector types.
//Zero copy in place is the minimal overhead possible of any solution.
//This works in all cases where libraries use single precision floats.
//Using repeated float also minimizes overhead in the wire format.
//The resulting packed proto encoding only needs a single TAG byte and a varint for the length,
//resulting in only 2-5 bytes of encoding overhead per vector block.
//"Parsing" repeated float is a minimal overhead memcopy of the floating point data, e.g. from the file/network stream buffer.
//LineSequence:
//A lineSequence is defined by a set of vertex points (x,y),
//connected contiguously in the listed order by straight line segments.
//A closed lineSequence can also be called a polygon.
message LineSequence {
repeated float points = 1; // len % 2 == 0, len >= 4
}
//LineSequence3D:
//A lineSequence3D is defined by a set of vertex points (x,y,z) in 3D space,
//connected contiguously in the listed order by straight line segments.
//A closed lineSequence can also be called a polygon.
message LineSequence3D {
repeated float points = 1; // len % 3 == 0, len >= 6
}
//Hatches:
//A hatch is a set of independent straight lines,
//each defined by one start and one end point (x,y) for 2D.
message Hatches {
repeated float points = 1; // len % 4 == 0, len >= 4
}
//Hatches3D:
//A hatch is a set of independent straight lines,
//each defined by one start and one end point (x,y,z) for 3D.
message Hatches3D {
repeated float points = 1; // len % 6 == 0, len >= 6
}
//PointSequence:
//A point sequence is a set of points, each marked
//for a fixed period of time. Each point consists of (x,y) for 2D.
message PointSequence {
repeated float points = 1; // len % 2 == 0, len >= 2
}
//PointSequence3D:
//A point sequence is a set of points, each marked
//for a fixed period of time. Each point consists of (x,y,z) for 3D.
message PointSequence3D {
repeated float points = 1; // len % 3 == 0, len >= 3
}
//An arc is defined by a start point on the circle,
//defined in relative cartesian coordinates to the center,
//a center point and an arc angle (degrees). Positive angles mean clockwise,
//negative counter-clockwise rotation.
//Multiple same radius/angle arcs are defined with repeated center coordinates (x,y).
message Arcs {
double angle = 1;
float start_dx = 2;
float start_dy = 3;
repeated float centers = 4; // len % 2 == 0, len >= 2
}
//An arc3D (edge of a plate) is defined by a start point on the circle,
//defined in relative cartesian coordinates to the center,
//a center point and an arc angle (degrees). Positive angles mean clockwise,
//negative counter-clockwise rotation.
//Multiple same radius/angle arcs are defined with repeated center coordinates (x,y,z) for 3D.
message Arcs3D {
double angle = 1;
float start_dx = 2;
float start_dy = 3;
float start_dz = 4;
repeated float centers = 5; // len % 3 == 0, len >= 3
}
//An ellipse is defined like an arc, with additional parameters
//defining the ellipse shape: a/b length of ellipse half axis
//phi0 phase zero angle (start point of ellipse relative to end of a)
message Ellipses {
float a = 1;
float b = 2;
double phi0 = 3;
Arcs ellipses_arcs = 4;
}
//Pause the exposure procedure. This can be necessary e.g. for thermal reasons,
//or for syncing mulitple laser scanner units, preventing overlap or smoke interaction.
message ExposurePause {
//static wait time in the exposure
uint64 pause_in_us = 1;
}
//Synchronization block for multi laser scanner unit systems.
//Creates dynamic dependencies between multiple lasers exposure orders that shall be enforced by the machine controller in real time.
message SynchronizationBlock {
//The SynchronizationBlock references another vector block to wait on in the same workplane by index.
//Exposure of the laser of SynchronizationBlock (referenced by laser_index) will pause and not continue
//until the block referenced by vector_block_index_to_wait_on has been fully executed.
//Caution must be taken to not create cyclic synchronization dependencies, which would cause a deadlock.
int32 vector_block_index_to_wait_on = 1;
}
//A LineSequence with additional adaption of one or more laser parameters along the vectors.
//Each point consists of (x,y,parameterValue1,parameterValue2...) for 2D.
//The parameter field defines which parameter values are contained inside points_with_paras.
//The count of the parameter field defines how many floats define parameters (and which) after x and y.
//Each parameterValue is the goal value that will be reached at the end of the vector,
//scaling linear along the vector. The goal gets priority and overwrites settings of the
//marking parameter set. All other values are still statically set as defined in the marking parameter set.
message LineSequenceParaAdapt {
repeated float points_with_paras = 1; // len % 3 == 0, len >= 3
repeated AdaptedParameter parameter = 2;
enum AdaptedParameter {
LASER_POWER_IN_W = 0;
LASER_FOCUS_SHIFT_IN_MM = 1;
LASER_PULSE_LENGTH_IN_US = 2;
LASER_PULSE_REPITION_RATE_IN_HZ = 3;
LASER_SPEED_IN_MM_PER_S = 4;
}
}
//A hatch divided into a line sequence with adaption parameter
//this vector block type saves significant amounts of vector block meta data
//compared to writing every hatch as its own LineSequenceParaAdapt block
message HatchesParaAdapt {
repeated LineSequenceParaAdapt hatchAsLinesequence = 1;
}
// Quadratic Bézier segments in 2D.
// Each segment: (x0, y0, cx, cy, x1, y1) => 6 floats/segment.
// Pack N: [x0,y0,cx,cy,x1,y1, x0,y0,cx,cy,x1,y1, ...]
message QuadraticBezierHatches {
repeated float segments = 1; // len % 6 == 0, len >= 6
}
// Cubic Bézier segments in 2D.
// Each segment: (x0, y0, c1x, c1y, c2x, c2y, x1, y1) => 8 floats/segment.
// Pack N: [x0,y0,c1x,c1y,c2x,c2y,x1,y1, ...]
message CubicBezierHatches {
repeated float segments = 1; // len % 8 == 0, len >= 8
}
// Linked Quadratic Bézier spline in 2D (continuous).
// start_control packs tuples (x_i, y_i, cx_i, cy_i) => 4 floats/tuple.
// The end of segment i is the start (x_{i+1},y_{i+1}); the last segment ends at (last_x,last_y).
message QuadraticBezierSpline {
repeated float start_control = 1; // len % 4 == 0, len >= 4
float last_x = 2;
float last_y = 3;
}
// Linked Cubic Bézier spline in 2D (continuous).
// start_control packs tuples (x_i, y_i, c1x_i, c1y_i, c2x_i, c2y_i) => 6 floats/tuple.
message CubicBezierSpline {
repeated float start_control = 1; // len % 6 == 0, len >= 6
float last_x = 2;
float last_y = 3;
}
// Quadratic Bézier segments in 3D.
// Each segment: (x0, y0, z0, cx, cy, cz, x1, y1, z1) => 9 floats/segment.
// Pack N: [x0,y0,z0,cx,cy,cz,x1,y1,z1, x0,y0,z0,cx,cy,cz,x1,y1,z1, ...]
message QuadraticBezierHatches3D {
repeated float segments = 1; // len % 9 == 0, len >= 9
}
// Cubic Bézier segments in 3D.
// Each segment: (x0, y0, z0, c1x, c1y, c1z, c2x, c2y, c2z, x1, y1, z1) => 12 floats/segment.
// Pack N: [x0,y0,z0,c1x,c1y,c1z,c2x,c2y,c2z,x1,y1,z1, ...]
message CubicBezierHatches3D {
repeated float segments = 1; // len % 12 == 0, len >= 12
}
// Linked Quadratic Bézier spline in 3D (continuous).
// start_control packs (x_i, y_i, z_i, cx_i, cy_i, cz_i) => 6 floats/tuple.
message QuadraticBezierSpline3D {
repeated float start_control = 1; // len % 6 == 0, len >= 6
float last_x = 2;
float last_y = 3;
float last_z = 4;
}
// Linked Cubic Bézier spline in 3D (continuous).
// start_control packs (x_i, y_i, z_i, c1x_i, c1y_i, c1z_i, c2x_i, c2y_i, c2z_i) => 9 floats/tuple.
message CubicBezierSpline3D {
repeated float start_control = 1; // len % 9 == 0, len >= 9
float last_x = 2;
float last_y = 3;
float last_z = 4;
}
}
//axis aligned rectangular box in 2D
//defined by the x and y coordinates of the lower left (min) and upper right (max) corner
message AxisAlignedBox2D {
float x_min = 1;
float y_min = 2;
float x_max = 3;
float y_max = 4;
}