Skip to content

Commit 07f02b1

Browse files
committed
Step export. U3D and PRC import (these are from 3D PDFs). Fixed error in duplicating solids for SolidAssembly.
1 parent 006b96b commit 07f02b1

11 files changed

Lines changed: 6897 additions & 6 deletions

File tree

‎STEPImportExport/FacetedStepWriter.cs‎

Lines changed: 835 additions & 0 deletions
Large diffs are not rendered by default.

‎STEPImportExport/README.md‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
11
# TVGL.STEPImportExport
22

3-
TVGL.STEPImportExport provides STEP (`.step`, `.stp`) file import capabilities for TVGL (Tessellation and Voxelization Geometry Library).
3+
TVGL.STEPImportExport provides STEP (`.step`, `.stp`) import and export capabilities for TVGL (Tessellation and Voxelization Geometry Library).
44

55
## Features
66
- **Accurate B-Rep Meshing**: Discretizes Boundary Representation solids into high-quality watertight triangle meshes powered by Open CASCADE Technology (OCCT).
77
- **Analytic Primitive Recovery**: Automatically extracts and maps analytic geometry surfaces (`Plane`, `Cylinder`, `Cone`, `Sphere`, `Torus`) with their exact mathematical parameters.
88
- **Full Doubly Linked Primitives**: Constituent `TriangleFace` objects and `PrimitiveSurface` objects are fully doubly linked (`face.BelongsToPrimitive` and `primitive.Faces`).
99
- **Freeform Surface Support**: Freeform surfaces (NURBS, B-Spline, Bezier, Offset) are represented as `UnknownRegion` primitives with their descriptive surface type preserved.
1010
- **Multi-Body & Assembly Support**: Reconstructs multi-body STEP files into individual `TessellatedSolid`s and `SolidAssembly` hierarchies.
11+
- **Hybrid Export**: `STEP.Save(solid, filePath)` and `STEP.SaveHybrid(solid, filePath)` preserve reliable TVGL planes, circularly bounded cylinders and cones, closed spheres, and closed ring tori as analytic STEP surfaces. Other regions use triangle faces.
12+
- **Faceted Export**: `STEP.SaveFaceted(solid, filePath)` writes every triangle as a bounded planar STEP face. Watertight meshes become faceted B-reps; open meshes become surface models.
13+
- **Assembly Export**: `STEP.Save(assembly, filePath)` writes transformed assembly instances as distinct STEP bodies.
14+
- **Stream Symmetry**: STEP solids and assemblies can be opened from or saved to caller-owned streams as well as files.
15+
- **Unit Preservation**: Export converts supported TVGL units to the millimeter representation declared in the STEP context, including analytic dimensions.
16+
17+
## Export fidelity
18+
19+
Faceted export preserves the TVGL triangle geometry and winding. It does not
20+
recreate analytic surfaces from primitive metadata. Hybrid export reconstructs
21+
the validated analytic cases above. Trimmed spheres and tori, cylinders or cones
22+
with non-circular trim curves, spindle tori, and NURBS regions remain faceted.
23+
Closed spheres are written as eight exact spherical octants and closed tori as
24+
sixteen exact analytic patches so their periodic topology is explicit. The
25+
writer uses a temporary file and replaces the requested destination only after
26+
the STEP write succeeds.
1127

‎STEPImportExport/STEP.cs‎

Lines changed: 778 additions & 0 deletions
Large diffs are not rendered by default.

‎STEPImportExport/STEPReconstructor.cs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ private static void ReconstructPrimitives(
102102
var faceSlice = new List<TriangleFace>(end - start);
103103
for (int t = start; t < end; t++)
104104
{
105-
faceSlice.Add(solid.Faces[t]);
105+
var face = solid.Faces[t];
106+
// Integrity repair can invalidate negligible triangles
107+
// created by OCCT tessellation. Do not pass those dead
108+
// faces into analytic primitive constructors.
109+
if (face?.A != null && face.B != null && face.C != null)
110+
faceSlice.Add(face);
106111
}
107112

108113
if (faceSlice.Count == 0)

‎TessellationAndVoxelizationGeometryLibrary/Constants.cs‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,22 @@ public enum FileType
380380
/// </summary>
381381
TVGLz,
382382

383+
/// <summary>
384+
/// Universal 3D, including the Right Hemisphere Adobe mesh extension.
385+
/// </summary>
386+
U3D = 19,
387+
388+
/// <summary>
389+
/// PRC (ISO 14739-1), the 3D format embedded in 3D PDFs. Its display tessellation and
390+
/// product structure are read.
391+
/// </summary>
392+
PRC = 20,
393+
383394
// now the 2D formats
384395
/// <summary>
385396
/// Simply a set of 2D coordinates, no additional information
386397
/// </summary>
387-
CSV,
398+
CSV = 13,
388399

389400
/// <summary>
390401
/// S Vector Graphics

‎TessellationAndVoxelizationGeometryLibrary/InputOutput Operations/IOFunctions.cs‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ private static bool Open<T>(Stream s, string filename, out T solid, TessellatedS
145145
case FileType.OBJ:
146146
solidInner = GetMostSignificantSolid(OBJFileData.OpenSolids(s, filename, tsBuildOptions), out _);
147147
break;
148+
case FileType.U3D:
149+
solidInner = GetMostSignificantSolid(U3DFileData.OpenSolids(s, filename, tsBuildOptions), out _);
150+
break;
151+
case FileType.PRC:
152+
solidInner = GetMostSignificantSolid(PRCFileData.OpenSolidAssembly(s, filename, tsBuildOptions), out _);
153+
break;
148154
case FileType.OFF:
149155
solidInner = OFFFileData.OpenSolid(s, filename, tsBuildOptions);
150156
break;
@@ -310,6 +316,12 @@ public static bool Open(Stream s, string filename, out TessellatedSolid[] tessel
310316
case FileType.OBJ:
311317
tessellatedSolids = OBJFileData.OpenSolids(s, filename, tsBuildOptions);
312318
break;
319+
case FileType.U3D:
320+
tessellatedSolids = U3DFileData.OpenSolids(s, filename, tsBuildOptions);
321+
break;
322+
case FileType.PRC:
323+
tessellatedSolids = PRCFileData.OpenSolids(s, filename, tsBuildOptions);
324+
break;
313325
case FileType.OFF:
314326
case FileType.PLY_ASCII:
315327
case FileType.PLY_Binary:
@@ -409,6 +421,12 @@ public static bool Open(Stream s, string filename, out SolidAssembly solidAssemb
409421
case FileType.OBJ:
410422
solidAssembly = new SolidAssembly(OBJFileData.OpenSolids(s, filename, tsBuildOptions));
411423
break;
424+
case FileType.U3D:
425+
solidAssembly = new SolidAssembly(U3DFileData.OpenSolids(s, filename, tsBuildOptions));
426+
break;
427+
case FileType.PRC:
428+
solidAssembly = PRCFileData.OpenSolidAssembly(s, filename, tsBuildOptions);
429+
break;
412430

413431
case FileType.OFF:
414432
case FileType.PLY_ASCII:
@@ -694,6 +712,8 @@ public static FileType GetFileTypeFromExtension(string extension)
694712
case "model": return FileType.Model3MF;
695713
case "amf": return FileType.AMF;
696714
case "obj": return FileType.OBJ;
715+
case "u3d": return FileType.U3D;
716+
case "prc": return FileType.PRC;
697717
case "off": return FileType.OFF;
698718
case "ply": return FileType.PLY_ASCII;
699719
case "shell": return FileType.SHELL;
@@ -724,6 +744,8 @@ public static string GetExtensionFromFileType(FileType fileType)
724744
case FileType.Model3MF: return "model";
725745
case FileType.AMF: return "amf";
726746
case FileType.OBJ: return "obj";
747+
case FileType.U3D: return "u3d";
748+
case FileType.PRC: return "prc";
727749
case FileType.OFF: return "off";
728750
case FileType.PLY_ASCII:
729751
case FileType.PLY_Binary: return "ply";
@@ -1662,4 +1684,4 @@ protected static string TvglDateMarkText
16621684
#endregion Save/Write
16631685
#endregion
16641686
}
1665-
}
1687+
}

0 commit comments

Comments
 (0)