OCCT画一个立方体

        BRepPrimAPI_MakeBox aBox(10., 10., 10.);
        std::cout << "Box creation failed: shape is null. 11:" << aBox.IsDone() << std::endl;

这段代码IsDone()一直是0,困扰了我很久。
后来借助AI 对源码的分析才搞明白需要这种写法,注意后面的Solid()方法

  TopoDS_Shape aShape = BRepPrimAPI_MakeBox(1, 1, 1).Solid();
aShape.DumpJson(std::cout);
 if (aShape.IsNull()) {
      std::cout << "Box creation failed: shape is null." << std::endl;
  }

构造函数底层逻辑

1. 构造函数执行流程

BRepPrimAPI_MakeBox::BRepPrimAPI_MakeBox(10., 10., 10.)
↓
调用 pmin(gp_Pnt(0,0,0), 10., 10., 10.) 计算最小点
↓ 
创建 gp_Ax2 坐标系: gp_Ax2(pmin(0,0,0,10,10,10), gp_Dir(0,0,1), gp_Dir(1,0,0))
↓
构造 BRepPrim_Wedge(myWedge): BRepPrim_Wedge(gp_Ax2, Abs(10), Abs(10), Abs(10))

2. 内部数据结构

  • myWedge: BRepPrim_Wedge 对象,存储几何信息
  • myShape: 继承自 BRepBuilderAPI_MakeShape 的结果存储

3. IsDone() 方法调用

bool IsDone() const { return BRepBuilderAPI_Command::IsDone(); }

时序图

ClientBRepPrimAPI_MakeBoxBRepPrim_Wedgegp_Ax2BRepBuilderAPI_MakeShapeBRepPrimAPI_MakeBox(10.,10.,10.)pmin(gp_Pnt(0,0,0),10,10,10)计算最小点 (0,0,0)gp_Ax2(pmin, gp_Dir(0,0,1), gp_Dir(1,0,0))创建坐标系new BRepPrim_Wedge(gp_Ax2,10,10,10)内部调用 BRepPrim_GWedge 构造初始化完成对象创建完成IsDone()IsDone()返回状态返回 trueClientBRepPrimAPI_MakeBoxBRepPrim_Wedgegp_Ax2BRepBuilderAPI_MakeShape

类图

contains
uses
uses
BRepBuilderAPI_Command
+IsDone() : bool
+Done() : void
«abstract»
BRepBuilderAPI_MakeShape
#myShape TopoDS_Shape
+Shape() : TopoDS_Shape
+Build() : void
BRepPrimAPI_MakeBox
-myWedge BRepPrim_Wedge
+BRepPrimAPI_MakeBox(dx,dy,dz)
+BRepPrimAPI_MakeBox(P,dx,dy,dz)
+BRepPrimAPI_MakeBox(P1,P2)
+Shell() : TopoDS_Shell
+Solid() : TopoDS_Solid
+Wedge()
BRepPrim_Wedge
+BRepPrim_Wedge(Axes,dx,dy,dz)
+Shell() : TopoDS_Shell
+Face(direction) : TopoDS_Face
«abstract»
BRepPrim_GWedge
+Axes gp_Ax2
+DX, DY, DZ Standard_Real
#myAxes gp_Ax2
#myDX, myDY, myDZ Standard_Real
gp_Ax2
-location gp_Pnt
-direction gp_Dir
-xDirection gp_Dir
+gp_Ax2(location, direction, xDirection)
gp_Pnt
-coord[3] Standard_Real
+gp_Pnt(x,y,z)

关键执行细节

  1. 坐标系创建: 使用默认坐标系,原点在(0,0,0),Z轴向上,X轴向右
  2. Wedge构造: Box实际上是特殊的Wedge(楔形体),所有侧面都是垂直的
  3. 延迟构建: 构造函数只设置参数,实际的几何体构建在调用Shape(), Solid(), Shell()时进行
  4. 状态管理: 通过继承的BRepBuilderAPI_Command管理构建状态

这个设计体现了OCCT的延迟计算模式和分层架构思想。

延迟构建

具体分析:

1. Shell() 函数
const TopoDS_Shell& BRepPrimAPI_MakeBox::Shell()
{
  myShape = myWedge.Shell();  // 构建Shell几何体
  Done();                      // 设置 myDone = true
  return TopoDS::Shell(myShape);
}
2. Solid() 函数
const TopoDS_Solid& BRepPrimAPI_MakeBox::Solid()
{
  BRep_Builder B;
  B.MakeSolid(TopoDS::Solid(myShape));  // 构建Solid几何体
  B.Add(myShape, myWedge.Shell());
  Done();                                // 设置 myDone = true
  return TopoDS::Solid(myShape);
}
3. Shape() 函数(基类实现)
const TopoDS_Shape& BRepBuilderAPI_MakeShape::Shape()
{
  if (!IsDone())  // 如果还没有完成
  {
    ((BRepBuilderAPI_MakeShape*)(void*)this)->Build();  // 调用Build()
    Check();      // 验证状态
  }
  return myShape;
}

Build()BRepPrimAPI_MakeBox 中的实现是:

void BRepPrimAPI_MakeBox::Build(const Message_ProgressRange& /*theRange*/)
{
  Solid();  // 调用Solid(),而Solid()会调用Done()
}

Done()方法的作用:

void BRepBuilderAPI_Command::Done()
{
  myDone = Standard_True;  // 直接设置myDone为true
}

执行流程总结:

  1. 构造函数:只设置参数,myDone = false(默认)
  2. 调用Shell()/Solid():构建几何体 + Done()myDone = true
  3. 调用Shape():检查IsDone(),如果false则调用Build()Solid()Done()myDone = true

所以您的问题中的这三个函数确实都会设置myDone为true,确保后续的IsDone()调用返回正确状态。这是OCCT状态管理模式的核心机制。

OccT (OpenCASCADE Technology) 是一个开源的几何建模库,主要用于三维CAD应用程序。要使用它来绘制一个圆柱外面包裹一层圆板,你可以按照以下步骤操作: 1. **创建圆柱**: - 首先,创建一个基本的圆柱体(Cylinder),可以使用`BRepBuilderAPI_MakeCylinder`创建,提供半径、高度作为参数。 ```c++ TopoDS_Shape cylinder = BRepBuilderAPI_MakeCylinder(cylinder_radius, cylinder_height).Shape(); ``` 2. **切割圆柱**: - 创建一个圆板,作为圆柱的截面。这个圆板应该比圆柱底端的直径略大一些,以便形成包裹效果。然后使用`BRepAlgoAPI_FaceCut`将圆板切到圆柱上生成一个新的形状。 ```c++ TopoDS_Shape circular_slab = BRepPrimAPI_MakeCircle(rounded_slab_radius).Shape(); TopoDS_Shape cut_shape = BRepAlgoAPI_FaceCut(cylinder, circular_slab).Shape(); ``` 3. **组合结果**: - 使用`BRepBuilderAPI_Transform`将切割后的圆板形变并附加到原圆柱表面,形成包裹效果。 ```c++ TopoDS_Edge edge = geom_traits.Surface(cut_shape).Edges().First(); gp_Pnt origin = ...; // 圆柱中心点 gp_Vec direction = ...; // 圆柱轴向 TopoDS_Shape transformed_slab = BRepBuilderAPI_Transform(circular_slab, origin, direction); cut_shape = TopoDS_Combination::Make(cut_shape, transformed_slab); ``` 4. **创建 OccT 对象**: - 最后,将计算出的拓扑结构转换成适合OpenCASCADE处理的数据结构,例如`ShapeAnalysis::ShapeExplorer`。 ```c++ ShapeAnalysis::ShapeExplorer explorer(cut_shape); // 现在你可以遍历并分析explorer中的三角面片 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

helloworddm

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值