cad-mesh-generation
# CAD and Mesh Generation Skill
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
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.