- Updated multiple files to replace instances of NCollection_Vector with NCollection_DynamicArray
18 KiB
OCCT AI Assistant Guidelines
This document provides comprehensive guidance for AI assistants (GitHub Copilot, Claude, ChatGPT, and others) working with the Open CASCADE Technology (OCCT) C++17+ 3D CAD/CAM/CAE library.
1. Core Directives
IMPORTANT: These are the most critical rules. Follow them strictly.
-
Memory Management is Paramount:
- ALWAYS use
occ::handle<ClassName>for any class inheriting fromStandard_Transient(e.g.,Geom_*,Poly_*,AIS_*,V3d_*). This is for reference-counted objects. - NEVER use raw pointers (
ClassName*) for these types, as it will cause memory leaks. - Correct:
occ::handle<Geom_Circle> aCircle = new Geom_Circle(...); - Wrong:
Geom_Circle* aCircle = new Geom_Circle(...); - Note: The legacy
Handle(ClassName)macro still exists butocc::handle<>is preferred in new code.
- ALWAYS use
-
Check Operation Status:
- After using an API that performs a geometric operation (e.g.,
BRepAlgoAPI_Fuse,BRepBuilderAPI_MakeEdge), ALWAYS check if the operation was successful using theIsDone()method before accessing the result. - Correct:
BRepAlgoAPI_Fuse aFuser(theShape1, theShape2); if (aFuser.IsDone()) { const TopoDS_Shape& aResult = aFuser.Shape(); } else { // Handle error }
- After using an API that performs a geometric operation (e.g.,
-
Strict Naming and File Conventions:
- Adhere to the strict
Package_ClassNameconvention. - Place new files in the correct directory:
src/Module/Toolkit/Package/. - After adding a file, ALWAYS update the corresponding
src/Module/Toolkit/Package/FILES.cmakefile.
- Adhere to the strict
-
Use Modern C++ Idioms:
- Use range-based
forloops and structured bindings where applicable. - Use the modern
TopExp_Explorerconstructor style. - Correct:
for (TopExp_Explorer anExp(theShape, TopAbs_FACE); anExp.More(); anExp.Next()) { ... } - Wrong:
for (TopExp_Explorer anExp; anExp.Init(theShape, TopAbs_FACE); anExp.More(); anExp.Next()) { ... }
- Use range-based
-
Safe Type Casting:
- When downcasting topological shapes, ALWAYS use the
TopoDShelper functions to avoid errors. - Correct:
const TopoDS_Face& aFace = TopoDS::Face(anExp.Current()); - Wrong:
const TopoDS_Face& aFace = (const TopoDS_Face&)anExp.Current();
- When downcasting topological shapes, ALWAYS use the
-
Handle Downcasting:
- Use
occ::down_cast<DerivedClass>(BaseHandle)to safely downcast handles. - Correct:
const occ::handle<Geom_Circle> aCircle = occ::down_cast<Geom_Circle>(aCurveHandle); // Alternative (legacy): occ::handle<Geom_Circle>::DownCast(aCurveHandle) - Wrong:
// Do not use C-style casts on handles Geom_Circle* aCircle = (Geom_Circle*)aHandle.Get();
- Use
-
Validate Handles for Null Safety:
- ALWAYS check that an
occ::handle<ClassName>is not null before dereferencing it:if (!theHandle.IsNull()) { // use theHandle }
- ALWAYS check that an
2. Project Overview
Open CASCADE Technology (OCCT) is a comprehensive C++ software development platform for 3D surface and solid modeling, CAD data exchange, and visualization. It's a modern C++17+ library providing services for CAD/CAM/CAE applications.
Architecture & Source Organization
src/: Source code, organized by aModule/Toolkit/Packagehierarchy.tests/: Draw Harness test files, organized by functionality.adm/: Administrative and build configuration files.samples/: Example applications.
3. Code Conventions
NEVER use non-ASCII symbols in code or comments.
Naming Patterns
| Element Type | Pattern | Example |
|---|---|---|
| Classes | Package_ClassName |
TopoDS_Shape, BRep_Builder |
| Public Methods | MethodName |
IsDone(), Shape() |
| Private Methods | methodName |
myInternalMethod() |
| Method Parameters | theParameterName |
theShape, theTolerance |
| Local Variables | aVariableName |
aBox, anExplorer |
| Class Member Fields | myFieldName |
myShape, myIsDone |
| Struct Member Fields | FieldVariableName |
Point, Value |
| Global Variables | THE_GLOBAL_VARIABLE |
THE_DEFAULT_PRECISION |
Primitive Types
Use standard C++ primitive types in all code. The old Standard_* typedefs are deprecated and must not be used:
| Use This | Instead of (Deprecated) | Usage |
|---|---|---|
int |
Integer values | |
double |
Floating-point numbers | |
bool |
Boolean values | |
float |
Single-precision floats | |
char |
Character values | |
uint8_t |
Byte values | |
size_t |
Size values | |
void* |
Generic pointers | |
char16_t |
Unicode characters | |
const char* |
C-style strings | |
true/false |
Boolean literals |
WARNING: All
Standard_*type aliases inStandard_TypeDef.hxxare markedStandard_DEPRECATEDand will be removed in future versions. Always use native C++ types directly.
Strings and Collections
ALWAYS use OCCT collection classes instead of STL containers:
| OCCT Type | Instead of | Description |
|---|---|---|
TCollection_AsciiString |
std::string |
ASCII string |
TCollection_ExtendedString |
std::wstring |
Unicode string |
NCollection_Array1<T> |
std::vector<T> |
Fixed-size array (1-based) |
NCollection_DynamicArray<T> |
std::vector<T> |
Dynamic array |
NCollection_List<T> |
std::list<T> |
Doubly-linked list |
NCollection_Sequence<T> |
std::deque<T> |
Indexed sequence |
NCollection_Map<K> |
std::unordered_set<K> |
Hash set |
NCollection_DataMap<K,V> |
std::unordered_map<K,V> |
Hash map |
NCollection_IndexedMap<K> |
- | Indexed hash set |
NCollection_IndexedDataMap<K,V> |
- | Indexed hash map |
IMPORTANT: Package-Specific Type Aliases Removed
Old package-specific type aliases have been removed from OCCT. You must use
NCollection_*templates directly with explicit types:
Removed Alias (Do Not Use) Use Instead TColStd_ListOfIntegerNCollection_List<int>TColStd_Array1OfRealNCollection_Array1<double>TColStd_SequenceOfIntegerNCollection_Sequence<int>TColStd_MapOfIntegerNCollection_Map<int>TColStd_DataMapOfIntegerRealNCollection_DataMap<int, double>TopTools_ListOfShapeNCollection_List<TopoDS_Shape>TopTools_MapOfShapeNCollection_Map<TopoDS_Shape>TColgp_Array1OfPntNCollection_Array1<gp_Pnt>TColgp_SequenceOfPntNCollection_Sequence<gp_Pnt>Exception:
TColStd_PackedMapOfIntegerstill exists as it has a specialized implementation.
If STL containers are absolutely necessary, use OCCT's allocators:
#include <NCollection_Allocator.hxx>
#include <NCollection_OccAllocator.hxx>
#include <NCollection_IncAllocator.hxx>
// Option 1: NCollection_Allocator - uses standard OCCT memory allocation
std::vector<gp_Pnt, NCollection_Allocator<gp_Pnt>> aPoints;
std::list<TopoDS_Shape, NCollection_Allocator<TopoDS_Shape>> aShapes;
// Option 2: NCollection_OccAllocator - with custom memory pool (preferred for performance)
occ::handle<NCollection_IncAllocator> anIncAlloc = new NCollection_IncAllocator();
NCollection_OccAllocator<gp_Pnt> anAllocator(anIncAlloc);
std::vector<gp_Pnt, NCollection_OccAllocator<gp_Pnt>> aPooledPoints(anAllocator);
Modern C++ Features
This is a C++17+ codebase. Use modern features where appropriate:
- Range-based
forloops - Structured bindings:
for (const auto& [aKey, aValue] : aMap) std::optionalfor optional return valuesstd::variantfor type-safe unionsif constexprfor compile-time conditions[[nodiscard]],[[maybe_unused]]attributes where appropriate
Use of auto Keyword
Use auto only in the following cases:
- Where syntax requires it (templates, structured bindings, lambdas)
- To omit the type of object in range-based
forloops - To omit the type of container iterators:
auto anIter = aContainer.begin()
Avoid auto in these cases:
- To omit long type names (use type aliases instead)
- To omit "obvious" return types
- Simply to avoid typing the actual type
Readability is more important than brevity. Always prefer explicit types.
Const Correctness
Use const for variables that will not be modified after initialization:
const double aTolerance = 0.001;
const TopoDS_Shape aShape = aBuilder.Shape();
Use constexpr for values that can be computed at compile time:
constexpr int THE_MAX_ITERATIONS = 100;
constexpr double THE_PI = 3.14159265358979323846;
Prefer const references to avoid unnecessary copies:
void ProcessShape(const TopoDS_Shape& theShape);
for (const TopoDS_Face& aFace : aFaces)
{
// ...
}
4. Step-by-Step Workflow: Adding a New Class
This example demonstrates adding a new class BRepLib_MyNewClass to the BRepLib package in the TKTopAlgo toolkit.
1. Create Header and Source Files:
cd src/ModelingAlgorithms/TKTopAlgo/BRepLib
touch BRepLib_MyNewClass.hxx BRepLib_MyNewClass.cxx
2. Implement the Class: Add content following all code conventions (see sections 3 and 7).
3. Add Files to Package CMake:
Edit src/ModelingAlgorithms/TKTopAlgo/BRepLib/FILES.cmake:
set(OCCT_BRepLib_FILES
...
BRepLib_MyNewClass.hxx
BRepLib_MyNewClass.cxx
)
4. Create a GTest:
cd src/ModelingAlgorithms/TKTopAlgo/GTests
touch BRepLib_MyNewClass_Test.cxx
5. Add GTest to CMake:
Edit src/ModelingAlgorithms/TKTopAlgo/GTests/FILES.cmake:
set(OCCT_TKTopAlgo_GTests_FILES
...
BRepLib_MyNewClass_Test.cxx
)
6. Build and Run:
cd build
cmake .. -DBUILD_GTEST=ON
cmake --build . --config Release
./bin/OpenCascadeGTest --gtest_filter="*MyNewClass*"
5. Build and Test System
Build System (CMake)
- Primary build system: CMake 3.16+
- Build Directory: Always build out-of-source (e.g.,
build/) - Quick Build:
mkdir -p build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_GTEST=ON cmake --build . --config Release --parallel - Environment: Before running OCCT executables, source the environment:
- Linux/macOS:
source build/env.sh - Windows:
build\env.bat
- Linux/macOS:
Testing Frameworks
- Draw Harness: Tcl-based interactive testing in
tests/. Run withDRAWEXE. - GTest: C++ unit tests in
src/.../GTests/. Enable with-DBUILD_GTEST=ON.
6. Common Patterns & Key Packages
Common Operations
- Shape Creation:
BRepPrimAPI_MakeBox,BRepPrimAPI_MakeCylinder - Boolean Operations:
BRepAlgoAPI_Fuse,BRepAlgoAPI_Cut,BRepAlgoAPI_Common - Shape Exploration:
TopExp_Explorer - Transformations:
gp_TrsfwithBRepBuilderAPI_Transform
Key Packages
| Package | Purpose | Module |
|---|---|---|
gp |
Geometric Primitives (Points, Vecs) | FoundationClasses |
Geom |
Geometric entities (Curves, Surfaces) | ModelingData |
TopoDS |
Topological Data Structures | ModelingData |
TopExp |
Exploring topological shapes | ModelingData |
BRepAlgoAPI |
High-level modeling algorithms | ModelingAlgorithms |
BRepPrimAPI |
Geometric primitives creation | ModelingAlgorithms |
AIS |
Application Interactive Services | Visualization |
Common Headers
#include <Standard_Handle.hxx> // occ::handle, occ::down_cast
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <Geom_Circle.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
#include <BRep_Builder.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <Standard_Failure.hxx>
#include <NCollection_List.hxx> // NCollection_List<T>
#include <NCollection_DataMap.hxx> // NCollection_DataMap<K,V>
#include <NCollection_IndexedDataMap.hxx>// NCollection_IndexedDataMap<K,V>
7. Code Documentation Style
Header Files (.hxx) - Method Documentation
Use Doxygen-style comments with //! prefix:
//! Brief description of the method functionality.
//! Additional details if needed.
//! @param[in] theInputParam description of input parameter
//! @param[out] theOutputParam description of output parameter
//! @param[in,out] theInOutParam description of in/out parameter
//! @return description of return value
Standard_EXPORT bool MethodName(const InputType& theInputParam,
OutputType& theOutputParam);
Rules:
@param[in]for input parameters@param[out]for output parameters@param[in,out]for bidirectional parameters@returnfor return value description
Source Files (.cxx) - Method Separators
Each method MUST be preceded by:
- A separator line of exactly 100 characters:
//followed by 98=signs - An empty line after the separator
//=================================================================================================
void MyClass::MyMethod(const TopoDS_Shape& theShape)
{
// Implementation
}
//=================================================================================================
bool MyClass::AnotherMethod()
{
// Implementation
}
DO NOT use old-style function guards:
// WRONG - Do not use this style:
//=================================================================================================
// purpose: Description of what the method does
// function: MyClass::MyMethod
//=================================================================================================
Technical Comments
Place implementation notes inside the method body:
- At the beginning for overall approach
- Inline where specific logic needs explanation
//=================================================================================================
void MyClass::ComplexMethod(const TopoDS_Shape& theShape)
{
// Using iterative approach for better performance with large shape hierarchies.
for (TopExp_Explorer anExp(theShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
// Handle degenerate faces separately
const TopoDS_Face& aFace = TopoDS::Face(anExp.Current());
// ...
}
}
8. GTest Guidelines
Test Location and Naming
- Location:
src/Module/Toolkit/GTests/ - File naming:
ClassName_Test.cxxorPackageName_Test.cxx
Test Structure
#include <gtest/gtest.h>
#include <MyClass.hxx>
// Test fixture (optional)
class MyClassTest : public testing::Test
{
protected:
void SetUp() override
{
// Setup code
}
};
// Test with fixture
TEST_F(MyClassTest, MethodName_Scenario)
{
// Arrange
MyClass anObject;
// Act
const bool isSuccess = anObject.SomeMethod();
// Assert
EXPECT_TRUE(isSuccess);
}
// Standalone test
TEST(MyClassTest, BasicFunctionality)
{
// Test implementation
}
Naming Convention
Pattern: TestFixture.MethodOrFeature_Scenario_ExpectedBehavior
Examples:
DE_WrapperTest.Read_ValidSTEPFile_ReturnsTrueBRepAlgoAPI_FuseTest.TwoBoxes_ProducesValidShapegp_PntTest.Distance_SamePoint_ReturnsZero
Assertions
EXPECT_*- non-fatal (test continues)ASSERT_*- fatal (test stops)
Common assertions:
EXPECT_TRUE(condition)/EXPECT_FALSE(condition)EXPECT_EQ(actual, expected)/EXPECT_NE(actual, expected)EXPECT_NEAR(actual, expected, tolerance)- for floating-pointEXPECT_THROW(statement, exception_type)- for exceptions
Running Tests
# Build
cmake ..
cmake --build .
# Run all
./bin/OpenCascadeGTest
# Run filtered
./bin/OpenCascadeGTest --gtest_filter="*MyClass*"
# List tests
./bin/OpenCascadeGTest --gtest_list_tests
9. Key Project Files
| File | Purpose |
|---|---|
src/MODULES.cmake |
Defines all modules |
src/Module/TOOLKITS.cmake |
Defines toolkits within a module |
src/Module/Toolkit/PACKAGES.cmake |
Defines packages within a toolkit |
src/Module/Toolkit/Package/FILES.cmake |
Lists source/header files (edit when adding files) |
src/Module/Toolkit/GTests/FILES.cmake |
Lists GTest source files |
src/Module/Toolkit/EXTERNLIB.cmake |
External library dependencies |
build/env.sh / build/env.bat |
Environment setup script |