GeometryHelper 13.5.0

dotnet add package GeometryHelper --version 13.5.0
                    
NuGet\Install-Package GeometryHelper -Version 13.5.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="13.5.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GeometryHelper" Version="13.5.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 13.5.0
                    
#r "nuget: GeometryHelper, 13.5.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@13.5.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=13.5.0
                    
Install as a Cake Addin
#tool nuget:?package=GeometryHelper&version=13.5.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
GeometryHelper.Export shapes written as OBJ, SVG and WKT: ObjWriter, SvgWriter, Wkt
GeometryHelper.Dxf DXF files read into shapes (DxfReader, DxfDocument, DxfShape), shapes written (DxfWriter), and a drawing edited with AutoCAD's classes and members, Dxf in front: DxfDatabase, its tables and records, DxfBlockTableRecord, DxfEntity and every entity class

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; reading, writing and editing DXF files, the editing with AutoCAD's classes and members; a drawing edited step by step and the points to check in AutoCAD
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.5.0 0 11/3/2026
13.4.0 110 11/2/2026
13.3.0 116 11/2/2026
13.2.0 109 11/1/2026
13.1.0 150 10/29/2026
13.0.0 168 10/28/2026
12.3.0 261 10/23/2026
12.2.0 268 10/14/2026
12.1.0 244 10/12/2026
12.0.0 259 10/7/2026
11.2.0 242 10/6/2026
11.1.0 257 10/6/2026
11.0.1 261 10/5/2026
11.0.0 277 10/5/2026
10.0.0 271 10/3/2026
9.0.2 271 10/1/2026
9.0.1 258 10/1/2026
9.0.0 266 10/1/2026
8.0.0 264 9/30/2026
7.0.0 251 9/29/2026
Loading failed

NEW IN 13.5.0

     A minor release: one public member added, DxfDatabase.FontSearchPath, and none removed or renamed. Most of it is
     DXF parity with AutoCAD 2021; the results callers will see change are listed under CHANGED. Three fixes are to the
     booleans of solids.

     NEW, DXF
     - DxfDatabase.FontSearchPath: folders, separated by semicolons and searched in their order, where the SHX and
       TrueType fonts (.ttf, .ttc, .otf of glyf outlines) of the drawing's text styles are read from, so that its words
       are measured as AutoCAD 2021 measures them: TEXT, ATTRIB and ATTDEF places and GeometricExtents, the ActualWidth
       and ActualHeight of a one-line MTEXT, multileaders met on the right, attribute definitions flipped and leaders'
       hooks exploded. Against AutoCAD 2021, 21 596 of 21 600 TEXTs of its own SHX fonts and 30 840 of 31 200 TEXTs of
       the TrueType fonts of Windows come out as it gives them. The results follow the fonts given. Empty, as every
       drawing is opened and made, nothing is read and nothing changes.

     FIXED, solids
     - A common part of two solids, and a difference, leave out an opening of a body whose material the result does not
       keep where it shares no space with the other body. A spiral girder less a spiral ramp holding a spiral tube as
       an opening came apart into 640 222 cells in 202 seconds on .NET 10 and 704 on .NET Framework 4.8 and was not
       worked out; it is cut into 18 345 in 1.6 and 2.7 seconds and holds what slicing gives. The openings of a union's
       bodies, and of the body a difference takes material from, are cut in as before.
     - A union, a common part and a difference of solids far out, and each cut of TrySubtractAll, are worked out near
       the origin: bodies reaching more than 2^20 out and more than 1 024 times the size of their box are moved by
       whole coordinates, worked out and moved back, a corner kept coming back as it was given, to the bit. Of 1 196
       such booleans ten million to a thousand million out, wrong at a thousandth 241 -> 14, at a hundredth 413 -> 15
       and not worked out 134 -> 49; 3 of 1 200 with a face exactly the tolerance off a wall's plane came out otherwise
       by up to 1.9. Within a million of the origin nothing changed, to the bit. Far out, booleans at a thousandth and
       a hundredth take 17 to 26 per cent longer, at a millionth a third less. GetVolume, TryCutOpenings, Section and
       Mesh3.ToCells of bodies far out are not moved yet.
     - A union, a common part or a difference that is not worked out is worked out once more where either body closes
       within the tolerance and not at the rounding of its coordinates, as a body cracked a hair wide does: its corners
       within the tolerance of each other made one and its faces lying in one plane merged. Of 45 000 booleans of a
       cracked U and a box at a thousandth, a hundredth and 0.05, 1 619 differences, 2 106 common parts and 2 063
       unions not worked out are right now, and none was made wrong. Every boolean worked out as the bodies came is as
       it was, to the bit, and takes as long as it did; one worked out again takes 1.4 to 2.5 milliseconds longer for
       such a U and box under .NET Framework 4.8.

     CHANGED, DXF: results callers will see change
     - Words given to a DxfMLeader put the base point of its content where a leader from the left would meet them, the
       gap short of the place given and as far below as the left is met, where the library put it at the words. Words
       turned in code turn the multileader's plane where no leader is landed yet; words mirrored are moved as AutoCAD
       2021 moves them, kept upright where FontSearchPath measures them; words of another text style are moved to where
       the multileader's font meets them, where FontSearchPath measures both.
     - new DxfMLeader() is of words: ContentType is MTextContent, where it was NoneContent. A new multileader writes
       what AutoCAD 2021 writes for one: ExtendLeaderToText true in a drawing of R2013 or later, a leader line added of
       no colour of its own, and TextColor the colour of the words given, BYLAYER for words made in code, where it was
       BYBLOCK.
     - DxfMLeader.RemoveFirstVertex and RemoveLastVertex take a leader line down to one vertex, where the library kept
       two; RemoveLastVertex refuses the last vertex of a leader of two lines or more (InvalidOperationException), as
       AutoCAD 2021 refuses it.
     - HandOverTo keeping the extension dictionary refuses the contexts of another kind of entity (ArgumentException)
       before anything is written, where it wrote a drawing AutoCAD 2021 crashed reading; not keeping it, the new
       entity writes the contexts of the copy it is handed.
     - HasContext answers false for an object that is never annotative, as a LINE or a layer, whatever context records
       it holds. DxfObjectContextCollection.AddContext names a scale's entry *A1, *A2 and on, as AutoCAD 2021 does,
       where the library gave A0, A1 and on.
     - DxfTable writes the reals it gives with their point (141 9.0, where it wrote 141 9), keeps each row's looks with
       the row while the drawing is open, as AutoCAD 2021 keeps them in its ROWTABLEFORMAT, and RemoveAllOverrides
       keeps the looks of the title's or the header's kind in a row of that kind out of its place.
     - Normal set on a TEXT, ATTDEF, ATTRIB, INSERT or SOLID keeps its points, turn and contexts in its plane, as
       AutoCAD 2021 does, where the library kept them where they stood in the world; DxfMText.Normal makes the MTEXT
       read along the new plane's x axis.
     - An annotative copy added to another drawing by AppendEntity, WblockCloneObjects or Insert keeps its contexts and
       those of its ATTRIBs, each on that drawing's scale of its scale's name where the two give the same scale. A
       hundred such copies of a drawing of 35 entities take 185 ms where they took 165 on .NET Framework 4.8.
     - With FontSearchPath given, a TEXT, ATTRIB or ATTDEF justified other than left on its baseline is put about its
       second point when it is edited or added, and a locked attribute definition is flipped, where it was refused.

     FIXED, DXF
     - A TransformBy that scales a multileader marks its scale as its own (bit 24); a multileader's leader lines of
       BYBLOCK, its 176, 294 and 295 are read and written as AutoCAD 2021 reads and writes them.
     - DxfTable.ClearTableStyleOverrides of 0 on a table of 400 rows takes 9 ms on .NET Framework 4.8, where 13.4.0
       took 22.
     - An attribute of several lines keeps its width factor; HandOverTo leaves the new entity its own extended data
       where the old one has none.

     Details in CHANGELOG.md.

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