Skip to content

Commit a4c911f

Browse files
authored
Merge pull request #20 from nullStack65/dev
Meshcutter fully working
2 parents c15bbf8 + 2c48418 commit a4c911f

26 files changed

+5848
-399
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Auto-merge release-please PRs
2+
# Automatically merges release-please PRs once CI passes
3+
4+
name: Auto-merge Release PRs
5+
6+
on:
7+
pull_request:
8+
branches: [releases]
9+
types: [opened, synchronize, reopened]
10+
11+
jobs:
12+
auto-merge:
13+
name: Auto-merge release-please PR
14+
runs-on: ubuntu-latest
15+
# Only run for release-please PRs
16+
if: startsWith(github.head_ref, 'release-please--')
17+
18+
permissions:
19+
contents: write
20+
pull-requests: write
21+
22+
steps:
23+
- name: Enable auto-merge
24+
uses: peter-evans/enable-pull-request-automerge@v3
25+
with:
26+
token: ${{ secrets.GITHUB_TOKEN }}
27+
pull-request-number: ${{ github.event.pull_request.number }}
28+
merge-method: squash

.github/workflows/ci.yml

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# CI - runs on PRs to releases branch
2-
# Full test matrix, linting, and build validation
2+
# Separated jobs for faster feedback and clearer results
33

44
name: CI
55

@@ -23,13 +23,13 @@ jobs:
2323
run: pip install black flake8
2424

2525
- name: Check formatting with black
26-
run: black --check --diff microfinity/ tests/
26+
run: black --check --diff microfinity/ meshcutter/ tests/
2727

2828
- name: Lint with flake8
29-
run: flake8 microfinity/ tests/ --max-line-length=120 --extend-ignore=E203,W503,F401,F403,F405,E402,F821,W293,W605,F841
29+
run: flake8 microfinity/ meshcutter/ tests/ --max-line-length=120 --extend-ignore=E203,W503,F401,F403,F405,E402,F821,W293,W605,F841
3030

31-
test:
32-
name: Test (Python ${{ matrix.python-version }})
31+
test-microfinity:
32+
name: Test microfinity (Python ${{ matrix.python-version }})
3333
runs-on: ubuntu-latest
3434
strategy:
3535
fail-fast: false
@@ -48,18 +48,61 @@ jobs:
4848
run: |
4949
pip install --upgrade pip
5050
pip install cadquery-ocp cadquery cqkit
51-
pip install pytest pytest-cov
51+
pip install pytest
5252
pip install -e .
5353
54-
- name: Run full test suite
55-
run: pytest -v --cov=microfinity --cov-report=xml
54+
- name: Run microfinity tests
55+
run: pytest tests/ --ignore=tests/test_meshcutter -v
5656

57-
- name: Upload coverage
58-
uses: codecov/codecov-action@v4
59-
if: matrix.python-version == '3.11'
57+
test-meshcutter-unit:
58+
name: Test meshcutter unit (Python ${{ matrix.python-version }})
59+
runs-on: ubuntu-latest
60+
strategy:
61+
fail-fast: false
62+
matrix:
63+
python-version: ["3.9", "3.10", "3.11", "3.12"]
64+
65+
steps:
66+
- uses: actions/checkout@v4
67+
68+
- name: Set up Python ${{ matrix.python-version }}
69+
uses: actions/setup-python@v5
70+
with:
71+
python-version: ${{ matrix.python-version }}
72+
73+
- name: Install dependencies
74+
run: |
75+
pip install --upgrade pip
76+
pip install cadquery-ocp cadquery cqkit
77+
pip install manifold3d
78+
pip install pytest
79+
pip install -e .
80+
81+
- name: Run meshcutter unit tests
82+
run: pytest tests/test_meshcutter -m "not integration" -v
83+
84+
test-meshcutter-integration:
85+
name: Test meshcutter integration
86+
runs-on: ubuntu-latest
87+
88+
steps:
89+
- uses: actions/checkout@v4
90+
91+
- name: Set up Python
92+
uses: actions/setup-python@v5
6093
with:
61-
files: ./coverage.xml
62-
fail_ci_if_error: false
94+
python-version: "3.11"
95+
96+
- name: Install dependencies
97+
run: |
98+
pip install --upgrade pip
99+
pip install cadquery-ocp cadquery cqkit
100+
pip install manifold3d
101+
pip install pytest
102+
pip install -e .
103+
104+
- name: Run meshcutter integration tests
105+
run: pytest tests/test_meshcutter -m "integration" -v
63106

64107
build:
65108
name: Build Package

.github/workflows/sync-to-dev.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Sync releases back to dev after release-please creates a release
2+
# This ensures dev stays up-to-date with version bumps and changelog updates
3+
4+
name: Sync to Dev
5+
6+
on:
7+
push:
8+
branches: [releases]
9+
paths:
10+
- 'pyproject.toml'
11+
- 'microfinity/__init__.py'
12+
- 'CHANGELOG.md'
13+
14+
jobs:
15+
sync:
16+
name: Sync releases to dev
17+
runs-on: ubuntu-latest
18+
# Only run if this looks like a release-please commit
19+
if: contains(github.event.head_commit.message, 'chore(releases)') || contains(github.event.head_commit.message, 'chore(main)')
20+
21+
steps:
22+
- uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0
25+
token: ${{ secrets.GITHUB_TOKEN }}
26+
27+
- name: Configure git
28+
run: |
29+
git config user.name "github-actions[bot]"
30+
git config user.email "github-actions[bot]@users.noreply.github.com"
31+
32+
- name: Sync version files to dev
33+
run: |
34+
# Get the version from releases branch
35+
VERSION=$(grep -m1 'version = ' pyproject.toml | cut -d'"' -f2)
36+
echo "Syncing version $VERSION to dev"
37+
38+
# Checkout dev branch
39+
git checkout dev
40+
41+
# Cherry-pick the version bump changes (if they apply cleanly)
42+
# Or directly update the version files
43+
git checkout releases -- pyproject.toml microfinity/__init__.py CHANGELOG.md
44+
45+
# Check if there are changes
46+
if git diff --quiet; then
47+
echo "No changes to sync"
48+
exit 0
49+
fi
50+
51+
# Commit and push
52+
git add pyproject.toml microfinity/__init__.py CHANGELOG.md
53+
git commit -m "chore: sync version $VERSION from releases"
54+
git push origin dev

CLAUDE.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Claude Project Context: Microfinity
2+
3+
This file provides context for Claude when working on this project.
4+
5+
## Project Overview
6+
7+
**Microfinity** is a Python library for creating Gridfinity-compatible objects using CadQuery. It includes:
8+
9+
1. **microfinity/** - CadQuery-based generator for boxes, baseplates, and spacers
10+
2. **meshcutter/** - Mesh-based tool to convert 1U Gridfinity boxes to micro-divided feet
11+
12+
## Key Architecture Decisions
13+
14+
### Meshcutter: Replace-Base Approach
15+
16+
The meshcutter uses a **replace-base pipeline** (not boolean subtraction) to convert 1U feet to micro-feet:
17+
18+
1. **Trim** the input mesh above z=5mm (keeps walls and interior)
19+
2. **Generate** fresh micro-feet base using microfinity's construction path
20+
3. **Union** the trimmed top with the new base
21+
22+
This produces geometry **identical** to natively-generated micro boxes (<1mm³ difference).
23+
24+
**Important**: The legacy boolean subtraction approach has been deprecated and removed.
25+
26+
### Gridfinity Constants
27+
28+
All Gridfinity constants should come from `meshcutter/core/constants.py`, which re-exports from `microfinity.core.constants`.
29+
30+
Key values:
31+
- `GRU = 42.0` - 1U pitch (mm)
32+
- `GR_TOL = 0.5` - Clearance between feet
33+
- `GR_BASE_HEIGHT = 4.75` - Foot height
34+
- `GR_BASE_CLR = 0.25` - Clearance above foot
35+
- `Z_SPLIT_HEIGHT = 5.0` - Where we cut between top and base
36+
37+
## Important Files
38+
39+
### Core Modules
40+
- `meshcutter/core/replace_base.py` - Main replace-base pipeline
41+
- `meshcutter/core/constants.py` - Centralized constants
42+
- `meshcutter/core/mesh_utils.py` - Mesh conversion utilities
43+
- `meshcutter/core/cq_utils.py` - CadQuery utilities
44+
- `meshcutter/core/grid_utils.py` - Grid/offset calculations
45+
46+
### CLI
47+
- `meshcutter/cli/meshcut.py` - Command-line interface
48+
49+
### Tests
50+
- `tests/test_meshcutter/test_golden.py` - Golden comparison tests
51+
- `tests/test_meshcutter/golden_utils.py` - Test utilities
52+
53+
## Refactoring Tracking
54+
55+
**IMPORTANT**: When completing refactoring tasks, update `REFACTOR_TODO.md` to mark items as complete.
56+
57+
The refactoring TODO file tracks:
58+
- DRY elimination (utility modules)
59+
- Module updates
60+
- Test creation
61+
- CI setup
62+
63+
## Testing
64+
65+
### Golden Tests
66+
Golden tests compare meshcutter output against microfinity-generated references:
67+
- Reference meshes are generated on-demand (not stored)
68+
- Acceptance threshold: <1mm³ total geometric difference
69+
- Test configurations: 1x1x1, 2x3x2, 1x1x3, 3x3x1
70+
71+
### Running Tests
72+
```bash
73+
# All meshcutter tests
74+
pytest tests/test_meshcutter/ -v
75+
76+
# Just golden tests
77+
pytest tests/test_meshcutter/test_golden.py -v
78+
79+
# Quick unit tests (skip slow golden tests)
80+
pytest tests/test_meshcutter/ -v -m "not golden"
81+
```
82+
83+
## Code Style
84+
85+
- **Line length**: 120 characters (configured in pyproject.toml)
86+
- **Formatter**: Black
87+
- **Type hints**: Use throughout, especially for public APIs
88+
- **Docstrings**: Google style
89+
90+
## Common Tasks
91+
92+
### Adding a New Micro-Division Size
93+
1. Update `meshcutter/core/grid_utils.py` if offset calculations change
94+
2. Add test configuration to `tests/test_meshcutter/test_golden.py`
95+
3. Update `docs/TODO_FUTURE_DIVISIONS.md`
96+
97+
### Updating Constants
98+
1. Check if constant exists in `microfinity.core.constants`
99+
2. If yes, re-export in `meshcutter/core/constants.py`
100+
3. If no, add to meshcutter-specific section
101+
102+
### Debugging Mesh Issues
103+
1. Use `mesh_utils.get_mesh_diagnostics()` for mesh info
104+
2. Export intermediate meshes with `mesh.export('/tmp/debug.stl')`
105+
3. View in external tool (MeshLab, Blender)

0 commit comments

Comments
 (0)