You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCascade创建3次B-spline代码报错:内存溢出排查

OpenCascade 3次Clamped B样条创建问题排查与修复

问题概述

尝试使用OpenCascade创建一条3次Clamped B样条(包含5个控制点、9个节点),但代码运行时Visual Studio 2022提示内存溢出,原代码如下:

原头文件

#include <TColStd_Array1OfReal.hxx>
#include <Geom_BSplineCurve.hxx>
#include <gp_Pnt.hxx>

原创建函数

Handle(Geom_BSplineCurve) CreateBSplineCurve()   //Create a handle pointer of B-spline with degree 3
{
    TColgp_Array1OfPnt controlPoints(1, 5);         //set five control points 
    controlPoints.SetValue(1, gp_Pnt(1, 1, 0));
    controlPoints.SetValue(2, gp_Pnt(2, 3, 0));
    controlPoints.SetValue(3, gp_Pnt(4, 5, 0));
    controlPoints.SetValue(4, gp_Pnt(7, 3, 0));
    controlPoints.SetValue(5, gp_Pnt(9, 6, 0));

    TColStd_Array1OfReal knots(1, 9); // set 9 knots 
    knots.SetValue(1, 0.0);
    knots.SetValue(2, 0.0);
    knots.SetValue(3, 0.0);
    knots.SetValue(4, 0.0);
    knots.SetValue(5, 0.5);
    knots.SetValue(6, 1.0);
    knots.SetValue(7, 1.0);
    knots.SetValue(8, 1.0);
    knots.SetValue(9, 1.0);
    
    TColStd_Array1OfInteger multiplicities(1,9); //every knots appear once 
    multiplicities.SetValue(1, 1);
    multiplicities.SetValue(2, 1);
    multiplicities.SetValue(3, 1);
    multiplicities.SetValue(4, 1);
    multiplicities.SetValue(5, 1);
    multiplicities.SetValue(6, 1);
    multiplicities.SetValue(7, 1);
    multiplicities.SetValue(8, 1);
    multiplicities.SetValue(9, 1);

    Standard_Integer degree = 3; // set degree equal to 3

    Handle(Geom_BSplineCurve) bsplineCurve = new Geom_BSplineCurve(controlPoints, knots, multiplicities, degree, Standard_False); 
    return bsplineCurve;
}

原主函数

int main()
{
    Handle(Geom_BSplineCurve) bsplineCurve = CreateBSplineCurve();
    std::cout << "Degree: " << bsplineCurve->Degree() << std::endl;

    return 0;
}

错误分析

  1. 节点与重数的参数逻辑错误
    OpenCascade的Geom_BSplineCurve构造函数要求:

    • knots数组存放唯一的、非递减排列的节点值
    • multiplicities数组对应每个节点的重复次数
      原代码将重复节点全部放入knots数组,同时设置每个重数为1,完全违反参数规则,导致内部计算时出现非法内存访问。
  2. Clamped B样条的重数设置错误
    Clamped B样条要求首尾节点的重数等于样条次数+1(3次样条对应重数4),原代码未正确设置该重数,导致样条数学结构不合法,触发内存溢出。

  3. 缺失必要头文件
    使用TColgp_Array1OfPnt但未包含对应头文件<TColgp_Array1OfPnt.hxx>,可能引发编译或运行时异常。

修正后的代码

修正后的头文件

#include <TColStd_Array1OfReal.hxx>
#include <Geom_BSplineCurve.hxx>
#include <gp_Pnt.hxx>
#include <TColgp_Array1OfPnt.hxx> // 补充缺失的头文件
#include <iostream> // 用于控制台输出

修正后的创建函数

Handle(Geom_BSplineCurve) CreateBSplineCurve()
{
    // 定义5个控制点
    TColgp_Array1OfPnt controlPoints(1, 5);
    controlPoints.SetValue(1, gp_Pnt(1, 1, 0));
    controlPoints.SetValue(2, gp_Pnt(2, 3, 0));
    controlPoints.SetValue(3, gp_Pnt(4, 5, 0));
    controlPoints.SetValue(4, gp_Pnt(7, 3, 0));
    controlPoints.SetValue(5, gp_Pnt(9, 6, 0));

    // 唯一节点:按非递减顺序排列
    TColStd_Array1OfReal knots(1, 3);
    knots.SetValue(1, 0.0);
    knots.SetValue(2, 0.5);
    knots.SetValue(3, 1.0);

    // 节点重数:首尾重数为4(3+1),中间节点重数1
    TColStd_Array1OfInteger multiplicities(1, 3);
    multiplicities.SetValue(1, 4);
    multiplicities.SetValue(2, 1);
    multiplicities.SetValue(3, 4);

    Standard_Integer degree = 3;

    // 创建非周期Clamped B样条
    Handle(Geom_BSplineCurve) bsplineCurve = new Geom_BSplineCurve(
        controlPoints, knots, multiplicities, degree, Standard_False
    );
    return bsplineCurve;
}

修正后的主函数

int main()
{
    Handle(Geom_BSplineCurve) bsplineCurve = CreateBSplineCurve();
    std::cout << "Degree: " << bsplineCurve->Degree() << std::endl;
    std::cout << "Is clamped spline: " << (bsplineCurve->IsClamped() ? "Yes" : "No") << std::endl;
    return 0;
}

修正说明

  • 节点数组改为唯一非递减值,重数数组对应每个节点的重复次数,符合OpenCascade构造函数的参数要求。
  • 首尾节点重数设为4,满足Clamped B样条的定义:样条会通过首尾控制点,且首尾处的导数约束符合规范。
  • 补充了缺失的头文件,消除潜在的编译问题。

内容的提问来源于stack exchange,提问作者ToastaFish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 21:47:10