# Foundation Classes

## gp

### gp_Trsf

Describes a general Transformation, describable via an invertible 4x4 matrix.

**Important:** Don't understand gp_Trsf's method "SetTransformation(gp_Axis3 fromSystem, gp_Axis3 toSystem)" as "create Transformation of origin of 'fromSystem' to origin of 'toSystem'. Instead it in fact creates the inverse transformation. Why? Take a vector, described as a coordinate tuple relative to the coordinate system 'fromSystem'. Applying the transformation created by 'SetTransformation' on this vectors coordinate tuple results in a new coordinate tuple, describing the same point in "absolute space" relative to the coordinate system 'toSystem'.

# Modeling Data

## BRep

##### BRep_Tools::CurveOnSurface

Returns curve, location as well as the parameter range of the edge for the representation determined by the surface. Edge orientation seems to be noticed

### BRepAdaptor

#### BRepAdaptor_Curve2d

Allows to create an adaptor for the 2d representation of an edge.

**Important:** The edge's orientation is not recognized, FirstParameter will not point to the beginning of a REVERSE-oriented edge but its end!

#### BRepAdaptor_Curve

Allows to create an adaptor for the 3d representation of an edge.

**Important:** The edge's orientation is not recognized, FirstParameter will not point to the beginning of a REVERSE-oriented edge but its end!

#### BRep_Builder

Low-level class to change topology datastructures

**Important:** The class has to be used in a specific (unusual) way, otherwise you will eventually cause a segmentation fault. The first method, you have to call is one of the "MakeX" methods first. You pass to the methode

the TopoDS_Shape object, you want to initalize. After that, you can start to call the builder's other methods

**Important:** If you want to change the tolerance of a shape using Update<Shape>, please note: The tolerance is only updated, if it is bigger than the current value!

```
TopoDS_Compound comp;
BRep_Builder build;
build.MakeCompound(comp);
build.Add(comp, ...);
...
```

(code is known to work with Open CASCADE versions: 6.3.0)

### BRepTools

#### BRepTools::WireExplorer

Allows to iterate over the edges in a wire in connection order.

**Important:** The orientation of the wire is respected and applied to the edges orientation!

### BRep_Tool

#### BRep_Tool::Curve

Allows to access the 3d curve representation of an edge.

**Important:** The edge has to have a 3d representation. Otherwise this function will simply return a useless uninitialized curve data structure causing a segmentation fault in the next OCC algorithm using the curve.

#### BRep_Tool::Surface

Allows to access the underlying Geom_Surface object of a TopoDS_Face.

**Important:** The method exists in 2 versions. One of them allows to pass a TopLoc_Location object. The transformation the location object is initalized with is **not** the location entry of the BRep_TFace object! It is instead the product of the BRep_TFace's transformation and the TopoDS_Face's transformation!

## GCPnts

### GCPnts_TangentialDeflection

You have to make sure, that

`CurvatureDeflection > Precision::Confusion () && AngularDeflection > Precision::Angular ()`

Otherwise an Construction_Error exception is thrown.

## GeomLib

### EvalMaxDistanceAlongParameter

This routine claims to calculate, for a given set of points on a curve A, the maximum distance to the respective points on a reference curve B (each point is projected onto B). The routine is internally using Extrema_LocateExtPC which seems to report the wrong result sometimes. For example, I was checking a line ((1,1,0) -> (0,0,0)) agains a NURBS rectangle (degree=1). Extrema_LocateExtPC wrongly reported (0,0,0) as the minimum projection of (1,0,0). This is clearly wrong!

## ProjLib

### ProjLib_ProjectOnPlane

Converts a 3d curve to it's threedimensionally described projection onto a arbitrary plane. You can project the curve using The projection can be done along every direction not parallel to the plane.

What happens when you're projecting a planar curve along a vector lying in it's plane? It's approximated using a BSpline curve.

### ProjLib_ProjectedCurve

Adaptor2d_Curve class to describe 3d curves lying on a surface as pcurves on the surface.

**Important:** All the "parametrized curve" properties are unimplemented. You cannot, for example, use D0 or D1. I have no idea why they left these methods unimplemented, but if you want to access curve points, you will have to first extract the actual curves (Geom_BSplineCurve, gp_Circ, …) and then access these…

# Modeling Algorithms

## BRepBuilderAPI

### BRepBuilderAPI_MakeEdge

Creates edges using 2d curves + surface or 3d curves.

**Important:** If the curve is closed and the vertices you pass to the routine are actually geometrically identical, **the routine fails!** Open CASCADE enforces topological identity of the vertices in this case. Maybe this behaviour was established, because otherwise Open CASCADE would have to communicate to the callee, which one of the two vertices was removed in order to uphold topological identity of vertices limiting a closed edge.

### BRepBuilderAPI_MakeEdge2d

Creates edges using existing 2d curves. The class basically wraps BRepLib_MakeEdge2d. The latter creates the edges by describing the 2d curves as pcurves bound to a plane which normal points along the z axis. The plane is created on the fly

` B.UpdateEdge(E,C,BRepLib::Plane(),TopLoc_Location(),preci);`

therefore it appears unwise to use MakeEdge2d if you will need the plane object later on (for example in order to use BRep_Tool::CurveOnSurface).

### BRepBuilderAPI_MakeFace

Creates faces.

**Important:** The builder assumes the initial wire to be the outer wire of the face. If you hand over an inner wire, it will nontheless be treated as an outer wire (reversed, if necessary, I assume). Still there is a possible solution to avoid the requirement of sorting your wires (outer wire first, inner wires following): Construct the builder using the default constructor, then call "Init", passing the surface as well as **false** for the boolean argument. This will create an **unbound** face. Passing this raw face to OCC algorithms would result in segmentation faults, but now you can add wires *in arbitrary order*. If one of those wires is an outer wire, the face will become valid!

**Important:** The builder expects the added edges to contain a pcurve representation. Otherwise, for some surfaces (e.g. cylindrical surfaces), the wire will be there but will not be used by Open CASCADE.

### BRepBuilderAPI_MakeWire

Creates wires.

**Important:** When you add an edge to the wire containing vertices overlapping through their tolerances (distance between vertices is smaller than maximum of their vertex tolerances), adding another edge will result in a strange behaviour in which both vertices will become topologically identical. So BRepBuilderAPI_MakeWire is actually changing the edge which was in there already. The resulting wire cannot be traversed by the WireExplorer anymore.

## BRepProj_Projection

The class allows you to do 2 kinds of projections of wires and edges from TopoDS on to a shape from TopoDS. The projection modes are:

- parallel projection (called "cylindrical projection" in the ref docs)
- conical projection (what kind of projection is that?)

**Important:** The reference docs document a boolean argument for the projection, specifying whether -if the target shape is a face- to consider the face boundary. This argument does not have any effect! It is unimplemented! Face boundary is always regarded. A possible workaround is to define a new TopoDS_Face including the complete surface - Annotation: In OCC 6.5.0 this boolean argument has been removed.

**Important II:** The routine fails if you try to project an arbitrary curve onto a plane surface having no UV-limits. Using Precision::Unlimited doesn't work either! You have to specify limited values for Umin, Umax, Vmin, Vmax!

**Important III:** BRepProj_Projection does not even try to preserve orientation of the wire, so the orientation is arbitrary after projection.

## ShapeAnalysis

### ShapeAnalysis_Edge

#### ShapeAnalysis_Edge::CheckVerticesWithCurve3d

**Important**: Returns TRUE, if one or two of the vertices are deviating from their counterparts on the 3d curve. Returns FALSE, if they botch match **OR** if there's no 3d curve. In that matter, the return value is chosen badly. In detail:

- if VERTEX 1 is deviating from the 3d curve, the status ShapeExtend_DONE1 is set
- if VERTEX 2 is deviating from the 3d curve, the status ShapeExtend_DONE2 is set
- if there's not 3d curve, the status ShapeExtend_FAIL1 is set

#### ShapeAnalysis_Edge::CheckVerticesWithPCurve

**Important**: Return value and status interpretation is equivalent to the CheckVerticesWithCurve3d counterpart!

#### ShapeAnalysis_Edge::CheckVertexTolerance

Returns TRUE, if one or two of the vertices don't lie in the vicinity of the affiliated pcurve coordinates within their respective tolerances. Returns FALSE, if both vertices comply **OR** something went wrong during the check.

In detail:

- if VERTEX 1 is deviating, the status ShapeExtend_DONE1 is set
- if VERTEX 2 is deviating, the status ShapeExtend_DONE2 is set
- if VERTEX 1 or VERTEX 2 is NULL (no Vertex attached to the edge shape), the status ShapeExtend_FAIL1 is set
- if no 3d curve can be aquired and the edge is not degenerated, the status ShapeExtend_FAIL2 is set
- if no pcurve can be aquired, the status ShapeExtend_FAIL3 is set

## ShapeFix

## ShapeFix_Edge

Provides a couple of routines to fix broken edges.

## ShapeFix_Wire

Provides means to fix a complete wire

**Important**: If one of the edges does not contain a pcurve, StatusEdgeCurves will return FAIL!

# ShapeUpgrade

## ShapeUpgrade_ShapeDivideAngle

This class allows to split a rotational symmetric (rotational symmetric along U !) face into segments. Each segment spans only up to a certain angle.

**Important**: It can happen sometimes that the edges created by this class lack the SameRange property, which is necessary (but not checked for) for many routines in OCC! What's even worse is that this is not always fixed by ShapeFix_Wire but can lead to extremely large tolerances for that edge (to fulfill the SameParam property). So make sure to manually enforce the SameRange property for all edges created in ShapeUpgrade_ShapeDivideAngle.