Claude
Skills
Sign in
Back

cad-mesh-generation

Included with Lifetime
$97 forever

# CAD and Mesh Generation Skill

General

What this skill does

# CAD and Mesh Generation Skill

```yaml
name: cad-mesh-generation
version: 1.0.0
category: programming
tags: [cad, mesh, freecad, gmsh, geometry, finite-element, marine-structures]
created: 2026-01-06
updated: 2026-01-06
author: Claude
description: |
  Expert CAD geometry and mesh generation using FreeCAD and GMSH. Create
  parametric marine structures, generate meshes for FEA/BEM, and export to
  various analysis software formats (AQWA, WAMIT, ANSYS, etc.).
```

## When to Use This Skill

Use this skill when you need to:
- Create parametric CAD models of vessels, platforms, or structures
- Generate meshes for finite element analysis (FEA)
- Generate panel meshes for boundary element methods (BEM/hydrodynamics)
- Automate geometry creation for marine structures
- Export geometry to AQWA, WAMIT, ANSYS, or other analysis tools
- Create complex geometries programmatically with Python
- Perform mesh quality checks and refinement

## Core Knowledge Areas

### 1. FreeCAD Python Scripting Basics

Creating geometry with FreeCAD Python API:

```python
import sys
from pathlib import Path
from typing import List, Tuple, Optional
import numpy as np

# Try to import FreeCAD, provide fallback for development
try:
    import FreeCAD
    import Part
    import Mesh
    import MeshPart
    FREECAD_AVAILABLE = True
except ImportError:
    FREECAD_AVAILABLE = False
    print("Warning: FreeCAD not available, using mock functions")

    # Mock FreeCAD classes for development
    class MockFreeCAD:
        @staticmethod
        def newDocument(name: str):
            print(f"[MOCK] Creating document: {name}")
            return MockDocument()

        class Vector:
            def __init__(self, x: float, y: float, z: float):
                self.x, self.y, self.z = x, y, z

    class MockDocument:
        def __init__(self):
            self.objects = []

        def addObject(self, obj_type: str, name: str):
            print(f"[MOCK] Adding object: {obj_type} - {name}")
            obj = MockObject(name)
            self.objects.append(obj)
            return obj

        def recompute(self):
            print("[MOCK] Recomputing document")

    class MockObject:
        def __init__(self, name: str):
            self.Name = name
            self.Shape = None

    class MockPart:
        @staticmethod
        def makeCylinder(radius, height, base=None, direction=None):
            print(f"[MOCK] Creating cylinder: r={radius}, h={height}")
            return MockShape()

        @staticmethod
        def makeBox(length, width, height, base=None, direction=None):
            print(f"[MOCK] Creating box: {length}x{width}x{height}")
            return MockShape()

    class MockShape:
        def fuse(self, other):
            print("[MOCK] Fusing shapes")
            return self

        def cut(self, other):
            print("[MOCK] Cutting shapes")
            return self

        def exportStep(self, filename):
            print(f"[MOCK] Exporting STEP: {filename}")

        def exportIges(self, filename):
            print(f"[MOCK] Exporting IGES: {filename}")

    if not FREECAD_AVAILABLE:
        FreeCAD = MockFreeCAD()
        Part = MockPart()

def create_cylinder_vessel(
    diameter: float,
    length: float,
    wall_thickness: float = None,
    name: str = "Vessel"
) -> Tuple[Any, Any]:
    """
    Create cylindrical vessel geometry in FreeCAD.

    Args:
        diameter: Vessel diameter [m]
        length: Vessel length [m]
        wall_thickness: Wall thickness [m] (None = solid)
        name: Object name

    Returns:
        Tuple of (document, shape)

    Example:
        >>> doc, shape = create_cylinder_vessel(
        ...     diameter=10.0,
        ...     length=100.0,
        ...     wall_thickness=0.05,
        ...     name="FPSO_Hull"
        ... )
    """
    # Create document
    doc = FreeCAD.newDocument(name)

    # Create outer cylinder
    outer_radius = diameter / 2
    outer_cyl = Part.makeCylinder(
        outer_radius,
        length,
        FreeCAD.Vector(0, 0, 0),
        FreeCAD.Vector(1, 0, 0)  # Along x-axis
    )

    # If wall thickness specified, make hollow
    if wall_thickness:
        inner_radius = outer_radius - wall_thickness
        inner_cyl = Part.makeCylinder(
            inner_radius,
            length,
            FreeCAD.Vector(0, 0, 0),
            FreeCAD.Vector(1, 0, 0)
        )
        # Subtract inner from outer
        vessel_shape = outer_cyl.cut(inner_cyl)
    else:
        vessel_shape = outer_cyl

    # Add to document
    vessel_obj = doc.addObject("Part::Feature", name)
    vessel_obj.Shape = vessel_shape

    doc.recompute()

    return doc, vessel_shape

def create_rectangular_pontoon(
    length: float,
    width: float,
    height: float,
    wall_thickness: float,
    name: str = "Pontoon"
) -> Tuple[Any, Any]:
    """
    Create rectangular pontoon geometry.

    Args:
        length: Pontoon length [m]
        width: Pontoon width [m]
        height: Pontoon height [m]
        wall_thickness: Wall thickness [m]
        name: Object name

    Returns:
        Tuple of (document, shape)

    Example:
        >>> doc, shape = create_rectangular_pontoon(
        ...     length=50.0,
        ...     width=10.0,
        ...     height=5.0,
        ...     wall_thickness=0.025,
        ...     name="Barge_Pontoon"
        ... )
    """
    doc = FreeCAD.newDocument(name)

    # Outer box
    outer_box = Part.makeBox(
        length,
        width,
        height,
        FreeCAD.Vector(0, 0, 0)
    )

    # Inner box (hollowed)
    inner_box = Part.makeBox(
        length - 2 * wall_thickness,
        width - 2 * wall_thickness,
        height - wall_thickness,  # Bottom plate thickness
        FreeCAD.Vector(wall_thickness, wall_thickness, wall_thickness)
    )

    # Subtract
    pontoon_shape = outer_box.cut(inner_box)

    # Add to document
    pontoon_obj = doc.addObject("Part::Feature", name)
    pontoon_obj.Shape = pontoon_shape

    doc.recompute()

    return doc, pontoon_shape

def export_geometry(
    shape: Any,
    output_file: Path,
    format: str = 'step'
) -> None:
    """
    Export FreeCAD shape to file.

    Args:
        shape: FreeCAD shape object
        output_file: Output file path
        format: Export format ('step', 'iges', 'stl')

    Example:
        >>> export_geometry(vessel_shape, Path('vessel.step'), 'step')
    """
    output_file.parent.mkdir(parents=True, exist_ok=True)

    if format.lower() == 'step':
        shape.exportStep(str(output_file))
    elif format.lower() == 'iges':
        shape.exportIges(str(output_file))
    elif format.lower() == 'stl':
        if FREECAD_AVAILABLE:
            # Convert to mesh first
            mesh = MeshPart.meshFromShape(
                shape,
                LinearDeflection=0.1,
                AngularDeflection=0.5,
                Relative=False
            )
            mesh.write(str(output_file))
        else:
            print(f"[MOCK] Exporting STL: {output_file}")
    else:
        raise ValueError(f"Unsupported format: {format}")

    print(f"Geometry exported: {output_file}")
```

### 2. GMSH Mesh Generation

Creating meshes with GMSH Python API:

```python
# Try to import gmsh
try:
    import gmsh
    GMSH_AVAILABLE = True
except ImportError:
    GMSH_AVAILABLE = False
    print("Warning: GMSH not available, using mock")

    # Mock gmsh module
    class MockGmsh:
        def initialize(self): pass
        def finalize(self): pass
        def open(self, filename): print(f"[MOCK] Opening: {filename}")
        def write(self, filename): print(f"[MOCK] Writing: {filename}")
        def clear(self): pass

        class model:
            @staticmethod
            def mesh():
                return MockGmshMesh()

            class geo:
                @staticmethod
                def addPoint(x, y, z, lc=0, tag=-1):
                    return tag if tag != -1 else 1

                @staticmethod
             

Related in General