auto: daily sync

This commit is contained in:
2026-02-18 08:00:16 +00:00
parent 8efa8ba0d1
commit 68a6b4763b
3 changed files with 16787 additions and 13 deletions

View File

@@ -140,6 +140,9 @@ def generate_triangulation_gmsh(geometry, params):
hole_centers = [] # For diagnostics
# --- Step 2: Add hole keepouts ---
# CRITICAL: Only add holes whose keepout is fully contained within
# the inner plate. Partially-outside keepouts cause 1D mesh
# intersections → Gmsh fails with 0 triangles.
for hole in geometry.get('holes', []):
diameter = float(hole.get('diameter', 10.0) or 10.0)
@@ -148,10 +151,22 @@ def generate_triangulation_gmsh(geometry, params):
hole_radius = diameter / 2.0
keepout_radius = hole_radius * (1.0 + d_keep)
# Check if keepout intersects inner plate
keepout_poly = Point(cx, cy).buffer(keepout_radius)
if not inner_plate.intersects(keepout_poly):
continue
# Check if keepout is fully inside inner plate
keepout_poly = Point(cx, cy).buffer(keepout_radius, resolution=32)
if not inner_plate.contains(keepout_poly):
# Try shrinking keepout to fit: find max radius that fits
dist_to_edge = inner_plate.exterior.distance(Point(cx, cy))
if dist_to_edge <= hole_radius * 1.05:
# Hole center is too close to edge — skip entirely
continue
# Use slightly smaller radius (leave 0.5mm clearance from boundary)
keepout_radius = min(keepout_radius, dist_to_edge - 0.5)
if keepout_radius <= hole_radius * 1.05:
continue
# Re-check containment
keepout_poly = Point(cx, cy).buffer(keepout_radius, resolution=32)
if not inner_plate.contains(keepout_poly):
continue
# Add circle
center_tag, hole_loop, arc_tags = _add_circle_to_gmsh(
@@ -171,8 +186,11 @@ def generate_triangulation_gmsh(geometry, params):
if hole_poly.is_empty or not inner_plate.intersects(hole_poly):
continue
# Clip to inner plate
clipped = inner_plate.intersection(hole_poly)
# Clip to inner plate (with inward offset to avoid boundary touching)
inner_shrunk = inner_plate.buffer(-0.5)
if inner_shrunk.is_empty:
inner_shrunk = inner_plate
clipped = inner_shrunk.intersection(hole_poly)
if clipped.is_empty or clipped.area < 1.0:
continue
@@ -209,7 +227,7 @@ def generate_triangulation_gmsh(geometry, params):
if hole_curves:
hole_dist = field.add("Distance")
field.setNumbers(hole_dist, "CurvesList", hole_curves)
field.setNumber(hole_dist, "Sampling", 100)
field.setNumber(hole_dist, "Sampling", 50)
hole_thresh = field.add("Threshold")
field.setNumber(hole_thresh, "InField", hole_dist)
@@ -222,7 +240,7 @@ def generate_triangulation_gmsh(geometry, params):
# --- Edge/boundary influence field: E(x) ---
edge_dist = field.add("Distance")
field.setNumbers(edge_dist, "CurvesList", outer_lines)
field.setNumber(edge_dist, "Sampling", 100)
field.setNumber(edge_dist, "Sampling", 50)
edge_thresh = field.add("Threshold")
field.setNumber(edge_thresh, "InField", edge_dist)
@@ -244,17 +262,13 @@ def generate_triangulation_gmsh(geometry, params):
# Algorithm 6 = Frontal-Delaunay (2D)
gmsh.option.setNumber("Mesh.Algorithm", 6)
# Quality settings
# Size control — let background field drive sizes
gmsh.option.setNumber("Mesh.MeshSizeMin", s_min * 0.8)
gmsh.option.setNumber("Mesh.MeshSizeMax", s_max * 1.2)
gmsh.option.setNumber("Mesh.MeshSizeFromPoints", 0)
gmsh.option.setNumber("Mesh.MeshSizeFromCurvature", 0)
gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0)
# Angle constraints for quality triangles
gmsh.option.setNumber("Mesh.MinimumCircleNodes", 12)
gmsh.option.setNumber("Mesh.MinimumCurveNodes", 3)
# --- Step 5: Generate mesh ---
gmsh.model.mesh.generate(2)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff