LNLib is a C++ NURBS Algorithms Library. 
These algorithms are primary referenced from The NURBS Book 2nd Edition. 
The APIs are re-designed to make it more friendly to users.
Please run build.bat first to construct C++ solution by CMake.
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 Decomposition Knot Insertion/Refinement/Removal Degree Elevation and Reduction | 
| Chapter 6 | Curve/Surface Point Inversion Surface Tangent Vector Inversion Curve/Surface Reparameterization Curve 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 Normal Curve Split/Segment/Merge/Offset Curve IsLinear/IsArc Curve Approximate Length Surface Approximate Area | 
| Curve Creation | Create Line/Cubic Hermite | 
| Tessellation | Curve Tessellation Surface Triangulation | 
LNLibViewer based on VTK
ND-LNLib based on LibTorch (PyTorch C++ version)
#include "LNObject.h"
#include "XYZ.h"
#include "XYZW.h"
#include "NurbsSurface.h"
#include "KnotVectorUtils.h"
#include <Geom_BSplineSurface.hxx>
void ConvertToOpenCascadeSurface(const LNLib::LN_NurbsSurface& surface, Handle(Geom_BSplineSurface)& internalSurface)
{
    LNLib::NurbsSurface::Check(surface);
    std::vector<double> knotU = surface.KnotVectorU;
    std::vector<double> knotV = surface.KnotVectorV;
    const int numPolesU = static_cast<int>(surface.ControlPoints.size());
    const int numPolesV = static_cast<int>(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<double, int> mapU = LNLib::KnotVectorUtils::GetKnotMultiplicityMap(knotU);
    TColStd_Array1OfReal knotsU(1, static_cast<int>(mapU.size()));
    TColStd_Array1OfInteger multsU(1, static_cast<int>(mapU.size()));
    
    std::vector<double> Ukeys;
    Ukeys.reserve(mapU.size());
    std::vector<int> 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<double, int> mapV = LNLib::KnotVectorUtils::GetKnotMultiplicityMap(knotV);
    TColStd_Array1OfReal knotsV(1, static_cast<int>(mapV.size()));
    TColStd_Array1OfInteger multsV(1, static_cast<int>(mapV.size()));
    std::vector<double> Vkeys;
    Vkeys.reserve(mapV.size());
    std::vector<int> 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 Library, which used for export nurbs surfaces to STEP or IGES format file.
Welcome to use https://deepwiki.com/BIMCoderLiang/LNLib powered by Devin.
Welcome join this project including discussions in Issues and make Pull requests.
LNLib is created by Yuqing Liang (BIMCoder Liang).
- bim.frankliang@foxmail.com
- 微信公众号:BIMCoder
The source code is published under LGPL 2.1, the license is available here.
The NURBS Book 2nd Edition by Les Piegl & Wayne Tiller




