GeomPP 0.14.0
See the version list below for details.
dotnet add package GeomPP --version 0.14.0
NuGet\Install-Package GeomPP -Version 0.14.0
<PackageReference Include="GeomPP" Version="0.14.0" />
<PackageVersion Include="GeomPP" Version="0.14.0" />
<PackageReference Include="GeomPP" />
paket add GeomPP --version 0.14.0
#r "nuget: GeomPP, 0.14.0"
#:package GeomPP@0.14.0
#addin nuget:?package=GeomPP&version=0.14.0
#tool nuget:?package=GeomPP&version=0.14.0
GeomPP — C# Bindings
C++/CLI bindings for geompp, targeting Windows x64.
Available on NuGet as GeomPP.
Supports .NET 8, .NET 9, .NET 10, and .NET Framework 4.8.
Changelog — full release notes for every version.
Install
dotnet add package GeomPP
or in your .csproj:
<PackageReference Include="GeomPP" Version="0.8.0" />
| Platform | .Net | .Net Framework |
|---|---|---|
| Windows x64 | 8 · 9 · 10 | 4.8 |
Supported types
| Type | 2D | 3D |
|---|---|---|
Point |
✓ | ✓ |
Vector |
✓ | ✓ |
Line |
✓ | ✓ |
Ray |
✓ | ✓ |
LineSegment |
✓ | ✓ |
Polyline |
✓ | ✓ |
Triangle |
✓ | ✓ |
Polygon |
✓ | ✓ |
BBox |
✓ | ✓ |
BBall |
✓ | ✓ |
BRect2D |
✓ | — |
BPrism3D |
— | ✓ |
Plane |
— | ✓ |
View2D |
✓ | — |
GeometryCollection |
✓ | ✓ |
WktParser |
✓ | ✓ |
All types expose ToWkt(), FromWkt(), ToFile(), FromFile(), AlmostEquals(), and the same
operators available in the C++ library.
Decimal precision for all <=> or AlmostEquals() or compare(a,b, epsilon) functions are managed by a global, thread local variable. It is best to set it up at the beginning of your program (in your main). The defalt is 3 decimals, or 0.001 tolorance.
G.Precision.DecimalPrecision = 6; // default: G.Precision.DP_THREE
Intersection methods return object (null when there is no intersection); use C# pattern matching
to extract the result type:
var result = line.Intersection(segment);
if (result is G.Point2D p) { /* point intersection */ }
if (result is G.LineSegment2D s) { /* overlap */ }
Platform note
GeomPP is built with C++/CLI and is Windows x64 only. It will not run on Linux, macOS, or 32-bit processes.
How to use it
You can look at the test suite to see detailed usage.
A quick list of code examples per topic is provided here.
👉 View Full Code Examples on Github
Build on Windows x64 manually
Build the C# DLL
# from the main directory, geompp
# .NET 8 (LTS, supported until Nov 2026)
msbuild geompp_csharp\GeomPP_Net8.vcxproj /p:Platform=x64 /p:GeomppBuildRoot="$PWD\build_win" [/p:Configuration=Release]
# .NET 9 (STS)
msbuild geompp_csharp\GeomPP_Net9.vcxproj /p:Platform=x64 /p:GeomppBuildRoot="$PWD\build_win" [/p:Configuration=Release]
# .NET 10 (LTS)
msbuild geompp_csharp\GeomPP.vcxproj /p:Platform=x64 /p:GeomppBuildRoot="$PWD\build_win" [/p:Configuration=Release]
# .NET Framework 4.8
msbuild geompp_csharp\GeomPP_Net48.vcxproj /p:Platform=x64 /p:GeomppBuildRoot="$PWD\build_win" [/p:Configuration=Release]
# run smoke tests, after build from the main directory geompp
dotnet test geompp_csharp\tests\GeomPPTests.csproj [-p:GeomPPConfiguration=Release]
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-windows7.0 is compatible. net9.0-windows was computed. net9.0-windows7.0 is compatible. net10.0-windows was computed. net10.0-windows7.0 is compatible. |
| .NET Framework | net48 is compatible. net481 was computed. |
-
.NETFramework 4.8
- No dependencies.
-
net10.0-windows7.0
- No dependencies.
-
net8.0-windows7.0
- No dependencies.
-
net9.0-windows7.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.17.3 | 100 | 8/15/2026 |
| 0.17.2 | 92 | 8/14/2026 |
| 0.16.2 | 88 | 8/6/2026 |
| 0.15.1 | 120 | 7/24/2026 |
| 0.14.0 | 105 | 7/21/2026 |
| 0.13.0 | 118 | 7/9/2026 |
| 0.12.0 | 105 | 7/8/2026 |
| 0.11.0 | 111 | 7/4/2026 |
| 0.10.1 | 125 | 6/23/2026 |
| 0.9.1 | 224 | 6/17/2026 |
| 0.8.2 | 118 | 5/18/2026 |
| 0.8.0 | 111 | 5/18/2026 |
| 0.7.0 | 104 | 5/6/2026 |
| 0.6.0 | 104 | 5/4/2026 |
| 0.5.0 | 104 | 5/1/2026 |
| 0.4.0 | 115 | 4/27/2026 |
| 0.1.2 | 124 | 4/13/2026 |
| 0.1.1 | 123 | 4/13/2026 |
| 0.1.0 | 125 | 4/9/2026 |
> C++ library — tagged `v0.14.0` · C# / NuGet — tagged `csharp-v0.14.0` · Python / PyPI — tagged `python-v0.14.0`
> Quadratic Bezier corner smoothing: `bezier_smoothing_2()` rounds a polyline corner (p0, p1, p2) with a quadratic Bezier arc (density-based or exact-count, with a tunable tiny-edge skip threshold), and `Polyline2D::Expand()` / `Polyline3D::Expand()` — the inverse of `Reduce()` — apply it to every inner corner of a polyline via a new `polyline_expansion()` free function.
### Added
**C++ core**
- `bezier_smoothing_2(PointT p0, PointT p1, PointT p2, double smoothness, double min_distance, double min_segment_length = DOUBLE_EPSILON)` (`calc_utils2d.hpp`) — trims tangent points into p1 by up to `smoothness` (∈ [0,1]) fraction of the shorter adjacent edge, then samples the resulting quadratic Bezier arc via De Casteljau's algorithm at roughly `min_distance` apart. An adjacent edge at or below `min_segment_length` isn't trimmed into (that tangent point falls back to `p1`); if both are, the whole corner collapses to `p1` (no curve). Templated over `PointT`; explicit-instantiated for `Point2D`/`Point3D`. Throws `std::invalid_argument` if `min_distance <= 0`.
- `bezier_smoothing_2(PointT p0, PointT p1, PointT p2, double smoothness, int num_segments, double min_segment_length = DOUBLE_EPSILON)` — same tangent trimming and sampling, but takes an exact segment count instead of a distance-derived one; a distinct overload rather than a parameter that reinterprets `min_distance`, since the two controls don't share a unit. Throws `std::invalid_argument` if `num_segments < 1`.
- `PolylineExpansionParams` (`constants.hpp`) — bundles `smoothness`, a `Mode` (`FixedSegments` / `MinDistance`) mirroring `bezier_smoothing_2`'s two overloads, `segments_per_corner`, `min_distance`, and `min_segment_length`.
- `polyline_expansion(std::vector<PointT> const& input, PolylineExpansionParams const& settings)` (`calc_utils2d.hpp`) — rounds every inner corner of a raw point list via `bezier_smoothing_2`, deduplicating consecutive points (a corner fully skipped by `min_segment_length`, or two adjacent corners' arcs meeting exactly at a shared edge's midpoint — each corner's trim is independently capped at half its shared edge, so adjacent arcs can touch but never cross) rather than emitting zero-length segments. Templated over `PointT`; explicit-instantiated for `Point2D`/`Point3D`.
- `Polyline2D::Expand(PolylineExpansionParams const& settings = PolylineExpansionParams{})` / `Polyline3D::Expand(...)` — the inverse of `Reduce()`: adds vertices rather than removing them. Thin wrappers delegating to `polyline_expansion()`.
**Python bindings**
- `bezier_smoothing_2(p0, p1, p2, smoothness, min_distance, min_segment_length=DOUBLE_EPSILON)` and `bezier_smoothing_2(p0, p1, p2, smoothness, num_segments, min_segment_length=DOUBLE_EPSILON)` — bound for both `Point2D` and `Point3D`; overload resolution follows pybind11's no-conversion-first pass, matching the C++ int-vs-double disambiguation.
- `PolylineExpansionMode` (`FixedSegments`, `MinDistance`), `PolylineExpansionParams(smoothness=0.5, mode=FixedSegments, segments_per_corner=4, min_distance=0.1, min_segment_length=DOUBLE_EPSILON)`, `polyline_expansion(points, settings)`.
- `Polyline2D.expand(settings=PolylineExpansionParams())` / `Polyline3D.expand(...)`.
**C# bindings**
- `GeomUtil.BezierSmoothing2(Point2D^, Point2D^, Point2D^, double, double)` / `(..., int)` — and the `Point3D^` overloads — plus `minSegmentLength` overloads of each.
- `PolylineExpansionMode`, `PolylineExpansionParams` (explicit-backing-field properties, matching this codebase's convention — no C++/CLI auto-properties elsewhere), `GeomUtil.PolylineExpansion(points, settings)`.
- `Polyline2D.Expand()` / `Polyline2D.Expand(PolylineExpansionParams^)` — and the `Polyline3D` equivalents.
### Fixed
- A pre-release iteration of `polyline_expansion()`/`Expand()` read a corner's `p0`/`p1` back out of the *already-built* output buffer instead of the original input knots — this broke the invariant that each corner's trim is bounded by its true adjacent-edge length (adjacent corners' arcs could no longer be guaranteed to meet without crossing), and on the very first corner processed could even set `p1 == p2`. Never released; caught during validation before landing. All `p0`/`p1`/`p2` are read directly from the original knot list, unconditionally.
- `size_t` → `std::size_t` normalized throughout `calc_utils2d.cpp`.
### Tests
- `test_calc_utils2d.cpp`: `BezierSmoothing2_*` — both overloads' throw paths, trimmed-tangent endpoint values (hand-verified), `smoothness=0` sharp-corner collapse, coincident-endpoint degeneracy (no NaN), exact point-count for `num_segments`, and `MinSegmentLength_*` (single-side skip, both-side skip, `DOUBLE_EPSILON` default, explicit-zero opt-out). `PolylineExpansion_*` — two-point no-op, single-corner trim, a dedicated multi-corner regression test proving each corner uses its own original knots, `min_segment_length` full-corner skip.
- `test_polyline2d.cpp` / `test_polyline3d.cpp`: `Expand_*` — unchanged below 3 knots, trimmed-tangent endpoints, `min_segment_length` full-skip matches the original polyline exactly, `MinDistance` mode density scaling, thrown-precondition propagation from `bezier_smoothing_2`.
- `test_geompp.py`: `TestBezierSmoothing2FreeFunction`, `TestPolylineExpansionParams`, `TestPolylineExpansionFreeFunction`, `TestPolyline2DExpand`, `TestPolyline3DExpand` — same coverage as the C++ suite, plus `Point3D` cases.
- `Program.cs`: equivalent `BezierSmoothing2_*`, `PolylineExpansionParams_*`, `PolylineExpansion_*`, `Polyline2D_Expand_*`, `Polyline3D_Expand_*` coverage.
---