OCC entities for arbitrary 3D geometry#
While meshwell provides convenient polygon-based entities (PolySurface,
PolyPrism), you can also wrap arbitrary OpenCASCADE shapes via
OCC_entity. This gives you full access to the OCP geometric modeler
while still benefiting from meshwell’s fragment/tagging/meshing workflow.
from functools import partial
from OCP.BRepPrimAPI import BRepPrimAPI_MakeBox
from OCP.gp import gp_Pnt
from meshwell.cad_occ import cad_occ
from meshwell.occ_entity import OCC_entity
from meshwell.occ_xao_writer import write_xao
/home/runner/work/meshwell/meshwell/.venv/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
def _make_box():
return BRepPrimAPI_MakeBox(gp_Pnt(0, 0, 0), 1, 1, 1).Shape()
box_entity = OCC_entity(
occ_function=_make_box,
physical_name="box",
mesh_order=1,
dimension=3,
)
write_xao(cad_occ([box_entity]), "box.xao")
You can wrap any zero-argument callable that returns a TopoDS_Shape:
primitives, boolean results, imported STEP bodies, etc. For parameterized
shapes, use functools.partial or a closure.
def cylinder(radius, height):
from OCP.BRepPrimAPI import BRepPrimAPI_MakeCylinder
return BRepPrimAPI_MakeCylinder(radius, height).Shape()
custom_entity = OCC_entity(
occ_function=partial(cylinder, radius=0.5, height=2.0),
physical_name="cyl",
mesh_order=1,
dimension=3,
)
write_xao(cad_occ([custom_entity]), "cyl.xao")
Use OCC_entity when you need:
Primitive shapes beyond polygon extrusion (spheres, cones, tori)
Shapes from external STEP / BREP files
Any OCP boolean composition you want processed as a single labeled entity
Naming individual points (0D entities)#
meshwell meshes are keyed by physical name. Regions (PolySurface), curves
(PolyLine), and auto-generated interfaces/boundaries all get names – and
so can an individual point, by wrapping a vertex in an OCC_entity with
dimension=0 and a physical_name. Build the vertex with
BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, 0.0)).Vertex(). The named vertex
survives CAD fragmentation and becomes a named mesh node (a vertex cell
block) within meshwell’s point-tolerance (~1e-5) of the requested coordinate.
Works inside a region, on an interface, or on a corner.
This is the building block for features that reference a specific vertex by name (e.g. boundary-layer fan points at a convex corner – see notebook 25).
import shapely # noqa: E402
from OCP.BRepBuilderAPI import BRepBuilderAPI_MakeVertex # noqa: E402
from meshwell.orchestrator import generate_mesh # noqa: E402
from meshwell.polysurface import PolySurface # noqa: E402
def named_point(x, y, name):
return OCC_entity(
occ_function=lambda: BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, 0.0)).Vertex(),
physical_name=name,
dimension=0,
)
sheet = PolySurface(
polygons=shapely.box(0, 0, 4, 2), physical_name="sheet", mesh_order=1
)
point_mesh = generate_mesh(
entities=[sheet, named_point(2.0, 1.0, "probe")],
dim=2,
output_mesh="named_point.msh",
default_characteristic_length=0.5,
)
print(
"named groups:",
sorted(k for k in point_mesh.cell_sets if not k.startswith("gmsh:")),
)
Info : Clearing all models and views...
Info : Done clearing all models and views
Info : Reading '/tmp/tmpmk7ayg6q/cad.xao'...
Info : Done reading '/tmp/tmpmk7ayg6q/cad.xao'
named groups: ['probe', 'sheet', 'sheet___None']