# LNLib
**Repository Path**: bimfrankliang/LNLib
## Basic Information
- **Project Name**: LNLib
- **Description**: NURBS Curve and Surface Algorithms Library, match the NURBS Book.
【LNLib库在Gitee的官方镜像】
- **Primary Language**: C++
- **License**: LGPL-2.1
- **Default Branch**: main
- **Homepage**: https://github.com/BIMCoderLiang/LNLib
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-11-08
- **Last Updated**: 2025-11-15
## Categories & Tags
**Categories**: mathlibs
**Tags**: NURBS, surface, curve, nurbs-book
## README
## Introduction
**LNLib is a C++ NURBS Algorithms Library.**
These algorithms are primary referenced from [The NURBS Book 2nd Edition](https://link.springer.com/book/10.1007/978-3-642-97385-7).
The APIs are re-designed to make it more friendly to users.
## Run LNLib
Please run build.bat first to construct C++ solution by CMake.
## Features
Basic Elements:
- UV
- XYZ
- XYZW
- Matrix4d
- LNObject
Algorithms in ***The Nurbs Book***:
|Chapter|Content|
|--|--|
|***Chapter 1*** | Basis Function Computation |
|***Chapter 1 to 4*** | Bezier/B-Spline/NURBS Curve and Surface |
|***Chapter 5*** | Curve and Surface DecompositionKnot Insertion/Refinement/RemovalDegree Elevation and Reduction |
|***Chapter 6*** | Curve/Surface Point InversionSurface Tangent Vector InversionCurve/Surface ReparameterizationCurve Transform and Reverse Surface Swap and Reverse|
|***Chapter 7*** | Create Arc/Conic Curve |
|***Chapter 8*** | Create Bilinear/Cylindrical/Ruled/Revolved/CornerFillet Surface |
|***Chapter 9*** | Global/Local Curve/Surface Interpolation and Approximation |
|***Chapter 10*** | Create Swung/Loft/Sweep/Gordon/Coons Surface |
|***Chapter 11*** | Curve Modification in Control Point Locations or Weight Values |
|***Chapter 12*** | Curve Clamp/UnClamp/IsClamp KnotVector IsUniform Curve IsClosed/IsPeriodic|
Additional Algorithms:
|Description|Content|
|--|--|
|***Basic Properties*** | Curve/Surface Curvature and NormalCurve Split/Segment/Merge/OffsetCurve IsLinear/IsArcCurve Approximate LengthSurface Approximate Area |
|***Curve Creation*** | Create Line/Cubic Hermite |
|***Tessellation*** | Curve Tessellation Surface Triangulation|
## Visualization
[LNLibViewer](https://github.com/BIMCoderLiang/LNLibViewer) based on [VTK](https://vtk.org/)
## NURBS Fitting by Neural Network
[ND-LNLib](https://github.com/BIMCoderLiang/NURBS-Diff-with-LNLib) based on [LibTorch](https://pytorch.org/cppdocs/installing.html) (PyTorch C++ version)

## Convert to OpenCascade NURBS surface
```C++
#include "LNObject.h"
#include "XYZ.h"
#include "XYZW.h"
#include "NurbsSurface.h"
#include "KnotVectorUtils.h"
#include
void ConvertToOpenCascadeSurface(const LNLib::LN_NurbsSurface& surface, Handle(Geom_BSplineSurface)& internalSurface)
{
LNLib::NurbsSurface::Check(surface);
std::vector knotU = surface.KnotVectorU;
std::vector knotV = surface.KnotVectorV;
const int numPolesU = static_cast(surface.ControlPoints.size());
const int numPolesV = static_cast(surface.ControlPoints[0].size());
TColgp_Array2OfPnt poles(1, numPolesU, 1, numPolesV);
TColStd_Array2OfReal weights(1, numPolesU, 1, numPolesV);
for (int i = 0; i < numPolesU; i++) {
for (int j = 0; j < numPolesV; j++) {
const LNLib::XYZW& wcp = surface.ControlPoints[i][j];
const LNLib::XYZ& cp = wcp.ToXYZ(true);
poles.SetValue(i+1, j+1, gp_Pnt(cp.GetX(), cp.GetY(), cp.GetZ()));
weights.SetValue(i+1, j+1, wcp.GetW());
}
}
std::map mapU = LNLib::KnotVectorUtils::GetKnotMultiplicityMap(knotU);
TColStd_Array1OfReal knotsU(1, static_cast(mapU.size()));
TColStd_Array1OfInteger multsU(1, static_cast(mapU.size()));
std::vector Ukeys;
Ukeys.reserve(mapU.size());
std::vector UMults;
UMults.reserve(mapU.size());
for (auto it = mapU.begin(); it != mapU.end(); ++it) {
Ukeys.emplace_back(it->first);
UMults.emplace_back(it->second);
}
for (int i = 0; i < Ukeys.size(); i++) {
knotsU.SetValue(i+1, Ukeys[i]);
}
for (int i = 0; i < UMults.size(); i++) {
multsU.SetValue(i+1, UMults[i]);
}
std::map mapV = LNLib::KnotVectorUtils::GetKnotMultiplicityMap(knotV);
TColStd_Array1OfReal knotsV(1, static_cast(mapV.size()));
TColStd_Array1OfInteger multsV(1, static_cast(mapV.size()));
std::vector Vkeys;
Vkeys.reserve(mapV.size());
std::vector VMults;
VMults.reserve(mapV.size());
for (auto it = mapV.begin(); it != mapV.end(); ++it) {
Vkeys.emplace_back(it->first);
VMults.emplace_back(it->second);
}
for (int i = 0; i < Vkeys.size(); i++) {
knotsV.SetValue(i+1, Vkeys[i]);
}
for (int i = 0; i < VMults.size(); i++) {
multsV.SetValue(i+1, VMults[i]);
}
internalSurface = new Geom_BSplineSurface(
poles, weights, knotsU, knotsV,
multsU, multsV,
surface.DegreeU, surface.DegreeV);
}
```
More Details could be found in [LNLibEx](https://github.com/BIMCoderLiang/LNLibEx) Library, which used for **export nurbs surfaces to STEP or IGES** format file.
## Online Document
Welcome to use https://deepwiki.com/BIMCoderLiang/LNLib powered by Devin.
## Contributing
Welcome join this project including discussions in **Issues** and make **Pull requests**.
**Other Contributors:** [csulijunji](https://github.com/csulijunji)
## Author
LNLib is created by Yuqing Liang (BIMCoder Liang).
- bim.frankliang@foxmail.com
- 微信公众号:**BIMCoder**
## License
The source code is published under [LGPL 2.1](https://www.gnu.org/licenses/), the license is available [here](LICENSE).
## Primary Reference
[The NURBS Book 2nd Edition](https://link.springer.com/book/10.1007/978-3-642-97385-7) by **Les Piegl & Wayne Tiller**