GeometryHelper 12.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package GeometryHelper --version 12.3.0
                    
NuGet\Install-Package GeometryHelper -Version 12.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GeometryHelper" Version="12.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GeometryHelper" Version="12.3.0" />
                    
Directory.Packages.props
<PackageReference Include="GeometryHelper" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GeometryHelper --version 12.3.0
                    
#r "nuget: GeometryHelper, 12.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GeometryHelper@12.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GeometryHelper&version=12.3.0
                    
Install as a Cake Addin
#tool nuget:?package=GeometryHelper&version=12.3.0
                    
Install as a Cake Tool

GeometryHelper

NuGet Version License: MIT

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .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.1.0 69 10/29/2026
13.0.0 95 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 257 10/7/2026
11.2.0 239 10/6/2026
11.1.0 254 10/6/2026
11.0.1 258 10/5/2026
11.0.0 273 10/5/2026
10.0.0 268 10/3/2026
9.0.2 267 10/1/2026
9.0.1 256 10/1/2026
9.0.0 263 10/1/2026
8.0.0 261 9/30/2026
7.0.0 246 9/29/2026
6.3.0 252 9/29/2026
6.2.0 252 9/29/2026
6.1.0 252 9/28/2026
6.0.0 255 9/28/2026
Loading failed

NEW IN 12.3.0

     NEW, reading DXF
     - DxfReader reads an ASCII DXF of R12 to R2018 into the library's shapes: Read(path), Read(stream) and
       Parse(text) give a DxfDocument of the Entities in file order, the Layers, the Units, the Version, what was
       Skipped by type and the Warnings. Lines, arcs, circles, ellipses, polylines with their bulges, splines,
       rays, xlines, points, 3D faces, solids and meshes are read, in 3D by default or, with
       DxfReadOptions.PlanAs2D, as the 2D shapes where they lie on the floor; ToMillimetres scales by INSUNITS.
     - Each DxfEntity keeps its Layer, Colour, TrueColour, Linetype, Lineweight, Thickness, Handle and, with
       KeepGroups, every group of it, extended data among them. DxfWriter.Add(DxfEntity) writes one back with
       its look, and a public constructor makes one in code.
     - Blocks and the INSERTs and MINSERTs that place them are read: each shape placed exactly by turns, even
       and uneven scalings and mirrors (a circle under an uneven scaling is the ellipse it becomes, an arc the
       exact spline), layer 0 and BYBLOCK taken from the INSERT, BlockPath and InsertHandles naming where it
       came from, DxfDocument.Blocks holding the blocks in their own coordinates. MaxPlacedEntities (2 000 000
       by default) bounds a file whose blocks multiply: 18 KB nesting 100 000 000 lines is read in 1.4 s.
     - Checked against ezdxf: every placed point within 1E-9 of where ezdxf puts it.

     NEW, shapes
     - GeoSpline2 and GeoSpline3, the NURBS curve in the plane and in space, with the five queries about every
       other shape from either side, transformations and flattening by a chord tolerance; written by DxfWriter
       as a SPLINE and by SvgWriter, and read from AutoCAD and IFC.
     - GeoXLine2 and GeoXLine3, the infinite line, and GeoSphere3, the solid ball, each with the queries of
       their dimension; the ball is written by ObjWriter, DxfWriter and Wkt as its triangles and read from IFC.
     - DxfWriter writes arcs and circles in space as an ARC and a CIRCLE in their own plane, not as chords;
       ObjWriter, SvgWriter and Wkt take the shapes they left out.

     FIXED, booleans and bodies
     - A union, a common part and a difference of two closed bodies give a body closed as Validate reads it,
       or say NotWorkedOut; welds keep faces on their planes; voids, chips and slabs thicker than the tolerance
       are cut; an opening the tolerance off a face is cut in closed; a beam less a bent bar no longer runs for
       minutes.
     - ConvexHull3 and ConvexHull2 hold every point within the tolerance; GeoObb3.Fit keeps the least box;
       Clash3.Find gives the same answer whichever part is listed first.

     FIXED, transformations and round shapes
     - Circles, arcs, edges, balls and rectangles moved by a map that is not a turn, shift or even scaling are
       refused where the moved shape would land off its true image by more than the point tolerance, and moved
       exactly where it would not; a plane is carried under even scalings of 1E5 and more.
     - Two circles within the point tolerance of each other everywhere are one circle; arcs a hair short of a
       whole turn, nearly flat arcs and edges with short chords are read and moved without throwing.

     FIXED, queries
     - Segments, rays, lines and chains against boxes, triangles, polygons and faces give a touch point where
       they touch alone, and no point where CollidesWith is false; arcs against them likewise.
     - Distances in the plane and in space are nought only where shapes truly meet, are exact near arcs, ellipse
       and face rims, and are the same whichever is asked first.
     - Curved offsets of loops that cross themselves or close slots give the right loops; point tests of loops
       of arcs answer right; flattening keeps the chord tolerance at any sweep.
     - ObjWriter, Wkt and DxfWriter print the same doubles on .NET Framework as on .NET.

     CHANGED
     - A union of two bodies lying face to face within the tolerance and apart, which came out open, now says
       NotWorkedOut; GeoObb3.IsDegenerate and Validate's NoVolume read against the point tolerance.
     - Arcs and edges moved by an equal-length skew are judged by where they land (InvalidOperationException
       when off); triangles with no area to the tolerance have no plane in their queries.
     - Rays and lines level over a flat shape get their crossing only within the vector tolerance; splines
       lying along each other are measured as they are in space.
     - Validate, IsClosed, SplitShells, hulls and face triangulation no longer slow with the square of their
       size; results of booleans and volumes move towards the exact ones, by up to the rounding.

     Nothing public is removed: a reflection diff against 12.2.0 finds 0 members removed and 1 959 added.

     Details in CHANGELOG.md.

     Earlier releases: https://github.com/nguyenthanguth/GeometryHelper/blob/main/CHANGELOG.md