# Using *OpenCascadeLink*

OpenCascade Primitives | Possible issues |

Operations on OpenCascade objects | Utility functions |

Import/Export | Application examples |

Units |

This section shows some of the ways that *OpenCascadeLink* can be applied. To use *OpenCascadeLink,* it must first be loaded.

Since many of the *OpenCascade* examples interact with the finite element mesh functionality the finite element package is also loaded.

*OpenCascade* Primitives

The first step is to create *OpenCascade* objects. There are several ways of doing this. For 3D objects the options are to:

### Solid 3D Primitives

Various Wolfram Language Graphics3D primitives can be represented in *OpenCascade*. These primitives are represented as solids.

#### Ball

#### CapsuleShape

#### Cone

#### Cuboid

#### Cylinder

#### Ellipsoid

#### FilledTorus

#### Hexahedron

#### Parallelepiped

#### Prism

#### Polyhedron

#### Pyramid

#### SphericalShell

#### Tetrahedron

### Extended Solid 3D Primitives

*OpenCascade* provides some primitives that do not have a direct correspondence in the Wolfram language.

#### Torus

Here the arguments are an axis around which the torus is located, a radius from the axis to the interior of the torus and a second radius specifying the the radius of the interior of the torus.

Partial tori are also possible.

### Surfaces Primitives

It is also possible to create instances of surface graphics primitives embedded in 3D. These represent face type *OpenCascade* objects.

#### BSplineSurface

A fully meshed ElementMesh can not be created from a non closed surface.

Closed B-splines are supported as long as the knots and weights are set to Automatic.

#### Disk in 3D

*OpenCascade* provides some primitives that do not have a direct correspondence in the Wolfram language.

A fully meshed ElementMesh can not be created from a surface.

#### Polygon

A fully meshed ElementMesh can not be created from a surface.

A shell is a collection of faces.

#### Triangle

A fully meshed ElementMesh can not be created from a non closed surface.

### Surfaces Meshes

#### ElementMesh

An ElementMesh is the mesh structure used in the wolfram language for finite element analysis. The creation of ElementMesh is documented in the reference pages of ToBoundaryMesh and ToElementMesh or the ElementMesh generation tutorial.

The conversion is computationally expensive since every surface element is mapped into an *OpenCascade* object and then sewed together. This type of shape creation should only be used if no other approach can be found.

Both, open and closed surfaces can be converted.

### Edge Primitives

It is also possible to create instances of edge graphics primitives embedded in 3D.

#### Line

A boundary ElementMesh can not be created from an *OpenCascade* shape of type wire. Wire objects can, however, be used for rotational or linear sweeps or combined with other wire or edge objects.

#### Combining wires

A collection of wires can be combined into a single wire.

The main usage of this is for convenience.

#### BezierCurve

A boundary ElementMesh can not be created from an *OpenCascade* shape of type wire. Wire objects can, however, be used for rotational or linear sweeps or combined with other wire or edge objects.

#### BSplineCurve

A boundary ElementMesh can not be created from an *OpenCascade* shape of type wire. Wire objects can, however, be used for rotational or linear sweeps or combined with other wire or edge objects.

### Extended Edge Primitives

*OpenCascade* provides some primitives that do not have a direct correspondence in the Wolfram language.

#### Circle in 3D

*OpenCascade* shape of type wire. Wire objects can, however, be used for rotational or linear sweeps or combined with other wire or edge objects.

### Surfaces from Edges

It's also possible to use wires to construct the boundary of surfaces. There are a few restrictions, however: Wires must not self intersect, the wires must form a closed loop and the surface that is to be formed must be planar.

### Solid 2D Primitives

*OpenCascade* is a 3D CAD engine. With that being said, it is still possible to convert 2D graphics primitives such as Disk, Rectangle etc to *OpenCascade* shapes. There are two main reasons for doing this:

The fundamental way this works is that 2D embedded objects are created in 3D in the - plane and the -value is assumed 0. Since the shapes created are embedded in 3D *OpenCascade* operations like extrusion, Boolean operations etc can be applied in the same way as in the rest of the system.

#### Workflow

As a first step we illustrate a work flow for both scenarios. Let's start with creating a half disk.

Note that the boundary mesh generated is embedded in 3D and the -extend is 0. The projection of this mesh to 3D will be shown in a minute.

Back to the half disk object. This Object can be projected to any other position by using a transformation function. This works the same way as with other OpenCascade shapes.

To create a 2D boundary mesh the function ElementMeshProjection can be used.

The boundary mesh refinement works in the standard way. This is described in more detail in the section Surface mesh generation.

Note that now the boundary representation is less jagged.

#### Annulus

#### Disk

#### FilledCurve

FilledCurve is not a region primitive. The main reason this graphics operation is partially supported in *OpenCascadeLink* is that in current versions of Mathematica there is no way to create a 2D region by connecting 1D segments that are embedded in 2D.

For graphics FilledCurve can be used to mean the region that is enclosed by the curve.

The way OpenCascadeLink supports FilledCurve, and JoinedCurve for that matter, is a bit different from what they support in Graphics. For example, a Circle, can not be used as a segment in Graphics but it can be used in OpenCascadeLink.

In the *OpenCascadeLink* implementation FilledCurve and JoinedCurve must not have missing segments.

JoinedCurve and FilledCurve options are currently not supported.

#### Parallelogram/Parallelepiped

#### Polygon

#### Rectangle

#### RegularPolygon

#### Triangle

#### Example

In this example we show how 2D graphics primitives can be used for creating a boundary element mesh. We would like to create a multi material region with a cutout described by a Bezier curve.

### Boundary 2D Primitives

Just like solid 2D graphics primitives can be converted, as explained in the section Solid 2D Primitives, we can also convert 2D edge or boundary graphics primitives such as Line and Circle.

The fundamental way this works is that 2D embedded objects are created in 3D in the - plane and the -value is assumed 0. Since the shapes created are embedded in 3D *OpenCascade* operations like extrusion, Boolean operations etc can be applied in the same way as in the rest of the system.

#### Workflow

As a first step we illustrate a work flow for both scenarios. Let's start with creating a half circle and a line that closes the half circle.

The next step is to connect the wires and create a face from them.

The creation of a face from a set of wires can be done in one go.

Note that the boundary mesh generated is embedded in 3D and the -extend is 0. The projection of this mesh to 3D will be shown in a minute.

Back to the half circle and line object. This Object can be projected to any other position by using a transformation function. This works the same way as with other *OpenCascade* shapes.

To create a 2D boundary mesh the function ElementMeshProjection can be used.

The boundary mesh refinement works in the standard way. This is described in more detail in the section Surface mesh generation.

Note that now the boundary representation is less jagged.

#### BezierCurve

#### BSplineCurve

#### Circle

#### JoinedCurve

JoinedCurve is not a region primitive. The main reason this graphics operation is partially supported in *OpenCascadeLink* is that in current versions of Mathematica there is no way to create a connected region of 1D segments that are embedded in 2D.

For graphics JoinedCurve can be used to mean the region that is enclosed by the curve.

The way OpenCascadeLink supports JoinedCurve, and FilledCurve for that matter, is a bit different from what they support in Graphics. For example, a Circle, can not be used as a segment in Graphics but it can be used in OpenCascadeLink.

In the *OpenCascadeLink* implementation FilledCurve and JoinedCurve must not have missing segments.

JoinedCurve and FilledCurve options are currently not supported.

#### Line

## Operations on *OpenCascade* objects

The following operations on *OpenCascade* objects are available:

### Surface mesh generation

Surfaces of *OpenCascade* objects can be meshed.

"AngularDeflection" and "LinearDeflection" specify the maximum amount a segment may deviate from the true surface. The concepts are best explained with the following illustration.

"AngularDeflection" specifies the maximum deflection angle α at the end nodes of a segment while "LinearDeflection" specifies the maximum deflection to the true curve within a segment. The Automatic default for the "AngularDeflection" is set to 0.5 degrees and the Automatic default for the "LinearDeflection" is set to 0.01 units of the relative size of the shape. For more information please consult the OpenCascade Documentation.

"ComputeInParallel" specifies if the surface discretization should be performed on multiple CPU cores. The Automatic default is set to False.

"RelativeDeflection" specifies if the deflection is relative or absolute to the size of the geometry. The Automatic default is set to True.

"Rediscretization" specifies if one of the input shapes already as a discretization attached to it if that discretization is to be reused. The Automatic default is set to False. This functionality is useful to have different levels of discretization on different parts in a multi material object. An example is given below in the section Internal boundaries refinement by sewing.

To make working with *OpenCascade* and the finite element method easier a function to mesh the surface and return a boundary ElementMesh is provided.

All options that are relevant for the ElementMesh generation can be specified via "ElementMeshOptions" and options relevant for OpenCascadeShapeSurfaceMesh can be specified via "ShapeSurfaceMeshOptions".

The "MarkerMethod" option allows to specify if markers should be added and how they should be computed. The default is to use "OpenCascade". Other options are "ElementMesh" and None to switch off markers entirely. Using "ElementMesh" as a "MarkerMethod" option can be useful if the generated surface consists of many single surface elements. In that case the "OpenCascade" method would attribute each element a unique marker which may be undesirable. With the method "ElementMesh", however, the markers are added based on their face normals and if those deviate by a certain amount. The ToBoundaryMesh reference page has more information on this topic.

### Part extraction

### Geometric transformations

As an alternative, the TransformationFunction can directly be applied during the creation of the *OpenCascade* shape by making use of a TransformedRegion.

To mirror a shape ReflectionTransform can be used.

### Sweeps

#### RotationalSweeps

*OpenCascade* can perform rotational sweeps. For this a surface is rotated around an axis. The rotation can be less than a full rotation.

*OpenCascade* can also perform rotational sweeps on wire objects.

Rotational sweeps can not be performed on Solid or CompoundSolid *OpenCascade* shape types.

*OpenCascade* can also perform rotational sweeps on edge objects.

Rotational sweeps can not be performed on Solid or CompoundSolid *OpenCascade* shape types.

##### Possible Issues

Rotational sweeps can not be performed when the axis intersects the shape to be swept and that shape does not have a vertex or edge at the intersection. Consider an example.

One way to fix this failure is to create a shape that has a vertex or edge along which the rotation is supposed to happen.

A more general approach, for example for spline curves, is to only model half the shape and perform the sweep for 2π in stead.

Rotational sweeps can not be performed on Solid or CompoundSolid *OpenCascade* shape types.

#### LinearSweeps

For a linear sweep of a surface and a direction needs to be give. The surface is then swept to the along this direction.

*OpenCascade* can also perform linear sweeps on wire objects.

Linear sweeps can not be performed on Solid or ComSolid *OpenCascade* shape types.

#### Sweeps along a path

Given a face and a path, OpenCascade can sweep the face along the path.

The path has to be either of type "Edge" or of type "Wire" and the surface must not contain a solid or compound.

### Boolean Operations

Some restrictions in computing Boolean operations are detailed in the Boolean possible issues section and the Boolean operations on solids section.

Boolean operations will always return compound objects.

#### Difference

Compute geometric differences of shapes.

#### Union

Compute geometric unions of shapes.

#### Intersection

Compute geometric intersection of shapes.

Intersections can also be generated from lower dimensional region objects.

#### Simplifications of Boolean operations

In some cases the surfaces resulting from Boolean operations can be simplified.

#### BooleanRegion

The *OpenCascadeLink* provides functionality to directly work with BooleanRegion objects.

As a convenience it is also possible to use OpenCascadeShape for BooleanRegion objects directly.

#### Boolean operations on solids

*OpenCascade* handles Boolean operations in a slightly different manner than the Wolfram Language Boolean operators RegionUnion, RegionIntersection and RegionDifference. It's illustrative to walk through several examples.

##### Solids overlapping

##### Solids touching at a face

The lowest dimensional object that can be returned from an *OpenCascase* Boolean operation is that of the minimal dimension of any argument given to the Boolean operation. For example, a Boolean operation of two *OpenCascade* solids can not return an *OpenCascade* face object.

Since there are no solids and no faces the conversion to a boundary element mesh will fail.

Note that the resulting full mesh will be open at the touching faces.

Note that the resulting solid has it's surface split according to the shape of the touching object.

Note that the resulting solid has it's surface split according to the shape of the touching object.

##### Solids touching at an edge

The lowest dimensional object that can be returned from an *OpenCascase* Boolean operation is that of the minimal dimension of any argument given to the Boolean operation. For example, a Boolean operation of two *OpenCascade* solids can not return an *OpenCascade* face object.

Note that the edge of resulting full mesh will be split at the touching edges.

Note that the edge of resulting boundary mesh will be split at the touching edges.

Note that the edge of resulting boundary mesh will be split at the touching edges.

### Shape splitting

When we have a shape, like a solid, sometimes we want to split that object into several parts. A solid can be split by another solid or by a face. The shape that is to be split is called the object and the shape that does the splitting is called the tool.

Note that we obtain a list of *OpenCascade* shape expressions.

The tool must no necessarily be an other solid, a face can also be used.

A solid can not be split by a wire. Faces can be split by other faces or wires.

It's important that the tool has the proper shape type. If an "Edge" type shape tools is given it is automatically converted to a "Wire" tool.

### Sewing

Surfaces that share edges can be sewn together. More technically, sewing is the process of stitching topologically disconnected faces into a shell.

A shell is a collection of faces. To create a solid either an option can be used during the sewing process or the function OpenCascadeShapeSolid can be used.

Sewing of B-Spline surfaces with other objects is possible. However, nodes need to match.

As a further example an Ellipsoid is created from 8 BSplineSurface patches.

Note, here the ordering of the control points is important. The orientation of the resulting surfaces can be fixed with OpenCascadeShapeFix as shown further down.

A possible issue is that *OpenCascade* is sensitive to the ordering of the surfaces given for sewing. This may be tricky to note as a displayed surface might look good but when, for example, Boolean operations are performed on the object unexpected results may happen.

### Internal boundaries

*OpenCascade* offers several ways to include internal boundaries for creating geometric models with multiple materials.

#### Internal boundaries by union of faces

Forming the union of solids will leave the position of the over lap open.

Note that at the overlap where the two cuboids touched the union is not closed. This may be undesirable if one is working with a multiple material region. One option to close the face at the overlap is to compute the union of all faces of the solids.

Note that now an interface exists between the two solids.

#### Internal boundaries by sewing

Shape sewing can also be used to generate shapes that have internal boundaries.

Note that computing the intersection returns a closed shape.

Since the intersection of the two shapes is closed by sewing that closed shape into the union of the shapes we have three internal regions. One in the cylinder on top of the cuboid, one in the cylinder that is inside the cuboid and one in the remaining cuboid.

#### Internal boundaries refinement by sewing

Sometimes it is desirable to have different internal boundaries discretized at different resolutions. This can be achieved by discretizing the respective boundaries to a desired level and then sew them together.

Now, what if you want to refine the inner cylinder and not the boundary of the cuboids? Changing the linear or angular deflection during on the sewn object is going to affect all boundaries. To still change the discretization of a single shape in the object it is possible to surface mesh that object and retain that discretization during the sewing.

Note, that the discretization is attached to the OpenCascadeShapeExpression.

To make use of previous boundary discretizations attached to an OpenCascadeShapeExpression the OpenCascadeShapeSurfaceMeshToBoundaryMesh needs the option "Rediscretization"False to make use of those previous discretizations if available.

Now, the inner cylinder is discretized at a different level then the remaining boundaries.

### Fillets

*OpenCascade* provides functionality to fillet shapes.

It is also possible to fillet only selected edges.

In OpenCascade every face has access to all the edges the face is comprised of. In the case of the cube each face is connected to 4 edges. Since there are 6 faces this makes a total of 24 edges that can be addressed of which 12 are duplicated.

Sometimes it is convenient to walk through all edges and see the effect a filleting has on the overall shape, or one needs to find the edge one wants to fillet. For this purpose there is a helper function called VisualizeEdgeFunction defined in the appendix that does that.

If the requested fillet radius is too large then the filleting will fail.

### Chamfers

Chamfers are similar to fillets. The difference is that chamfers are not rounded but planes. The chamfers created are symmetric and the function's parameter specifies the distance tangential to which the chamfer surface will be created.

Sometimes it is convenient to walk through all edges and see the effect a chamfer has on the overall shape, or one needs to find the edge one wants to chamfer. For this purpose there is a helper function called VisualizeEdgeFunction defined in the appendix that does that.

### Lofting

A loft is surface or solid the is generated by creating surfaces that pass through wires. The concept is easily understood once a visualization has explained it.

The loft command will greate a surface or a solid by creating surfaces that pass through the given objects.

Loft can be generated from "Wire" or "Face" shape objects. All objects need to be of the same type though.

By default, a loft created from wire objects will return an open shell.

To generate a solid suitable for a full mesh generation set the option "BuildSolid"True.

When a loft is generated from faces, a solid is returned automatically.

### Shelling

*OpenCascade* provides functionality to shell shapes.

Sometimes it is convenient to walk through all faces and see the effect a shelling has on the overall shape, or one needs to find the face one wants to use for shelling. For this purpose there is a helper function called VisualizeFaceFunction defined in the appendix that does that.

### De-featuring

*OpenCascade* provides functionality to de-feature shapes.

### Shape Simplification

*OpenCascade* provides functionality to simplify shapes.

### Shape Healing

*OpenCascade* provides functionality to heal shapes. Healing means that, for example, broken ordering of surfaces can be fixed.

## Import/Export

*OpenCascade* can read and write various computer aided design relevant file formats. Import and Export of the these file formats is partially implemented.

#### STL Export

*OpenCascade* can export STL files.

Boundary normals in *OpenCascade* are in the opposite direction then what they are in the wolfram language. If an exported STL shows signs of the normals being in the 'wrong' direction one can convert the shape to an ElementMesh and that to a MeshRegion. The MeshRegion can then be exported as a STL file with Export.

#### STL Import

*OpenCascade* can import STL files.* *

Note that an import of a STL file with OpenCascadeShapeImport will result in a boundary mesh that has unique markers assigned to each surface element.

This may not be wanted. To avoid that the options "MarkerMethod""ElementMesh" or "MarkerMethod"None may be specified.

#### Step Export

*OpenCascade* can export STEP files.* *

#### Step Import

*OpenCascade* can import STEP files.* *

Step assemblies are imported as *OpenCascade* Compounds. The function OpenCascadeShapeNumberOfSolids can be used to find the number of solids parts in the assembly and the function OpenCascadeShapeSolids can extract the parts.

#### BRep Export

*OpenCascade* can export BRep files.* *

#### BRep Import

*OpenCascade* can import BRep files.* *

## Units

The default of *OpenCascadeLink* uses no units.

By default *OpenCascade* operates with the length unit of millimeter, these can be requested.

## Possible issues

#### Boolean operation issues

The lowest dimensional object that can be returned from an *OpenCascase* Boolean operation is that of the minimal dimension of any argument given to the Boolean operation. For example, a Boolean operation of two *OpenCascade* solids can not return an *OpenCascade* face object.

A boundary mesh can not be generated because the resulting *OpenCascade* shape intersection does not contain information on the lower dimensional face object.

Consider the case of a face and a cuboid touching.

The lowest dimensional argument to the *OpenCascade* Boolean intersection operation was the face object. Since the resulting operation is also a face object the object information is present in the resulting shape object and can be meshed.

#### Tolerance issues

The standard tolerance for OpenCascade is . If you are dealing with geometries that have components in that scale it is recommenced to rescale the geometry. Once the geometry is generated then the boundary mesh can be rescaled again to the original scale.

Depending on the operating system this may show a defect. For convenience the defect is reproduced below.

A Boolean operation below the default OpenCascade tolerance of can lead to defects.

A solution for this is to scale the geometry.

As a second step the boundary mesh can be rescaled to it's intended scale.

One thing to keep in mind though, is that a subsequent finite element analysis might benefit if the geometry is left in the rescale size and the PDE coefficients are adjusted to the new length scale. This can improve the stability of numerical solutions. This is outlined, for example, in the solid mechanics monograph.

## Utility functions

The function VisualizeEdgeFunction can be used to scroll through the edges of a region and apply an edge operation.

The function VisualizeFaceFunction can be used to scroll through the faces of a region and apply a face operation.