GeometryHelper 12.2.0
See the version list below for details.
dotnet add package GeometryHelper --version 12.2.0
NuGet\Install-Package GeometryHelper -Version 12.2.0
<PackageReference Include="GeometryHelper" Version="12.2.0" />
<PackageVersion Include="GeometryHelper" Version="12.2.0" />
<PackageReference Include="GeometryHelper" />
paket add GeometryHelper --version 12.2.0
#r "nuget: GeometryHelper, 12.2.0"
#:package GeometryHelper@12.2.0
#addin nuget:?package=GeometryHelper&version=12.2.0
#tool nuget:?package=GeometryHelper&version=12.2.0
GeometryHelper
Geometry for engineering drawings and models, in two dimensions and in three, with the label placement
that runs on the 2D half. Written in C# and targeting netstandard2.0, so it loads into the
.NET Framework hosts that Tekla Structures and AutoCAD provide as well as into modern .NET.
Every comparison that floating point error can affect takes a Tolerance, because coordinates that come
out of a BIM model are never exact.
Use the default tolerance. The overloads without a tolerance read Tolerance.Global, which starts as
Tolerance.Default: a thousandth of a millimetre for points and for flatness, in a model in millimetres. That is as
exact as the corners of a modelled part are: two parts a hundredth apart are apart, and a thin overlap holds what it
holds. A finer tolerance cuts as slivers the few ten-thousandths a modeller's rounding leaves faces off flat and parts
apart, many times slower; a coarser one, passed to the call that needs it, takes what touches within it for touching.
Never new Tolerance(): made so, every threshold is 0. For parts drawn against each other, as a model's are, cut with a
SolidBooleanOptions whose Contact takes faces a hundredth apart for touching, and take a part's net body with
TrySubtractAll: within a thousandth alone, a part keeps a skin of itself where a cutter's face stood a few
thousandths inside it. A body read open, by copies of an edge a hair apart or by a face left out, is closed by
TryClose within a gap of its own, a hole filled only where asked, with a report of what it changed or why it would not.
Installation
dotnet add package GeometryHelper
Quick start
using GeometryHelper; // Tolerance, Angle, OffsetOptions
using GeometryHelper.Enums; // LineEnd, OffsetJoin, PointLocation
using GeometryHelper.Geometry; // every Geo type, 2D and 3D
using GeometryHelper.Core; // every operation
// In the plane: grow a slab, then cut an opening out of it.
var slab = new GeoPolygon2(new GeoPoint2(0, 0), new GeoPoint2(4000, 0),
new GeoPoint2(4000, 2000), new GeoPoint2(0, 2000));
var duct = new GeoPolygon2(new GeoPoint2(1000, 500), new GeoPoint2(1400, 500),
new GeoPoint2(1400, 900), new GeoPoint2(1000, 900));
GeoPolygon2 grown = slab.Offset(50.0)[0]; // 4100 x 2100
GeoFace2 pierced = Boolean2.Subtract(grown, duct)[0]; // one face, one hole
// In space: a beam trimmed where it runs into a wall.
var beam = new GeoLine3(new GeoPoint3(0, 0, 0), new GeoPoint3(3000, 0, 0));
var wall = new GeoPlane3(new GeoPoint3(2500, 0, 0), GeoVector3.XAxis);
beam.TryTrimTo(wall, LineEnd.End, out GeoLine3 cut); // (0,0,0) -> (2500,0,0)
What is inside
| Namespace | Holds |
|---|---|
GeometryHelper |
Tolerance, Angle, OffsetOptions, GeometryHelperLog, MassProperties3, MeasureComparison3 |
GeometryHelper.Enums |
PointLocation, PlaneSide, LineSide, LineEnd, LineExtension, OffsetJoin, VolumeMethod, AreaMethod |
GeometryHelper.Geometry |
30 immutable shapes: GeoPoint2 … GeoFace2 in the plane, GeoPoint3 … GeoSolid3 in space, arcs and the chains that carry them, and a transformation and a local coordinate system for each dimension |
GeometryHelper.Core |
35 operation classes, each dimension mirroring the other: Boolean2/Boolean3, Offset2/Offset3, Distance2/Distance3, … plus Arc2, Corner2 for chamfering and rounding, PlanarMap, which carries flat shapes between the two, and Measure3, a body's volume, mass and area read more than one way |
GeometryHelper.Spatial |
GeoBvh2 and GeoBvh3, the bounding volume hierarchies for large chains and meshes |
GeometryHelper.Extension |
turning raw point lists into geometry |
GeometryHelper.Arranging |
label placement: Arranger, ArrangeItem, ArrangeResult, ArrangeOptions, one greedy placement |
GeometryHelper.Meshing |
closed shapes of the plane and flat shapes of space broken into triangles, grids, strips or convex pieces, and bodies cut into the cells of a grid: GeoMesh2, Mesh2, GeoMesh3, Mesh3, MeshKind, MeshOptions, MeshPlacement3, GeoCellGrid3, GeoCell3, CellOptions3, CellAxis, GridAlignment |
GeometryHelper.Packing |
boxes onto sheets of paper: SheetPacker, Sheet, PackOptions, PackResult |
Every operation is reachable both ways: the static form names the larger shape first, and the instance form sits on whichever of the two reads better where you are calling from.
Because both dimensions are one assembly, a flat shape in space can be laid out in its own plane, worked on with the whole 2D half of the library, and put back:
GeoCoordinateSystem3 frame = plate.GetFrame();
GeoFace2 flat = plate.ProjectToFace2(frame);
GeoFace3 back = flat.Subtract(openings)[0].ToFace3(frame);
Guides
The whole of it, searchable, with every type and member: https://nguyenthanguth.github.io/GeometryHelper/.
| Guide | Covers |
|---|---|
| Shared types | Tolerance, Angle, the enumerations, OffsetOptions, GeometryHelperLog |
| Geometry in the plane | points to polygons and faces; extending, trimming, offsetting, combining regions |
| Meshing the plane | triangles, grids of panels or tiles with joints and alignment, strips and convex pieces, edge to edge |
| Geometry in space | points to solids; splitting, boolean bodies, meshes, local frames |
| Meshing in space | flat shapes of space in panels, tiles, strips and triangles; bodies and boxes cut into blocks, bays and lifts; the cases, drawn and checked |
| Label placement | labels placed greedily, clear of each other and of blocked regions |
| Packing boxes onto sheets | drawing views onto A0 to A4 sheets or sheets of a size of their own, a new sheet when one is full |
Coverage
dotnet test tests/GeometryHelper.UnitTest --collect:"XPlat Code Coverage"
writes a Cobertura file under TestResults. Only this library is counted.
Build and Test
dotnet build src/GeometryHelper/GeometryHelper.csproj
dotnet test tests/GeometryHelper.UnitTest/GeometryHelper.UnitTest.csproj
Warnings are errors in CI, and every public member is documented, so a missing XML comment or a stale
cref fails the build rather than landing quietly. Every example printed in the guides is also a test.
Licence
MIT. The clipping engine of Clipper2, by Angus Johnson, which is compiled into this package and resolves regions in the plane, is under the Boost Software License 1.0; THIRD-PARTY-NOTICES.md in the package holds its notice.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages (5)
Showing the top 5 NuGet packages that depend on GeometryHelper:
| Package | Downloads |
|---|---|
|
GeometryHelper.IfcConvert
Converts geometry between IFC (via xBIM) and GeometryHelper: points, vectors, matrices, faces, and solids. |
|
|
GeometryHelper.CadConvert
Converts geometry between AutoCAD and GeometryHelper: points, vectors, lines, polylines, polygons, circles, and bounding boxes. |
|
|
GeometryHelper.TeklaConvert.2026
Converts geometry between Tekla Structures 2026 and GeometryHelper: points, vectors, segments, planes, coordinate systems, bounding boxes, transformation matrices, and the faces and loops of a Tekla solid. Also reads the objects of IFC reference models into solids placed where Tekla shows them, through GeometryHelper.IfcConvert. Built for Tekla Structures 2026; install the package whose year matches your Tekla. |
|
|
GeometryHelper.TeklaConvert.2020
Converts geometry between Tekla Structures 2020 and GeometryHelper: points, vectors, segments, planes, coordinate systems, bounding boxes, transformation matrices, and the faces and loops of a Tekla solid. Also reads the objects of IFC reference models into solids placed where Tekla shows them, through GeometryHelper.IfcConvert. Built for Tekla Structures 2020; install the package whose year matches your Tekla. |
|
|
GeometryHelper.TeklaConvert.2025
Converts geometry between Tekla Structures 2025 and GeometryHelper: points, vectors, segments, planes, coordinate systems, bounding boxes, transformation matrices, and the faces and loops of a Tekla solid. Also reads the objects of IFC reference models into solids placed where Tekla shows them, through GeometryHelper.IfcConvert. Built for Tekla Structures 2025; install the package whose year matches your Tekla. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 13.2.0 | 8 | 11/1/2026 |
| 13.1.0 | 78 | 10/29/2026 |
| 13.0.0 | 101 | 10/28/2026 |
| 12.3.0 | 260 | 10/23/2026 |
| 12.2.0 | 263 | 10/14/2026 |
| 12.1.0 | 238 | 10/12/2026 |
| 12.0.0 | 258 | 10/7/2026 |
| 11.2.0 | 240 | 10/6/2026 |
| 11.1.0 | 255 | 10/6/2026 |
| 11.0.1 | 259 | 10/5/2026 |
| 11.0.0 | 274 | 10/5/2026 |
| 10.0.0 | 269 | 10/3/2026 |
| 9.0.2 | 268 | 10/1/2026 |
| 9.0.1 | 257 | 10/1/2026 |
| 9.0.0 | 264 | 10/1/2026 |
| 8.0.0 | 262 | 9/30/2026 |
| 7.0.0 | 249 | 9/29/2026 |
| 6.3.0 | 253 | 9/29/2026 |
| 6.2.0 | 253 | 9/29/2026 |
| 6.1.0 | 253 | 9/28/2026 |
NEW IN 12.2.0
NEW, the ray in the plane
- GeoRay2, an origin and a direction it runs along for ever, the counterpart of GeoRay3. It is asked what a
segment is asked, against every shape in the plane, and every shape that takes a GeoLine2 takes a GeoRay2 back.
PlanarMap.ProjectToRay2/ToRay3, GeoBvh2.GetIntersections and GeoTransform2 take it too.
FIXED, collisions in the plane read by the tolerance everywhere
- Two shapes in the plane collide exactly where they come within the point tolerance of each other: they cross,
one holds the other, or their boundaries pass within EqualPoint. Segments and rays against open curves, curved
loops, polygons, rectangles, triangles and faces, and every pair of curves, now read so; distances still give
the gap, and are nought only where the shapes truly cross or overlap.
- Two segments no longer collide, nor measure nought, where a crossing lies up to the tolerance past their ends:
corners 0.00156 apart at 1E-3 are apart. TryIntersectWith still places such a crossing.
- A segment inside a circle's tangent band gets its true crossings; a curved loop near a chord of a bowed edge is
read by its true boundary; nearly flat arcs keep their crossings whichever is asked first; tolerance forms read
the tolerance passed all the way down.
- Label placement no longer puts a label within the tolerance of a line or region kept clear.
FIXED, fillets and chamfers
- A fillet is the arc on the inside of the corner and never runs past it: no more cusps where the radius was
small against the tolerance. A corner that does not turn is left alone.
- A fillet or chamfer taking an edge whole, give or take the tolerance, meets its neighbour instead of throwing;
a chain's end points never move. Corner3, and the Tekla bars and ties built through it, no longer throw on tiny
bends.
- A curved chain that drops a repeated vertex keeps the bulge of the edge that still has a length.
FIXED, offsets
- Curved offsets keep what stands exactly the distance from the shape: folds are cut where they come nearer,
closing corners are no longer bridged, an arc whose radius runs out is gone round at its two ends, holes are
kept however their pieces meet, and the answer no longer depends on the start vertex or direction.
- Curved offsets join corners as the straight ones do: a chamfer at the distance, a miter squared off at the
limit. They no longer throw at a coarse tolerance.
- A straight polyline's offset is its band's edge with no fragments past a sharp corner or lying on the
polyline, and its pieces are ordered in near-linear time: 10 000 vertices in 0.57 s where it took 36 s.
- A flat chain in space that encloses no area has its plane; round joins keep within OffsetOptions.ArcTolerance.
CHANGED
- Offsetting in a plane in space no longer slows with the square of its edges where neighbouring points are
counted: 100 000 vertices in 1.0 s where it took 15.9 s. Results are unchanged.
- Reading a near miss as a collision measures a distance where only a crossing was looked for: such pairs, and
curved offsets of shapes with a few edges, take up to about twice as long; curved offsets of large shapes are
many times faster.
Details in CHANGELOG.md.
Earlier releases: https://github.com/nguyenthanguth/GeometryHelper/blob/main/CHANGELOG.md