{"id":13627387,"url":"https://github.com/hhoppe/Mesh-processing-library","last_synced_at":"2025-04-16T19:31:34.314Z","repository":{"id":45290426,"uuid":"77887760","full_name":"hhoppe/Mesh-processing-library","owner":"hhoppe","description":"C++ libraries and programs demonstrating mesh processing research published in ACM SIGGRAPH (1992-2003)","archived":false,"fork":false,"pushed_at":"2025-04-13T06:00:40.000Z","size":77537,"stargazers_count":847,"open_issues_count":1,"forks_count":137,"subscribers_count":34,"default_branch":"main","last_synced_at":"2025-04-14T13:08:37.228Z","etag":null,"topics":["mesh-processing","triangle-mesh"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hhoppe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-01-03T05:48:29.000Z","updated_at":"2025-04-14T01:28:27.000Z","dependencies_parsed_at":"2025-04-14T11:46:41.068Z","dependency_job_id":null,"html_url":"https://github.com/hhoppe/Mesh-processing-library","commit_stats":{"total_commits":515,"total_committers":3,"mean_commits":"171.66666666666666","dds":0.003883495145631022,"last_synced_commit":"145bcc6c970823671162611d2d94692dd7ef86da"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhoppe%2FMesh-processing-library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhoppe%2FMesh-processing-library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhoppe%2FMesh-processing-library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhoppe%2FMesh-processing-library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hhoppe","download_url":"https://codeload.github.com/hhoppe/Mesh-processing-library/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249268556,"owners_count":21240944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mesh-processing","triangle-mesh"],"created_at":"2024-08-01T22:00:33.516Z","updated_at":"2025-04-16T19:31:34.305Z","avatar_url":"https://github.com/hhoppe.png","language":"C++","funding_links":[],"categories":["General Libraries"],"sub_categories":[],"readme":"# Mesh Processing Library\n\n\u003c!--\nPreview exact GitHub rendering using \"env grip\"; it automatically calls GitHub API and serves webpage; really nice.\nGitHub-specific syntax: https://help.github.com/categories/writing-on-github/\nNice docs in http://daringfireball.net/projects/markdown/syntax\n\n[//]: # (Another way to insert comments -- after a blank line)\n--\u003e\n\n\n## Overview\n\nThis package contains C++ libraries and programs demonstrating mesh processing research\npublished in ACM SIGGRAPH (1992\u0026ndash;2003):\n\n- \u003cem\u003esurface reconstruction\u003c/em\u003e (from unorganized, unoriented points)\n- \u003cem\u003emesh optimization\u003c/em\u003e\n- \u003cem\u003esubdivision surface fitting\u003c/em\u003e\n- \u003cem\u003emesh simplification\u003c/em\u003e\n- \u003cem\u003eprogressive meshes\u003c/em\u003e (level-of-detail representation)\n- \u003cem\u003egeomorphs\u003c/em\u003e (smooth transitions across LOD meshes)\n- \u003cem\u003eview-dependent mesh refinement\u003c/em\u003e\n- \u003cem\u003esmooth terrain LOD\u003c/em\u003e\n- \u003cem\u003eprogressive simplicial complexes\u003c/em\u003e\n- \u003cem\u003eoptimized mesh traversal\u003c/em\u003e (for transparent vertex caching)\n- \u003cem\u003espherical parameterization\u003c/em\u003e\n\nThe source code has been updated to modern C++ style and for cross-platform use.\n\n\n## Requirements / dependencies\n\nThe code can be compiled with Microsoft Visual Studio using the solution (`*.sln`)\nand project (`*.vcxproj`) files.\n\nOn Unix (Linux, Mac OS, and Cygwin),\nthe code compiles using the `clang` and `gcc` compilers and GNU `make`.\n\nReading/writing of images and videos is enabled using several options.\nIf available, image I/O can use `libpng`/`libjpeg` or Windows Imaging Component (WIC).\nVideo I/O can use Windows Media Foundation (WMF).\nAcross all platforms, if the command \u003ca href=\"https://ffmpeg.org/\"\u003e`ffmpeg`\u003c/a\u003e\nis present in the `PATH`,\nit is spawned in a piped subprocess for both image and video I/O.\n\nOn Mac OS X, it is necessary to install\n\u003ca href=\"https://www.xquartz.org/\"\u003e`XQuartz`\u003c/a\u003e for `X11` support and\n\u003ca href=\"https://evermeet.cx/ffmpeg/\"\u003e`ffmpeg`\u003c/a\u003e for image/video I/O.\n\n\n## Code compilation\n\n### Build using Microsoft Visual Studio\n\nOpen the `mesh_processing.sln` file and build the solution\n(typically as a `\"ReleaseMD - x64\"` build).\nExecutables are placed in `bin`, `bin/debug`, `bin/Win32`, or `bin/Win32/debug`,\ndepending on the build configuration.\n\n\n### Build using GNU `make`\n\nThe `CONFIG` environment variable determines\nwhich `make/Makefile_config_*` definition file is loaded.\nOn Windows, `CONFIG` can be chosen among `{win, w32, cygwin, mingw, mingw32, clang}`,\ndefaulting to `win` if undefined.\nOn Unix platforms (Linux and Mac OS), `CONFIG=unix` is the unique and default setting.\n\nFor example, to build using the Microsoft `cl` compiler (Debug, placing `*.exe` into directory `bin/win`):\n\u003cbr/\u003e`make -j8`\u003cbr/\u003e\n\nTo build all programs (into either `bin/unix` or `bin/win`) and run all unit tests:\n\u003cbr/\u003e`make -j test`\n\nTo build on Unix, forcing the use of the `gcc` compiler (default is `clang`):\n\u003cbr/\u003e`make CC=gcc -j`\n\nTo build just the main library using the `mingw gcc` compiler on Windows:\n\u003cbr/\u003e`make CONFIG=mingw -j libHh`\n\nTo build the `Filtermesh` program (into `bin/clang`) using the `clang` compiler on Windows:\n\u003cbr/\u003e`make CONFIG=clang -j Filtermesh`\n\nTo build all programs (into `bin/cygwin`) and run all demos using the `gcc` compiler under Cygwin:\n\u003cbr/\u003e`make CONFIG=cygwin -j demos`\n\nTo clean up all files in all configurations:\n\u003cbr/\u003e`make CONFIG=all -j deepclean`\n\nNote that additional options such as debug/release, 32-bit/64-bit, and\ncompiler tool paths/parameters are set in the various `make/Makefile_*` files.\nThese need to be adjusted depending on the versions and installation paths of the tools.\nFor instance, the line\n`\"rel ?= 0\"` in `make/Makefile_config_win` specifies a debug (non-release) build, and\n`\"$(call prepend_PATH,...)\"` in `make/Makefile_base_vc` sets the compiler directory.\n\n\n## Publications and associated programs/demos\n\n\u003ctable id=\"publications\"\u003e\n\n \u003ctr id=\"pub_recon\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/recon.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/recon/\"\u003eSurface reconstruction from unorganized points\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eHugues Hoppe, Tony DeRose, Tom Duchamp, John McDonald, Werner Stuetzle.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eACM SIGGRAPH 1992 Proceedings\u003c/cite\u003e. (\u003ca href=\"https://dl.acm.org/doi/book/10.1145/3596711\"\u003e\u003cem\u003e2023 Seminal Paper\u003c/em\u003e\u003c/a\u003e.)\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eSigned-distance field estimated from a set of unoriented noisy points.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_recon\"\u003e\u003ccode\u003eRecon\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_recon_*.{sh,bat}\u003c/code\u003e, \u003ccode\u003eview_recon_*.{sh,bat}\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003ctr id=\"pub_meshopt\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/meshopt.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/meshopt/\"\u003eMesh optimization\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eHugues Hoppe, Tony DeRose, Tom Duchamp, John McDonald, Werner Stuetzle.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eACM SIGGRAPH 1993 Proceedings\u003c/cite\u003e.\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eTraversing the space of triangle meshes to optimize model fidelity and conciseness.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_Meshfit\"\u003e\u003ccode\u003eMeshfit\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_recon_*\u003c/code\u003e, \u003ccode\u003eview_recon_*\u003c/code\u003e, \u003ccode\u003ecreate_simplified_using_meshopt\u003c/code\u003e, \u003ccode\u003eview_simplified_using_meshopt\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003ctr id=\"pub_psrecon\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/psrecon.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/psrecon/\"\u003ePiecewise Smooth Surface Reconstruction\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eHugues Hoppe, Tony DeRose, Tom Duchamp, Michael Halstead, Hubert Jin, John McDonald, Jean Schweitzer, Werner Stuetzle.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eACM SIGGRAPH 1994 Proceedings\u003c/cite\u003e.\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eSubdivision surfaces with sharp features, and their automatic creation by data fitting.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_Subdivfit\"\u003e\u003ccode\u003eSubdivfit\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_recon_cactus\u003c/code\u003e, \u003ccode\u003eview_recon_cactus\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003ctr id=\"pub_pm\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/pm.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/pm/\"\u003eProgressive meshes\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eHugues Hoppe.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eACM SIGGRAPH 1996 Proceedings\u003c/cite\u003e. (\u003ca href=\"https://dl.acm.org/doi/book/10.1145/3596711\"\u003e\u003cem\u003e2023 Seminal Paper\u003c/em\u003e\u003c/a\u003e.)\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eEfficient, lossless, continuous-resolution representation of surface triangulations.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_MeshSimplify\"\u003e\u003ccode\u003eMeshSimplify\u003c/code\u003e\u003c/a\u003e, \u003ca href=\"#prog_reverselines\"\u003e\u003ccode\u003ereverselines\u003c/code\u003e\u003c/a\u003e, \u003ca href=\"#prog_Filterprog\"\u003e\u003ccode\u003eFilterprog\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_geomorphs\u003c/code\u003e, \u003ccode\u003eview_geomorphs\u003c/code\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003ctr id=\"pub_efficientpm\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/efficientpm.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/efficientpm/\"\u003eEfficient implementation of progressive meshes\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eHugues Hoppe.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eComputers \u0026amp; Graphics\u003c/cite\u003e, 22(1), 1998.\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eProgressive mesh data structures compatible with GPU vertex buffers.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_FilterPM\"\u003e\u003ccode\u003eFilterPM\u003c/code\u003e\u003c/a\u003e, \u003ca href=\"#prog_G3dOGL\"\u003e\u003ccode\u003eG3dOGL\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_pm_club\u003c/code\u003e, \u003ccode\u003eview_pm_club\u003c/code\u003e, \u003ccode\u003edetermine_approximation_error\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003c!--\u003ctr id=\"pub_newqem\"\u003e\n     \u003ctd class=\"lcell\"\u003e\n      \u003cimg class=\"thumbnail\" src=\"thumbnails/newqem.red.jpg\" alt=\"\"/\u003e\n     \u003c/td\u003e\n     \u003ctd class=\"rcell\"\u003e\n      \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/newqem/\"\u003eNew quadric metric for simplifying meshes with appearance attributes\u003c/a\u003e.\u003c/div\u003e\n      \u003cdiv class=\"authors\"\u003eHugues Hoppe.\u003c/div\u003e\n      \u003cdiv class=\"pub\"\u003e\u003ccite\u003eIEEE Visualization 1999 Conference\u003c/cite\u003e.\u003c/div\u003e\n      \u003cdiv class=\"desc\"\u003e\u003cem\u003eEfficient simplification metric designed around correspondence in 3D space.\u003c/em\u003e\u003c/div\u003e\n      \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_MeshSimplify\"\u003e\u003ccode\u003eMeshSimplify\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n      \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_pm_gaudipark\u003c/code\u003e, \u003ccode\u003eview_pm_gaudipark\u003c/code\u003e\u003c/div\u003e\n     \u003c/td\u003e\n \u003c/tr\u003e--\u003e\n\n \u003ctr id=\"pub_vdrpm\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/vdrpm.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/vdrpm/\"\u003eView-dependent refinement of progressive meshes\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eHugues Hoppe.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eACM SIGGRAPH 1997 Proceedings\u003c/cite\u003e.\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eLossless multiresolution structure for incremental local refinement/coarsening.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_FilterPM\"\u003e\u003ccode\u003eFilterPM\u003c/code\u003e\u003c/a\u003e, \u003ca href=\"#prog_G3dOGL\"\u003e\u003ccode\u003eG3dOGL\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_sr_office\u003c/code\u003e, \u003ccode\u003eview_sr_office\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003ctr id=\"pub_svdlod\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/svdlod.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/svdlod/\"\u003eSmooth view-dependent level-of-detail control and its application to terrain rendering\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eHugues Hoppe.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eIEEE Visualization 1998 Conference\u003c/cite\u003e. (\u003ca href=\"https://ieeevis.org/year/2023/info/awards/test-of-time-awards#scivis\"\u003e\u003cem\u003e2023 Test of Time Award\u003c/em\u003e\u003c/a\u003e.)\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eVisually smooth adaptation of mesh refinement using cascaded temporal geomorphs.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_StitchPM\"\u003e\u003ccode\u003eStitchPM\u003c/code\u003e\u003c/a\u003e, \u003ca href=\"#prog_G3dOGL\"\u003e\u003ccode\u003eG3dOGL\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_terrain_hierarchy\u003c/code\u003e, \u003ccode\u003eview_terrain_hierarchy\u003c/code\u003e, \u003ccode\u003ecreate_sr_terrain\u003c/code\u003e, \u003ccode\u003eview_sr_terrain\u003c/code\u003e, \u003ccode\u003eview_gcanyon_*\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003ctr id=\"pub_psc\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/psc.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/psc/\"\u003eProgressive simplicial complexes\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eJovan Popovic, Hugues Hoppe.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eACM SIGGRAPH 1997 Proceedings\u003c/cite\u003e.\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eProgressive encoding of both topology and geometry.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_G3dOGL\"\u003e\u003ccode\u003eG3dOGL\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003eview_psc_drumset\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003ctr id=\"pub_tvc\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/tvc.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/tvc/\"\u003eOptimization of mesh locality for transparent vertex caching\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eHugues Hoppe.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eACM SIGGRAPH 1999 Proceedings\u003c/cite\u003e.\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eFace reordering for efficient GPU vertex cache, advocating a FIFO policy.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_MeshReorder\"\u003e\u003ccode\u003eMeshReorder\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_vertexcache_bunny\u003c/code\u003e, \u003ccode\u003eview_vertexcache_bunny\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n \u003ctr id=\"pub_sphereparam\"\u003e\n  \u003ctd class=\"lcell\"\u003e\n   \u003cimg class=\"thumbnail\" src=\"thumbnails/sphereparam.red.jpg\" alt=\"\"/\u003e\n  \u003c/td\u003e\n  \u003ctd class=\"rcell\"\u003e\n   \u003cdiv class=\"title\"\u003e\u003ca href=\"https://hhoppe.com/proj/sphereparam/\"\u003eSpherical parameterization and remeshing\u003c/a\u003e.\u003c/div\u003e\n   \u003cdiv class=\"authors\"\u003eEmil Praun, Hugues Hoppe.\u003c/div\u003e\n   \u003cdiv class=\"pub\"\u003e\u003ccite\u003eACM SIGGRAPH 2003 Proceedings\u003c/cite\u003e.\u003c/div\u003e\n   \u003cdiv class=\"desc\"\u003e\u003cem\u003eRobust mapping of a surface onto a sphere, allowing 2D-grid resampling.\u003c/em\u003e\u003c/div\u003e\n   \u003cdiv class=\"bins\"\u003e\u003cspan class=\"sprogram\"\u003ePrograms:\u003c/span\u003e \u003ca href=\"#prog_SphereParam\"\u003e\u003ccode\u003eSphereParam\u003c/code\u003e\u003c/a\u003e, \u003ca href=\"#prog_SphereSample\"\u003e\u003ccode\u003eSphereSample\u003c/code\u003e\u003c/a\u003e\u003c/div\u003e\n   \u003cdiv class=\"demos\"\u003e\u003cspan class=\"sdemos\"\u003eDemos:\u003c/span\u003e \u003ccode\u003ecreate_spherical_param_bunny\u003c/code\u003e, \u003ccode\u003eview_spherical_param_bunny\u003c/code\u003e\u003c/div\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\n\u003c/table\u003e\n\n\n## Demos\n\nAfter the code is compiled, the demos can be run as follows.\n\nIn Windows, create, view, and clean up all the results using the `batch` scripts:\n```shell\ndemos/all_demos_create_results.bat\ndemos/all_demos_view_results.bat\nall_demos_clean.bat\n```\n\nOn Unix-based systems (e.g. Linux, Mac OS, Cygwin), either run the `bash` scripts:\n```shell\ndemos/all_demos_create_results.sh\ndemos/all_demos_view_results.sh\ndemos/all_demos_clean.sh\n```\n\nor alternatively (and faster), invoke `make` to create all results in parallel and then view them sequentially:\n\n\u003cpre\u003e\nmake \u003cem\u003e[CONFIG=\u003cvar\u003econfig\u003c/var\u003e]\u003c/em\u003e -j demos\n\u003c/pre\u003e\n\nNote that pressing the \u003ckbd\u003eEsc\u003c/kbd\u003e key closes any open program window.\n\n\n## Filter programs\n\nAll programs recognize the argument `--help` (or `-?`) to show their many options.\n\nThe programs `Filterimage`, `Filtermesh`, `Filtervideo`,\n`FilterPM`, and `Filterframe` are all designed to:\n- read media from `stdin` (or from files or procedures specified as initial arguments),\n- perform operations specified by arguments, and\n- write media to `stdout` (unless `-nooutput` is specified).\n\nFor example, the **`Filterimage`** command\u003ca id=\"prog_Filterimage\"\u003e\u003c/a\u003e\n```shell\nFilterimage demos/data/gaudipark.png -rotate 20 -cropleft 100 -cropright 100 \\\n  -filter lanczos6 -scaletox 100 -color 0 0 255 255 -boundary border -cropall -20 \\\n  -setalpha 255 -color 0 0 0 0 -drawrectangle 30% 30% -30% -30% -gdfill \\\n  -info -to jpg \u003egaudipark.new.jpg\n```\n- reads the specified image,\n- rotates it 20 degrees counterclockwise (with the default reflection boundary rule),\n- crops its left and right sides by 100 pixels,\n- scales it uniformly to a horizontal resolution of 100 pixels using a 6\u0026times;6 Lanczos filter,\n- adds a 20-pixel blue border on all sides,\n- adds an alpha channel and creates an undefined (`alpha=0`) rectangular region in the image center,\n- fills this region using gradient-domain smoothing,\n- outputs some statistics on pixel colors (to `stderr`), and\n- writes the result to a file under a different encoding.\n\nAs another example, the **`FilterPM`** command\u003ca id=\"prog_FilterPM\"\u003e\u003c/a\u003e\n```shell\nFilterPM demos/data/standingblob.pm -info -nfaces 1000 -outmesh | \\\n  Filtermesh -info -signeddistcontour 60 -genus | \\\n  G3dOGL -key DmDe\n```\n- reads a \u003cem\u003eprogressive mesh\u003c/em\u003e stream to construct a mesh with 1000 faces,\n- reports statistics on the mesh geometry,\n- remeshes the surface as the zero isocontour of its signed-distance function on a 60\u003csup\u003e3\u003c/sup\u003e grid,\n- reports the new mesh genus, and\n- shows the result in an interactive viewer using the specified view parameters,\n- simulating keypresses \u003ckbd\u003eDm\u003c/kbd\u003e to enable flat shading and \u003ckbd\u003eDe\u003c/kbd\u003e to make mesh edges visible.\n\nThe **`Filtermesh`** command\u003ca id=\"prog_Filtermesh\"\u003e\u003c/a\u003e\n```shell\nFilterPM demos/data/spheretext.pm -nf 2000 -outmesh | \\\n  Filtermesh -angle 35 -silsubdiv -silsubdiv -mark | \\\n  G3dOGL -key DmDeDbJ---- -st demos/data/spheretext.s3d\n```\n- reads a 2000-face mesh, marks all edges with dihedral angle greater than 35 degrees as sharp,\n- applies two steps of adaptive subdivision near these sharp edges, and\n- shows the result flat-shaded (\u003ckbd\u003eDm\u003c/kbd\u003e), with edges (\u003ckbd\u003eDe\u003c/kbd\u003e),\n  without backface culling (\u003ckbd\u003eDb\u003c/kbd\u003e), spinning (\u003ckbd\u003eJ\u003c/kbd\u003e) somewhat slowly (\u003ckbd\u003e----\u003c/kbd\u003e),\n- starting from the view parameters stored in the `spheretext.s3d` file.\n\nThe **`Filtervideo`** command\u003ca id=\"prog_Filtervideo\"\u003e\u003c/a\u003e\n```shell\nFiltervideo demos/data/palmtrees_small.mp4 -filter keys -scaleu 1.5 \u003epalmtrees_small.scale1.5.mp4\n```\n- reads the video (entirely into memory),\n- uniformly scales the two spatial dimensions by a factor 1.5 using the Keys bicubic filter, and\n- saves the new video.\n\nThe command\n```shell\nFiltervideo demos/data/palmtrees_small.mp4 -info -trimbeg 4 -boundary clamped -trimend -20% | \\\n    -tscale 1.5 -framerate 150% -croprectangle 50% 50% 400 240 -gamma 1.5 -bitrate 10m | \\\n  VideoViewer demos/data/palmtrees_small.mp4 - -key =an\n```\n- reads the video (entirely into memory),\n- reports statistics on the color channels,\n- trims off 4 frames at the beginning,\n- adds repeated copies of the last frames (with length 20% of the video),\n- temporally scales the content by a factor of 1.5 and adjusts the framerate accordingly,\n- spatially crops a centered rectangle with width 400 pixels and height 240 pixels,\n- adjusts the color gamma,\n- sets the output bitrate to 10 megabits/sec, and\n- shows the result (`-` for `stdin`) together with the original video in an interactive viewer,\n- with keypress \u003ckbd\u003e=\u003c/kbd\u003e to scale the window by 2, \u003ckbd\u003ea\u003c/kbd\u003e to loop all (two) videos,\n  and \u003ckbd\u003en\u003c/kbd\u003e to initially select the next video.\n\n\n## Surface reconstruction\n\n### \u003ca id=\"prog_recon\"\u003e\u003c/a\u003eRecon\n\nThis program reads a list of 3D (x, y, z) points assumed to be sampled near some unknown manifold surface,\nand reconstructs an approximating triangle mesh.\nFor example,\n```shell\nRecon \u003cdemos/data/distcap.pts -samplingd 0.02 | \\\n  Filtermesh -genus -rmcomp 100 -fillholes 30 -triangulate -genus | tee distcap.recon.m | \\\n  G3dOGL -st demos/data/distcap.s3d -key DmDe\n```\n- reads the text file of points,\n- reconstructs a triangle mesh assuming a max sample spacing (\u0026delta;+\u0026rho; in paper) of 2% of the bounding volume,\n- reports the genus of this initial mesh,\n- removes all connected components with fewer than 100 triangle faces,\n- fills and triangulates any hole bounded by 30 or fewer mesh edges,\n- reports the genus of the modified mesh,\n- saves it to a file, and\n- displays it interactively starting from a specified viewpoint, with flat-shaded faces (\u003ckbd\u003eDm\u003c/kbd\u003e)\n  and mesh edges (\u003ckbd\u003eDe\u003c/kbd\u003e).\n  \nTo show the progression of the Marching Cubes algorithm,\n```shell\nRecon \u003cdemos/data/distcap.pts -samplingd 0.02 -what c | \\\n  Filtera3d -split 30 | G3dOGL -key DCDb -st demos/data/distcap_backside.s3d -terse\n```\n- selects the 'c' (cubes) output stream,\n- forces a frame refresh every 30 polygon primitive, and\n- shows the result without display-list caching (\u003ckbd\u003eDC\u003c/kbd\u003e) and without backface culling (\u003ckbd\u003eDb\u003c/kbd\u003e).\n\nTo show a similar streaming reconstruction of the surface mesh,\n```shell\nRecon \u003cdemos/data/distcap.pts -samplingd 0.02 -what m | Filtermesh -toa3d | \\\n  Filtera3d -split 30 | \\\n  G3dOGL demos/data/distcap.pts -key DCDb -st demos/data/distcap_backside.s3d -terse -input -key _Jo\n```\n- selects the default 'm' (mesh) output stream,\n- converts the mesh to a stream of polygons, and\n- shows the points and streamed reconstruction with a slow (\u003ckbd\u003e_\u003c/kbd\u003e) rotation (\u003ckbd\u003eJ\u003c/kbd\u003e)\n  about the object frame (\u003ckbd\u003eo\u003c/kbd\u003e).\n \nThe same program can also read a list of 2D (y, z) points to reconstruct an approximating curve:\n```shell\nRecon \u003cdemos/data/curve1.pts -samplingd 0.06 -grid 30 | \\\n  Filtera3d -joinlines | tee curve1.a3d | \\\n  G3dOGL demos/data/curve1.pts -input -st demos/data/curve1.s3d\n```\n\n### \u003ca id=\"prog_Meshfit\"\u003e\u003c/a\u003eMeshfit\n\nGiven an initial mesh and a list of 3D points, this program optimizes both the mesh connectivity and\ngeometry to improve the fit, i.e. minimizing the squared distances from the points to the surface.\nFor example,\n```shell\nMeshfit -mfile distcap.recon.m -file demos/data/distcap.pts -crep 1e-5 -reconstruct | \\\n  tee distcap.opt.m | G3dOGL -st demos/data/distcap.s3d -key DmDe\n```\n- reads the previously reconstructed mesh and the original list of points,\n- applies an optimized sequence of perturbations to improve both the mesh connectivity and geometry,\n- using a specified tradeoff between mesh conciseness and fidelity\n  (\u003cvar\u003ec\u003csub\u003erep\u003c/sub\u003e\u003c/var\u003e=1e-4 yields a coarser mesh),\n- saves the result to a file, and displays it interactively.\n\nThe input points can also be sampled from an existing surface, e.g.:\n```shell\nFiltermesh demos/data/blob5.orig.m -randpts 10000 -vertexpts | \\\n  Meshfit -mfile demos/data/blob5.orig.m  -file - -crep 1e-6 -simplify | \\\n  G3dOGL -st demos/data/blob5.s3d -key DmDe\n```\n\nTo view the real-time fitting optimization,\n```shell\nMeshfit -mfile distcap.recon.m -file demos/data/distcap.pts \\\n  -crep 1e-5 -outmesh - -record -reconstruct | \\\n  G3dOGL -st demos/data/distcap.s3d -key DmDeDC -async -terse\n```\n- writes both the initial mesh and the stream of mesh modifications, and\n- displays the changing mesh asynchronously with display-list caching disabled (\u003ckbd\u003eDC\u003c/kbd\u003e).\n\n### \u003ca id=\"prog_Polyfit\"\u003e\u003c/a\u003ePolyfit\n\nThis related program performs a similar optimization of a 1D polyline (either open or closed)\nto fit a set of 2D points.  For example,\n```shell\nPolyfit -pfile curve1.a3d -file demos/data/curve1.pts -crep 3e-4 -spring 1 -reconstruct | \\\n  G3dOGL demos/data/curve1.pts -input -st demos/data/curve1.s3d\n```\n- reads the previously reconstructed polyline and the original list of points,\n- optimizes vertex positions and simplifies the number of line segments according to some representation cost, and\n- displays the result together with the original points.\n\n### \u003ca id=\"prog_Subdivfit\"\u003e\u003c/a\u003eSubdivfit\n\nIn a subdivision surface representation, a coarse base mesh tagged with \u003cem\u003esharp\u003c/em\u003e edges\ndefines a \u003cem\u003epiecewise smooth\u003c/em\u003e surface as the limit of a subdivision process.\nSuch a representation both improves geometric fidelity and leads to a more concise description.\n```shell\nFiltermesh distcap.opt.m -angle 52 -mark | \\\n  Subdivfit -mfile - -file demos/data/distcap.pts -crep 1e-5 -csharp .2e-5 -reconstruct \u003edistcap.sub0.m\n```\n- reads the previously optimized mesh and tags all edges with dihedral angle greater than 52 degrees as \u003cem\u003esharp\u003c/em\u003e,\n- loads this tagged mesh and the original list of points,\n- optimizes the mesh connectivity, geometry, and assignment of sharp edges to fit a\n  \u003cem\u003esubdivision surface\u003c/em\u003e to the points,\n- with a representation cost of `1e-5` per vertex and `.2e-5` per sharp edge, and\n- saves the resulting optimized base mesh to a file.  (The overall process takes a few minutes.)\n\nTo view the result,\n```shell\nG3dOGL distcap.sub0.m \"Subdivfit -mf distcap.sub0.m -nsub 2 -outn |\" \\\n  -st demos/data/distcap.s3d -key NDmDe -hwdelay 5 -hwkey N\n```\n- reads the base mesh together with a second mesh obtained by applying two iterations of subdivision,\n- shows the first mesh (\u003ckbd\u003eN\u003c/kbd\u003e) with flat-shaded faces and edges (\u003ckbd\u003eDmDe\u003c/kbd\u003e),\n- waits for 5 seconds, and displays the second mesh (\u003ckbd\u003eN\u003c/kbd\u003e) as a smooth surface without edges.\n\n### \u003ca id=\"prog_MeshDistance\"\u003e\u003c/a\u003eMeshDistance\n\nThis program computes measures of differences between two meshes.\nIt samples a dense set of points from a first mesh and computes the\nprojections of each point onto the closest point on a second mesh.\n```shell\nMeshDistance -mfile distcap.recon.m -mfile distcap.opt.m -bothdir 1 -maxerror 1 -distance\n```\n- `MeshDistance` loads the earlier results of mesh reconstruction and mesh optimization,\n- computes correspondences from points sampled on each mesh to the other mesh (in both directions), and\n- reports differences in geometric distance, color, and surface normals,\n  using both L\u003csup\u003e2\u003c/sup\u003e (rms) and L\u003csup\u003e\u0026infin;\u003c/sup\u003e (max) norms.\n\n\n## Mesh simplification\n\nGiven a mesh, `MeshSimplify` applies a sequence of \u003cem\u003eedge collapse\u003c/em\u003e operations\nto simplify it to a coarse \u003cem\u003ebase mesh\u003c/em\u003e while trying to best preserve the appearance of the original model.\nIt supports many different simplification criteria, as well as face properties,\nedges tagged as sharp, and vertex and corner attributes\n(\u003cvar\u003en\u003csub\u003ex\u003c/sub\u003e\u003c/var\u003e,\u003cvar\u003en\u003csub\u003ey\u003c/sub\u003e\u003c/var\u003e,\u003cvar\u003en\u003csub\u003ez\u003c/sub\u003e\u003c/var\u003e normals,\n\u003cvar\u003er\u003c/var\u003e,\u003cvar\u003eg\u003c/var\u003e,\u003cvar\u003eb\u003c/var\u003e colors, and \u003cvar\u003eu\u003c/var\u003e,\u003cvar\u003ev\u003c/var\u003e texture coordinates).\n\nFor example,\u003ca id=\"prog_MeshSimplify\"\u003e\u003c/a\u003e\n```shell\nMeshSimplify demos/data/club.orig.m -prog club.prog -simplify \u003eclub.base.m\n```\n- reads the original mesh and randomly samples points over its surface,\n- progressively simplifies it by examining point residual distances, while recording changes to a `*.prog` file, and\n- writes the resulting base mesh.\n\nThe next step is to reverse the sequence of stored edge collapses,\ni.e. forming a progressive sequence of \u003cem\u003evertex splits\u003c/em\u003e: \u003ca id=\"prog_reverselines\"\u003e\u003c/a\u003e\n```shell\nreverselines club.prog \u003eclub.rprog\n```\n\nWe construct a concise \u003cem\u003eprogressive mesh\u003c/em\u003e by encoding the base mesh together\nwith the sequence of vertex splits that exactly recover the original mesh:\u003ca id=\"prog_Filterprog\"\u003e\u003c/a\u003e\n```shell\nFilterprog -fbase club.base.m -fprog club.rprog -pm_encode \u003eclub.pm\n```\n\nThe complete process from the original mesh to the progressive mesh is implemented by the script call\n```shell\ndemos/bin/meshtopm.{sh,bat} demos/data/club.orig.m \u003eclub.pm\n```\n\nGiven a progressive mesh, we can interactively traverse its continuous levels of detail:\n```shell\nG3dOGL -pm_mode club.pm -st demos/data/club.s3d -lightambient .4\n```\n- by dragging the left vertical slider using the left or right mouse button, and\n- toggling mesh edges using the \u003ckbd\u003eDe\u003c/kbd\u003e key sequence.\n \nWe can also define geomorphs between discrete levels of detail, e.g.\n```shell\nFilterPM club.pm -nfaces 2000 -geom_nfaces 3300 -geom_nfaces 5000 -geom_nfaces 8000 | \\\n  G3dOGL -st demos/data/club.s3d -key SPDeN -lightambient .5 -thickboundary 1 -video 101 - | \\\n  VideoViewer - -key m\n```\n- creates a geomorph between 2000 and 3300 faces, another between 3300 and 5000 faces, and one more,\n- shows these in a viewer with the level-of-detail slider enabled (\u003ckbd\u003eS\u003c/kbd\u003e),\n- selects all three geomorph meshes (\u003ckbd\u003eP\u003c/kbd\u003e), enables mesh edges (\u003ckbd\u003eDe\u003c/kbd\u003e),\n  selects the first mesh (\u003ckbd\u003eN\u003c/kbd\u003e),\n- records a video of 101 frames while moving the LOD slider, and\n- shows the resulting video with mirror looping enabled (\u003ckbd\u003em\u003c/kbd\u003e).\n\nThis example displays a progressive mesh after truncating all detail below 300 faces and above 10000 faces:\n```shell\nFilterPM demos/data/standingblob.pm -nf 300 -truncate_prior -nf 10000 -truncate_beyond | \\\n  G3dOGL -pm_mode - -st demos/data/standingblob.s3d\n```\n\nAs an example of simplifying meshes with appearance attributes,\n\u003c!-- MeshSimplify - -nfaces 4000 -minqem -norfac 0. -colfac 1. -neptfac 1e5 -simplify | \\ --\u003e\n```shell\nFilterimage demos/data/gaudipark.png -scaletox 200 -tomesh | \\\n  MeshSimplify - -nfaces 4000 -simplify | \\\n  G3dOGL -st demos/data/imageup.s3d -key De -lightambient 1 -lightsource 0\n```\n- forms a planar grid mesh whose 200\u0026times;200 vertices have colors sampled from a downsampled image,\n- simplifies the mesh to 4000 faces while minimizing color differences,\n  \u003c!-- - ignoring surface normals and giving high weight to boundary accuracy, and--\u003e\n- shows the result with mesh edges (\u003ckbd\u003eDe\u003c/kbd\u003e) and only ambient lighting.\n\n\n## Selective view-dependent mesh refinement\n\nWithin `demos/create_sr_office`, the script call\n```shell\nmeshtopm.{sh,bat} demos/data/office.nf80000.orig.m -vsgeom \u003eoffice.sr.pm\n```\ncreates a progressive mesh in which the simplified vertices are constrained to lie\nat their original positions (`-vsgeom`).\nThis enables selective refinement, demonstrated by\n```shell\nG3dOGL -eyeob demos/data/unit_frustum.a3d -sr_mode office.sr.pm -st demos/data/office_srfig.s3d \\\n  -key ,DnDeDoDb -lightambient .4 -sr_screen_thresh .002 -frustum_frac 2\n```\n\nThe mesh is adaptively refined within the view frustum, shown as the inset rectangle (key \u003ckbd\u003eDo\u003c/kbd\u003e)\nor in the top view (key \u003ckbd\u003eDr\u003c/kbd\u003e).  Drag the mouse buttons to rotate, pan, and dolly the object.\n\n\n## Terrain level-of-detail control\n\nWithin `demos/create_sr_terrain.{sh,bat}`,\n```shell\nFilterimage demos/data/gcanyon_elev_crop.bw.png -tobw -elevation -step 6 -scalez 0.000194522 \\\n    -removekinks -tomesh | \\\n  Filtermesh -assign_normals \u003egcanyon_sq200.orig.m\ndemos/bin/meshtopm.{sh,bat} gcanyon_sq200.orig.m -vsgeom -terrain \u003egcanyon_sq200.pm\n```\n- converts an elevation image to a smoothed terrain grid mesh, and\n- simplifies it to create a selectively refinable mesh.\n\nThen, within `demos/view_sr_terrain.sh`,\n```shell\n(common=\"-eyeob demos/data/unit_frustum.a3d -sr_mode gcanyon_sq200.pm -st demos/data/gcanyon_fly_v98.s3d \\\n   -texturemap demos/data/gcanyon_color.1024.png -key DeDtDG -sr_screen_thresh .02292 -sr_gtime 64 \\\n   -lightambient .5\"; \\\n export G3D_REV_AUTO=1; \\\n G3dOGL $common -geom 800x820+100+10 -key \"\u0026O\" -key ,o----J | \\\n   G3dOGL $common -geom 800x820+920+10 -async -killeof -input -key Dg)\n```\n\n- opens two synchronized side-by-side windows of the same texture mapped terrain,\n- in which the first windows shows the temporal pops resulting from instantaneous mesh operations,\n- whereas the second window shows the smooth appearance provided by runtime geomorphs (\u003ckbd\u003eDg\u003c/kbd\u003e).\n\nFor large terrain meshes, we form a hierarchical progressive mesh by partitioning the terrain mesh into tiles,\nsimplifying each tile independently to form a progressive mesh,\nstitching the progressive meshes together 2-by-2,\nand recursively simplifying and merging at coarser pyramid levels.\n\nAn example is presented in `demos/create_terrain_hierarchy`.  It makes use of \u003ca id=\"prog_StitchPM\"\u003e\u003c/a\u003e\n```shell\nStitchPM -rootname terrain.level0 -blockx 2 -blocky 2 -blocks 32 -stitch \u003eterrain.level0.stitched.pm\n```\nto assemble each 2-by-2 set of progressive mesh tiles `terrain.level0.x{0,1}.y{0,1}.pm` at the finest level.\n\nThe script `demos/view_gcanyon_interactive` launches an interactive flythrough over a Grand Canyon terrain model,\nusing a progressive mesh precomputed from an original 4096\u0026times;2048 height field.\n\nAlternatively, `demos/view_gcanyon_frames` shows a real-time flythrough using a pre-recorded flight path,\nwhereby keystroke commands embedded within the input stream automatically change viewing modes.\n\n\n## Topology simplification\n\nThe program **`MinCycles`** removes topological noise from a mesh\nby iteratively pinching off the smallest nonseparating cycle of edges until a\nspecified criterion (cycle length, number of cycle edges, number of cycles, or mesh genus) is reached.\n\nFor example, within `demos/create_topologically_simplified.{sh,bat}`, \u003ca id=\"prog_MinCycles\"\u003e\u003c/a\u003e\n```shell\nFilterPM demos/data/office.pm -nf 200000 -outmesh | \\\n  MinCycles - -frac_cycle_length 1.2 -max_cycle_length 0.10 | \\\n  G3dOGL -st demos/data/office.s3d -key DeDEJ---- -thickboundary 0 -lightambient .9\n```\n- extracts a mesh of 200000 faces from a progressive mesh,\n- closes 46 topological handles to reduce the mesh genus from 50 to 4,\n- where the final remaining handle would require a nonseparating cycle of length greater than `0.10`.\n- speeding up the process by identifying approximately shortest nonseparating cycles\n  within a factor 1.2 of optimal, and\n- shows the resulting closed edge cycles (tagged as sharp) in blue.\n\n\n## \u003ca id=\"prog_MeshReorder\"\u003e\u003c/a\u003eOptimized mesh traversal\n\nThe program **`MeshReorder`** reorders the triangle faces (and optionally vertices) within a mesh\nto exploit GPU vertex caching and thereby minimize memory bandwidth and shading cost.\n\nFor example, within `demos/create_vertexcache_bunny`,\n```shell\nMeshReorder data/bunny.orig.m -fifo -cache_size 16 -analyze -meshify5 -color_corners 1 -analyze \\\n    \u003edata/bunny.vertexcache.m\n```\n- simulates traversal using a FIFO cache of 16 vertices and reports cache miss rates,\n- optimizes the triangle face ordering,\n- reports the updated cache miss rate, and\n- writes the mesh with corner colors that identify cache misses.\n\nThen, within `demos/view_vertexcache_bunny`,\n```shell\nG3dOGL data/bunny.vertexcache.m -st data/bunny.s3d -key DmDTDTDC\n```\nvisualizes the resulting sequence of triangle strips and cache misses.\n\n\n## \u003ca id=\"prog_SphereParam\"\u003e\u003c/a\u003eSpherical parameterization\n\nThe program **`SphereParam`** computes spherical coordinates `sph` at the mesh vertices\nso as to minimize parametric stretch from the sphere to the surface mesh.\n\nFor example, within `demos/create_spherical_param_bunny`,\n```shell\nmeshtopm.{sh,bat} data/bunny.orig.m -minqem -vsgeom -dihallow | \\\n  SphereParam - -rot data/bunny.s3d \u003edata/bunny.sphparam.m\n```\n- creates a progressive mesh (`*.pm`) stream minimizing a quadric error metric (`qem`),\n- runs a coarse-to-fine spherical parameterization optimization,\n- aligning the spherical coordinates to the model's default view (`bunny.s3d`), and\n- writes the spherically parameterized mesh.\n\nThen, within `demos/view_spherical_param_bunny`,\n```shell\nFiltermesh data/bunny.sphparam.m -renamekey v sph P | \\\n  G3dOGL - -st data/unitsphere_ang.s3d -key DeoJ\n```\n- transfers each vertex's spherical coordinates `sph` to its position `P`,\n- visualizes the resulting triangulated sphere domain,\n- showing mesh edges (`De`) and rotating slowly (`J`) about the object axis (`o`).\n\n\n## \u003ca id=\"prog_SphereSample\"\u003e\u003c/a\u003eSpherical resampling\n\nThe program **`SphereSample`** computes uniform samplings of a spherically parameterized mesh.\n\nFor example, within `demos/create_create_spherical_param_bunny`,\n```shell\nSphereSample -egrid 128 -domain octaflat -scheme best -param data/bunny.sphparam.m \\\n    -rot data/bunny.s3d -keys imageuv -remesh | \\\n  Filtermesh -renamekey v imageuv uv \u003edata/bunny.spheresample.remesh.m\n```\n- defines an effective 128\u0026times;128 regular grid\n- using a flat-octahedron domain mapped on the sphere,\n- maps these samples onto the bunny mesh using its spherical parameterization,\n- generates a remesh where vertices include image-space coordinates (`imageuv`),\n- renames those coordinates to `uv` coordinates, and\n- writes the final remesh.\n\nAlso,\n```shell\nSphereSample -egrid 1024 -omit_faces -domain octaflat -scheme best -param data/bunny.sphparam.m \\\n    -rot data/identity.s3d -signal N -write_texture \\\n    data/bunny.spheresample.octaflat.unrotated.normalmap.png\n```\n- defines an effective 1024\u0026times;1024 regular grid\n- using a flat-octahedron domain mapped on the sphere,\n- maps these samples onto the bunny mesh using its spherical parameterization,\n- samples the surface normal (`N`) field, and\n- writes these sampled normal vectors as RGB colors in a normap-map `png` image.\n\nThen, within `demos/view_vertexcache_bunny`,\n```shell\nG3dOGL data/bunny.spheresample.remesh.m -st data/bunny.s3d \\\n    -texturemap data/bunny.spheresample.octaflat.unrotated.normalmap.png \\\n    -texturenormal 1 -key DmDe -hwkey '(DtDe)' -hwdelay 1.0\n```\n- renders the remesh using flat shading (`Dm`) and mesh edges (`De`), and\n- after 1 second, enables normal-mapping using the normals stored in the `png` image.\n\n\n## \u003ca id=\"prog_G3dOGL\"\u003e\u003c/a\u003eGeometry viewer\n\nThe **`G3dOGL`** program shows interactive rasterized renderings of 3D (and 2D) geometry,\nrepresented as\n\n- streams of polygons/polylines/points (`*.a3d` format),\n- triangle meshes including geomorphs (`*.m`),\n- progressive meshes (`*.pm`),\n- encoded selectively refinable meshes (`*.srm`),\n- progressive simplicial complexes (`*.psc`), or\n- simple `*.ply` files.\n\nPlease see the many examples presented earlier.\nThe viewer can also read `*.frame` elements to position the viewer and the objects in world space.\nElements of `*.a3d`, `*.m`, and `*.frame` streams can all be interleaved in a single input stream.\n\nThe viewer can take image snapshots (see `demos/create_rendered_mechpart_image`) and\nrecord videos (see `demos/create_rendered_mechpart_video`).\n\nThe mouse/keyboard UI controls include:\n\u003cpre\u003e\n Mouse movements:\n left mouse:          rotate\n middle mouse:        pan\n right mouse:         dolly\n shift-left:          pan\n shift-middle mouse:  roll\n shift-right mouse:   zoom\n (mouse movements are with respect to current object; see '0-9' below)\n\n Important key strokes:\n ? : print complete list of keys\n D?: print list of keys prefixed by 'D'\n De: toggle edges\n Ds: toggle shading of faces\n Db: toggle backface culling\n Dm: toggle Gouraud/flat shading\n DP: save current window as an image file\n DS: toggle show some sliders\n S : toggle show some other sliders\n j : jump to a default viewpoint\n J : automatically rotate object\n D/: edit viewpoint filename\n , : read the viewpoint\n . : save the viewpoint\n 0-9: select object (0=eye_frame, 1=first object, 2=second object...)\n u : display/hide current object\n N : select next object\n P : select previous object\n -=: decrease/increase the magnitude of all movements\n f : toggle flying (usually with '0' eye selected)\n\u003c/pre\u003e\n\nTo record a 6-second (360-frame) video of a rotating mesh and then view the resulting video:\n\n```shell\nG3dOGL demos/data/standingblob.orig.m -st demos/data/standingblob.s3d -key iioJ \\\n  -video 360 output_video.mp4\nVideoViewer output_video.mp4\n```\n\nThe related program **`G3dVec`** shows wireframe hidden-line-removed renderings of `*.a3d` streams and `*.m` meshes.\nIt can write vector-based Postscript figures (see `demos/view_hidden_line_removed`).\n\nIn both programs, the keys \u003ckbd\u003e?\u003c/kbd\u003e and \u003ckbd\u003eD?\u003c/kbd\u003e show a list of available keyboard commands.\n\n## \u003ca id=\"prog_VideoViewer\"\u003e\u003c/a\u003eImage/video viewer\n\nThe **`VideoViewer`** program enables interactive viewing and simple editing of both images and videos.\nAgain, the key \u003ckbd\u003e?\u003c/kbd\u003e shows a list of available keyboard commands.\nPress \u003ckbd\u003epageup\u003c/kbd\u003e/\u003ckbd\u003epagedown\u003c/kbd\u003e to quickly browse through the videos and/or images in a directory.\nAudio is not currently supported.\n\n\n## File formats\n\n### Mesh (`*.m`)\n\nSee the documentation at the end of `libHh/GMesh.h`\n\nA mesh is a set of vertices and faces.  These in turn also define edges and corners.\nArbitrary string tuples can be associated with vertices, faces, edges, and corners.\nExamples of string tuples:\n`{normal=(.1 .2 .3) rgb=(1 1 1) matid=5 material=\"string\"}`.\nSee the several `demos/data/*.m` files for examples of the mesh format.\nNote that the indices of vertices and faces start at 1 instead of 0;\nin hindsight that was a poor choice.\n\n### Geometry stream (`*.a3d`, `*.pts`)\n\nSee the documentation at the end of `libHh/A3dStream.h`\n\nThe stream contains polygons, polylines, points, and control codes\n(like end-of-frame, end-of-input, change-of-object).\nUnlike in a mesh, these primitives do not share vertices.  The stream can be either text or binary.\n\n### Frame stream (`*.frame`, `*.s3d`)\n\nSee the documentation at the end of `libHh/FrameIO.h`\n\nThis text or binary format encodes a 4\u0026times;3 affine transformation\n(plus an object id and a scalar field-of-view zoom).\nIt is used to record default viewing configurations, and sequences of frames for flythroughs.\nIt usually represents the linear transform from object space (or eye space) to world space.\nThe stream can be either text or binary.\n\n### Progressive mesh (`*.pm`)\n\nThis is a binary representation that consists of a coarse base mesh and a sequence of vertex split records.\n\n### Edge collapse / vertex split records (`*.prog`, `*.rprog`)\n\nThese are temporary text files containing verbose information for a sequence of edge collapse / vertex split records\nused by MeshSimplify / reverselines / Filterprog to create a progressive mesh.\n\n\n## Libraries\n\nThe library \u003ca href=\"https://github.com/hhoppe/Mesh-processing-library/tree/main/libHh\"\u003e`libHh`\u003c/a\u003e\ncontains the main reusable classes.\nAll files include `Hh.h` which sets up a common cross-platform environment.\n\nThe libraries \u003ca href=\"https://github.com/hhoppe/Mesh-processing-library/tree/main/libHwWindows\"\u003e`libHwWindows`\u003c/a\u003e\nand \u003ca href=\"https://github.com/hhoppe/Mesh-processing-library/tree/main/libHwX\"\u003e`libHwX`\u003c/a\u003e\ndefine different implementations of a simple windowing interface (class `Hw`),\nunder `Win32` and `X Windows`, respectively.\nBoth implementations support `OpenGL` rendering.\n\n\n## Code details\n\nThe include file \u003ccode\u003elibHh/\u003cb\u003eRangeOp\u003c/b\u003e.h\u003c/code\u003e defines many functions that act on \u003cem\u003eranges\u003c/em\u003e,\nwhich are containers or views for which `begin()` and `end()` are defined.\nFor example, the function call `hh::fill(ar, 1.f)` assigns the value `1.f` to all\nelements in the array named `ar`,\nand the function call `hh::mean(matrix)` computes the average value of all entries in the\nnamed `matrix`.\n\nThe debugging macro \u003ccode\u003e\u003cb\u003eSHOW\u003c/b\u003e(expr)\u003c/code\u003e outputs `expr = ...` on `stderr`\nand also returns `expr`.\nIt also accepts multiple arguments in which case it returns `void`.\nFor example, `SHOW(min(1, 2), \"hello\", 3*2)` outputs the line `min(1, 2)=1 hello 3*2=6`.\nNote the special treatment of literal string values.\n\nUnicode strings are stored using \u003cb\u003eUTF-8\u003c/b\u003e encoding into ordinary `std::string` variables.\nThe functions `hh::utf16_from_utf8()` and `hh::utf8_from_utf16()` convert to and from the\n`std::wstring` UTF-16 encodings used in `Win32` system calls.\n\nAll files use end-of-line encodings based on Unix `'\\n'` LF (rather than DOS `'\\r\\n'` CR+LF).\nAll streams are opened in binary mode.  This allows text and binary to coexist in the same file.\n\n\n## License\n\nSee \u003ca href=\"https://github.com/hhoppe/Mesh-processing-library/tree/main/LICENSE\"\u003e`LICENSE`\u003c/a\u003e.\nThis project has adopted the \u003ca href=\"https://opensource.microsoft.com/codeofconduct/\"\u003eMicrosoft Open Source Code of Conduct\u003c/a\u003e.  For more information see the \u003ca href=\"https://opensource.microsoft.com/codeofconduct/faq/\"\u003eCode of Conduct FAQ\u003c/a\u003e or contact \u003ca href=\"mailto:opencode@microsoft.com\"\u003eopencode@microsoft.com\u003c/a\u003e with any additional questions or comments.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhhoppe%2FMesh-processing-library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhhoppe%2FMesh-processing-library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhhoppe%2FMesh-processing-library/lists"}