-
Notifications
You must be signed in to change notification settings - Fork 63
Improve "difference mesh" generation, triangulation, and refactor code #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ansonl
wants to merge
38
commits into
ChHarding:main
Choose a base branch
from
ansonl:topbot
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…to this mega change since I changed a lot.
…le in this commit so it's easier to just pull in the changes.
…d raster add/minus/scaling in grid.__init__(). Removed tile_info.user_offset because it was redundant to minus the minimum height of the raster then add user_offset (which is the minimum height of raster - user defined min_elev).
…zip_file_name takes precedence for ZIP and folder name
… on the dilation mask if needed
…his fixes an issue where the top=notNaN and bottom=NaN in later raster processing step leads to the bottom being forced to base in that location.
…er start, and work in progress for edge fitting with coordinate transform functions
…lippingInfo class as WIP for polygon edge clipping.
…t disjoint check between boundary polygon and quad works
…the edge_interpolation variant since we still want to keep it for interp and clip other variants by setting cells to nan
handle case where quad is entirely contained in boundary poly handle case where quad has intersections with boundary poly, flatten the resulting intersection geometries into a single list and do not count point intersections
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
Add new infrastructure files from feature/unit_tests_and_linting: - CI/CD pipeline (.github/workflows/ci.yml) - Pre-commit hooks configuration - Development documentation and guides - Docker container for CI testing - Makefile for task automation - Python project configuration (pyproject.toml) - Pytest configuration (conftest.py) - UV lock file for dependencies - Refactoring documentation These files do not exist in PR ChHarding#111 and can be safely added. Part of integration effort to merge PR ChHarding#111 with feature/unit_tests_and_linting. Tracked in merging_plan.md. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
Merge configuration files from feature/unit_tests_and_linting: - .gitignore: Add additional ignore patterns (*.tif, *old.*, *.xml) - LICENSE: Add GPL v3 license file - environment.yml: Pin Python to 3.12, clean up formatting - requirements.txt: Fix trailing whitespace - setup.py: Improve formatting, update Python requirement to 3.12 - stuff/example_config.json: Fix trailing newline Changes are primarily formatting improvements and Python 3.12 standardization. All functional aspects of PR ChHarding#111 preserved. Part of integration effort to merge PR ChHarding#111 with feature/unit_tests_and_linting. Tracked in merging_plan.md Phase 2. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
Update documentation from feature/unit_tests_and_linting: - ReadMe.md: Fix trailing whitespace, update branch reference (master→main), add tile naming convention documentation - NEWS.md: Fix trailing whitespace throughout Changes are primarily formatting fixes with one useful addition: the tile naming convention documentation clarifies how tiles are numbered in multi-tile outputs. Part of integration effort to merge PR ChHarding#111 with feature/unit_tests_and_linting. Tracked in merging_plan.md Phase 3. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
… (Phase 4.1) Apply minimal formatting improvements while preserving PR ChHarding#111's architecture: - Change triple single quotes to triple double quotes for docstrings - Alphabetize imports - Remove unused 'dirname' import - Improve error handling (Exception -> ImportError) - Use f-strings for error messages - Add explicit exit code (sys.exit(1)) - Fix trailing whitespace - Improve string formatting with parentheses - Fix None comparisons (== None -> is not None) - Apply black and isort formatting PRESERVED from PR ChHarding#111: - TouchTerrainConfig class usage (critical new architecture) - All functional logic and structure - New example_config.json generation method Part of integration effort to merge PR ChHarding#111 with feature/unit_tests_and_linting. Tracked in merging_plan.md Phase 4.1. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
CRITICAL DECISION: Kept 3 core files entirely from PR ChHarding#111: 1. TouchTerrainEarthEngine.py (2054 lines) - Introduces RasterVariants, ProcessingTile, CellClippingInfo classes - 2500+ line difference from feature branch - Feature branch lacks these critical mesh generation classes - Has 100+ linting issues, but fixing risks breaking functionality 2. grid_tesselate.py (1780 lines) - Defines RasterVariants (line 456) and ProcessingTile (line 601) - 1800+ line difference, fundamental architectural changes - These classes are core to new mesh generation approach 3. utils.py (344 lines) - Adds 4 new coordinate transformation functions - Essential for polygon clipping feature - Feature branch has only 7 functions vs PR ChHarding#111's 11 functions **Rationale**: PR ChHarding#111's architecture is fundamentally different and more advanced. Feature branch refactoring would require rewriting to accommodate new classes. Linting improvements can be addressed in follow-up PR after verifying functionality works correctly. Updated merging_plan.md to reflect these decisions and document rationale. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
Test Status Summary: ✅ 7 GPX tests PASSING ⚡ 20 EE tests properly skipped (fast, no auth attempts) 🎯 Test run time: 12.75 seconds ✅ Integration validated: PR ChHarding#111 code works correctly Key Achievements: - Installed shapely dependency (new requirement from PR ChHarding#111) - Fixed EE test skipping using pytest_collection_modifyitems hook - Removed test/* from .gitignore - All available tests pass without failures The integration is stable and ready for further phases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
Apply code quality improvements from feature/unit_tests_and_linting to 5 supporting modules: 1. TouchTerrainGPX.py - Better formatting, docstrings, error handling 2. Coordinate_system_conv.py - Type hints, tests, improved error messages 3. calculate_ticks.py - Complete rewrite with better algorithm and tests 4. config.py - Better env var handling and documentation 5. vectors.py - Formatting improvements These files do not depend on PR ChHarding#111's new classes (RasterVariants, ProcessingTile, etc.) and can be safely updated with the feature branch improvements. PR ChHarding#111's new files are already present and untouched: - user_config.py (TouchTerrainConfig class) - tile_info.py (TouchTerrainTileInfo class) - polygon_test.py (polygon testing utilities) Test Status: 7 passed, 20 skipped in 12.63s ✅ Part of integration effort to merge PR ChHarding#111 with feature/unit_tests_and_linting. Tracked in merging_plan.md Phase 4.3. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
- Mark all supporting modules as completed with verification results - Document specific improvements applied from feature branch - Update strategy notes to reflect actual merge outcomes - Maintain tracking of PR ChHarding#111 contributions while incorporating feature branch enhancements
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
- Updated merging_plan.md to reflect completed Phase 5 and 6 merges - Applied feature branch improvements including code formatting, import organization, and error handling - Preserved PR ChHarding#111 functionality while incorporating code quality enhancements - Updated test files to match new function signatures and improved test structure - Completed merge of static assets, templates, and test data files with whitespace cleanup
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
- Fix trailing whitespace in GPX test files and documentation - Fix end-of-file formatting in data files and configs - Fix None comparison in TouchTerrainEarthEngine.py (line 2366) - Apply formatting to notebooks and VSCode configs Note: Remaining linting issues in core files (TouchTerrainEarthEngine.py, grid_tesselate.py, utils.py, polygon_test.py) are deferred to post-integration cleanup to preserve PR ChHarding#111's critical mesh generation logic. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
nirabo
added a commit
to nirabo/TouchTerrain_for_CAGEO
that referenced
this pull request
Oct 14, 2025
Testing and validation complete: - All tests passing (7 passed, 20 skipped) - Dependencies verified - Pre-commit formatting applied - Integration validated Deferred 138 linting errors in PR ChHarding#111 core files to post-integration cleanup. Ready for pull request creation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
93 tasks
Find the intersection polygon between each raster cell and the clipping polygon. Sort all individual edges of intersection polygons into buckets stored in RasterVariants based on if the edge lies on a cardinal direction edge of the cell quad. Marks all interior edges as needing walls created. Add shapely_utils with functions for flattening shapely geometries
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I have refined Chris' difference mesh generation code, removed some redundant steps, and added some new steps needed to get more seamless meshes. I have also refactored the code and class organization a bit to play better with code editor autocomplete such as VSCode intellisense.
This is a draft of my changes to Touch Terrain. I'll edit this PR and add my changes for a little while until it is ready to merge.Difference Mesh
Tweaked Chris' code to get the "difference mesh" to generate at the correct height with the right walls. The difference mesh is the mesh made from the subtraction of a "top" and "bottom" DEM. The walls are created at the right locations by dilating twice.
Two modes are referred to in the code:
Normal Mode
Generates a mesh for the passed in raster with bottom surface flat along the base.
top_elevation_hintshould be passed when generating a raster that will be the "bottom" raster of a related Difference Mesh.Difference Mesh Mode
Generates a mesh that is sandwiched between two rasters.
Config values related to Difference Mesh mode are:
Mesh Limitations
TouchTerrain's current mesh generation is limited to creating connected volumes with quads as the "top" and "bottom" surfaces of the volume. Real vertical quads connecting a top and bottom quad as "walls" are only allowed at the true X/Y borders of a connected area. This means that a vertical quad (wall) is not generated to connect vertices of 2 quads that are both on the "top" or "bottom" surface.
↓ This limitation leads to mesh generations where 2 volumes share edges. Because an edge should only have 2 faces, this is technically non-manifold.

The 2 volumes are normally closed on their own and the only connection between them are shared edges with no shared volume going through them so this should not cause issues for most usages. It's easy to tell where one volume begins and ends by eye. Hopefully our mesh processing software is smart enough.
The mesh size reduction method in #99 still works despite these technically non-manifold edges because Blender correctly recognizes these edges as part of the "outside edge border".
In the future, we should look into adding a way for top/bottom quad of a
cellto connect to the quad along the same surface of anothercellby a vertical quad.cell's bottomquadcenter value is at the base and it could connect to bordering bottom quads' edges by a vertical quad to avoid the non-manifold edges seen in the animation above where the 2 width gap straddling the highlighted edges that should be along the base is forced to have a "transition" distance of at least 1 cell to get cells that are completely along the base (or actually gapped like in the picture).Make the difference mesh manifold at edges
Remove zero height volumes that occur near the edges of the difference mesh (where the top and bottom mesh have the same Z coordinates) so that the mesh is manifold. This cleanup is in
cell.remove_zero_height_volumes()The removal in NW and SE directions works best when splitting edge rotation is set to favor less steep split edges. Thus
remove_zero_height_volumes()is only active and needed whensplit_rotation = 1↓ Before with zero volume shapes


↓ After removing zero volume shapes
Quad Triangulation Splitting Edge Rotation
Add feature to rotate the splitting edge when triangulating
quads so that the edge orientation can favor less/more steep split edges + flat borders. This occurs inquad.get_triangles()The original behavior of constant edge orientation from NW-SE is still the default behavior.
↓ Before


↓ After
Fixed W/E X coordinate flipped bug
The W/E locations for X coordinate in
createCells()was flipped and noticed in a previous code comment. This made the assignment of the cell's quad's corner vertices confusing because we were flipping the W/E back again during the vertex creation.9297859
This is fixed in the linked commit of this PR so that the X coordinates assigned for W/E now reflect the right W or E directions.
Code refactor
Partially updated the code to PEP standard. Such as
UpperCaseClassNamefor class names andlower_case_underscorefor variable names. It makes Touch Terrain easier to read and debug in code editors with Python linting such as VSCode.Python type hints (Requires Python 3.10+)
Added Python type hints to make code readability and debugging easier. Types have been assigned to some of the variables but more type hints need to be added in the future to make the code "pass" compile time type checking.
Hovering over type hinted variables now tells you what it represents and what it is used for.
Python docstrings
Added new and converted existing docstrings to be formatted correctly.
Numpy
Some files imported
numpyasnpand some had justnumpyso I changed the references in TouchTerrainEarthEngine.py to leavenumpyasnumpyto be consistent.Touch Terrain Config
Configuration is defined as a class
TouchTerrainConfiginstead of adict[str, Any]. Config values centrally managed in a single location inuser_config.pyas class attributes allow type hinting and hover to view documentation on that value.The class attribute also makes it less likely to make a typo with IDE autocomplete versus manually typing a text key for dictionary.
Touch Terrain Tile Info
tile_infois is defined as a classTouchTerrainTileInfoinstead of adict[str, Any]. Similar benefits as the transition toTouchTerrainConfig.TouchTerrainTileInfois defined intile_info.py.TouchTerrainConfigis now stored in tile infos underTouchTerrainTileInfo.configso that the config values can be accessed in a single point of truth instead of copying each config value into a dictionary.Multiple Raster Version Management with
RasterVariantsLots of raster operations done in Touch Terrain affect some or all of the rasters for a single DEM. Keeping track of multiple variants of a DEM with variables like
top,top_nan,top_dilatedis easy to forget making a change to a single variant.Raster variants for the same DEM in various stages of processing are kept in
RasterVariantswhich each variant stored as an attirbute such asoriginal,nan_close, anddilated. There is also a newedge_interpolationwhich uses the DEM from an optionalimportedDEM_interpconfig option to interpolate the top vertex values for thebottom_thru_basecase.RasterVariantssupports+,-,*operators so all raster variants stored asnumpy.ndarraycan be modified at once as ifRasterVariantswas a singlenumpy.ndarray. In the example below, all bottom DEM raster variants' arrays are increased by a constant value.ProcessingTileProcessingTilecontains attributes about the processing tile that were previously passed passed as individual parameters. Now it is easier to pass data along for tile logic by adding it to this new class instead of creating new parameters.Other Changes/Notes
DEM_nameconfig for locally imported DEM andconfig_path(automatically set in standalone mode)zip_file_nameorDEM_nameorconfig_path(checked in that order) is now used as the exported ZIP filename.DEM_nameorconfig_path(checked in that order) is now used as the mesh filename.If only one tile is generated, the exported filename does not include the
_tile_1_1at the end of the filename.tileScaleconfig optionThe map scale can now be directly specified with
tileScaleconfig option. Specified tile scale takes precedence overtilewidth.Other PRs
Incorporated #109, #106
Test environment
I used conda and virtual environment for testing and running TouchTerrain. For anyone else working with a local directory install of TouchTerrain in a similar environment, I recommend cloning the repo into its own folder.
I keep the data files in a separate directory at the top level named like
touchterrain-devso the the repo code folder and the data folder are in the same top level directory.To run TouchTerrain with from
TouchTerrain_standalone.pyin the code folder but use the data folder as the working directory, you can reference the python file in the code folder while in data folder. Likepython ../TOUCHTERRAIN_FOR_CAGEO/TouchTerrain_standalone.pyOr open VSCode in the code folder (workspace folder) and use a VSCode launch configuration setup to debug in the data folder (cwd):
I have added a VSCode
launch.jsonto the repo that I use. It has some left over test cases right now and I will clean up the file and add some test configs in the future. Mylaunch.jsonis setup to run with the JSON config files and DEMs in the../touchterrain-dev(data) folder relative to the repo (code) folder as described above.