AMCAX Kernel
Geometry kernel for CAD/CAE/CAM
九韶内核 1.0.0.0
载入中...
搜索中...
未找到
STEP 文件读写示例

概述

本教程介绍了 AMCAX STEP Reader(下称 Reader 或 StepReader)和 AMCAX STEP Writer(下称 Writer 或 StepWriter)的基本用法。 此外,本模块还提供了将读取数据转换为 Mesh 格式的 AMCAX STEP Mesh Reader(下称 StepMeshReader)。 目前没有提供以 STEP 协议导出 Mesh 数据的接口。

所需知识

开发人员需具备现代 C++ 编程、3D 几何建模和 B-Rep 拓扑结构的基础知识。AMCAX 内核及 StepReader / StepWriter 基于 C++17 标准开发,广泛应用 STL 容器与算法。

导入部分

引入头文件

StepReader

本示例程序中 Reader 部分只需要引入一个头文件:

Class for reading and translating STEP files into TopoShape objects.

StepMeshReader

若需要使用 Mesh 相关接口,则需要使用 StepMeshReader。StepMeshReader 在以下头文件中定义。StepMeshReader 是 Reader 的子类,在其基础上追加了 Mesh 相关功能。

Class for reading STEP file and convert solids / shells to mesh.

另外,StepMeshReader作为可以接受多种 Traits 的模板类型,如果未在编译参数中定义相关宏,也可通过如下方式在代码中启用对应 Traits 类型:

// 可根据具体情况替换为其它宏
#define AMCAXMeshing_Enable_CommonTraits

创建 Reader 对象

StepReader

STEP Reader 不提供静态函数,所有操作均需基于对象。 构造时需要传入一个文件名 (std::string) 或输入流 (std::istream) 作为参数:

std::ifstream ifs("/path/to/input.step");
if (!ifs.is_open())
{
return 1;
}
Class for reading and translating STEP files into TopoShape objects.
定义 StepReader.hpp:29

或者

AMCAX::STEP::StepReader reader("/path/to/input.step");

StepMeshReader

类似的,StepMeshReader 也提供了相同的构造器:

MeshReader reader(ifs);
Class for reading STEP file and convert solids / shells to mesh.
定义 StepMeshReader.hpp:26

或者

MeshReader reader("/path/to/input.step");

(可选)设置缩放

默认情况下,Reader 会以毫米为单位长度,对读取到的模型进行缩放操作。 可通过如下代码调整单位缩放设置:

reader.SetUnit(AMCAX::STEP::StepLengthUnit::PresetLengthUnit::NOSCALE);

在转换完成后,亦可以通过 StepReader::GetUnit() / StepMeshReader::GetUnit() 或 StepData::Factors() / StepMeshData::Factors() 获取 STEP 文件中提供的单位。

(可选)设置进度汇报

无论是对 Reader 或是对 StepMeshReader,加载进度都是通过回调函数汇报的。然而,其使用的参数稍有不同:

StepReader

一般来说,c1 表示已处理的图形数量,c2 表示总图形数。

reader.SetProgressCallback(
{
std::cout << " State: " << int(state) << std::endl;
if (c2.type == AMCAX::STEP::StepProgressCarrier::U64_TYPE && c2.payload.u64)
{
std::cout << " Carrier1: " << c1.payload.u64 << std::endl;
std::cout << " Carrier2: " << c2.payload.u64 << std::endl;
}
});
A class used for representing the states in the progress of the STEP process.
定义 StepProgress.hpp:54
A carrier for carrying data the progress of the STEP process.
定义 StepProgress.hpp:18

对于每个状态及其参数的含义,可以参考 <step/StepProgress.hpp>

StepMeshReader

StepMeshReader 的回调函数与 Reader 基本一致,仅 State 的类型有一点区别:

reader.SetProgressCallback(
{
std::cout << " State: " << int(state) << std::endl;
if (c2.type == AMCAX::STEP::StepProgressCarrier::U64_TYPE && c2.payload.u64)
{
std::cout << " Carrier1: " << c1.payload.u64 << std::endl;
std::cout << " Carrier2: " << c2.payload.u64 << std::endl;
}
});
Class used for reporting the state of the STEP process.
定义 StepMeshProgress.hpp:16

对于每个状态及其参数的含义,可以参考 <step/mesh/StepMeshProgress.hpp>

读取文件

在构建 Reader 或 StepMeshReader 对象后,便可以读取文件:

bool topo_success = reader.Read();

不管是对 Reader 还是对 StepMeshReader,这一步都将完成 STEP 至 TopoShape 的翻译工作。 Read() 方法阻塞当前线程直至解析完成。受到软硬件以及输入文件的复杂度差异影响,运行时间会持续数毫秒到数十分钟不等。 若在前一步骤中使用 std::istream 作为参数,用户需要确保在这一函数执行完毕前该输入流的生命周期不会失效。 如果读取失败,Read() 会返回 false 。

提前获得已经完成的结果

虽然 Read() 函数会阻塞当前进程,但有一部分数据在其执行早期或中期就已经准备完毕,可以提前获取。 用户可以将 AMCAX::STEP::DataCallback 作为参数传递给 Read() 函数,该 DataCallback 会在相关数据准备完毕时被调用。

bool topo_success = reader.Read([&reader](AMCAX::STEP::DataEvent e,
const AMCAX::STEP::ProductPtr p,
size_t rep_idx)
{
switch (e)
{
{
// 这个事件表示 Product 树已经组装完毕,
// 用户可以通过 reader.GetShapes() 获取结果。
// 对于所有节点,ProductName、Description、Location、Target、Children 及相关接口均可使用。
// 对于包含图形数据的 Product 节点,此处也已经使用空数据进行填充。
break;
}
{
// 这个事件表示某一个图形数据已经准备完毕。
// 用户可以通过 p->ShapeAt(rep_idx) 获取图形,
// 同时通过 p->PropertyChainAt(rep_idx) 获取相关属性,
// p->FactorAt(rep_idx) 和 p->ShapeRepresentationAt(rep_idx) 处的数据也已经可用
break;
}
{
// 这个事件表示某一个图形与属性数据(AMCAXAf Label 格式)已经准备完毕。
// 用户可以通过 p->LabelAt(rep_idx) 获取数据。
// 对于同一个 TopoShape,LabelReady 事件会在 ShapeReady 之后出现,
// 且两个事件中的 p 参数与 rep_idx 参数会保持一致。
break;
}
default:;
}
});
DataEvent
定义 StepProgress.hpp:134
@ ProductReady
This event indicates that the Product tree is fully constructed, all the data, other than Shapes,...
定义 StepProgress.hpp:142
@ LabelReady
This event comes with 2 parameters. he first one is the pointer to the StepData object....
定义 StepProgress.hpp:152
@ ShapeReady
This event comes with 2 parameters. The first one is the pointer to the StepData object....
定义 StepProgress.hpp:147

需要注意的是,由于 callback 函数是直接在执行线程中被调用的,如果用户提供的函数定义过于复杂,可能会影响到后续计算的执行。 如果用户在 Read() 函数阻塞期间对获取到的数据执行 std::move 或 StepData::AddShape 等操作,可能会产生未定义的结果。

(仅 Mesh)将 TopoShape 转换为 Mesh 格式

完成 STEP 的翻译工作之后,便可以进行 TopoShape 至 Mesh 的转换工作。

bool mesh_success = reader.ToMesh();

其中,ToMesh() 接受一个可选的 double 类型参数作为网格化的参数。

创建用于储存数据的容器

StepReader

本模块的读、写子模块均使用 AMCAX::STEP::StepDataList 传输数据:

AMCAX::STEP::StepDataList shapes;

AMCAX::STEP::StepData 类型由 <step/StepData.hpp> 头文件定义,但一般情况下无需显式引入该头文件。

StepMeshReader

类似的,StepMeshReader 作为 Reader 的扩展,使用 AMCAX::STEP::StepMeshDataList 类型传输数据:

AMCAX::STEP::StepMeshDataList<AMCAX::Meshing::Mesh::TriSoupTraits_Coord> shapes;

定义于 <step/mesh/StepMeshData.hpp>。

获取结果

不管是对 Reader 还是对 StepMeshReader,获取翻译结果的代码都是相同的:

shapes = reader.GetShapes();

StepReader

根据文件的内容和转换的情况,shapes 中会包含 0 或更多 StepData 对象。 StepData 对应 STEP 文件中的 Product 实体,是用来传输 STEP 数据的类。 因此, StepData.hpp 中也定义了一个 ProductPtr,作为 std::shared_ptr<StepData> 的别名。 此类主要包含以下成员变量:

  1. 当前 Product 的名称、描述信息,通过 ProductName() 与 Description() 获取;
  2. 当前 Product 的 Child Product,即当前 StepData 节点的子树,数量为 0 或更多,通过 Children() / ChildAt(size_t) 获取;
  3. 当前 Product 的 TopoShape,数量为 0 或更多,通过 Shapes() / ShapeAt(size_t) 获取;
  4. 当前 Product 下针对每个 TopoShape 的属性(如名称、颜色)和缩放信息,通过 PropertyChains() 与 Factors() 获取;
  5. 当前 Product 装配至上级 Product 时使用的位移、旋转信息,通过 Location() 获取;

如果多个 Product 节点之间通过 Children() 形成树状结构,则表示 Product 之间的装配。可以遍历先前获取到的 StepDataList,判断每个 StepData 对象中 ChildrenSize() 是否全部为 0,来确认当前文件是否包含装配结构。 另外,对于包含装配结构的情况,由于同一个 Product 可以配合不同的位移、旋转信息,任意多次装配进不同的上级 Product,StepData 为了减少重复信息,提供了 Shadow 节点的概念。

Shadow 节点

Shadow 节点被定义为仅包含位移、旋转信息(Location)的节点。用户可以通过 StepData::IsShadow() 判断当前节点是否为 Shadow 节点,可以通过 StepData::Target() 获取实际储存数据的节点。 虽然没有直接存储图形数据,如果对 Shadow 节点调用 StepData::Shapes() / StepData::Children() 等函数,会自动返回 Target 节点上的数据。 如果不需要使用 Shadow 节点相关特性,可以通过以下方法将整个 Product 树转换为普通节点:

/* ProductPtr 是 std::shared_ptr<StepData> 的别名 */
void ConvertToNormal(ProductPtr& root)
{
if (root->IsShadow())
{
// 将 Target 节点的数据复制到当前节点,并将类型转换为普通节点
// 需要注意的是,MarkNormal 也会对 Target 节点的 Children 执行深拷贝
// 用户后续如果需要更新子树,则也需要在当前节点的子树和 Target 节点的子树上同时操作。
root->MarkNormal();
}
for(size_t i = 0; i < root->ChildrenSize(); ++i)
{
ConvertToNormal(root->ChildAt(i));
}
}
ProductPtr node = shapes[0];
ConvertToNormal(node);

StepMeshReader

结构、成员与 StepData 基本一致,但是增加了如下变量:

  1. 当前 Product 的 Mesh 数据,通过 Meshes() 获取。

(可选,仅 TopoShape)将树状 StepData 转换为一维数组

如果不需要保留 Product 的装配结构信息,可以将树状 Product 树状结构转换为一维数组,每个节点中有且只有 1 个 TopoShape,且没有子节点。

// header file
// ...
// or
AMCAX::STEP::StepDataList shapesN2 = AMCAX::STEP::StepDataTool::Flatten(shapes);
Utility class for operations on STEP shape data structures.
static AMCAX_API StepDataList & FlattenInplace(StepDataList &shapes, bool unrolling=true)
Flatten a StepData tree into a one-dimensional array, in place.
static AMCAX_API StepDataList Flatten(const StepDataList &shapes, bool unrolling=true)
Create a flattened, one-dimensional copy of a StepData tree.

获取 sub-shape 的属性信息

获取到具体的 TopoShape 之后,可以通过 TopoIterator、TopoExplorer、TopoExplorerTool 等由 AMCAX 内核提供的接口获取其 sub-shape。 可以通过以下代码获取其名称等信息:

// 假设 shapes 中包含至少一个 Product 树
std::shared_ptr<AMCAX::STEP::StepData> treeroot = shapes[0];
// 假设当前 StepData 节点中包含至少一个 TopoShape,且其中类型为 Compound
AMCAX::TopoShape compound = treeroot->Shapes()[0];
const AMCAX::STEP::PropertyChain& props = treeroot->PropertyChains()[0];
// PropertyChain 作为一个 std::vector 的别名,其元素类型为 std::pair<TopoShape, StepPropertyUnit>;
// 由 StepReader 输出的 PropertyChain 中,每个 sub-shape 均只会出现一次;
// StepPropertyUnit 重载了 operator+=(),允许不同的对象之间进行合并、覆盖操作。
// 因此,如果用户预期对属性会有比较频繁的查找和更新操作,
// 也可以尝试构建 std::unordered_map<TopoShape, StepPropertyUnit>
for (AMCAX::TopoExplorer exp(compound, AMCAX::ShapeType::Solid);
exp.More();
exp.Next())
{
const AMCAX::TopoShape solid = exp.Current();
auto it = std::find_if(props.begin(), props.end(),
[&solid](const AMCAX::STEP::PropertyPair& pair)
{ return solid.IsSame(pair.first); });
if (it != props.end())
{
const StepPropertyUnit& property = it->second;
if (property.NameHasValue())
{ /* do something with name */ }
if (property.ColorHasValue())
{ /* do something with color */ }
}
}
用于遍历 B-Rep 结构的工具类
定义 TopoExplorer.hpp:14
AMCAX_API bool More() const
判断遍历器中是否还有形状未遍历
形状的基类,包含具有位置和方向信息的基础形状
定义 TopoShape.hpp:15

(仅 Mesh)获取 Mesh 信息

由于 Mesh 数据是由 TopoShape 转换而来的,因此当且仅当一个 StepMeshData 节点中包含 TopoShape 数据时,才可能出现对应的 Mesh 数据。 Mesh 的转换工作由 StepMesh 类完成,可以参考 <step/mesh/StepMesh.hpp> 获取更多信息。现阶段 StepMesh 只接受类型为 Solid 的 TopoShape。 参考以下代码,获取 Mesh 数据以及对应的 TopoShape,名称,颜色等信息:

// 此处假设 shapes 中包含至少一个 StepMeshData 树
std::shared_ptr<AMCAX::STEP::StepMeshData<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>> root = shapes[0];
// 此处假设该 StepMeshData 树的 root 节点中包含 2 个 TopoShape,即 Shapes().size() 为 2
// 此处假设第一个 Shape 的类型为 Compound,其中包含 3 个 solid,一个 face
// 此处假设第二个 Shape 的类型为 Solid
std::cout << meshes.size() << '\n'; // "2",每个 TopoShape,无论其中包含几个 Solid,
// 都与一个 std::vector<AMCAX::StepMesh<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>> 对应
AMCAX::TopoShape& shape0 = root->ShapeAt(0);
std::vector<StepMesh<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>>& meshes0 = root->MeshAt(0);
std::cout << meshes0.size() << '\n'; // "3",因为该 Compound 拥有 3 个 Solid sub-shape,且 StepMesh 只处理 Solid 类型
AMCAX::TopoShape& shape1 = root->ShapeAt(1);
std::vector<StepMesh<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>>& meshes1 = root->MeshAt(1);
std::cout << meshes1.size() << '\n'; // "1",因为第二个 shape 本身类型为 Solid,因此只包含一个 solid
std::vector<AMCAX::TopoShape> solidSet0;
for (AMCAX::TopoExplorer exp(shape0, AMCAX::ShapeType::Solid); exp.More(); exp.Next())
{
solidSet0.push_back(exp.Current());
}
// 获取第一个 shape 对应的 Mesh 数据,name、color 信息
for (size_t solidIndex = 0; solidIndex < solidSet0.size(); ++solidIndex)
{
const AMCAX::TopoShape& solid = solidSet0[solidIndex];
// 通过 index 访问对应的 Mesh
// 关于获取 solid name 和 solid color 的部分,请参考前一小节中的内容
// doSomethingWith(curMesh, name, color);
}
// 获取第一个 shape 对应的 Mesh 数据,name、color 信息
// 与第一个 shape 的代码基本一致,此处不再重复
Class for reading STEP file and convert solid to mesh.
定义 StepMeshData.hpp:22

(仅 Mesh)将 StepMeshData 转换为 StepData

在部分情况下,也会出现需要将 StepMeshData 转换为基类 StepData、或是将 StepMeshDataList 转换为 StepDataList 的场景。 可以参考以下代码:

using MeshDataList = AMCAX::STEP::StepMeshDataList<AMCAX::Meshing::Mesh::TriSoupTraits_Coord>;
MeshDataList smdl = reader.GetShapes();
AMCAX::STEP::StepDataList sdl;
sdl.reserve(smdl.size());
for (auto& smdptr : smdl)
{
sdl.push_back(smdptr->ToStepData());
}

(仅 TopoShape)提取 StepData 中的 TopoShape

虽然上文中已经给出使用 StepData::Shape() 获取 TopoShape 的方法,但考虑到每个 StepData 对象中可能包含不止一个图形数据,且装配结构中的情况可能更为复杂,模块中也提供了额外的方法提供完整的 TopoShape 对象:

仅获取当前 StepData 储存的 TopoShape

for (std::shared_ptr<StepData> node : reader.GetShapes())
{
TopoShape cur_shape = node->OneShape(/* recursive = */ false);
// 如果 node 中的 Shapes 为空,则返回 Null Shape;
// 如果 node 中的 Shapes 长度为 1,则直接返回该 Shape;
// 如果 node 中的 Shapes 长度大于 1,则返回所有 Shape 组成的 Compound。
}

获取当前 StepData 以及其所有 Children 组成的 TopoShape

for (std::shared_ptr<StepData> node : reader.GetShapes())
{
TopoShape cur_shape = node->OneShape(/* recursive = */ true);
}

获取完整 StepDataList 组成的 TopoShape

TopoShape result = AMCAX::STEP::StepDataTool::MakeCompound(reader.GetShapes());
static AMCAX_API AMCAX::TopoShape MakeCompound(const std::shared_ptr< StepData > &root)
Create a TopoShape by combining all shapes in a StepData tree.

(仅 TopoShape) 导出部分

导入头文件

本示例程序中 Writer 部分只需要引入一个头文件,通过以下代码将该头文件加入程序:

Class for exporting TopoShape objects and related data to STEP files.

创建 Writer 对象

以下代码通过指定输出文件之文件名(路径)的方式创建并初始化一个 Writer 对象:

AMCAX::STEP::StepWriter writer("/path/to/output.step");
Class for exporting TopoShape objects and related data to STEP files.
定义 StepWriter.hpp:30

同 Reader 类似, Writer 可以接受输出流作为构造参数:

std::ofstream ofs("/path/to/output.step");
if (!ofs.is_open())
{
return 1;
}

注意:若指定输出文件已存在,将被覆盖。

(可选)设置缩放

只要输入的 TopoShape 符合输出条件,Writer 就会假设其单位长度为 1 毫米,并直接将其数值以不做缩放的方式输出至文件。 然而,假使该 TopoShape 创建时使用了其他单位,这会导致导出的图形尺寸不符。

虽然不会对输出的数值进行缩放,但可以通过以下代码调整 STEP 文件中定义的单位长度:

writer.SetUnit(AMCAX::STEP::StepLengthUnit::PresetLengthUnit::CENTIMETRE);

需要在导出图形数据之前完成该操作。

(可选)设置进度汇报

和 Reader 一样,Writer 也使用回调函数进行进度汇报,参考以下代码:

writer.SetProgressCallback(
{
std::cout << " State: " << int(state) << std::endl;
if (c2.type == AMCAX::STEP::StepProgressCarrier::U64_TYPE && c2.payload.u64)
{
std::cout << " Carrier1: " << c1.payload.u64 << std::endl;
std::cout << " Carrier2: " << c2.payload.u64 << std::endl;
}
});

进行导出

(可选)写文件头

为了在 STEP 文件头部添加必要的信息,用户需要首先调用:

writer.Init();

这一步将在文件中输出 ISO 标准编号,应用协议版本,以及其它一些必要的实体。 为了保证文件格式,需要在 Init() 执行完毕后再将 TopoShape 传入 Writer。 不过,默认情况下,Writer 会自动执行 Init()。

写 TopoShape

无论是一次性将包含所有 TopoShape 的 AMCAX::STEP::StepDataList 传入 Writer,还是多次调用函数传入,都有一样的效果。 也就是说,除去出于展示需要而特别指定颜色的部分,以下两段代码的效果是一致的:

// 假设 StepDataList shapes 包含至少3个元素;
AMCAX::STEP::StepDataList shape_part_0 = {shapes.begin(), shapes.begin() + shapes.size() - 2};
std::shared_ptr<AMCAX::STEP::StepData> shape_part_1 = shapes[shapes.size() - 2];
AMCAX::TopoShape shape_last = shapes.back()->Shapes().front();
writer.WriteShapes(shape_part_0);
writer.WriteShape(shape_part_1);
writer.WriteShape(shape_last);

writer.WriteShapes(shapes);

写 Label

AMCAXAf Label 是一种支持属性的图形格式,因此,直接将 Label 传递给 Writer,也可以导出带有属性的图形数据:

// init and setup root;
writer.WriteShape(root);
// or writer.WriteLabel(root);
The class of Label
定义 Label.hpp:26

然而,由于 StepData 类同时储存 TopoShape 和 Label 两种数据,因此在将 StepData 对象传递给 Writer 时,需要明确告知 writer 使用何种数据:

// init and setup root;
auto node = std::make_shared<AMCAX::STEP::StepData>();
// AddShape(Label) 会同时更新 Shapes 和 Labels,而对于 PropertyChains 和其它数据则使用空数据进行占位
node->AddShape(root);
// 合法,但只会输出不包含任何属性信息的 TopoShape
writer.WriteShape(node);
// 使用 Label 中的完整信息进行输出
writer.WriteLabel(root);

完成导出并保存文件

默认情况下,StepWriter 在析构时才会执行真正的导出工作,并关闭输出流(当且仅当该 Writer 对象是使用文件路径创建的)。然而,也可以通过以下代码手动完成导出:

writer.Done();

注意:如果再次对该 Writer 对象调用 Init() 函数,已输出的文件将会被覆盖。

简化接口

AMCAX::STEP::StepDataTool 类中,除了对 StepReader 产生的 StepDataList 操作的工具函数以外,亦提供了简化的接口提供导入、导出 TopoShape 的功能。 注意其中零件名称、装配、颜色、渲染等信息可能不会被保留。 其使用方式如下:

bool success = AMCAX::STEP::StepDataTool::Read(shape, "/path/to/input.step");
if (success)
{
AMCAX::STEP::StepDataTool::Write(shape, "/path/to/output.step");
}
static AMCAX_API bool Write(const AMCAX::TopoShape &s, std::ostream &os)
Write a TopoShape to a stream in STEP format.
static AMCAX_API bool Read(AMCAX::TopoShape &s, std::istream &is)
Read a TopoShape from a stream in STEP format.

点击这里example01可获得 Reader 的完整源码,大家根据学习需要自行下载。 点击这里example02可获得 StepMeshReader 的完整源码,大家根据学习需要自行下载。

附录

#include <iostream>
// 输出 Product 树状结构
void printProductName(const std::shared_ptr<AMCAX::STEP::StepData> node, int indent = 0)
{
for (int i = 0; i < indent; ++i)
{
std::cout << "| ";
}
if (node->IsShadow())
{
std::cout << "SHADOW: " << node->ProductName() << std::endl;
}
else
{
std::cout << node->ProductName() << std::endl;
for (const std::shared_ptr<AMCAX::STEP::StepData> child : node->Children())
{
printProductName(child, indent + 1);
}
}
}
// 输出 Product 树中所有 Solid 的命名
void printSolidName(const std::shared_ptr<AMCAX::STEP::StepData> node, int indent = 0)
{
for (size_t i = 0; i < node->ShapesSize(); ++i)
{
const AMCAX::TopoShape& origShape = node->ShapeAt(i);
const AMCAX::STEP::PropertyChain& props = node->PropertyChainAt(i);
for (AMCAX::TopoExplorer SolidExp(origShape, AMCAX::ShapeType::Solid);
SolidExp.More();
SolidExp.Next())
{
const AMCAX::TopoShape& solid = SolidExp.Current();
auto it = std::find_if(props.begin(), props.end(),
[&solid](const AMCAX::STEP::PropertyPair& pair)
{ return solid.IsSame(pair.first); });
if (it != props.end() && (*it).second.NameHasValue())
{
std::string name = (*it).second.Name();
std::cout << '"' << name << std::endl;
}
}
}
for (const std::shared_ptr<AMCAX::STEP::StepData> child : node->Children())
{
printSolidName(child, indent + 1);
}
}
int main()
{
AMCAX::STEP::StepDataList shapes;
/**** Reading Part ****/
AMCAX::STEP::StepReader reader("D:/examples/tank.step");
// 设置导入的图形在内核中使用的单位。此操作会造成图形的缩放。
reader.SetUnit(AMCAX::STEP::StepLengthUnit::PresetLengthUnit::METRE);
bool topo_success = reader.Read();
if (!topo_success)
{
return -1;
}
shapes = reader.GetShapes();
// 输出 Product 树的名称以树中所有 Solid 的名称
for (std::shared_ptr<AMCAX::STEP::StepData> root : shapes)
{
printProductName(root);
printSolidName(root);
}
// 将 StepDataList 中的图形数据提取出来
// 将 StepDataList 的树状结构转换为一维数组
AMCAX::STEP::StepDataList flatten = AMCAX::STEP::StepDataTool::Flatten(shapes);
/**** Writing Part ****/
AMCAX::STEP::StepWriter writer("./output.step");
// 设置导出的图形在 STEP 文件中的格式。此操作只会影响输出的单位信息。
writer.SetUnit(AMCAX::STEP::StepLengthUnit::PresetLengthUnit::METRE);
writer.Init();
writer.WriteShapes(shapes);
writer.Done();
}
用于遍历 B-Rep 结构的工具类
B-Rep 结构迭代器的类