auto: daily sync
This commit is contained in:
@@ -140,6 +140,9 @@ def generate_triangulation_gmsh(geometry, params):
|
|||||||
hole_centers = [] # For diagnostics
|
hole_centers = [] # For diagnostics
|
||||||
|
|
||||||
# --- Step 2: Add hole keepouts ---
|
# --- 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', []):
|
for hole in geometry.get('holes', []):
|
||||||
diameter = float(hole.get('diameter', 10.0) or 10.0)
|
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
|
hole_radius = diameter / 2.0
|
||||||
keepout_radius = hole_radius * (1.0 + d_keep)
|
keepout_radius = hole_radius * (1.0 + d_keep)
|
||||||
|
|
||||||
# Check if keepout intersects inner plate
|
# Check if keepout is fully inside inner plate
|
||||||
keepout_poly = Point(cx, cy).buffer(keepout_radius)
|
keepout_poly = Point(cx, cy).buffer(keepout_radius, resolution=32)
|
||||||
if not inner_plate.intersects(keepout_poly):
|
if not inner_plate.contains(keepout_poly):
|
||||||
continue
|
# 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
|
# Add circle
|
||||||
center_tag, hole_loop, arc_tags = _add_circle_to_gmsh(
|
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):
|
if hole_poly.is_empty or not inner_plate.intersects(hole_poly):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Clip to inner plate
|
# Clip to inner plate (with inward offset to avoid boundary touching)
|
||||||
clipped = inner_plate.intersection(hole_poly)
|
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:
|
if clipped.is_empty or clipped.area < 1.0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -209,7 +227,7 @@ def generate_triangulation_gmsh(geometry, params):
|
|||||||
if hole_curves:
|
if hole_curves:
|
||||||
hole_dist = field.add("Distance")
|
hole_dist = field.add("Distance")
|
||||||
field.setNumbers(hole_dist, "CurvesList", hole_curves)
|
field.setNumbers(hole_dist, "CurvesList", hole_curves)
|
||||||
field.setNumber(hole_dist, "Sampling", 100)
|
field.setNumber(hole_dist, "Sampling", 50)
|
||||||
|
|
||||||
hole_thresh = field.add("Threshold")
|
hole_thresh = field.add("Threshold")
|
||||||
field.setNumber(hole_thresh, "InField", hole_dist)
|
field.setNumber(hole_thresh, "InField", hole_dist)
|
||||||
@@ -222,7 +240,7 @@ def generate_triangulation_gmsh(geometry, params):
|
|||||||
# --- Edge/boundary influence field: E(x) ---
|
# --- Edge/boundary influence field: E(x) ---
|
||||||
edge_dist = field.add("Distance")
|
edge_dist = field.add("Distance")
|
||||||
field.setNumbers(edge_dist, "CurvesList", outer_lines)
|
field.setNumbers(edge_dist, "CurvesList", outer_lines)
|
||||||
field.setNumber(edge_dist, "Sampling", 100)
|
field.setNumber(edge_dist, "Sampling", 50)
|
||||||
|
|
||||||
edge_thresh = field.add("Threshold")
|
edge_thresh = field.add("Threshold")
|
||||||
field.setNumber(edge_thresh, "InField", edge_dist)
|
field.setNumber(edge_thresh, "InField", edge_dist)
|
||||||
@@ -244,17 +262,13 @@ def generate_triangulation_gmsh(geometry, params):
|
|||||||
# Algorithm 6 = Frontal-Delaunay (2D)
|
# Algorithm 6 = Frontal-Delaunay (2D)
|
||||||
gmsh.option.setNumber("Mesh.Algorithm", 6)
|
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.MeshSizeMin", s_min * 0.8)
|
||||||
gmsh.option.setNumber("Mesh.MeshSizeMax", s_max * 1.2)
|
gmsh.option.setNumber("Mesh.MeshSizeMax", s_max * 1.2)
|
||||||
gmsh.option.setNumber("Mesh.MeshSizeFromPoints", 0)
|
gmsh.option.setNumber("Mesh.MeshSizeFromPoints", 0)
|
||||||
gmsh.option.setNumber("Mesh.MeshSizeFromCurvature", 0)
|
gmsh.option.setNumber("Mesh.MeshSizeFromCurvature", 0)
|
||||||
gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 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 ---
|
# --- Step 5: Generate mesh ---
|
||||||
gmsh.model.mesh.generate(2)
|
gmsh.model.mesh.generate(2)
|
||||||
|
|
||||||
|
|||||||
14909
tools/adaptive-isogrid/test_data/rib_profile_sandbox_1_gmsh.json
Normal file
14909
tools/adaptive-isogrid/test_data/rib_profile_sandbox_1_gmsh.json
Normal file
File diff suppressed because it is too large
Load Diff
1851
tools/adaptive-isogrid/test_data/rib_profile_sandbox_2_gmsh.json
Normal file
1851
tools/adaptive-isogrid/test_data/rib_profile_sandbox_2_gmsh.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user