Open CASCADE (OCC) 是一个开源的 CAD/CAM/CAE 几何建模内核,它提供了多种容器类来存储和管理数据。下面我将详细介绍 Open CASCADE 中的主要容器类及其使用方法。
1. NCollection 容器
Open CASCADE 提供了一套名为 NCollection 的高效容器模板库,类似于 STL 但针对 CAD 应用进行了优化。
1.1 NCollection_Array1 - 一维数组
#include <NCollection_Array1.hxx>
#include <iostream>
int main() {
// 创建一个包含5个整数的数组,索引从1到5
NCollection_Array1<int> arr(1, 5);
// 填充数组
for (int i = arr.Lower(); i <= arr.Upper(); i++) {
arr(i) = i * 10;
}
// 访问和打印数组元素
std::cout << "Array elements:" << std::endl;
for (int i = arr.Lower(); i <= arr.Upper(); i++) {
std::cout << "arr(" << i << ") = " << arr(i) << std::endl;
}
// 检查边界
try {
std::cout << "Attempting to access arr(0): ";
std::cout << arr(0) << std::endl; // 这将抛出异常
} catch (Standard_OutOfRange&) {
std::cout << "Out of range exception caught!" << std::endl;
}
return 0;
}
1.2 NCollection_List - 双向链表
#include <NCollection_List.hxx>
#include <iostream>
int main() {
// 创建一个整数链表
NCollection_List<int> list;
// 添加元素
list.Append(10);
list.Append(20);
list.Append(30);
list.Prepend(5); // 在开头添加
// 遍历链表
std::cout << "List contents:" << std::endl;
for (NCollection_List<int>::Iterator it(list); it.More(); it.Next()) {
std::cout << it.Value() << std::endl;
}
// 检查是否包含某个值
bool contains20 = list.Contains(20);
std::cout << "List contains 20: " << (contains20 ? "true" : "false") << std::endl;
// 删除元素
list.Remove(20);
// 再次遍历
std::cout << "List after removing 20:" << std::endl;
for (NCollection_List<int>::Iterator it(list); it.More(); it.Next()) {
std::cout << it.Value() << std::endl;
}
return 0;
}
1.3 NCollection_Map - 哈希映射
#include <NCollection_Map.hxx>
#include <NCollection_DefaultHasher.hxx>
#include <iostream>
int main() {
// 创建一个整数到字符串的映射
NCollection_Map<int, NCollection_DefaultHasher<int>> intMap;
// 添加元素
intMap.Add(1);
intMap.Add(2);
intMap.Add(3);
// 检查元素是否存在
std::cout << "Map contains 2: " << (intMap.Contains(2) ? "true" : "false") << std::endl;
std::cout << "Map contains 5: " << (intMap.Contains(5) ? "true" : "false") << std::endl;
// 遍历映射
std::cout << "Map contents:" << std::endl;
for (NCollection_Map<int, NCollection_DefaultHasher<int>>::Iterator it(intMap); it.More(); it.Next()) {
std::cout << it.Key() << std::endl;
}
// 删除元素
intMap.Remove(2);
// 再次检查
std::cout << "After removal, map contains 2: "
<< (intMap.Contains(2) ? "true" : "false") << std::endl;
return 0;
}
1.4 NCollection_DataMap - 键值对映射
#include <NCollection_DataMap.hxx>
#include <TCollection_AsciiString.hxx>
#include <iostream>
int main() {
// 创建一个字符串到整数的映射
NCollection_DataMap<TCollection_AsciiString, int> strToIntMap;
// 添加元素
strToIntMap.Bind("one", 1);
strToIntMap.Bind("two", 2);
strToIntMap.Bind("three", 3);
// 访问元素
if (strToIntMap.IsBound("two")) {
std::cout << "Value for 'two': " << strToIntMap.Find("two") << std::endl;
}
// 遍历映射
std::cout << "DataMap contents:" << std::endl;
NCollection_DataMap<TCollection_AsciiString, int>::Iterator it(strToIntMap);
for (; it.More(); it.Next()) {
std::cout << it.Key() << " => " << it.Value() << std::endl;
}
// 更新值
strToIntMap("two") = 22;
// 检查更新
std::cout << "Updated value for 'two': " << strToIntMap.Find("two") << std::endl;
// 删除元素
strToIntMap.UnBind("two");
// 检查删除
std::cout << "After removal, 'two' exists: "
<< (strToIntMap.IsBound("two") ? "true" : "false") << std::endl;
return 0;
}
2. TCollection 容器
TCollection 是 Open CASCADE 提供的另一组容器类,主要用于字符串处理。
2.1 TColStd_Array1OfReal - 实数数组
#include <TColStd_Array1OfReal.hxx>
#include <iostream>
int main() {
// 创建一个实数数组,索引从0到4
TColStd_Array1OfReal realArray(0, 4);
// 填充数组
for (int i = realArray.Lower(); i <= realArray.Upper(); i++) {
realArray(i) = i * 1.5;
}
// 访问和打印数组元素
std::cout << "Real array elements:" << std::endl;
for (int i = realArray.Lower(); i <= realArray.Upper(); i++) {
std::cout << "realArray(" << i << ") = " << realArray(i) << std::endl;
}
// 修改元素
realArray(2) = 99.9;
// 显示修改后的值
std::cout << "Modified realArray(2) = " << realArray(2) << std::endl;
return 0;
}
2.2 TColStd_SequenceOfReal - 实数序列
#include <TColStd_SequenceOfReal.hxx>
#include <iostream>
int main() {
// 创建一个实数序列
TColStd_SequenceOfReal realSeq;
// 添加元素
realSeq.Append(1.1);
realSeq.Append(2.2);
realSeq.Append(3.3);
// 在开头插入
realSeq.Prepend(0.0);
// 遍历序列
std::cout << "Sequence contents:" << std::endl;
for (int i = 1; i <= realSeq.Length(); i++) {
std::cout << "realSeq(" << i << ") = " << realSeq.Value(i) << std::endl;
}
// 删除元素
realSeq.Remove(2); // 删除第二个元素
// 再次遍历
std::cout << "Sequence after removal:" << std::endl;
for (int i = 1; i <= realSeq.Length(); i++) {
std::cout << "realSeq(" << i << ") = " << realSeq.Value(i) << std::endl;
}
return 0;
}
2.3 TColStd_ListOfInteger - 整数列表
#include <TColStd_ListOfInteger.hxx>
#include <iostream>
int main() {
// 创建一个整数列表
TColStd_ListOfInteger intList;
// 添加元素
intList.Append(10);
intList.Append(20);
intList.Append(30);
// 在开头插入
intList.Prepend(5);
// 遍历列表
std::cout << "List contents:" << std::endl;
TColStd_ListIteratorOfListOfInteger it(intList);
for (; it.More(); it.Next()) {
std::cout << it.Value() << std::endl;
}
// 查找元素
Standard_Integer toFind = 20;
if (intList.Contains(toFind)) {
std::cout << "List contains " << toFind << std::endl;
} else {
std::cout << "List does not contain " << toFind << std::endl;
}
// 删除元素
intList.Remove(toFind);
// 再次检查
std::cout << "After removal, list contains " << toFind << ": "
<< (intList.Contains(toFind) ? "true" : "false") << std::endl;
return 0;
}
3. 几何容器
Open CASCADE 还提供了一些专门用于几何数据的容器。
3.1 TColgp_Array1OfPnt - 点数组
#include <TColgp_Array1OfPnt.hxx>
#include <gp_Pnt.hxx>
#include <iostream>
int main() {
// 创建一个包含3个点的数组
TColgp_Array1OfPnt points(1, 3);
// 填充点
points.SetValue(1, gp_Pnt(0, 0, 0));
points.SetValue(2, gp_Pnt(1, 0, 0));
points.SetValue(3, gp_Pnt(1, 1, 0));
// 访问和打印点
std::cout << "Point array contents:" << std::endl;
for (int i = points.Lower(); i <= points.Upper(); i++) {
gp_Pnt p = points.Value(i);
std::cout << "Point " << i << ": ("
<< p.X() << ", " << p.Y() << ", " << p.Z() << ")" << std::endl;
}
// 修改点
points(2).SetY(2.0);
// 显示修改后的点
gp_Pnt modified = points.Value(2);
std::cout << "Modified point 2: ("
<< modified.X() << ", " << modified.Y() << ", " << modified.Z() << ")" << std::endl;
return 0;
}
3.2 TColGeom_Array1OfBSplineCurve - B样条曲线数组
#include <TColGeom_Array1OfBSplineCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
int main() {
// 创建控制点
TColgp_Array1OfPnt poles(1, 4);
poles.SetValue(1, gp_Pnt(0, 0, 0));
poles.SetValue(2, gp_Pnt(1, 1, 0));
poles.SetValue(3, gp_Pnt(2, 1, 0));
poles.SetValue(4, gp_Pnt(3, 0, 0));
// 创建节点和重数
TColStd_Array1OfReal knots(1, 2);
knots.SetValue(1, 0.0);
knots.SetValue(2, 1.0);
TColStd_Array1OfInteger mults(1, 2);
mults.SetValue(1, 4);
mults.SetValue(2, 4);
// 创建B样条曲线
Handle(Geom_BSplineCurve) curve1 =
new Geom_BSplineCurve(poles, knots, mults, 3);
// 创建另一个曲线
poles.SetValue(2, gp_Pnt(1, 2, 0));
Handle(Geom_BSplineCurve) curve2 =
new Geom_BSplineCurve(poles, knots, mults, 3);
// 创建B样条曲线数组
TColGeom_Array1OfBSplineCurve curves(1, 2);
curves.SetValue(1, curve1);
curves.SetValue(2, curve2);
// 访问曲线
Handle(Geom_BSplineCurve) firstCurve = curves.Value(1);
gp_Pnt startPoint = firstCurve->Value(firstCurve->FirstParameter());
gp_Pnt endPoint = firstCurve->Value(firstCurve->LastParameter());
// 打印曲线信息
std::cout << "First curve:" << std::endl;
std::cout << " Start point: (" << startPoint.X() << ", "
<< startPoint.Y() << ", " << startPoint.Z() << ")" << std::endl;
std::cout << " End point: (" << endPoint.X() << ", "
<< endPoint.Y() << ", " << endPoint.Z() << ")" << std::endl;
return 0;
}
4. 高级容器操作
4.1 容器间的转换
#include <TColStd_ListOfInteger.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <NCollection_List.hxx>
#include <iostream>
int main() {
// 创建一个NCollection列表
NCollection_List<int> nList;
nList.Append(1);
nList.Append(2);
nList.Append(3);
// 转换为TColStd列表
TColStd_ListOfInteger tList;
for (NCollection_List<int>::Iterator it(nList); it.More(); it.Next()) {
tList.Append(it.Value());
}
// 转换为序列
TColStd_SequenceOfInteger seq;
TColStd_ListIteratorOfListOfInteger it(tList);
for (; it.More(); it.Next()) {
seq.Append(it.Value());
}
// 打印序列内容
std::cout << "Sequence converted from NCollection list:" << std::endl;
for (int i = 1; i <= seq.Length(); i++) {
std::cout << seq.Value(i) << " ";
}
std::cout << std::endl;
return 0;
}
5. 性能考虑
Open CASCADE 容器与 STL 容器的选择:
NCollection vs STL:
- NCollection 针对 CAD 数据进行了优化
- 内存管理更符合 Open CASCADE 的整体架构
- 与 Open CASCADE 其他类集成更好
何时使用 STL:
- 需要与标准 C++ 代码交互时
- 需要 STL 特定算法时
- 性能测试显示 STL 在特定场景下更优时
总结
Open CASCADE 提供了丰富的容器类,包括:
- NCollection 容器:通用模板容器,类似 STL 但针对 CAD 优化
- TCollection 容器:主要用于字符串和基本数据类型
- 几何专用容器:如 TColgp_Array1OfPnt 等,用于几何数据
选择容器时应考虑:
- 数据类型和大小
- 需要的操作(随机访问、插入、删除等)
- 性能要求
- 与其他 Open CASCADE 类的互操作性
以上代码示例展示了各种容器的创建、填充、访问、修改和遍历操作,涵盖了 Open CASCADE 容器的主要功能。