Table of Contents

From C++ to C#

NetOcc is generated from OCCT's headers: a C++ signature decides its C# signature. With the rules below, OCCT's reference manual and C++ code translate line by line.

What a C++ type becomes

flowchart LR
    transient["Standard_Transient subclass<br/>Geom_Circle, AIS_Shape"] -->|holds one reference| c1["C# class"]
    other["any other class<br/>TopoDS_Shape, BRepPrimAPI_MakeBox"] -->|owns the object| c2["C# class"]
    value["fixed-layout value<br/>gp_Pnt, Bnd_Box, Quantity_Color"] -->|same memory layout| c3["C# struct"]
    enumeration["enum"] --> c4["C# enum"]
    functions["namespace functions<br/>TopoDS::Face"] --> c5["static class"]

All classes are IDisposable, see Object lifetimes.

Names

C++ C#
package gp, class gp_Pnt namespace OCC.Core.gp, gp_Pnt
nested Geom_Curve::ResD1 Geom_Curve_ResD1: scopes joined by _
namespace functions TopoDS::Face(shape) a static class: TopoDS.Face(shape)
GeomAbs_CurveType enum a C# enum with OCCT's values and underlying type
typedef NCollection_Array1<gp_Pnt> TColgp_Array1OfPnt class TColgp_Array1OfPnt
a parameter named like a C# keyword (string) suffixed: string_

Handles

Handle(T) is T: the proxy holds one reference on the object, and null is a null handle. A C# cast never reaches the C++ object, so casts go through DownCast:

Geom_Curve curve = new Geom_Circle(new gp_Ax2(), 10); // a Handle(Geom_Curve) in C++
var circle = Geom_Circle.DownCast(curve);             // the circle, or null
var line = Geom_Line.DownCast(curve);                 // null: it isn't a line
var radius = circle?.Radius();

Value types

All of gp, Bnd_Box, Quantity_Color, Poly_Triangle and a few more are C# structs with OCCT's memory layout: no allocation, passed by pointer to OCCT. Their methods run OCCT's code, and OCCT's arithmetic operators (+, -, *, /, ^) are C# operators. Other classes have none; OCCT's operators mostly repeat a named member, which they have (Multiplied, IsEqual, Value):

var sum = new gp_Vec(1, 0, 0) + new gp_Vec(0, 1, 0);   // operator+
var scaled = sum * 2;                                  // operator*
var dot = sum * new gp_Vec(1, 0, 0);                   // gp_Vec * gp_Vec: the dot product
var cross = new gp_Vec(1, 0, 0) ^ new gp_Vec(0, 1, 0); // operator^: the cross product

Plain data (OCCT 8's evaluation results) is a struct with public fields: curve.EvalD1(u).Point.

Parameters

C++ C#
T& of a number, enum or struct ref T (never out: OCCT may read it first)
const T& of a struct in T
T& or const T& of a class the proxy
Handle(T)& ref T: the variable gets the object OCCT puts there
T* of numbers or structs a C# array, pinned for the call (double[], gp_Pnt[])
T* of a class the proxy, null for nullptr
void*, function pointers, pointers OCCT keeps IntPtr
int (&)[3] an array of exactly three
Message_ProgressRange at the end, defaulted left out
default arguments overloads
// Standard_Real& First, Standard_Real& Last: ref, initialized first
double first = 0, last = 0;
var curve = BRep_Tool.Curve(edge, ref first, ref last);

// Bnd_Box& (a struct): ref as well
var bounds = new Bnd_Box();
OCC.Core.BRepBndLib.BRepBndLib.Add(box, ref bounds);

A member returning T& of a number, enum or struct is a C# ref return, read and written in place:

// Standard_Real& Value(int, int): a ref return, read and written in place
var matrix = new math_Matrix(1, 2, 1, 2, 0.0);
matrix.Value(1, 2) = 5.0;
ref var cell = ref matrix.Value(2, 1);
cell = 7.0;

A member returning a class by reference gives a proxy that borrows the object and keeps its owner alive. So does a copy that refers to its owner, such as BRepGraph.Topo()'s view of the graph or V3d_Viewer.ActiveViewIterator()'s iterator over the viewer's views. A member returning *this for chaining returns void.

Collections

OCCT's arrays, lists, sequences and maps are C# classes named by OCCT's aliases, IEnumerable<T>, with indexers using OCCT's bounds:

// arrays from C# arrays, numbered from 1; indexers use OCCT's bounds
var points =
  new TColgp_Array1OfPnt([new gp_Pnt(0, 0, 0), new gp_Pnt(10, 0, 0), new gp_Pnt(10, 10, 0)]);
var second = points[2];
gp_Pnt[] copy = points.ToArray();

// or with bounds of your choice
var weights = new TColStd_Array1OfReal(0, 2);
weights[0] = 1.0;

// sequences grow, and count from 1
var sequence = new TColStd_SequenceOfReal();
sequence.Append(1.5);
sequence.Append(2.5);
var sum = sequence.Sum(); // IEnumerable<double>: LINQ works

// maps: an indexed map numbers its keys from 1
var faces = new TopTools_IndexedMapOfShape();
TopExp.MapShapes(new BRepPrimAPI_MakeBox(1, 1, 1).Shape(), TopAbs_ShapeEnum.TopAbs_FACE, faces);
var index = faces.FindIndex(faces[3]); // 3
Collection Indexed From
*_Array1Of*, *_Array2Of* by the bounds given (Lower() to Upper()) a C# array: 1
*_SequenceOf* yes 1
*_ListOf* no: enumerate, First(), Last()
*_IndexedMapOf*, *_IndexedDataMapOf* by number, and FindIndex(key) 1
*_MapOf* no: a set, Contains(key)
*_DataMapOf* by key, ContainsKey(key); enumerates KeyValuePairs

The handle-managed variants (TColgp_HArray1OfPnt) derive from their collection. Count is OCCT's Extent() or Length(). A bad index throws:

Action beyond = () => _ = points[4]; // Standard_OutOfRange, as an OcctException

Strings and the standard library

// Standard_GUID: System.Guid
Guid id = TDataStd_Real.GetID();

// std::optional<gp_Pnt>: gp_Pnt?, null for an empty box
gp_Pnt? centre = new Bnd_Box().Center();

// TCollection_AsciiString and const char*: string
Geom_Curve curve = new Geom_Circle(new gp_Ax2(), 1);
string name = curve.DynamicType().Name(); // "Geom_Circle"
C++ C#
const char*, TCollection_AsciiString, std::string, std::string_view string (UTF-8)
const char16_t*, TCollection_ExtendedString string (UTF-16)
Standard_GUID System.Guid
std::array<double, 3> double[]
std::optional<T> T?
std::pair<A, B> a class with First and Second
std::bitset<N> ulong
std::complex<double> OCC.Core.Complex
std::ostream&, std::istream& System.IO.Stream, see Files
char byte (its bits, not a character)
char32_t uint (a code point)
size_t ulong; on x86 a larger value throws OcctException

Errors

OCCT's Standard_Failure and its subclasses arrive as OcctException, see Errors.

Deprecated and left out

What OCCT marks deprecated is wrapped and [Obsolete]. What can't be mapped is left out, each member with its reason in Skipped members: members OCCT declares but never exports, raw pointers into structs, streams OCCT would keep beyond a call, template instances C# can't create or name.