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

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

Working with 2D graphics primitives the possibility are to:

### Solid 3D Primitives

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

#### Ball

Create two distinct Ball primitives in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the first OpenCascade shape.
Generate a boundary ElementMesh from the second OpenCascade shape.
Visualize the boundary ElementMesh.
Generate the full ElementMesh.
Generate several Ball primitives in OpenCascade.

#### CapsuleShape

Create a CapsuleShape primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Visualize the fully meshed ElementMesh.

#### Cone

Create a Cone primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Visualize the fully meshed ElementMesh.

#### Cuboid

Create a Cuboid primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Visualize the fully meshed ElementMesh.

#### Cylinder

Create a Cylinder primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh and the graphics primitive.
Visualize the fully meshed ElementMesh.

#### Ellipsoid

Create a Ellipsoid primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh and the graphics primitive.
Visualize the fully meshed ElementMesh.

#### FilledTorus

Create a FilledTorus primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh and the graphics primitive.
Visualize the fully meshed ElementMesh.

#### Hexahedron

Create a Hexahedron primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Visualize the fully meshed ElementMesh.

#### Parallelepiped

Create a Parallelepiped primitive in OpenCascade.
Look at the OpenCascade shape type.
Extract and visualize the boundary mesh and the Parallelepiped.

#### Prism

Create a Prism primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh and the graphics primitive.
Visualize the fully meshed ElementMesh.

#### Polyhedron

Create a Polyhedron primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Visualize the fully meshed ElementMesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Create a Polyhedron primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Visualize the fully meshed ElementMesh.

#### Pyramid

Create a Pyramid primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Visualize the fully meshed ElementMesh.

#### SphericalShell

Create a SphericalShell primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Mesh the region while keeping a region hole. Visualize the fully meshed ElementMesh.

#### Tetrahedron

Create a Tetrahedron primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Visualize the fully meshed ElementMesh.

### 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.

Create a Torus primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the first OpenCascade shape.
Visualize the boundary ElementMesh.
Generate the full ElementMesh.

Partial tori are also possible.

Create and visualize a refined partial Torus primitive in OpenCascade.

### Surfaces Primitives

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

#### BSplineSurface

Set up a pipe section using a B-spline surface with weights:
Create a BSplineSurface primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh with the B-spline surface.

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.

Set up a pipe section using a closed B-spline surface with weights:
Create a BSplineSurface primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh with the B-spline surface.

#### Disk in 3D

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

Visualize a disk that has it's center at {0,0,1} and a plane with a normal in direction {0,-1,0}, a radius of 1/2 and an arc length from π to 2 π.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Show the boundary ElementMesh with the graphics.

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

#### Polygon

Create a Polygon primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.

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

Create a Polygon with a hole in OpenCascade.
Look at the OpenCascade shape type.

A shell is a collection of faces.

Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.
Specify a self intersecting Polygon in OpenCascade.
Look at the OpenCascade shape type.
Surface meshes can not be generated from a self intersecting Polygon.

#### Triangle

Create a Triangle primitive in OpenCascade.
Look at the OpenCascade shape type.
Generate a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh.

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.

Create and visualize a boundary ElementMesh.
Convert a boundary ElementMesh to an OpenCascade object.

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.

Look at the OpenCascade shape type.

Both, open and closed surfaces can be converted.

Create and visualize a boundary ElementMesh.
Convert a boundary ElementMesh to an OpenCascade object.
Look at the OpenCascade shape type.

### Edge Primitives

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

#### Line

Create a Line primitive in OpenCascade.
Look at the OpenCascade shape type.

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.

Create several lines.
Visualize the lines.
Create several wires.
Combine several wires into a single wire.
Look at the OpenCascade shape type.

The main usage of this is for convenience.

#### BezierCurve

Create a BezierCurve.
Visualize the BezierCurve.
Create a BezierCurve primitive in OpenCascade.
Look at the OpenCascade shape type.

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.

Create a Line.
Create an OpenCascade face from the BezierCurve and Line wires.
Visualize the mesh face.

#### BSplineCurve

Create a BSplineCurve.
Visualize the BSplineCurve.
Create a BSplineCurve primitive in OpenCascade.
Look at the OpenCascade shape type.

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.

Create and visualize an axis around which we will rotate the BSpline curve.
Create a rotational sweep of the BSplineCurve.
Visualize the discretized surface and the original BSpline curve.

### Extended Edge Primitives

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

#### Circle in 3D

Visualize a circle that has it's center at {0,0,1} and a plane with a normal in direction {0,-1,0}, a radius of 1/2 and an arc length from π to 2 π.
Look at the OpenCascade shape type.

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.

### 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.

Create several edge primitives.
Visualize the edges.
Create several wires.
Combine several wires into a single wire.
Convert the closed wire to a surface.
Discretize and visualize the surface.

### 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 creation of a region might be simpler in 2D than in 3D
• Using the OpenCascade engine for 2D boundary element mesh generation

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.

We start by looking at a workflow.

#### Workflow

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

Create a half disk.
Inspect the shape type.
Convert the OpenCascade shape into a boundary mesh.

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.

Visualize the boundary mesh.

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.

Create a transformation function.
Apply the transformation function to the OpenCascade shape.
Visualize the boundary mesh.

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

Create a half disk, generate a boundary mesh and project the mesh to 2D.

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

Create a half disk, generate a refined boundary mesh and project the mesh to 2D.

Note that now the boundary representation is less jagged.

#### Annulus

Create a 2D Annulus in OpenCascade.
Inspect the shape type.
Visualize the surface mesh.

#### Disk

Create a 2D Disk in OpenCascade.
Inspect the shape type.
Visualize the surface mesh.

#### 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.

Create a boundary curve of 1D segments embedded in 2D.

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

Create 2D FilledCurve.
Create the 2D FilledCurve in OpenCascade.
Inspect the shape type.
Create and visualize the boundary surface mesh.

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.

Create a filled curve with a a Circle segment.
Visualize the graphics filled curve with a helper function.
Inspect the shape type.
Create and visualize the boundary surface mesh.

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

Create a filled curve where the segments are not connected.
The conversion to OpenCascade will fail.

JoinedCurve and FilledCurve options are currently not supported.

#### Parallelogram/Parallelepiped

Create a 2D Parallelogram in OpenCascade.
Inspect the shape type.
Visualize the surface mesh.

#### Polygon

Create a 2D Polygon in OpenCascade.
Inspect the shape type.
Visualize the surface mesh.

#### Rectangle

Create a 2D Rectangle in OpenCascade.
Inspect the shape type.
Visualize the surface mesh.

#### RegularPolygon

Create a 2D RegularPolygon in OpenCascade.
Inspect the shape type.
Visualize the surface mesh.

#### Triangle

Create a 2D Triangle in OpenCascade.
Inspect the shape type.
Visualize the surface mesh.

#### 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.

Create graphics primitives.
Visualize the graphics primitives with an empty FaceForm and a black EdgeForm.
Create a union of the Disk faces.
Create the cut shape.
Compute the difference of the region with the cut.
Create a refined boundary surface mesh.
Project the 3D surface mesh to a 2D mesh.
Visualize the 2D mesh.
Create and visualize a 2D boundary mesh.
Create and visualize a full 2D element mesh, with markers and a refined subregion.

### 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.

Create a half disk.
Inspect the shape types.

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

Connect wires and create a face.
Inspect the shape type.

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

Connect wires and create a face in one go.
Inspect the shape type.
Convert the OpenCascade shape into a boundary mesh.

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.

Visualize the boundary mesh.

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.

Create a transformation function.
Apply the transformation function to the OpenCascade shape.
Visualize the boundary mesh.

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

Generate a boundary mesh and project the mesh to 2D.

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

Generate a refined boundary mesh and project the mesh to 2D.

Note that now the boundary representation is less jagged.

#### BezierCurve

Create a BezierCurve.
Convert the curve to an OpenCacade shape.
Inspect the type of the shape.

#### BSplineCurve

Create a BSplineCurve.
Convert the curve to an OpenCacade shape.
Inspect the type of the shape.

#### Circle

Create a Circle.
Convert the circle to an OpenCacade shape.
Inspect the type of the shape.

#### 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.

Create a boundary curve of 1D segments embedded in 2D.

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

Create JoinedCurve.
Inspect the shape type.

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.

Create a joined curve with a a Circle segment.
Visualize the graphics filled curve with a helper function.
Inspect the shape type.

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

Create a joined curve where the segments are not connected.
The conversion to OpenCascade will fail.

JoinedCurve and FilledCurve options are currently not supported.

#### Line

Create a Line.
Convert the circle to an OpenCacade shape.
Inspect the type of the shape.

The following operations on OpenCascade objects are available:

### Surface mesh generation

Surfaces of OpenCascade objects can be meshed.

Generate a surface mesh.
Extract and visualize the coordinates from the meshed shape.
Extract and visualize the surface elements from the meshed shape.

"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.

Extract a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh extracted from the OpenCascade shape.
Note that sub-surfaces have appropriate boundary markers.
Create and visualize a full mesh.

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.

Extract a boundary ElementMesh from the OpenCascade shape with a refined surface mesh.
Visualize the boundary ElementMesh extracted from the OpenCascade shape.

### Part extraction

Create a shape.
Extract the number of faces.
Extract the faces.
Extract the type.
Generate a boundary mesh from one of the faces.
Extract the number of vertices.
Extract the vertices.
Extract the type.

### Geometric transformations

Create a shape.
Rotate the shape.
Extract a boundary ElementMesh from the OpenCascade shape.
Visualize the boundary ElementMesh and the shape rotated in the Wolfram language.

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

Create a rotated shape.
Extract and visualize the boundary ElementMesh and the shape rotated in the Wolfram language.

To mirror a shape ReflectionTransform can be used.

Create a mirrored shape.
Extract and visualize the boundary ElementMesh and the shape rotated in the Wolfram language.

### 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.

Create a polygon face in OpenCascade.
Look at the OpenCascade shape type.
Specify a rotation axis and the amount of the rotation.
Look at the OpenCascade shape type.
Extract and visualize the boundary mesh, the rotation axis of rotation and the polygon face.
Generate a full mesh.

OpenCascade can also perform rotational sweeps on wire objects.

Create a Line primitive in OpenCascade.
Look at the OpenCascade shape type.
Specify a rotation axis and the amount of the rotation.
Look at the OpenCascade shape type.
Extract and visualize the boundary mesh, the rotation axis of rotation and the Line edge.

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

OpenCascade can also perform rotational sweeps on edge objects.

Visualize a Circle in 3D.
Look at the OpenCascade shape type.
Specify a rotation axis and the amount of the rotation.
Look at the OpenCascade shape type.
Extract and visualize the boundary mesh, the rotation axis of rotation and the Line edge.

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.

Create a Line primitive in OpenCascade.
Create an axis and visualize the line in 3D.
Failure of a sweep.

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.

Insert a vertex at the intersection of the axis and the wire.
Visualize the sweep.

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

Sweep of half the shape around 2 π.

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.

Create a polygon face in OpenCascade.
Look at the OpenCascade shape type.
Sweep the surface along the direction from {1/2,1/2,0} to {1,1,1}.
Look at the OpenCascade shape type.
Extract and visualize the boundary mesh, the rotation axis of rotation and the polygon face.
Generate a full mesh.

OpenCascade can also perform linear sweeps on wire objects.

Create a Line primitive in OpenCascade.
Look at the OpenCascade shape type.
Sweep the surface along the axis {1/2,1/2,0} to {1,1,1}.
Look at the OpenCascade shape type.
Extract and visualize the boundary mesh, the rotation axis of rotation and the Line edge.

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.

Create Bezier curve and a polygon:
Visualize the geometric primitives:

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

Inspect the shape types:
Create the path sweep:
Inspect the shape type of the sweep:
Create the boundary element mesh:
Visualize the element mesh, the starting face and in red the path:

### 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.

Generate two Ball shapes.
Look at the OpenCascade shape type.
Compute the geometric difference between the two shapes
Look at the OpenCascade shape type.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Generate a Prism and a Ball Graphics3D primitive.
Visualize the scene.
Compute the geometric difference.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Create a SphericalShell and a Cylinder shape.
Compute the geometric difference of the shapes
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Create a Polyhedron and a Ball primitive in OpenCascade.
Compute the geometric difference of the shapes
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize a cross section through the boundary ElementMesh with markers highlighted.
Generate a full mesh.

#### Union

Compute geometric unions of shapes.

Generate two Ball shapes.
Look at the OpenCascade shape type.
Compute the geometric union.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Create a Ball and a Hexahedron shape.
Compute the geometric union of the shapes
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Create a Ball and a Pyramid shape.
Compute the geometric union of the shapes
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Create a SphericalShell and a Cylinder shape.
Look at the OpenCascade shape type.
Compute the geometric union of the shapes
Look at the OpenCascade shape type.
Extract the boundary mesh.
Visualize the boundary ElementMesh..
Generate a full mesh.

#### Intersection

Compute geometric intersection of shapes.

Generate two Ball shapes.
Compute the geometric union.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Create a Ball and a Hexahedron shape.
Compute the geometric intersection of the shapes
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Create a Ball and a Pyramid shape.
Compute the geometric intersection of the shapes
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Create a SphericalShell and a Cylinder shape.
Look at the OpenCascade shape type.
Compute the geometric intersection of the shapes.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Visualize the boundary ElementMesh..
Generate a full mesh.

Intersections can also be generated from lower dimensional region objects.

Create a Cone and a Polygon shape.
Look at the OpenCascade shape type.
Compute the geometric intersection of the shapes.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Visualize the boundary ElementMesh.
Visualize the boundary ElementMesh in the Cone.

#### Simplifications of Boolean operations

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

A default union of two cuboids:
A union of two cuboids with surface simplification:

#### BooleanRegion

Generate a BooleanRegion shape.

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

Alternative to generate a BooleanRegion shape.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.
Generate a BooleanRegion shape.
Extract and visualize the boundary mesh.
Generate a BooleanRegion shape.
Extract and visualize the boundary mesh.

#### 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
Create two overlapping cubes.
Setup the shapes.
Intersection
Compute the intersection.
Visualize the Boolean operation.
Union
Compute the union.
Visualize the Boolean operation.
Difference
Compute the first difference.
Visualize the Boolean operation.
Compute the second difference.
Visualize the Boolean operation.
##### Solids touching at a face
Create two touching cubes.
Setup the shapes.
Intersection
Compute the intersection.

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.

Extract the number of faces.

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

Converting a shape with no faces or solids will fail.
Union
Compute the union.
Visualize the Boolean operation.

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

Visualize the full mesh and note that the union of the solids is open at the touching faces.
Difference
Compute the first difference.
Visualize the Boolean operation.

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

Visualize the boundary mesh and it's split surface.
Compute the second difference.
Visualize the Boolean operation.

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

##### Solids touching at an edge
Create two touching cubes that touch at an edge.
Setup the shapes.
Intersection
Compute the intersection.

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.

Extract the number of edges.
Union
Compute the union.
Visualize the Boolean operation.

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

Visualize the full mesh and note that the union of the solids is split at the touching edges.
Difference
Compute the first difference.
Visualize the Boolean operation.

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

Visualize the boundary mesh and it's split surface.
Compute the second difference.
Visualize the Boolean operation.

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.

Define a shape that is to be split.
Define a shape that is the splitting tool.
Inspect the object's shape type.
Inspect the tool's shape type.
Visualize the object and the tool.
Split the object with the tool.

Note that we obtain a list of OpenCascade shape expressions.

Generate boundary meshes from the split object.
Visualize the boundary meshes.
Show the edge frame of the split objects on top of the original object and the tool.
Generate full meshes from the split objects.

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

Set up a surface as a splitting tool.
Inspect the shape type of the tool.
Visualize the shape and the tool.
Split the shape with the tool.
Visualize the boundary meshes of the split object.

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

Create an object.
Create a tool.
Inspect the tool's shape type.
Visualize the object and the tool.
Split the shape with the tool.
Visualize the boundary meshes of the split object.

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.

Generate a list of polygons.
Look at the OpenCascade shape type.
Sew the faces together.
Look at the OpenCascade shape type.

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.

Sew the faces together.
Look at the OpenCascade shape type.
Extract and visualize the boundary ElementMesh.
Create and visualize a full mesh.

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

Create a PolarPlot.
Extract the coordinates from the PolarPlot.
Make use of a function to parameterize the coordinates of the shape.
Construct the BSplineSurface.
Visualize the BSplineSurface and the top and bottom cap.
Sew the surfaces together.
Look at the OpenCascade shape type.
Convert to a solid.
Extract and visualize the boundary mesh.
Generate a full mesh.

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

Create and visualize an Ellipsoid.
Compute the eigenvalues and eigenvectors of the Ellipsoid.
Compute the TransformationFunction to map a unit Ball onto the Ellipsoid.
Set up the control points for 8 B-Spline surfaces and generate the surfaces.

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.

Convert the B-Spline surfaces into OpenCascade expressions.
Sew the surfaces together and make the shape a solid.
Look at the OpenCascade shape type.
Extract and visualize the boundary mesh.

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.

Compute the Boolean union of a the ellipsoid and a cuboid.

### 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.

Create two touching cubes that touch at an edge.
Form the union and visualize the full mesh.

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.

Extract all faces from the solids and compute the union of the faces.
Visualize the full mesh.
Extract the boundary mesh.

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.

Generate two shapes.
Compute the geometric union between the two shapes.
Visualize the resulting union.
Compute the geometric intersection between the two shapes.
Visualize the resulting intersection.

Note that computing the intersection returns a closed shape.

Sew the faces together.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.

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.

Generate a full mesh.
Check that all markers are present.
Visualize the parts specified by the markers.
Visualize a cross section through the mesh with markers highlighted.

#### 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.

Create symbolic regions:
Convert the symbolic regions to OpenCascade and sew them together:
Discretize the boundary and visualize the discretization:

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.

Discretize the cylinder:

Note, that the discretization is attached to the OpenCascadeShapeExpression.

Sew the shapes together:

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.

Create the boundary ElementMesh by not re-discretizeing if shapes already have a boundary discretization attached:

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

### Fillets

OpenCascade provides functionality to fillet shapes.

Generate a shape.
Look at the OpenCascade shape type.
Fillet all edges with a radius of 0.25.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate a full mesh.

It is also possible to fillet only selected edges.

Generate a shape.
Look at the number of edges in the shape.

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.

Fillet edges number 1 and 7 with a radius of 0.25.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.

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.

Interactively apply the filleting function to edges of the shape.
Generate a shape.
Fillet the shape with a radius of 0.125.
Extract the boundary mesh.
Visualize the boundary ElementMesh.

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

Filleting a shape with too large a radius will fail.
Use a radius that can be filleted.
Extract the boundary mesh.

### 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.

Generate a shape.
Look at the OpenCascade shape type.
Apply chamfer to edges 5 and 6.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate the full mesh.

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.

Interactively apply the chamfer function to edges of the shape.

### 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.

Create and visualize a set of Line objects.

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

Convert the graphics primitives to OpenCascade shapes.

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

Inspect the types of the shapes.
Create a loft.
Visualize the loft and the original wires

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

Inspect the shape type of the loft.

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

Generate solid loft.
Generate and visualize a full mesh.
Visualize the mesh and the wires

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

### Shelling

OpenCascade provides functionality to shell shapes.

Generate a shape.
Look at the OpenCascade shape type.
Find the number of faces in the shape.
Shell the shape by removing faces 2 and 3.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate the full mesh.

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.

Interactively apply the chamfer function to faces of the shape.

### De-featuring

OpenCascade provides functionality to de-feature shapes.

Generate a shape.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Find the number of faces.
Extract the boundary element markers.
Visualize the boundary ElementMesh with faces 11 and 12 highlighted.
De-feature the shape by removing faces 11 and 12.
Extract and visualize the boundary ElementMesh of the de-featured shape.
Visualize the boundary ElementMesh with faces 8 and 12 highlighted.
De-feature the shape by removing faces 8 and 12.
Extract and visualize the boundary ElementMesh of the de-featured shape.
Look at the OpenCascade shape type.

### Shape Simplification

OpenCascade provides functionality to simplify shapes.

Generate a shape.
Look at the OpenCascade shape type.
Extract the boundary mesh.
Find the number of faces.
Extract the boundary element markers.
Extract the boundary mesh.
Find the number of faces.

### Shape Healing

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

Fix a broken shape:

## 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

Create a shape.
Export the shape as a STL file.
Import the generated STL with Import.
Visualize the boundary ElementMesh.

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.

Convert a shape to a MeshRegion for STL export.

#### STL Import

Import a STL file.
Extract the boundary mesh.
Visualize the boundary ElementMesh.

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.

Inspect the boundary element markers.

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

Extract the boundary mesh and have the markers computed in the Wolfram language.
Inspect the boundary element markers.
Visualize the boundary ElementMesh with markers highlighted.

#### Step Export

Create a shape.
Export the shape as a STEP file.

#### Step Import

Set up the example directory path.
Import a step file.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate the full mesh.
Import a step file.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate the full mesh.

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

Create a shape.
Export the shape as a BRep file.

#### BRep Import

Set up the example directory path.
Import a brep file.
Extract the boundary mesh.
Look at the boundary element marker union and create colors for the markers.
Visualize the boundary ElementMesh with markers highlighted.
Generate the full mesh with mesh order 1.

## Units

Set up the example directory path.
Import a step file.
Extract the boundary mesh.
Inspect the length unit.

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

Extract the boundary mesh with units of millimeters.
Inspect the length unit.
Extract and rescale the boundary mesh with custom units.
Inspect the length unit.
Convert the boundary mesh to a full mesh and inspect the units.

## 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.

Create two touching cubes.
Look at the OpenCascade shape types.
Construct the intersection.
Look at the intersection shape type.

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

Extract the boundary mesh.
Look at the number of faces.

Consider the case of a face and a cuboid touching.

Look at the OpenCascade shape types.
Construct the intersection.
Look at the intersection shape type.

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.

Visualize the boundary mesh.

#### 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.

Create and visualize a geometry below the standard OpenCascade tolerance.

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.

Scale the geometry.

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

Inspect the length unit of the boundary mesh.
Set a length unit.
Rescale the mesh.
Inspect the region bounds.

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

VisualizeEdgeFunction

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

A utility function to interactively visualize edge operations.
VisualizeFaceFunction

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

A utility function to interactively visualize edge operations.