├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .gitmodules ├── Documentation.txt ├── Makefile ├── Makefile_excludes ├── README.md ├── RetopoFlow.LICENSE ├── __init__.py ├── addon_common ├── .gitignore ├── CookieCutter.LICENSE ├── README.md ├── common │ ├── __init__.py │ ├── bezier.py │ ├── blender.py │ ├── blender_cursors.py │ ├── blender_preferences.py │ ├── bmesh_render.py │ ├── boundvar.py │ ├── colors.py │ ├── config │ │ └── ui_defaultstyles.css │ ├── debug.py │ ├── decorators.py │ ├── drawing.py │ ├── eventhandler.py │ ├── fontmanager.py │ ├── fonts │ │ ├── DejaVuSansMono.LICENSE │ │ ├── DejaVuSansMono.ttf │ │ ├── DroidSans-Blender.ttf │ │ ├── DroidSans.LICENSE │ │ ├── DroidSerif-Bold.ttf │ │ ├── DroidSerif-BoldItalic.ttf │ │ ├── DroidSerif-Italic.ttf │ │ ├── DroidSerif-Regular.ttf │ │ ├── DroidSerif.LICENSE │ │ ├── OpenSans-Bold.ttf │ │ ├── OpenSans-BoldItalic.ttf │ │ ├── OpenSans-Italic.ttf │ │ └── OpenSans.LICENSE │ ├── fsm.py │ ├── functools.py │ ├── globals.py │ ├── gpustate.py │ ├── hasher.py │ ├── html_to_unicode.py │ ├── human_readable.py │ ├── image_preloader.py │ ├── images │ │ ├── checkmark.png │ │ ├── close.png │ │ ├── collapse_close.png │ │ ├── collapse_open.png │ │ └── radio.png │ ├── inspect.py │ ├── irc.py │ ├── logger.py │ ├── markdown.py │ ├── maths.py │ ├── maths_accel.py │ ├── metaclasses.py │ ├── parse.py │ ├── profiler.py │ ├── shaders │ │ ├── arrow.glsl │ │ ├── bmesh_render_edges.glsl │ │ ├── bmesh_render_faces.glsl │ │ ├── bmesh_render_prefix.glsl │ │ ├── bmesh_render_verts.glsl │ │ ├── circle_2D.glsl │ │ ├── circle_3D.glsl │ │ ├── lineseg_2D.glsl │ │ ├── point_2D.glsl │ │ ├── triangle_2D.glsl │ │ ├── triangle_3D.glsl │ │ └── ui_element.glsl │ ├── text.py │ ├── timerhandler.py │ ├── ui_core.py │ ├── ui_core_content.py │ ├── ui_core_debug.py │ ├── ui_core_defaults.py │ ├── ui_core_dirtiness.py │ ├── ui_core_draw.py │ ├── ui_core_elements.py │ ├── ui_core_events.py │ ├── ui_core_fonts.py │ ├── ui_core_images.py │ ├── ui_core_layout.py │ ├── ui_core_markdown.py │ ├── ui_core_preventmulticalls.py │ ├── ui_core_properties.py │ ├── ui_core_style.py │ ├── ui_core_utilities.py │ ├── ui_document.py │ ├── ui_draw.py │ ├── ui_event.py │ ├── ui_linefitter.py │ ├── ui_settings.py │ ├── ui_styling.py │ ├── undostack.py │ ├── updater_core.py │ ├── updater_ops.py │ ├── updater_tmp │ │ └── .gitignore │ ├── useractions.py │ └── utils.py ├── cookiecutter │ ├── __init__.py │ ├── cookiecutter.py │ ├── cookiecutter_actions.py │ ├── cookiecutter_blender.py │ ├── cookiecutter_debug.py │ ├── cookiecutter_exceptions.py │ ├── cookiecutter_fsm.py │ ├── cookiecutter_modal.py │ └── cookiecutter_ui.py ├── ext │ ├── apng.py │ ├── png.py │ └── termcolor.py ├── hive │ ├── __init__.py │ └── hive.py ├── scripts │ ├── speedtest.py │ ├── strip_debugging.py │ └── update_copyright_date.py └── terminal │ ├── __init__.py │ ├── deepdebug.py │ └── term_printer.py ├── blender_manifest.toml ├── config ├── background.jpg ├── keymaps.py ├── options.py ├── retopoflow.html └── ui.css ├── devnotes ├── blender280notes.md ├── blenderbugs.md ├── demonotes.md ├── todo.md └── versionbump.md ├── docs ├── CNAME ├── Gemfile ├── Gemfile.lock ├── _config.yml ├── _data │ ├── keymaps.yml │ └── options.yml ├── _layouts │ └── default.html ├── addon_updater.md ├── assets │ └── css │ │ ├── main.css │ │ └── style-old.scss ├── changelist.md ├── contours.md ├── debugging.md ├── faq.md ├── general.md ├── images │ ├── addon_updater_advanced.png │ ├── addon_updater_button.png │ ├── addon_updater_system.png │ ├── blendermarket.png │ ├── blendermarket_screenshot.png │ ├── contours-icon.png │ ├── debugging_enable.png │ ├── debugging_open.png │ ├── delete_dialog_pie.png │ ├── global_exception.png │ ├── help_contours.png │ ├── help_knife.png │ ├── help_loops.png │ ├── help_patches.png │ ├── help_polypen.png │ ├── help_polypen_modes_options_pie.png │ ├── help_polystrips.png │ ├── help_relax.png │ ├── help_select.png │ ├── help_strokes.png │ ├── help_strokes_modes_options_pie.png │ ├── help_themes.png │ ├── help_tweak.png │ ├── install.png │ ├── keymap_all.png │ ├── keymap_button.png │ ├── keymap_insert.png │ ├── knife-icon.png │ ├── loops-icon.png │ ├── orange-turbine.png │ ├── patches-icon.png │ ├── pie_menu.png │ ├── polypen-icon.png │ ├── polystrips-icon.png │ ├── relax-icon.png │ ├── retopoflow_3_feature.png │ ├── select-icon.png │ ├── selection_options.png │ ├── start_rf_create_new_target.png │ ├── start_rf_quickstart.png │ ├── start_rf_tool.png │ ├── strokes-icon.png │ ├── tweak-icon.png │ ├── warning_viewlock.png │ └── warnings.png ├── index.md ├── issue_template.md ├── issue_template_simple.md ├── keymap_editor.md ├── knife.md ├── loops.md ├── patches.md ├── polypen.md ├── polystrips.md ├── quick_start.md ├── relax.md ├── select.md ├── strokes.md ├── table_of_contents.md ├── tweak.md ├── warnings.md └── welcome.md ├── docs_config ├── CNAME ├── Gemfile ├── Gemfile.lock ├── _config.yml ├── default.html └── main.css ├── help ├── addon_updater.md ├── changelist.md ├── contours.md ├── debugging.md ├── faq.md ├── general.md ├── images │ ├── addon_updater_advanced.png │ ├── addon_updater_advanced.thumb.png │ ├── addon_updater_button.png │ ├── addon_updater_button.thumb.png │ ├── addon_updater_system.png │ ├── addon_updater_system.thumb.png │ ├── blendermarket.png │ ├── blendermarket.thumb.png │ ├── blendermarket_screenshot.png │ ├── blendermarket_screenshot.thumb.png │ ├── contours-icon.png │ ├── contours-icon.thumb.png │ ├── debugging_enable.png │ ├── debugging_enable.thumb.png │ ├── debugging_open.png │ ├── debugging_open.thumb.png │ ├── delete_dialog_pie.png │ ├── delete_dialog_pie.thumb.png │ ├── global_exception.png │ ├── global_exception.thumb.png │ ├── help_contours.png │ ├── help_contours.thumb.png │ ├── help_knife.png │ ├── help_knife.thumb.png │ ├── help_loops.png │ ├── help_loops.thumb.png │ ├── help_patches.png │ ├── help_patches.thumb.png │ ├── help_polypen.png │ ├── help_polypen.thumb.png │ ├── help_polypen_modes_options_pie.png │ ├── help_polypen_modes_options_pie.thumb.png │ ├── help_polystrips.png │ ├── help_polystrips.thumb.png │ ├── help_relax.png │ ├── help_relax.thumb.png │ ├── help_select.png │ ├── help_select.thumb.png │ ├── help_strokes.png │ ├── help_strokes.thumb.png │ ├── help_strokes_modes_options_pie.png │ ├── help_strokes_modes_options_pie.thumb.png │ ├── help_themes.png │ ├── help_themes.thumb.png │ ├── help_tweak.png │ ├── help_tweak.thumb.png │ ├── install.png │ ├── install.thumb.png │ ├── keymap_all.png │ ├── keymap_all.thumb.png │ ├── keymap_button.png │ ├── keymap_button.thumb.png │ ├── keymap_insert.png │ ├── keymap_insert.thumb.png │ ├── knife-icon.png │ ├── knife-icon.thumb.png │ ├── loops-icon.png │ ├── loops-icon.thumb.png │ ├── orange-turbine.png │ ├── orange-turbine.thumb.png │ ├── patches-icon.png │ ├── patches-icon.thumb.png │ ├── pie_menu.png │ ├── pie_menu.thumb.png │ ├── polypen-icon.png │ ├── polypen-icon.thumb.png │ ├── polystrips-icon.png │ ├── polystrips-icon.thumb.png │ ├── relax-icon.png │ ├── relax-icon.thumb.png │ ├── retopoflow_3_feature.png │ ├── retopoflow_3_feature.thumb.png │ ├── select-icon.png │ ├── select-icon.thumb.png │ ├── selection_options.png │ ├── selection_options.thumb.png │ ├── start_rf_create_new_target.png │ ├── start_rf_create_new_target.thumb.png │ ├── start_rf_quickstart.png │ ├── start_rf_quickstart.thumb.png │ ├── start_rf_tool.png │ ├── start_rf_tool.thumb.png │ ├── strokes-icon.png │ ├── strokes-icon.thumb.png │ ├── tweak-icon.png │ ├── tweak-icon.thumb.png │ ├── warning_viewlock.png │ ├── warning_viewlock.thumb.png │ ├── warnings.png │ └── warnings.thumb.png ├── index.md ├── issue_template.md ├── issue_template_simple.md ├── keymap_editor.md ├── knife.md ├── loops.md ├── patches.md ├── polypen.md ├── polystrips.md ├── quick_start.md ├── relax.md ├── select.md ├── strokes.md ├── table_of_contents.md ├── tweak.md ├── warnings.md └── welcome.md ├── hive.json ├── icons ├── blendermarket.png ├── contours-icon.png ├── knife-icon.png ├── loops-icon.png ├── orange-turbine.png ├── patches-icon.png ├── polypen-icon.png ├── polystrips-icon.png ├── relax-icon.png ├── select-icon.png ├── strokes-icon.png └── tweak-icon.png ├── matcaps ├── license.txt ├── retopoflow_dark.exr └── retopoflow_light.exr ├── retopoflow ├── __init__.py ├── blenderregister.py ├── helpsystem.py ├── html │ ├── alert_dialog.html │ ├── delete_dialog.html │ ├── geometry.html │ ├── help_dialog.html │ ├── keymaps_dialog.html │ ├── loading_dialog.html │ ├── main_full.html │ ├── main_tiny.html │ ├── options_dialog.html │ ├── pie_menu.html │ ├── quit_dialog.html │ └── updater_dialog.html ├── keymapsystem.py ├── retopoflow.py ├── rf │ ├── __init__.py │ ├── rf_blender_objects.py │ ├── rf_blender_save.py │ ├── rf_drawing.py │ ├── rf_fsm.py │ ├── rf_grease.py │ ├── rf_helpsystem.py │ ├── rf_instrument.py │ ├── rf_keymapsystem.py │ ├── rf_normalize.py │ ├── rf_piemenu.py │ ├── rf_sources.py │ ├── rf_spaces.py │ ├── rf_target.py │ ├── rf_tools.py │ ├── rf_ui.py │ ├── rf_ui_alert.py │ ├── rf_undo.py │ └── rf_updatersystem.py ├── rfmesh │ ├── rfmesh.py │ ├── rfmesh_render.py │ └── rfmesh_wrapper.py ├── rftool.py ├── rftool_contours │ ├── __init__.py │ ├── contours.py │ ├── contours_ops.py │ ├── contours_options.html │ ├── contours_props.py │ └── contours_utils.py ├── rftool_knife │ ├── knife.py │ ├── knife_insert.py │ └── knife_options.html ├── rftool_loops │ ├── loops.py │ └── loops_insert.py ├── rftool_patches │ ├── patches.py │ └── patches_options.html ├── rftool_polypen │ ├── polypen.py │ ├── polypen_insert.py │ └── polypen_options.html ├── rftool_polystrips │ ├── polystrips.py │ ├── polystrips_ops.py │ ├── polystrips_options.html │ ├── polystrips_props.py │ └── polystrips_utils.py ├── rftool_relax │ ├── relax.py │ └── relax_options.html ├── rftool_select │ ├── select.py │ └── select_options.html ├── rftool_strokes │ ├── strokes.py │ ├── strokes_insert.py │ ├── strokes_options.html │ └── strokes_utils.py ├── rftool_tweak │ ├── tweak.py │ └── tweak_options.html ├── rfwidget.py ├── rfwidgets │ ├── __init__.py │ ├── rfwidget_brushfalloff.py │ ├── rfwidget_brushstroke.py │ ├── rfwidget_default.py │ ├── rfwidget_hidden.py │ ├── rfwidget_linecut.py │ └── rfwidget_selectbox.py ├── updater.py └── updatersystem.py └── scripts ├── __init__.py ├── convert_docs_for_web.py ├── create_thumbnails.py ├── detect_filename_case_conflicts.py ├── download_b280.py ├── download_b281.py ├── download_b282.py ├── get_hive_value.py ├── memlimited.sh ├── modal_event_reporting.blend └── prep_help_for_online.py /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **PLEASE READ THE FOLLOWING AND USE THE TEMPLATE TO POST YOUR ISSUE** 2 | 3 | *Questions not directly related to the RetopoFlow project are considered general and should be posted elsewhere (e.g. git, blender, python, etc).* 4 | 5 | **Before raising the issue, please check the following first:** 6 | 7 | - [ ] Read through the README.md file in the branch used to assure the process taken is correct 8 | - [ ] Check the existing [issues](https://github.com/CGCookie/retopoflow/issues) and [pull requests](https://github.com/CGCookie/retopoflow/pulls) to make sure the issue has not already been reported and/or fixed. 9 | - [ ] You can replicate the bug and will provide as much info as possible with blend files, screenshots, logfiles, as well as show the expected result and actual result. 10 | 11 |   12 | 13 | Issue Template 14 | ----------------------------------- 15 | 16 | --- 17 | Please prefix your issue name with one of the following: **[BUG]** **[PROPOSAL]** **[QUESTION]** 18 | 19 | Retopoflow Version: {*add here*} 20 | 21 | Blender Version/Hash: {*add here*} 22 | 23 | Platform Version/Distribution: {*add here*} 24 | 25 |   26 | 27 | **Issue:** 28 | 29 | {*enter your issue here*} 30 | 31 | {*add any screenshots of the issue here*} 32 | 33 | 34 | 35 |   36 | 37 | **How to Reproduce:** 38 | 39 | - {*add your list replication steps*} 40 | 41 | {*attach any files needed to replicate the issue*} -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please prefix your pull request with one of the following: **[FEATURE]** **[FIX]** **[IMPROVEMENT]**. 2 | 3 | **In raising this pull request, I confirm the following (please check boxes):** 4 | 5 | - [x] I have read and understood the [contributors guide](). _not present at this time_ 6 | - [ ] I have checked that another pull request for this purpose does not exist. 7 | - [ ] I have considered, and confirmed that this submission will be valuable to others. 8 | - [ ] I accept that this submission may not be used, and the pull request closed at the will of the maintainer. 9 | - [ ] I give this submission freely, and claim no ownership to its content. 10 | 11 | **My familiarity with the project is as follows (check one):** 12 | 13 | - [ ] I have never used the project. 14 | - [ ] I have used the project briefly. 15 | - [ ] I have used the project extensively, but have not contributed previously. 16 | - [ ] I am an active contributor to the project. 17 | 18 | **If the project maintainer has any additional requirements, they will be listed here.** 19 | 20 | - No additional requirements. 21 | 22 | --- 23 | 24 | {pull request content here} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VSCode specific 2 | .vscode/ 3 | 4 | # Cython specific 5 | retopoflow/cy/*.html 6 | retopoflow/cy/*.cpp 7 | retopoflow/cy/*.c 8 | retopoflow/cy/_tests/ 9 | 10 | # do not include the CG Cookie built indicator file 11 | .cgcookie 12 | 13 | 14 | # Byte-compiled / optimized / DLL files 15 | __pycache__/ 16 | *.py[cod] 17 | 18 | # C extensions 19 | *.so 20 | 21 | # But include our specific Cython compiled files 22 | !retopoflow/cy/*.so 23 | !retopoflow/cy/*.pyd 24 | 25 | # Distribution / packaging 26 | .Python 27 | env/ 28 | build/ 29 | develop-eggs/ 30 | dist/ 31 | downloads/ 32 | eggs/ 33 | lib64/ 34 | parts/ 35 | sdist/ 36 | var/ 37 | *.egg-info/ 38 | .installed.cfg 39 | *.egg 40 | 41 | # PyInstaller 42 | # Usually these files are written by a python script from a template 43 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 44 | *.manifest 45 | *.spec 46 | 47 | # Installer logs 48 | pip-log.txt 49 | pip-delete-this-directory.txt 50 | 51 | # Unit test / coverage reports 52 | htmlcov/ 53 | .tox/ 54 | .coverage 55 | .cache 56 | nosetests.xml 57 | coverage.xml 58 | 59 | # Translations 60 | *.mo 61 | *.pot 62 | 63 | # Django stuff: 64 | *.log 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | docs/_site/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Mac OS X 74 | .DS_Store 75 | .project 76 | .pydevproject 77 | 78 | # thumbnail generator temp file 79 | _temporary.thumb.png 80 | 81 | # updater 82 | retopoflow_updater/updater_status.json 83 | retopoflow_updater_status.json 84 | updater_tmp/* 85 | 86 | # RF options files 87 | RetopoFlow_options 88 | RetopoFlow_options.json 89 | 90 | # RF Custom keymaps 91 | RetopoFlow_keymaps.json 92 | 93 | # RF backup file 94 | RetopoFlow_backup.blend 95 | 96 | # RF screenshot 97 | RetopoFlow_screenshot.png 98 | 99 | # Profiler output file 100 | profiler_data.txt 101 | RetopoFlow_profiler.txt 102 | 103 | # Debug output 104 | RetopoFlow_debug.txt 105 | RetopoFlow_debug.txt.bkp 106 | 107 | system-info.txt 108 | 109 | # Blender symlinks 110 | blender 111 | b280 112 | b281 113 | b281a 114 | b282 115 | b282a 116 | b283 117 | b290 118 | b291 119 | b292 120 | b293 121 | b293-lts 122 | b300 123 | 124 | # test models folder 125 | test-models 126 | 127 | # temp folders 128 | tmp/ 129 | test/ 130 | issues/ 131 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "addon_common"] 2 | path = addon_common 3 | url = git@github.com:CGCookie/addon_common.git 4 | -------------------------------------------------------------------------------- /Documentation.txt: -------------------------------------------------------------------------------- 1 | All of RetopoFlow's documentation can be seen in the RetopoFlow menu in Blender and at https://docs.retopoflow.com/ -------------------------------------------------------------------------------- /Makefile_excludes: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | 3 | /debug.txt 4 | 5 | test-models 6 | test_models 7 | /tools/ 8 | /retopoflow_updater/ 9 | /updater_tmp/ 10 | /icons/working/ 11 | tmp/ 12 | /scripts/ 13 | /test/ 14 | /test-models/* 15 | /help/web/ 16 | /help/web_config/ 17 | /devnotes/ 18 | /issues/ 19 | 20 | updater_tmp/*.json 21 | 22 | .DS_Store 23 | .*/ 24 | 25 | .gitignore 26 | 27 | *.orig 28 | *.sh 29 | *.xcf 30 | *.svg 31 | *.blend* 32 | 33 | RetopoFlow_options.* 34 | RetopoFlow_keymaps.* 35 | RetopoFlow_profiler.* 36 | RetopoFlow_screenshot.* 37 | RetopoFlow_debug.* 38 | 39 | retopoflow.sublime* 40 | 41 | Makefile 42 | Makefile_excludes 43 | 44 | system-info.txt 45 | 46 | blender 47 | b278c 48 | b279 49 | b279a 50 | b279b 51 | b280 52 | b281 53 | b281a 54 | b282 55 | b282a 56 | b283 57 | b290 58 | b291 59 | b292 60 | b293 61 | 62 | .git 63 | .gitmodules 64 | 65 | issues/ 66 | 67 | docs/ 68 | docs_config/ 69 | 70 | retopoflow3 71 | -------------------------------------------------------------------------------- /RetopoFlow.LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2023 Orange Turbine 2 | http://orangeturbine.com 3 | retopoflow@cgcookie.com 4 | 5 | Created by Dr. Jonathan Denning, Patrick Moore, Jonathan Williamson, and Jonathan Lampel 6 | 7 | All code included in this repository is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | All non-code assets, unless otherwise stated, are property of CG Cookie Inc and may not be distributed with the source code unless granted permission by Orange Turbine. 21 | -------------------------------------------------------------------------------- /addon_common/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | # addon updater temp folder 107 | common/updater_tmp/* 108 | !common/updater_tmp/.gitignore 109 | -------------------------------------------------------------------------------- /addon_common/README.md: -------------------------------------------------------------------------------- 1 | # addon_common 2 | 3 | This repo contains the CookieCutter Blender add-on framework. 4 | 5 | ## Example Add-on 6 | 7 | As an example add-on, see the [ExtruCut](https://github.com/CGCookie/ExtruCut) project. 8 | 9 | ## resources 10 | 11 | - Blender Conference 2018 workshop [slides](https://gfx.cse.taylor.edu/courses/bcon18/index.md.html?scale) and [presentation](https://www.youtube.com/watch?v=YSHdSNhMO1c) 12 | -------------------------------------------------------------------------------- /addon_common/common/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = [ 23 | 'bezier', 24 | 'blender', 25 | 'blender_preferences', 26 | 'bmesh_render', 27 | 'boundvar', 28 | 'colors', 29 | 'debug', 30 | 'decorators', 31 | 'drawing', 32 | 'fontmanager', 33 | 'fsm', 34 | 'globals', 35 | 'hasher', 36 | 'irc', 37 | 'logger', 38 | 'markdown', 39 | 'maths', 40 | 'metaclasses', 41 | 'parse', 42 | 'profiler', 43 | 'shaders', 44 | 'ui_core', 45 | 'ui_document', 46 | 'ui_styling', 47 | 'ui_core_utilities', 48 | 'updater_core', 49 | 'updater_ops', 50 | 'useractions', 51 | 'utils', 52 | ] 53 | 54 | 55 | import bpy 56 | if bpy.app.version >= (3, 2, 0): 57 | # import the following only to populate the globals 58 | from . import debug as _ 59 | from . import drawing as _ 60 | from . import logger as _ 61 | from . import profiler as _ 62 | from . import ui_core as _ 63 | -------------------------------------------------------------------------------- /addon_common/common/blender_preferences.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | import bpy 23 | 24 | 25 | def get_preferences(ctx=None): 26 | return (ctx if ctx else bpy.context).preferences 27 | 28 | 29 | def mouse_doubleclick(): 30 | # time/delay (in seconds) for a double click 31 | return bpy.context.preferences.inputs.mouse_double_click_time / 1000 32 | 33 | def mouse_drag(): 34 | # number of pixels to drag before tweak/drag event is triggered 35 | return bpy.context.preferences.inputs.drag_threshold_mouse 36 | 37 | def mouse_move(): 38 | # number of pixels to move before the cursor is considered to have moved 39 | # (used for cycling selected items on successive clicks) 40 | return bpy.context.preferences.inputs.move_threshold 41 | 42 | def mouse_select(): 43 | # returns 'LEFT' if LMB is used for selection or 'RIGHT' if RMB is used for selection 44 | 45 | user_keyconfigs = bpy.context.window_manager.keyconfigs.user 46 | map_select_type = {'LEFTMOUSE': 'LEFT', 'RIGHTMOUSE': 'RIGHT'} 47 | 48 | try: 49 | select_type = user_keyconfigs.keymaps['3D View'].keymap_items['view3d.select'].type 50 | return map_select_type[select_type] 51 | except Exception as e: 52 | if hasattr(mouse_select, 'reported'): return # already reported 53 | mouse_select.reported = True 54 | print('Addon Common: Exception caught in mouse_select') 55 | print('NOTE: only reporting this once') 56 | print(f'Exception: {e}') 57 | 58 | return 'LEFT' # fallback to 'LEFT' 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /addon_common/common/fonts/DejaVuSansMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/DejaVuSansMono.ttf -------------------------------------------------------------------------------- /addon_common/common/fonts/DroidSans-Blender.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/DroidSans-Blender.ttf -------------------------------------------------------------------------------- /addon_common/common/fonts/DroidSerif-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/DroidSerif-Bold.ttf -------------------------------------------------------------------------------- /addon_common/common/fonts/DroidSerif-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/DroidSerif-BoldItalic.ttf -------------------------------------------------------------------------------- /addon_common/common/fonts/DroidSerif-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/DroidSerif-Italic.ttf -------------------------------------------------------------------------------- /addon_common/common/fonts/DroidSerif-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/DroidSerif-Regular.ttf -------------------------------------------------------------------------------- /addon_common/common/fonts/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /addon_common/common/fonts/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /addon_common/common/fonts/OpenSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/fonts/OpenSans-Italic.ttf -------------------------------------------------------------------------------- /addon_common/common/functools.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | from inspect import isfunction, signature 23 | 24 | 25 | ################################################## 26 | 27 | 28 | # find functions of object that has key attribute 29 | # returns list of (attribute value, fn) 30 | def find_fns(obj, key, *, full_search=False): 31 | classes = type(obj).__mro__ if full_search else [type(obj)] 32 | members = [getattr(cls, k) for cls in classes for k in dir(cls) if hasattr(cls, k)] 33 | # test if type is fn_type rather than isfunction() because bpy has problems! 34 | # methods = [member for member in members if isfunction(member)] 35 | fn_type = type(find_fns) 36 | methods = [member for member in members if type(member) == fn_type] 37 | return [ 38 | (getattr(method, key), method) 39 | for method in methods 40 | if hasattr(method, key) 41 | ] 42 | 43 | def self_wrapper(self, fn): 44 | sig = signature(fn) 45 | params = list(sig.parameters.values()) 46 | if params[0].name != 'self': return fn 47 | def wrapped(*args, **kwargs): 48 | return fn(self, *args, **kwargs) 49 | return wrapped 50 | -------------------------------------------------------------------------------- /addon_common/common/globals.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | ''' 23 | This code helps prevent circular importing. 24 | Each of the main common objects are referenced here. 25 | ''' 26 | 27 | class GlobalsMeta(type): 28 | # allows for `Globals.drawing` instead of `Globals.get('drawing')` 29 | def __setattr__(self, name, value): 30 | self.set(value, objtype=name) 31 | def __getattr__(self, objtype): 32 | return self.get(objtype) 33 | 34 | class Globals(metaclass=GlobalsMeta): 35 | __vars = {} 36 | 37 | @staticmethod 38 | def set(obj, objtype=None): 39 | Globals.__vars[objtype or type(obj).__name__.lower()] = obj 40 | return obj 41 | 42 | @staticmethod 43 | def is_set(objtype): 44 | return Globals.__vars.get(objtype, None) is not None 45 | 46 | @staticmethod 47 | def get(objtype): 48 | return Globals.__vars.get(objtype, None) 49 | 50 | @staticmethod 51 | def __getattr__(objtype): 52 | return Globals.get(objtype) 53 | -------------------------------------------------------------------------------- /addon_common/common/html_to_unicode.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | 23 | no_arrows = { 24 | ' ': ' ', 25 | '`': '`', 26 | '<': '<', 27 | '>': '>', 28 | # '→': '→', 29 | } 30 | 31 | arrows = { # https://www.toptal.com/designers/htmlarrows/arrows/ 32 | '↑': '↑', 33 | '↓': '↓', 34 | '←': '←', 35 | '→': '→', 36 | '↔': '↔', 37 | '↕': '↕', 38 | '⇑': '⇑', 39 | '⇓': '⇓', 40 | '⇐': '⇐', 41 | '⇒': '⇒', 42 | '⇔': '⇔', 43 | '⇕': '⇕', 44 | } 45 | 46 | all_chars = no_arrows | arrows 47 | -------------------------------------------------------------------------------- /addon_common/common/images/checkmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/images/checkmark.png -------------------------------------------------------------------------------- /addon_common/common/images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/images/close.png -------------------------------------------------------------------------------- /addon_common/common/images/collapse_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/images/collapse_close.png -------------------------------------------------------------------------------- /addon_common/common/images/collapse_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/images/collapse_open.png -------------------------------------------------------------------------------- /addon_common/common/images/radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/addon_common/common/images/radio.png -------------------------------------------------------------------------------- /addon_common/common/logger.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2014 Plasmasolutions 3 | software@plasmasolutions.de 4 | 5 | Created by Thomas Beck 6 | Donated to CGCookie and the world 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | import bpy 23 | 24 | from .blender import show_blender_popup, show_blender_text 25 | 26 | from .globals import Globals 27 | 28 | class Logger: 29 | _log_filename = 'Logger' 30 | _divider = '\n\n%s\n' % ('='*80) 31 | 32 | @staticmethod 33 | def set_log_filename(path): 34 | Logger._log_filename = path 35 | 36 | @staticmethod 37 | def get_log_filename(): 38 | return Logger._log_filename 39 | 40 | @staticmethod 41 | def get_log(create=True): 42 | if Logger._log_filename not in bpy.data.texts: 43 | if not create: return None 44 | old = { t.name for t in bpy.data.texts } 45 | # create a log file for recording 46 | bpy.ops.text.new() 47 | for t in bpy.data.texts: 48 | if t.name in old: continue 49 | t.name = Logger._log_filename 50 | break 51 | else: 52 | assert False 53 | return bpy.data.texts[Logger._log_filename] 54 | 55 | @staticmethod 56 | def has_log(): 57 | return Logger.get_log(create=False) is not None 58 | 59 | @staticmethod 60 | def add(line): 61 | try: 62 | log = Logger.get_log() 63 | log.write('%s%s' % (Logger._divider, str(line))) 64 | except Exception as e: 65 | print(f'Logger: Caught exception while trying to write to log') 66 | print(f' {line=}"') 67 | print(f' {e}') 68 | 69 | @staticmethod 70 | def open_log(): 71 | if Logger.has_log(): 72 | show_blender_text(Logger._log_filename) 73 | else: 74 | show_blender_popup(f'Log file ({Logger._log_filename}) not found') 75 | 76 | logger = Logger() 77 | Globals.set(logger) 78 | 79 | -------------------------------------------------------------------------------- /addon_common/common/metaclasses.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 Taylor University, CG Cookie 3 | 4 | Created by Dr. Jon Denning and Spring 2015 COS 424 class 5 | 6 | Some code copied from CG Cookie Retopoflow project 7 | https://github.com/CGCookie/retopoflow 8 | 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | ''' 22 | 23 | 24 | from abc import ABCMeta, abstractmethod 25 | 26 | ''' 27 | RegisterRFClasses handles self registering classes to simplify creating new tools, cursors, etc. 28 | With self registration, the new entities only need to by imported in, and they automatically 29 | show up as an available entity. 30 | ''' 31 | 32 | 33 | class SingletonClass(type): 34 | ''' 35 | from https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python 36 | ''' # noqa 37 | 38 | _instances = {} 39 | 40 | def __call__(cls, *args, **kwargs): 41 | if cls not in cls._instances: 42 | supercls = super(SingletonClass, cls) 43 | cls._instances[cls] = supercls.__call__(*args, *kwargs) 44 | return cls._instances[cls] 45 | 46 | # def __getattr__(cls, name): 47 | # return cls._instances[cls].__getattr__(name) 48 | 49 | 50 | class RegisterClass(type): 51 | ''' 52 | # from http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Metaprogramming.html#example-self-registration-of-subclasses 53 | ''' # noqa 54 | 55 | def __init__(cls, name, bases, nmspc): 56 | super(RegisterClass, cls).__init__(name, bases, nmspc) 57 | if not hasattr(cls, 'registry'): 58 | cls.registry = set() 59 | cls.registry.add(cls) 60 | cls.registry -= set(bases) # Remove base classes 61 | 62 | # Metamethods, called on class objects: 63 | def __iter__(cls): 64 | return iter(cls.registry) 65 | 66 | def __str__(cls): 67 | if cls in cls.registry: 68 | return cls.__name__ 69 | return cls.__name__ + ": " + ", ".join([sc.__name__ for sc in cls]) 70 | 71 | def __len__(cls): 72 | return len(cls.registry) 73 | 74 | 75 | class SingletonRegisterClass(SingletonClass, RegisterClass): 76 | pass 77 | -------------------------------------------------------------------------------- /addon_common/common/shaders/triangle_2D.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | */ 21 | 22 | struct Options { 23 | mat4 MVPMatrix; // pixel matrix 24 | vec4 pos0; 25 | vec4 color0; 26 | vec4 pos1; 27 | vec4 color1; 28 | vec4 pos2; 29 | vec4 color2; 30 | }; 31 | 32 | uniform Options options; 33 | 34 | const bool srgbTarget = true; 35 | 36 | 37 | ///////////////////////////////////////////////////////////////////////// 38 | // vertex shader 39 | 40 | in vec2 pos; // x: [0,1], alpha. y: [0,1], beta 41 | 42 | out vec4 color; 43 | 44 | void main() { 45 | float a = clamp(pos.x, 0.0, 1.0); 46 | float b = clamp(pos.y, 0.0, 1.0); 47 | float c = 1.0 - a - b; 48 | vec2 p = (options.pos0 * a + options.pos1 * b + options.pos2 * c).xy; 49 | gl_Position = options.MVPMatrix * vec4(p, 0.0, 1.0); 50 | color = options.color0 * a + options.color1 * b + options.color2 * c; 51 | } 52 | 53 | 54 | ///////////////////////////////////////////////////////////////////////// 55 | // fragment shader 56 | 57 | in vec4 color; 58 | 59 | out vec4 outColor; 60 | 61 | vec4 blender_srgb_to_framebuffer_space(vec4 in_color) 62 | { 63 | if (srgbTarget) { 64 | vec3 c = max(in_color.rgb, vec3(0.0)); 65 | vec3 c1 = c * (1.0 / 12.92); 66 | vec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4)); 67 | in_color.rgb = mix(c1, c2, step(vec3(0.04045), c)); 68 | } 69 | return in_color; 70 | } 71 | 72 | void main() { 73 | outColor = color; 74 | // https://wiki.blender.org/wiki/Reference/Release_Notes/2.83/Python_API 75 | outColor = blender_srgb_to_framebuffer_space(outColor); 76 | } 77 | 78 | -------------------------------------------------------------------------------- /addon_common/common/shaders/triangle_3D.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | */ 21 | 22 | struct Options { 23 | mat4 MVPMatrix; // view matrix 24 | vec4 pos0; 25 | vec4 color0; 26 | vec4 pos1; 27 | vec4 color1; 28 | vec4 pos2; 29 | vec4 color2; 30 | }; 31 | 32 | uniform Options options; 33 | 34 | const bool srgbTarget = true; 35 | 36 | 37 | ///////////////////////////////////////////////////////////////////////// 38 | // vertex shader 39 | 40 | in vec2 pos; // x: [0,1], alpha. y: [0,1], beta 41 | 42 | out vec4 color; 43 | 44 | void main() { 45 | float a = clamp(pos.x, 0.0, 1.0); 46 | float b = clamp(pos.y, 0.0, 1.0); 47 | float c = 1.0 - a - b; 48 | vec3 p = vec3(options.pos0) * a + vec3(options.pos1) * b + vec3(options.pos2) * c; 49 | gl_Position = options.MVPMatrix * vec4(p, 1.0); 50 | color = options.color0 * a + options.color1 * b + options.color2 * c; 51 | } 52 | 53 | 54 | ///////////////////////////////////////////////////////////////////////// 55 | // fragment shader 56 | 57 | in vec4 color; 58 | 59 | out vec4 outColor; 60 | 61 | vec4 blender_srgb_to_framebuffer_space(vec4 in_color) 62 | { 63 | if (srgbTarget) { 64 | vec3 c = max(in_color.rgb, vec3(0.0)); 65 | vec3 c1 = c * (1.0 / 12.92); 66 | vec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4)); 67 | in_color.rgb = mix(c1, c2, step(vec3(0.04045), c)); 68 | } 69 | return in_color; 70 | } 71 | 72 | 73 | void main() { 74 | outColor = color; 75 | // https://wiki.blender.org/wiki/Reference/Release_Notes/2.83/Python_API 76 | outColor = blender_srgb_to_framebuffer_space(outColor); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /addon_common/common/text.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | import re 23 | 24 | def fix_string(s, *, remove_indentation=True, remove_initial_newline=True, remove_trailing_spaces=True): 25 | if remove_initial_newline: 26 | s = re.sub(r'^\n', '', s) 27 | 28 | if remove_trailing_spaces: 29 | s = re.sub(r' +\n', '\n', s) 30 | s = re.sub(r' +$', '', s) 31 | 32 | if remove_indentation: 33 | indent = min(( 34 | len(line) - len(line.lstrip()) 35 | for line in s.splitlines() 36 | if line.strip() 37 | ), default=0) 38 | 39 | s = '\n'.join( 40 | line if not line.strip() else line[indent:] 41 | for line in s.splitlines() 42 | ) 43 | 44 | return s 45 | -------------------------------------------------------------------------------- /addon_common/common/ui_core_debug.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | 23 | class UI_Core_Debug: 24 | def _init_debug(self): 25 | self._debug_list = [] 26 | 27 | def debug_print(self, d, already_printed): 28 | sp = ' '*d 29 | tag = self.as_html 30 | tagc = f'' 31 | tagsc = f'{tag[:-1]} />' 32 | if self in already_printed: 33 | print(f'{sp}{tag}...{tagc}') 34 | return 35 | already_printed.add(self) 36 | if self._pseudoelement == 'text': 37 | innerText = self._innerText.replace('\n', '\\n') if self._innerText else '' 38 | print(f'{sp}"{innerText}"') 39 | elif self._children_all: 40 | print(f'{sp}{tag}') 41 | for c in self._children_all: 42 | c.debug_print(d+1, already_printed) 43 | print(f'{sp}{tagc}') 44 | else: 45 | print(f'{sp}{tagsc}') 46 | 47 | def structure(self, depth=0, all_children=False): 48 | l = self._children if not all_children else self._children_all 49 | return '\n'.join([(' '*depth) + str(self)] + [child.structure(depth+1) for child in l]) 50 | 51 | -------------------------------------------------------------------------------- /addon_common/common/ui_core_defaults.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | from .maths import Color, NumberUnit 23 | 24 | class UI_Core_Defaults: 25 | font_family = 'sans-serif' 26 | font_style = 'normal' 27 | font_weight = 'normal' 28 | font_size = NumberUnit(12, 'pt') 29 | font_color = Color((0, 0, 0, 1)) 30 | whitespace = 'normal' 31 | -------------------------------------------------------------------------------- /addon_common/common/ui_core_preventmulticalls.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | 23 | class UI_Core_PreventMultiCalls: 24 | multicalls = {} 25 | 26 | @staticmethod 27 | def reset_multicalls(): 28 | # print(UI_Core_PreventMultiCalls.multicalls) 29 | UI_Core_PreventMultiCalls.multicalls = {} 30 | 31 | def record_multicall(self, label): 32 | # returns True if already called! 33 | d = UI_Core_PreventMultiCalls.multicalls 34 | if label not in d: d[label] = { self._uid } 35 | elif self._uid not in d[label]: d[label].add(self._uid) 36 | else: return True 37 | return False 38 | 39 | -------------------------------------------------------------------------------- /addon_common/common/ui_settings.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | 23 | DEBUG_COLOR_CLEAN = False 24 | DEBUG_PROPERTY = 'style' # selector, style, content, size, layout, blocks 25 | DEBUG_COLOR = 1 # 0:time since change, 1:time of change 26 | 27 | DEBUG_DIRTY = False 28 | 29 | DEBUG_LIST = False 30 | 31 | CACHE_METHOD = 2 # 0:none, 1:only root, 2:hierarchical, 3:text leaves, 4:hierarchical but random 32 | 33 | ASYNC_IMAGE_LOADING = True 34 | 35 | 36 | -------------------------------------------------------------------------------- /addon_common/common/updater_tmp/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore -------------------------------------------------------------------------------- /addon_common/cookiecutter/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = ['cookiecutter', 'test'] 23 | 24 | -------------------------------------------------------------------------------- /addon_common/cookiecutter/cookiecutter_actions.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | 4 | https://github.com/CGCookie/retopoflow 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | ''' 19 | 20 | import sys 21 | import copy 22 | import math 23 | import time 24 | 25 | import bpy 26 | 27 | from ..common.useractions import ActionHandler 28 | 29 | 30 | class CookieCutter_Actions: 31 | def _cc_actions_init(self): 32 | self._cc_actions = ActionHandler(self.context) 33 | self._timer = self._cc_actions.start_timer(10) 34 | 35 | def _cc_actions_update(self): 36 | self._cc_actions.update(self.context, self.event, fn_debug=self.debug_print_actions) 37 | 38 | def _cc_actions_end(self): 39 | self._timer.done() 40 | self._cc_actions.done() 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /addon_common/cookiecutter/cookiecutter_blender.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | 4 | https://github.com/CGCookie/retopoflow 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | ''' 19 | 20 | import math 21 | from inspect import ismethod, isfunction, signature 22 | from contextlib import contextmanager 23 | 24 | import bpy 25 | 26 | from ..common.blender import region_label_to_data, create_simple_context, StoreRestore, BlenderSettings 27 | from ..common.decorators import blender_version_wrapper, ignore_exceptions 28 | from ..common.functools import find_fns, self_wrapper 29 | from ..common.debug import debugger 30 | from ..common.blender_cursors import Cursors 31 | from ..common.utils import iter_head 32 | 33 | 34 | 35 | class CookieCutter_Blender(BlenderSettings): 36 | def _cc_blenderui_init(self): 37 | self.storerestore_init() 38 | for _,fn in find_fns(self, '_blender_change_callback'): 39 | self.register_blender_change_callback(self_wrapper(self, fn)) 40 | self._storerestore.store_all() 41 | 42 | @staticmethod 43 | def blender_change_callback(fn): 44 | fn._blender_change_callback = True 45 | return fn 46 | def register_blender_change_callback(self, fn): 47 | self._storerestore.register_storage_change_callback(fn) 48 | def blender_change_init(self, storage): 49 | self._storerestore.init_storage(storage) 50 | 51 | def _cc_blenderui_end(self, ignore=None): 52 | self._storerestore.restore_all(ignore=ignore) 53 | 54 | self.header_text_restore() 55 | self.statusbar_text_restore() 56 | self.cursor_restore() 57 | 58 | 59 | -------------------------------------------------------------------------------- /addon_common/cookiecutter/cookiecutter_debug.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | 4 | https://github.com/CGCookie/retopoflow 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | ''' 19 | 20 | from ..common.blender import get_text_block 21 | 22 | 23 | class CookieCutter_Debug: 24 | cc_debug_print_to = 'CookieCutter_Debug' 25 | cc_debug_all_enabled = False 26 | cc_debug_actions_enabled = False 27 | 28 | def debug_print(self, label, *args, override_enabled=False, **kwargs): 29 | if not override_enabled and not self.cc_debug_all_enabled: return 30 | 31 | text_block = get_text_block(self.cc_debug_print_to) 32 | assert text_block 33 | text_block.cursor_set(0x7fffffff) # move cursor to last line 34 | text_block.write(f'{label}: {", ".join(args)}\n') 35 | for k,v in kwargs.items(): 36 | text_block.write(f' {k} = {v}\n') 37 | text_block.write('\n') 38 | 39 | def debug_print_actions(self, *args, **kwargs): 40 | self.debug_print( 41 | 'Action', 42 | *args, 43 | override_enabled=self.cc_debug_actions_enabled, 44 | **kwargs 45 | ) 46 | -------------------------------------------------------------------------------- /addon_common/cookiecutter/cookiecutter_fsm.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | https://github.com/CGCookie/retopoflow 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program. If not, see . 14 | ''' 15 | 16 | import bpy 17 | 18 | from ..common.debug import debugger 19 | from ..common.fsm import FSM 20 | from ..common.timerhandler import TimerHandler 21 | 22 | class CookieCutter_FSM: 23 | def _cc_fsm_init(self): 24 | self.fsm = FSM(self, start='main') 25 | self.fsm.add_exception_callback(lambda e: self._handle_exception(e, 'handle exception caught by FSM')) 26 | # def callback(e): self._handle_exception(e, 'handle exception caught by FSM') 27 | # self.fsm.add_exception_callback(callback) 28 | 29 | def _cc_fsm_update(self): 30 | self.fsm.update() 31 | 32 | def _cc_fsm_force_event(self): 33 | # add some NOP event to event queue to force modal operator to be called again right away 34 | 35 | # # warp cursor to same spot 36 | # # DOES NOT WORK: (event.mouse_x, event.mouse_y) might be incorrect!!! 37 | # self.context.window.cursor_warp(self.event.mouse_x, self.event.mouse_y) 38 | 39 | # # simulate an event 40 | # # DOES NOT WORK: only works with `--enable-event-simulate`, but then Blender cannot accept any input!!! 41 | # self.context.window.event_simulate(type='NONE', value='NOTHING') 42 | 43 | # # register a short-lived timer (only returns `None`) 44 | # # DOES NOT WORK: these timers do NOT cause modal operator to be called for some reason :( 45 | # bpy.app.timers.register(lambda:None, first_interval=0.01) 46 | 47 | # create a short-lived WindowManager timer 48 | # self.actions might not yet be created! 49 | if not hasattr(self, '_cc_force_event_handler'): 50 | self._cc_force_event_handler = TimerHandler(120, context=self.context, enabled=False) 51 | self._cc_force_event_handler.start() 52 | 53 | def _cc_fsm_stop_force_event(self): 54 | if hasattr(self, '_cc_force_event_handler'): 55 | self._cc_force_event_handler.stop() 56 | -------------------------------------------------------------------------------- /addon_common/hive/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = [ 23 | 'hive', 24 | ] 25 | 26 | -------------------------------------------------------------------------------- /addon_common/hive/hive.py: -------------------------------------------------------------------------------- 1 | import re 2 | import json 3 | 4 | from ..terminal import term_printer 5 | from ..common.blender import get_path_from_addon_root 6 | 7 | class Hive: 8 | _hive_data_path = get_path_from_addon_root('hive.json') 9 | _hive_data = json.load(open(_hive_data_path, 'rt')) 10 | 11 | @staticmethod 12 | def get(k, *, default=None): 13 | return Hive._hive_data.get(k, default) 14 | 15 | @staticmethod 16 | def __getitem__(k): 17 | return Hive.get(k) 18 | 19 | @staticmethod 20 | def get_version(k): 21 | v = Hive.get(k) 22 | return tuple(int(i) for i in v.split('.')) if v else None 23 | 24 | @staticmethod 25 | def to_bl_info(): 26 | get, ver = Hive.get, Hive.get_version 27 | bl_info_from_hive = { 28 | 'name': get('name'), 29 | 'description': get('description'), 30 | 'author': get('author'), 31 | 'blender': ver('blender minimum version'), 32 | 'version': ver('version'), 33 | 'doc_url': get('documentation url'), 34 | 'tracker_url': get('issue url'), 35 | 'location': get('blender location'), 36 | 'category': get('blender category'), 37 | } 38 | if get('release').lower() != 'official': 39 | bl_info_from_hive['warning'] = get('release').title() 40 | return bl_info_from_hive 41 | 42 | @staticmethod 43 | def update_bl_info(bl_info, init_filepath): 44 | bl_hive = Hive.to_bl_info() 45 | same = True 46 | same &= all(k in bl_info and bl_info[k] == bl_hive[k] for k in bl_hive) 47 | same &= all(k in bl_hive and bl_hive[k] == bl_info[k] for k in bl_info) 48 | if same: return 49 | 50 | # changes detected! update! 51 | term_printer.boxed('RetopoFlow: UPDATING __init__.py!', color='black', highlight='yellow', margin=' ') 52 | init_file = open(init_filepath, 'rt').read() 53 | insert = '\n' + '\n'.join([ 54 | f'''{f' "{k}":':20s}{f'"{v}"' if isinstance(v, str) else f'{v}'},''' 55 | for (k,v) in Hive.to_bl_info().items() 56 | ]) 57 | init_file = re.sub( 58 | r'(?Pbl_info *= *\{)(?P[^}]+)(?P\})', 59 | rf'\1{insert}\3', 60 | init_file 61 | ) 62 | open(init_filepath, 'wt').write(init_file) 63 | -------------------------------------------------------------------------------- /addon_common/scripts/speedtest.py: -------------------------------------------------------------------------------- 1 | import timeit 2 | from collections import namedtuple 3 | 4 | from ..maths import Vector, Point, Direction, Normal 5 | 6 | NTPoint = namedtuple('Point', ['x', 'y', 'z']) 7 | 8 | kwargs = { 9 | 'number': 10000, 10 | 'globals': globals(), 11 | } 12 | 13 | timings = [] 14 | timings += [timeit.timeit('[Vector((0,1,2)) for i in range(1000)]', **kwargs)] 15 | #timings += [timeit.timeit('[VectorOld((0,1,2)) for i in range(1000)]', **kwargs)] 16 | timings += [timeit.timeit('[Point((0,1,2)) for i in range(1000)]', **kwargs)] 17 | timings += [timeit.timeit('[Direction((0,1,2)) for i in range(1000)]', **kwargs)] 18 | timings += [timeit.timeit('[Normal((0,1,2)) for i in range(1000)]', **kwargs)] 19 | timings += [timeit.timeit('[(0,1,2) for i in range(1000)]', **kwargs)] 20 | timings += [timeit.timeit('[[0,1,2] for i in range(1000)]', **kwargs)] 21 | timings += [timeit.timeit('[NTPoint(0,1,2) for i in range(1000)]', **kwargs)] 22 | 23 | 24 | print(timings) 25 | -------------------------------------------------------------------------------- /addon_common/scripts/strip_debugging.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import re 5 | import sys 6 | import glob 7 | 8 | if len(sys.argv) < 2 or sys.argv[1] != 'YES!': 9 | print('CAUTION: running this will alter **ALL** .py files in every subdirectory!') 10 | print('To ensure you are certain you want to run it, call %s again with the argument "YES!"' % sys.argv[0]) 11 | sys.exit(1) 12 | 13 | 14 | re_function = re.compile(r'\n(?P *)(?P@profiler\.function)\n') 15 | re_add_note = re.compile(r'\n(?P *)(?Pprofiler\.add_note\(.*?\))\n') 16 | re_withcode = re.compile(r'\n(?P *)(?Pwith profiler\.code\(.*?\)( +as +.*?)?:)\n') 17 | re_dprint = re.compile(r'\n(?P *)(?P(Debugger\.)?dprint\(.*?\))\n') 18 | 19 | ignore_pyfiles = { 20 | 'profiler.py', 21 | 'debug.py', 22 | } 23 | ignore_folders = { 24 | '__pycache__', 25 | } 26 | 27 | def go(root): 28 | for fn in glob.glob('*.py'): 29 | if fn in ignore_pyfiles: continue 30 | f = open(fn, 'rt').read() 31 | of = str(f) 32 | while True: 33 | m = re_function.search(f) 34 | if not m: break 35 | replace = '\n%s# %s\n' % (m.group('indent'), m.group('pr')) 36 | f = f[:m.start()] + replace + f[m.end():] 37 | while True: 38 | m = re_add_note.search(f) 39 | if not m: break 40 | replace = '\n%s# %s\n' % (m.group('indent'), m.group('pr')) 41 | f = f[:m.start()] + replace + f[m.end():] 42 | while True: 43 | m = re_withcode.search(f) 44 | if not m: break 45 | replace = '\n%sif True: # %s\n' % (m.group('indent'), m.group('pr')) 46 | f = f[:m.start()] + replace + f[m.end():] 47 | while True: 48 | m = re_dprint.search(f) 49 | if not m: break 50 | replace = '\n%s# %s\n%spass\n' % (m.group('indent'), m.group('dp'), m.group('indent')) 51 | f = f[:m.start()] + replace + f[m.end():] 52 | if f == of: continue 53 | open(fn, 'wt').write(f) 54 | 55 | for fn in glob.glob('*'): 56 | if not os.path.isdir(fn): continue 57 | if fn in ignore_folders: continue 58 | os.chdir(fn) 59 | go(os.path.join(root, fn)) 60 | os.chdir('..') 61 | 62 | go('.') -------------------------------------------------------------------------------- /addon_common/scripts/update_copyright_date.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import re 4 | from datetime import date 5 | from pathlib import Path 6 | 7 | 8 | year = f'{date.today().year:04d}' 9 | 10 | ignore_dirs = {'.git', 'ext'} 11 | update_exts = {'.py', '.glsl', '.css'} 12 | ignore_exts = {'.ttf', '.exr', '.blend', '.pack', '.mtl', '.json', '.m4v', '.md', '.LICENSE', '.jpg', '.html', '.blend1', '.png', '.pyc', '.yml', '.gitignore', '.lock', '.scss', '.txt', '.obj', '', '.sh'} 13 | unhandled_exts = set() 14 | unhandled_paths = [] 15 | 16 | 17 | def process(p): 18 | global year, update_exts, unhandled_exts, unhandled_paths, ignore_exts, ignore_dirs 19 | if p.is_file(): 20 | if p.stem.startswith('.'): return 21 | if p.suffix not in update_exts: 22 | if p.suffix in ignore_exts: return 23 | if p.suffix in unhandled_exts: return 24 | unhandled_exts.add(p.suffix) 25 | unhandled_paths.append(p) 26 | return 27 | orig = p.read_text() 28 | updated = re.sub(r'Copyright \(C\) (?P\d+)', f'Copyright (C) {year}', orig) 29 | if orig == updated: return 30 | print(f'Updating: {p}') 31 | # print(updated) 32 | p.write_text(updated) 33 | elif p.is_dir(): 34 | if p.stem in ignore_dirs: return 35 | for np in p.glob('*'): 36 | process(np) 37 | else: 38 | unhandled_paths.append(p) 39 | 40 | process(Path('.')) 41 | print() 42 | print(f'Unhandled Extensions: {unhandled_exts}') 43 | print(f'Unhandled Paths:') 44 | print('\n'.join(f'- {p}' for p in unhandled_paths)) -------------------------------------------------------------------------------- /addon_common/terminal/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = ['deepdebug'] -------------------------------------------------------------------------------- /blender_manifest.toml: -------------------------------------------------------------------------------- 1 | schema_version = "1.0.0" 2 | 3 | id = "retopoflow" 4 | version = "3.4.7" 5 | name = "RetopoFlow 3" 6 | tagline = "A suite of retopology tools for Blender through a unified retopology mode" 7 | maintainer = "Orange Turbine - Dr. Jon Denning, Jonathan Williamson, Jonathan Lampel, JF Matheu " 8 | # Supported types: "add-on", "theme" 9 | type = "add-on" 10 | 11 | # Optional: add-ons can list which resources they will require: 12 | # * "files" (for access of any filesystem operations) 13 | # * "network" (for internet access) 14 | # * "camera" (to capture photos and videos) 15 | # * "microphone" (to capture audio) 16 | # permissions = [] 17 | 18 | # Optional link to documentation, support, source files, etc 19 | website = "https://docs.retopoflow.com/" 20 | 21 | # Optional list defined by Blender and server, see: 22 | # https://docs.blender.org/manual/en/dev/extensions/tags.html 23 | tags = ["Modeling", "Mesh"] 24 | 25 | blender_version_min = "3.6.0" 26 | # Optional: maximum supported Blender version 27 | # blender_version_max = "5.1.0" 28 | 29 | # License conforming to https://spdx.org/licenses/ (use "SPDX: prefix) 30 | # https://docs.blender.org/manual/en/dev/extensions/licenses.html 31 | license = [ 32 | "SPDX:GPL-2.0-or-later", 33 | ] 34 | # Optional: required by some licenses. 35 | copyright = [ 36 | "2024 Orange Turbine, Autotroph Inc" 37 | ] -------------------------------------------------------------------------------- /config/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/config/background.jpg -------------------------------------------------------------------------------- /devnotes/blender280notes.md: -------------------------------------------------------------------------------- 1 | # Blender 2.80 Notes 2 | 3 | 4 | [Blender 2.80 Python API Changes](https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API) 5 | 6 | [GPU Shader Module](https://docs.blender.org/api/blender2.8/gpu.html) 7 | 8 | [GPU Types](https://docs.blender.org/api/blender2.8/gpu.types.html) 9 | 10 | [Updating Scripts from 2.7x](https://en.blender.org/index.php/Dev:2.8/Source/Python/UpdatingScripts) 11 | 12 | [UI Design](https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API/UI_DESIGN) 13 | 14 | [Update Addons with both Blender 2.8 and 2.7 Supoport | Moo-Ack!](https://theduckcow.com/2019/update-addons-both-blender-28-and-27-support/) -------------------------------------------------------------------------------- /devnotes/blenderbugs.md: -------------------------------------------------------------------------------- 1 | If install add-on, ex: RetopoFlow, but after enabling change the name, ex: retopoflow, Blender's startup crashes and does not start up add-on 2 | 3 | Traceback (most recent call last): 4 | File "/home/jon/software/blender-2.82a/2.82/scripts/modules/addon_utils.py", line 351, in enable 5 | mod = __import__(module_name) 6 | ModuleNotFoundError: No module named 'RetopoFlow' 7 | -------------------------------------------------------------------------------- /devnotes/demonotes.md: -------------------------------------------------------------------------------- 1 | - adjusting ps segment count on thin surfaces causes problems [screencap](https://cl.ly/mNg5) 2 | - adjusting ps segment count can sometimes split strip in two, preventing changing count further 3 | - adjusting counts push to undo stack multiple times 4 | - undo stack actions should be more informative (for instrumentation) 5 | - integrate edge-patches 6 | - symmetry along y and z 7 | 8 | - PP: quad from three verts?? 9 | - tweak connected 10 | - turning on symmetry should snap/merge target geo on other side? 11 | - button to snap target to source 12 | - settings need to be saved between sessions 13 | - polypen crashes (trying to create edge between verts that have edge?) 14 | - dissolve edges, verts, faces, etc in pp 15 | 16 | - "add edge loops with something like loop cut" 17 | - reimplement f2 18 | - fill in gap between strips with single button 19 | - work in blender 2.8 20 | - update blender button tooltips 21 | - snap merge upon move 22 | - deselect in PS? 23 | - change radius of strip, similar to segment count -------------------------------------------------------------------------------- /devnotes/todo.md: -------------------------------------------------------------------------------- 1 | - IMPORTANT, BEFORE RELEASE 2 | - remove sprint and other debug calls 3 | - use stopwatch to wrap select single so that smart selection is more dependable 4 | - general rotate and scale need updated! (rf_fsm.py) 5 | 6 | - Contours 7 | - move label position code into separate method called on target or view change 8 | - new cut into symmetry line sometimes doesn't stick to line of symmetry 9 | 10 | - PolyPen 11 | - moving verts near symmetry line can be difficult 12 | 13 | - Relax 14 | - Use 3D accel structure. note: verts change position, but accel struct will see only initial position... probably ok, though! 15 | 16 | - Loops and Strokes 17 | - remove Stopwatch, and handle this code correctly! 18 | - add planar rotation to loops (in addition to screen rotation, similar to contours) 19 | 20 | - Strokes 21 | - remove internal mergeSnapped code 22 | - improve move selected code (base on PolyPen or Select) 23 | 24 | - General 25 | - predraw Drawing callback only fires if pre3d, post3d, or post2d exists! 26 | - general rotate and scale should have viz 27 | - build accel structs async 28 | - add clamp to symmetry option to prevent verts from moving away from symmetry line?? 29 | - new method for finding nearest geometry (use selection framebuffer, see draw_selection_buffer) 30 | 31 | 32 | - Symmetry 33 | - If action (ex: grab) is started on mirrored side, updates should be be mirrored correctly -------------------------------------------------------------------------------- /devnotes/versionbump.md: -------------------------------------------------------------------------------- 1 | # Version Bump 2 | 3 | When doing a version bump, update the versions in the following files: 4 | 5 | - `hive.json` 6 | - update `"version": "3.2.5"` 7 | - update `"release": "alpha"` (alpha, beta, release candidate 1, release candidate 2, official) 8 | - `help/changelist.md` 9 | - add new section 10 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | docs.retopoflow.com -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Hello! This is where you manage which Jekyll version is used to run. 4 | # When you want to use a different version, change it below, save the 5 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so: 6 | # 7 | # bundle exec jekyll serve 8 | # 9 | # This will help ensure the proper Jekyll version is running. 10 | # Happy Jekylling! 11 | gem "jekyll", "~> 3.9.0" 12 | 13 | # This is the default theme for new Jekyll sites. You may change this to anything you like. 14 | gem "minima", "~> 2.0" 15 | 16 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and 17 | # uncomment the line below. To upgrade, run `bundle update github-pages`. 18 | # gem "github-pages", group: :jekyll_plugins 19 | 20 | # If you have any plugins, put them here! 21 | group :jekyll_plugins do 22 | gem "jekyll-feed", "~> 0.6" 23 | end 24 | 25 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 26 | # and associated library. 27 | install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do 28 | gem "tzinfo", "~> 1.2" 29 | gem "tzinfo-data" 30 | end 31 | 32 | # Performance-booster for watching directories on Windows 33 | gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform? 34 | 35 | # kramdown v2 ships without the gfm parser by default. If you're using 36 | # kramdown v1, comment out this line. 37 | gem "kramdown-parser-gfm" 38 | 39 | gem "github-pages", group: :jekyll_plugins 40 | 41 | gem "webrick", "~> 1.8" 42 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | # theme: jekyll-theme-tactile 2 | theme: jekyll-theme-minimal 3 | title: RetopoFlow 4 | description: A suite of retopology tools for Blender 5 | logo: images/retopoflow_3_feature.png 6 | show_downloads: false 7 | -------------------------------------------------------------------------------- /docs/_data/options.yml: -------------------------------------------------------------------------------- 1 | warning_max_sources: '1m' 2 | warning_max_target: '20k' 3 | rf_version: 3.4.4 -------------------------------------------------------------------------------- /docs/addon_updater.md: -------------------------------------------------------------------------------- 1 | # RetopoFlow Updater System 2 | 3 | Keep RetopoFlow up-to-date with the latest official releases using the updater system! 4 | 5 | 1. Click the "Check for updates" button in the RetopoFlow menu. 6 | 2. If the "Update now" button... 7 | 8 | - stays disabled: no updates are ready at the moment. 9 | - becomes enabled: click it to download and install the latest release of RetopoFlow. 10 | 11 | For those who would like to try the pre-releases or try out latest bug fixes, use the "Updater System". 12 | 13 | IMPORTANT: The RetopoFlow Updater System can break your RetopoFlow installation! 14 | To fix a broken RetopoFlow install, simply download and install the latest version from [Blender Market](https://blendermarket.com/products/retopoflow). 15 | 16 | ![](images/addon_updater_button.png) 17 | 18 | The RetopoFlow Updater System will show the last 10 or so releases/pre-releases. 19 | Choose one of the releases then click the "Load" button to download and install that exact version. 20 | 21 | ![](images/addon_updater_system.png) 22 | 23 | If you wish to try a specific branch or commit, specify the branch or commit hash in the "Advanced: Commit / Branch" text box, then click the "Load" button. 24 | 25 | ![](images/addon_updater_advanced.png) 26 | 27 | -------------------------------------------------------------------------------- /docs/assets/css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | --- 3 | --- 4 | 5 | @import "{{ site.theme }}"; 6 | */ 7 | 8 | body { 9 | background: rgba(32, 32, 32, 1.0); 10 | color: rgb(216, 216, 216); 11 | font-size: 14px; 12 | } 13 | 14 | section a { 15 | text-decoration-line: underline; 16 | color: rgb(221, 221, 221); 17 | } 18 | 19 | h1, h2, h3 { 20 | color: white; 21 | } 22 | 23 | h1 a { 24 | color: white; 25 | } 26 | 27 | h2 { 28 | margin-top: 48px; 29 | margin-bottom: 12px; 30 | } 31 | 32 | strong { 33 | color: white; 34 | } 35 | 36 | code { 37 | /*display: inline-block;*/ 38 | border: 1px solid rgba(0,0,0,0.5); 39 | background: rgba(64, 64, 64, 0.75); 40 | color: white; 41 | padding: 2px 4px; 42 | } 43 | 44 | img { 45 | vertical-align: bottom; 46 | } 47 | 48 | li img { 49 | width: 24px; 50 | height: 24px; 51 | padding-top: 8px; 52 | padding-right: 8px; 53 | } 54 | 55 | h1 img { 56 | width: 32px; 57 | height: 32px; 58 | } 59 | 60 | a:hover { 61 | font-weight: unset; 62 | color: white; 63 | } 64 | 65 | th, td { 66 | border: 0px; 67 | } 68 | th { 69 | color: #888; 70 | } 71 | 72 | 73 | /* undo theme styling on header and footer */ 74 | header { 75 | padding-left: 1px; 76 | } 77 | header ul { 78 | list-style: none; 79 | /*height: fit-content;*/ 80 | height: auto; 81 | background: rgba(32, 32, 32, 1.0);; 82 | border: 0px; 83 | } 84 | header li { 85 | width: auto; 86 | float: none; 87 | border: 0px; 88 | height: auto; 89 | } 90 | header ul li a { 91 | line-height: unset; 92 | text-align: left; 93 | height: auto; 94 | color: rgb(221, 221, 221); 95 | font-size: 16px; 96 | } 97 | header ul li a:hover { 98 | font-weight: unset; 99 | color: white; 100 | } 101 | header ul li a:focus { 102 | font-weight: unset; 103 | color: white; 104 | border: 0px; 105 | } 106 | header ul li a:active { 107 | background: transparent; 108 | } 109 | footer { 110 | color: rgb(96, 96, 96); 111 | background-color: rgba(32, 32, 32, 1.0); 112 | position: fixed; 113 | bottom: 0; 114 | } 115 | footer a { 116 | color: rgb(96, 96, 96); 117 | text-decoration: underline; 118 | } -------------------------------------------------------------------------------- /docs/assets/css/style-old.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import "{{ site.theme }}"; 5 | 6 | p { 7 | color: black; 8 | } 9 | 10 | a { 11 | color: black; 12 | } 13 | 14 | downloads { 15 | background-color: darkslategray; 16 | } -------------------------------------------------------------------------------- /docs/contours.md: -------------------------------------------------------------------------------- 1 | # ![](images/contours-icon.png) Contours Help 2 | 3 | Shortcut: {{ site.data.keymaps.contours_tool }} 4 | 5 | The Contours tool gives you a quick and easy way to retopologize cylindrical forms. 6 | For example, it's ideal for organic forms, such as arms, legs, tentacles, tails, horns, etc. 7 | 8 | The tool works by drawing strokes perpendicular to the form to define the contour of the shape. 9 | Each additional stroke drawn will either extrude the current selection or cut a new loop into the edges drawn over. 10 | 11 | You may draw strokes in any order, from any direction. 12 | 13 | ![](images/help_contours.png) 14 | 15 | 16 | ## Creating 17 | 18 | 19 | | :--- | :--- | :--- | 20 | | {{ site.data.keymaps.insert }} | : | draw contour stroke perpendicular to form. newly created contour extends selection if applicable. | 21 | | {{ site.data.keymaps.increase_count }} | : | increase segment counts in selected loop | 22 | | {{ site.data.keymaps.decrease_count }} | : | decrease segment counts in selected loop | 23 | | {{ site.data.keymaps.fill }} | : | bridge selected edge loops | 24 | 25 | 26 | ## Selecting 27 | 28 | 29 | | :--- | :--- | :--- | 30 | | {{ site.data.keymaps.select_single }}, {{ site.data.keymaps.select_single_add }} | : | select edge | 31 | | {{ site.data.keymaps.select_smart }}, {{ site.data.keymaps.select_smart_add }} | : | smart select loop | 32 | | {{ site.data.keymaps.select_paint }}, {{ site.data.keymaps.select_paint_add }} | : | paint edge selection | 33 | | {{ site.data.keymaps.select_path_add }} | : | select edges along shortest path | 34 | | {{ site.data.keymaps.select_all }} | : | select / deselect all | 35 | | {{ site.data.keymaps.deselect_all }} | : | deselect all | 36 | 37 | ## Transforming 38 | 39 | 40 | | :--- | :--- | :--- | 41 | | {{ site.data.keymaps.action }} | : | grab and slide selected geometry under mouse | 42 | | {{ site.data.keymaps.grab }} | : | slide selected loop | 43 | | {{ site.data.keymaps.rotate_plane }} | : | rotate selected loop in plane | 44 | | {{ site.data.keymaps.rotate_screen }} | : | rotate selected loop in screen | 45 | | {{ site.data.keymaps.smooth_edge_flow }} | : | smooths edge flow of selected geometry | 46 | 47 | ## Other 48 | 49 | 50 | | :--- | :--- | :--- | 51 | | {{ site.data.keymaps.delete }} | : | delete/dissolve/collapse selected | 52 | 53 | ## Tips 54 | 55 | - Extrude Contours from an existing edge loop by selecting it first. 56 | - Contours works with symmetry, enabling you to contour torsos and other symmetrical objects! 57 | 58 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | # RetopoFlow FAQ 2 | 3 | Below are answers to some common questions with RetopoFlow. 4 | 5 | 6 | ## Q: I cannot create new geometry! Help!? 7 | 8 | All of the tools (except Patches, Tweak, and Relax) create geometry using {{ site.data.keymaps.insert }} action. 9 | Selection uses the {{ site.data.keymaps.select_single }} action. 10 | See [General Help](general.md) for more actions. 11 | 12 | 13 | ## Q: Why can I not select the geometry? 14 | 15 | If you have symmetry turned on, you can only select the geometry on the non-mirrored side of the model. 16 | Sometimes the geometry can snap to source surfaces that are "hidden" (see next Q). 17 | 18 | 19 | ## Q: Why is my geometry below the source mesh? 20 | 21 | Sometimes when the source mesh contains objects that overlap (or nearly overlap), RetopoFlow will snap geometry to the inner surface. 22 | Use the "Push and Snap" operation under Options > Target Cleaning to push the vertices out along normal before snapping them back to the source surface. 23 | 24 | 25 | ## Q: I have symmetry turned on, but why is it not working? 26 | 27 | RetopoFlow's symmetry follows Blender's symmetry model, where symmetry is based on the origin of the target object. 28 | In fact, enabling symmetry in RetopoFlow will add a Mirror Modifier to the target object in Blender. 29 | 30 | RetopoFlow will create the new target object similar to Blender---at the 3D Cursor---so make sure to position correctly the 3D Cursor before creating a new target mesh. 31 | If you have already started working on a target mesh, edit the origin as you would in Blender. 32 | 33 | 34 | ## Q: How do I continue working on a previous target? 35 | 36 | To continue working on a target mesh, select the target, switch to Edit Mode, then choose one of the RetopoFlow tools from the RetopoFlow menu. 37 | 38 | -------------------------------------------------------------------------------- /docs/images/addon_updater_advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/addon_updater_advanced.png -------------------------------------------------------------------------------- /docs/images/addon_updater_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/addon_updater_button.png -------------------------------------------------------------------------------- /docs/images/addon_updater_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/addon_updater_system.png -------------------------------------------------------------------------------- /docs/images/blendermarket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/blendermarket.png -------------------------------------------------------------------------------- /docs/images/blendermarket_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/blendermarket_screenshot.png -------------------------------------------------------------------------------- /docs/images/contours-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/contours-icon.png -------------------------------------------------------------------------------- /docs/images/debugging_enable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/debugging_enable.png -------------------------------------------------------------------------------- /docs/images/debugging_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/debugging_open.png -------------------------------------------------------------------------------- /docs/images/delete_dialog_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/delete_dialog_pie.png -------------------------------------------------------------------------------- /docs/images/global_exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/global_exception.png -------------------------------------------------------------------------------- /docs/images/help_contours.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_contours.png -------------------------------------------------------------------------------- /docs/images/help_knife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_knife.png -------------------------------------------------------------------------------- /docs/images/help_loops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_loops.png -------------------------------------------------------------------------------- /docs/images/help_patches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_patches.png -------------------------------------------------------------------------------- /docs/images/help_polypen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_polypen.png -------------------------------------------------------------------------------- /docs/images/help_polypen_modes_options_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_polypen_modes_options_pie.png -------------------------------------------------------------------------------- /docs/images/help_polystrips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_polystrips.png -------------------------------------------------------------------------------- /docs/images/help_relax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_relax.png -------------------------------------------------------------------------------- /docs/images/help_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_select.png -------------------------------------------------------------------------------- /docs/images/help_strokes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_strokes.png -------------------------------------------------------------------------------- /docs/images/help_strokes_modes_options_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_strokes_modes_options_pie.png -------------------------------------------------------------------------------- /docs/images/help_themes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_themes.png -------------------------------------------------------------------------------- /docs/images/help_tweak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/help_tweak.png -------------------------------------------------------------------------------- /docs/images/install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/install.png -------------------------------------------------------------------------------- /docs/images/keymap_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/keymap_all.png -------------------------------------------------------------------------------- /docs/images/keymap_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/keymap_button.png -------------------------------------------------------------------------------- /docs/images/keymap_insert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/keymap_insert.png -------------------------------------------------------------------------------- /docs/images/knife-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/knife-icon.png -------------------------------------------------------------------------------- /docs/images/loops-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/loops-icon.png -------------------------------------------------------------------------------- /docs/images/orange-turbine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/orange-turbine.png -------------------------------------------------------------------------------- /docs/images/patches-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/patches-icon.png -------------------------------------------------------------------------------- /docs/images/pie_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/pie_menu.png -------------------------------------------------------------------------------- /docs/images/polypen-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/polypen-icon.png -------------------------------------------------------------------------------- /docs/images/polystrips-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/polystrips-icon.png -------------------------------------------------------------------------------- /docs/images/relax-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/relax-icon.png -------------------------------------------------------------------------------- /docs/images/retopoflow_3_feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/retopoflow_3_feature.png -------------------------------------------------------------------------------- /docs/images/select-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/select-icon.png -------------------------------------------------------------------------------- /docs/images/selection_options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/selection_options.png -------------------------------------------------------------------------------- /docs/images/start_rf_create_new_target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/start_rf_create_new_target.png -------------------------------------------------------------------------------- /docs/images/start_rf_quickstart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/start_rf_quickstart.png -------------------------------------------------------------------------------- /docs/images/start_rf_tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/start_rf_tool.png -------------------------------------------------------------------------------- /docs/images/strokes-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/strokes-icon.png -------------------------------------------------------------------------------- /docs/images/tweak-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/tweak-icon.png -------------------------------------------------------------------------------- /docs/images/warning_viewlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/warning_viewlock.png -------------------------------------------------------------------------------- /docs/images/warnings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/docs/images/warnings.png -------------------------------------------------------------------------------- /docs/issue_template.md: -------------------------------------------------------------------------------- 1 | **PLEASE READ THE FOLLOWING AND USE THE TEMPLATE TO POST YOUR ISSUE** 2 | 3 | *Questions not directly related to the RetopoFlow project are considered general and should be posted elsewhere (e.g. git, blender, python, etc).* 4 | 5 | **Before raising the issue, please check the following first:** 6 | 7 | - [ ] Read through the README.md file in the branch used to assure the process taken is correct 8 | - [ ] Check the existing [issues](https://github.com/CGCookie/retopoflow/issues) and [pull requests](https://github.com/CGCookie/retopoflow/pulls) to make sure the issue has not already been reported and/or fixed. 9 | - [ ] You can replicate the bug and will provide as much info as possible with blend files, screenshots, logfiles, as well as show the expected result and actual result. 10 | 11 | Please prefix your issue name with one of the following: **[BUG]** **[PROPOSAL]** **[QUESTION]** 12 | 13 | 14 | Issue Template 15 | ----------------------------------- 16 | 17 | RetopoFlow Version: {*add here*} 18 | 19 | Blender Version/Hash: {*add here*} 20 | 21 | Platform Version/Distribution: {*add here*} 22 | 23 | 24 | **Issue:** 25 | 26 | {*enter your issue here*} 27 | 28 | {*add any screenshots of the issue here*} 29 | 30 | 31 | **How to Reproduce:** 32 | 33 | - {*add your list replication steps*} 34 | 35 | {*attach any files needed to replicate the issue*} 36 | 37 | 38 | 39 | Automatically Generated Info 40 | ----------------------------------- 41 | 42 | -------------------------------------------------------------------------------- /docs/issue_template_simple.md: -------------------------------------------------------------------------------- 1 | **PLEASE READ THE FOLLOWING AND USE THE TEMPLATE TO POST YOUR ISSUE** 2 | 3 | *Questions not directly related to the RetopoFlow project are considered general and should be posted elsewhere (e.g. git, blender, python, etc).* 4 | 5 | **Before raising the issue, please check the following first:** 6 | 7 | - [ ] Read through the README.md file in the branch used to assure the process taken is correct 8 | - [ ] Check the existing [issues](https://github.com/CGCookie/retopoflow/issues) and [pull requests](https://github.com/CGCookie/retopoflow/pulls) to make sure the issue has not already been reported and/or fixed. 9 | - [ ] You can replicate the bug and will provide as much info as possible with blend files, screenshots, logfiles, as well as show the expected result and actual result. 10 | 11 | Please prefix your issue name with one of the following: **[BUG]** **[PROPOSAL]** **[QUESTION]** 12 | 13 | 14 | Issue Template 15 | ----------------------------------- 16 | 17 | **Issue:** 18 | 19 | {*enter your issue here*} 20 | 21 | {*add any screenshots of the issue here*} 22 | 23 | 24 | **How to Reproduce:** 25 | 26 | - {*add your list replication steps*} 27 | 28 | {*attach any files needed to replicate the issue*} 29 | 30 | 31 | 32 | Automatically Generated Info 33 | ----------------------------------- 34 | 35 | -------------------------------------------------------------------------------- /docs/keymap_editor.md: -------------------------------------------------------------------------------- 1 | # RetopoFlow Keymap Editor 2 | 3 | RetopoFlow has a very basic keymap editor to allow some customization of interaction. 4 | 5 | Start the editor by clicking the Keymap button in the Config section of the RetopoFlow Blender menu. 6 | 7 | ![](images/keymap_button.png) 8 | 9 | IMPORTANT: This editor is an early prototype, and not all keymap settings will work as expected. 10 | 11 | Navigate the action categories to find lists of actions, each with a set of interactions that can be customized. 12 | 13 | - Click on the big button with interactions as text (example: Ctrl+LMB) will edit that specific interaction for the RetopoFlow action. 14 | - Click on the button with a `✕` to delete that interaction. 15 | - Click the `+ Add New Keymap` to add a new interaction for the action. 16 | - Click the `Reset Keymap` button to reset that action's keymaps to the default interactions. 17 | - Click the `Reset All` button at the bottom to reset _all_ of the custom keymaps back to their default interactions. 18 | 19 | ![](images/keymap_all.png) 20 | 21 | When editing an interaction, a window will display with all the ways to map an interaction to the action. 22 | 23 | ![](images/keymap_insert.png) 24 | 25 | -------------------------------------------------------------------------------- /docs/knife.md: -------------------------------------------------------------------------------- 1 | # ![](images/knife-icon.png) Knife Help 2 | 3 | Shortcut: {{ site.data.keymaps.knife_tool }} 4 | 5 | Quick Shortcut: {{ site.data.keymaps.knife_quick }} 6 | 7 | The Knife tool allows you to cut into the existing geometry similarly to Blender's Knife tool. 8 | 9 | ![](images/help_knife.png) 10 | 11 | Note: the Knife tool will only cut into existing geometry; it will not create new vertices, edges, or faces. 12 | 13 | If nothing is selected, the first insert will 14 | 15 | - insert a new detached vertex if the mouse is hovering a face, 16 | - split the hovered edge, 17 | - select the hovered vertex, or 18 | - set a knife starting point (does _not_ create a new vertex). 19 | 20 | The subsequent insertions will cut in new edges, splitting faces and edges accordingly. 21 | 22 | Note: an existing face will not be split until there are distinct entrance and exit vertices. 23 | Until the face can split, the created vertices and edges will be non-manifold (possibly detached) geometry. 24 | 25 | 26 | 27 | ## Creating 28 | 29 | 30 | | :--- | :--- | :--- | 31 | | {{ site.data.keymaps.insert }} | : | insert geometry connected to selected geometry | 32 | | {{ site.data.keymaps.knife_reset }} | : | resets the knife starting point | 33 | 34 | ## Selecting 35 | 36 | 37 | | :--- | :--- | :--- | 38 | | {{ site.data.keymaps.select_single }}, {{ site.data.keymaps.select_single_add }} | : | select geometry | 39 | | {{ site.data.keymaps.select_paint }}, {{ site.data.keymaps.select_paint_add }} | : | paint geometry selection | 40 | | {{ site.data.keymaps.select_path_add }} | : | select along shortest path | 41 | | {{ site.data.keymaps.select_all }} | : | select / deselect all | 42 | | {{ site.data.keymaps.deselect_all }} | : | deselect all | 43 | 44 | 45 | ## Transforming 46 | 47 | 48 | | :--- | :--- | :--- | 49 | | {{ site.data.keymaps.grab }} | : | grab and move selected geometry | 50 | | {{ site.data.keymaps.action }} | : | grab and move selected geometry under mouse | 51 | | {{ site.data.keymaps.smooth_edge_flow }} | : | smooths edge flow of selected geometry | 52 | 53 | ## Other 54 | 55 | 56 | | :--- | :--- | :--- | 57 | | {{ site.data.keymaps.delete }} | : | delete/dissolve/collapse selected | 58 | | {{ site.data.keymaps.rip }} | : | rip selected edge | 59 | | {{ site.data.keymaps.rip_fill }} | : | rip and fill selected edge | 60 | 61 | -------------------------------------------------------------------------------- /docs/loops.md: -------------------------------------------------------------------------------- 1 | # ![](images/loops-icon.png) Loops Help 2 | 3 | Shortcut: {{ site.data.keymaps.loops_tool }} 4 | 5 | Quick Shortcut: {{ site.data.keymaps.loops_quick }} 6 | 7 | 8 | The Loops tool allows you to insert new edge loops along a face loop and slide any edge loop along the source mesh. 9 | The Loops tool also works on any strip of edges. 10 | 11 | ![](images/help_loops.png) 12 | 13 | ## Creating 14 | 15 | 16 | | :--- | :--- | :--- | 17 | | {{ site.data.keymaps.insert }} | : | insert edge loop | 18 | 19 | 20 | ## Selecting 21 | 22 | 23 | | :--- | :--- | :--- | 24 | | {{ site.data.keymaps.select_single }}, {{ site.data.keymaps.select_single_add }} | : | select edges | 25 | | {{ site.data.keymaps.select_smart }}, {{ site.data.keymaps.select_smart_add }} | : | smart select loop | 26 | | {{ site.data.keymaps.select_paint }}, {{ site.data.keymaps.select_paint_add }} | : | paint edge selection | 27 | | {{ site.data.keymaps.select_path_add }} | : | select edges along shortest path | 28 | | {{ site.data.keymaps.select_all }} | : | select / deselect all | 29 | | {{ site.data.keymaps.deselect_all }} | : | deselect all | 30 | 31 | 32 | ## Transforming 33 | 34 | 35 | | :--- | :--- | :--- | 36 | | {{ site.data.keymaps.slide }} | : | slide loop | 37 | | {{ site.data.keymaps.action }} | : | if mouse over unselected geometry, smart select loop under mouse.
grab and slide selected geometry under mouse | 38 | | {{ site.data.keymaps.smooth_edge_flow }} | : | smooths edge flow of selected geometry | 39 | 40 | ## Other 41 | 42 | 43 | | :--- | :--- | :--- | 44 | | {{ site.data.keymaps.delete }} | : | delete/dissolve/collapse selected | 45 | | {{ site.data.keymaps.rip }} | : | rip selected edge | 46 | | {{ site.data.keymaps.rip_fill }} | : | rip and fill selected edge | 47 | 48 | -------------------------------------------------------------------------------- /docs/patches.md: -------------------------------------------------------------------------------- 1 | # ![](images/patches-icon.png) Patches Help 2 | 3 | Shortcut: {{ site.data.keymaps.patches_tool }} 4 | 5 | 6 | The Patches tool helps fill in holes in your topology. 7 | Select the strip of boundary edges that you wish to fill. 8 | 9 | ![](images/help_patches.png) 10 | 11 | ## Creating 12 | 13 | 14 | | :--- | :--- | :--- | 15 | | {{ site.data.keymaps.action_alt1 }} | : | toggle vertex as a corner | 16 | | {{ site.data.keymaps.fill }} | : | create visualized patch | 17 | | {{ site.data.keymaps.increase_count }} | : | increase segment count when bridging | 18 | | {{ site.data.keymaps.decrease_count }} | : | decrease segment count when bridging | 19 | 20 | 21 | ## Selecting 22 | 23 | 24 | | :--- | :--- | :--- | 25 | | {{ site.data.keymaps.select_single }}, {{ site.data.keymaps.select_single_add }} | : | select edge | 26 | | {{ site.data.keymaps.select_smart }}, {{ site.data.keymaps.select_smart_add }} | : | smart select boundary edges | 27 | | {{ site.data.keymaps.select_paint }}, {{ site.data.keymaps.select_paint_add }} | : | paint edge selection | 28 | | {{ site.data.keymaps.select_path_add }} | : | select edges along shortest path | 29 | | {{ site.data.keymaps.select_all }} | : | select / deselect all | 30 | | {{ site.data.keymaps.deselect_all }} | : | deselect all | 31 | 32 | 33 | ## Transforming 34 | 35 | 36 | | :--- | :--- | :--- | 37 | | {{ site.data.keymaps.action }} | : | grab and move selected geometry under mouse | 38 | | {{ site.data.keymaps.grab }} | : | grab and move selected geometry | 39 | 40 | 41 | ## Notes 42 | 43 | The Patches tool currently only handles a limited number of selected regions. 44 | More support coming soon! 45 | 46 | - 2 connected strips in an L-shape 47 | - 2 parallel strips: the two strips must contain the same number of edges 48 | - 3 connected strips in a C-shape: first and last strips must contain the same number of edges 49 | - 4 strips in a rectangular loop: opposite strips must contain the same number of edges 50 | 51 | 52 | If no pre-visualized regions show after selection, no geometry will be created after pressing {{ site.data.keymaps.fill }}. 53 | 54 | Adjust the Angle parameter to help Patches determine which connected edges should be in the same strip. 55 | Alternatively, you can manually toggle vertex corners using {{ site.data.keymaps.action_alt0 }}. 56 | 57 | -------------------------------------------------------------------------------- /docs/polystrips.md: -------------------------------------------------------------------------------- 1 | # ![](images/polystrips-icon.png) PolyStrips Help 2 | 3 | Shortcut: {{ site.data.keymaps.polystrips_tool }} 4 | 5 | 6 | The PolyStrips tool provides quick and easy ways to map out key face loops for complex models. 7 | For example, if you need to retopologize a human face, creature, or any other complex organic or hard-surface object. 8 | 9 | PolyStrips works by hand drawing strokes on to the high-resolution source object. 10 | The strokes are instantly converted into spline-based strips of polygons. 11 | 12 | Any continuous quad strip may be manipulated with PolyStrips via the auto-generated spline handles. 13 | 14 | ![](images/help_polystrips.png) 15 | 16 | ## Creating 17 | 18 | 19 | | :--- | :--- | :--- | 20 | | {{ site.data.keymaps.insert }} | : | draw strip of quads | 21 | | {{ site.data.keymaps.brush_radius }} | : | adjust brush size | 22 | | {{ site.data.keymaps.action }} | : | grab and move selected geometry | 23 | | {{ site.data.keymaps.increase_count }} | : | increase segment counts in selected strip | 24 | | {{ site.data.keymaps.decrease_count }} | : | decrease segment counts in selected strip | 25 | 26 | 27 | ## Selecting 28 | 29 | 30 | | :--- | :--- | :--- | 31 | | {{ site.data.keymaps.select_single }}, {{ site.data.keymaps.select_single_add }} | : | select face | 32 | | {{ site.data.keymaps.select_paint }}, {{ site.data.keymaps.select_paint_add }} | : | paint face selection | 33 | | {{ site.data.keymaps.select_path_add }} | : | select faces along shortest path | 34 | | {{ site.data.keymaps.select_all }} | : | select / deselect all | 35 | | {{ site.data.keymaps.deselect_all }} | : | deselect all | 36 | 37 | 38 | ## Control Points 39 | 40 | The following actions apply to when the mouse is hovering over control points of selected strip. 41 | 42 | 43 | | :--- | :--- | :--- | 44 | | {{ site.data.keymaps.action }} | : | grab and move control point under mouse | 45 | | {{ site.data.keymaps.action_alt0 }} | : | grab and move all inner control points around neighboring outer control point | 46 | | {{ site.data.keymaps.action_alt1 }} | : | scale strip width by dragging on inner control point | 47 | 48 | 49 | ## Transforming 50 | 51 | 52 | | :--- | :--- | :--- | 53 | | {{ site.data.keymaps.action }} | : | grab and move selected geometry under mouse | 54 | | {{ site.data.keymaps.grab }} | : | grab and move selected geometry | 55 | 56 | 57 | ## Other 58 | 59 | 60 | | :--- | :--- | :--- | 61 | | {{ site.data.keymaps.delete }} | : | delete/dissolve/collapse selected | 62 | | {{ site.data.keymaps.rip }} | : | rip selected edge | 63 | | {{ site.data.keymaps.rip_fill }} | : | rip and fill selected edge | 64 | 65 | -------------------------------------------------------------------------------- /docs/relax.md: -------------------------------------------------------------------------------- 1 | # ![](images/relax-icon.png) Relax Help 2 | 3 | Shortcut: {{ site.data.keymaps.relax_tool }} 4 | 5 | Quick Shortcut: {{ site.data.keymaps.relax_quick }} 6 | 7 | 8 | The Relax tool allows you to easily relax the vertex positions using a brush. 9 | 10 | ![](images/help_relax.png) 11 | 12 | ## Transforming 13 | 14 | 15 | | :--- | :--- | :--- | 16 | | {{ site.data.keymaps.brush }} | : | relax all vertices within brush | 17 | | {{ site.data.keymaps.brush_alt }} | : | relax only selected vertices within brush | 18 | 19 | ## Changing Brush Options 20 | 21 | 22 | | :--- | :--- | :--- | 23 | | {{ site.data.keymaps.brush_radius }} | : | adjust brush size | 24 | | {{ site.data.keymaps.brush_strength }} | : | adjust brush strength | 25 | | {{ site.data.keymaps.brush_falloff }} | : | adjust brush falloff | 26 | 27 | These options can also be stored as presets in the Brush Options panel. 28 | 29 | To quickly switch between presets, use the {{ site.data.keymaps.pie_menu_alt0 }} pie menu. 30 | 31 | ## Masking 32 | 33 | Relax has several options to control which vertices are or are not moved. 34 | Each option is below, along with setting and description. 35 | 36 | ### Boundary 37 | 38 | 39 | | :--- | :--- | :--- | 40 | | Exclude | : | Relax vertices not along boundary | 41 | | Slide | : | Relax vertices along boundary, but move them by sliding along boundary | 42 | | Include | : | Relax all vertices within brush, regardless of being along boundary | 43 | 44 | ### Symmetry 45 | 46 | 47 | | :--- | :--- | :--- | 48 | | Exclude | : | Relax vertices not along symmetry plane | 49 | | Slide | : | Relax vertices along symmetry plane, but move them by sliding along symmetry plane | 50 | | Include | : | Relax all vertices within brush, regardless of being along symmetry plane | 51 | 52 | ### Hidden 53 | 54 | 55 | | :--- | :--- | :--- | 56 | | Exclude | : | Relax only visible vertices | 57 | | Include | : | Relax all vertices within brush, regardless of visibility | 58 | 59 | ### Selected 60 | 61 | 62 | | :--- | :--- | :--- | 63 | | Exclude | : | Relax only unselected vertices | 64 | | Only | : | Relax only selected vertices | 65 | | All | : | Relax all vertices within brush, regardless of selection | 66 | 67 | -------------------------------------------------------------------------------- /docs/select.md: -------------------------------------------------------------------------------- 1 | # ![](images/select-icon.png) Select Help 2 | 3 | Shortcut: {{ site.data.keymaps.select_tool }} 4 | 5 | Quick Shortcut: {{ site.data.keymaps.select_quick }} 6 | 7 | The select tool allows you to box select vertices. 8 | 9 | Note: This tool is very basic at the moment. 10 | 11 | ![](images/help_select.png) 12 | 13 | 14 | ## Selecting 15 | 16 | 17 | | :--- | :--- | :--- | 18 | | {{ site.data.keymaps.select_box }} | : | box select vertices | 19 | | {{ site.data.keymaps.select_box_del }} | : | remove vertices from selection | 20 | | {{ site.data.keymaps.select_box_add }} | : | add vertices to selection | 21 | 22 | 23 | ## General 24 | 25 | 26 | | :--- | :--- | :--- | 27 | | {{ site.data.keymaps.grab }} | : | grab and move selected geometry | 28 | | {{ site.data.keymaps.rotate }} | : | rotate selected geometry | 29 | | {{ site.data.keymaps.scale }} | : | scale selected geometry | 30 | | {{ site.data.keymaps.delete }} | : | delete/dissolve/collapse selected | 31 | | {{ site.data.keymaps.rip }} | : | rip selected edge | 32 | | {{ site.data.keymaps.rip_fill }} | : | rip and fill selected edge | 33 | 34 | -------------------------------------------------------------------------------- /docs/table_of_contents.md: -------------------------------------------------------------------------------- 1 | # Table of Contents 2 | 3 | Help Shortcut: {{ site.data.keymaps.all_help }} 4 | 5 | Below are links to all of the help documents built into RetopoFlow. 6 | 7 | ## General 8 | 9 | The following documents provide help generally across all of RetopoFlow. 10 | 11 | - [Quick Start Guide](quick_start.md) 12 | - [A Welcome to You from Us](welcome.md) 13 | - [RetopoFlow FAQ](faq.md) 14 | - [General Hotkeys and Options](general.md) 15 | 16 | ## Tools 17 | 18 | The following documents provide help for specific RetopoFlow tools. 19 | 20 | - ![Select icon](images/select-icon.png) [Select](select.md) 21 | - ![Contours icon](images/contours-icon.png) [Contours](contours.md) 22 | - ![PolyStrips icon](images/polystrips-icon.png) [PolyStrips](polystrips.md) 23 | - ![Strokes icon](images/strokes-icon.png) [Strokes](strokes.md) 24 | - ![Patches icon](images/patches-icon.png) [Patches](patches.md) 25 | - ![PolyPen icon](images/polypen-icon.png) [PolyPen](polypen.md) 26 | - ![Knife icon](images/knife-icon.png) [Knife](knife.md) 27 | - ![Loops icon](images/loops-icon.png) [Loops](loops.md) 28 | - ![Tweak icon](images/tweak-icon.png) [Tweak](tweak.md) 29 | - ![Relax icon](images/relax-icon.png) [Relax](relax.md) 30 | 31 | ## Additional Information 32 | 33 | The following links provide additional information. 34 | 35 | - [Change list](changelist.md) 36 | - [Warnings Details](warnings.md) 37 | - Blender Market: [RetopoFlow](https://blendermarket.com/products/retopoflow) 38 | - Twitter: [RetopoFlow](https://twitter.com/RetopoFlow), [RetopoFlow Dev](https://twitter.com/RetopoFlow_Dev) 39 | - GitHub: [Issues](https://github.com/CGCookie/retopoflow/issues) 40 | 41 | The following provide additional information about more advanced RetopoFlow features. 42 | 43 | - [Debbuging](debugging.md) 44 | - [Updater System](addon_updater.md) 45 | - [Keymap Editor](keymap_editor.md) 46 | 47 | -------------------------------------------------------------------------------- /docs/tweak.md: -------------------------------------------------------------------------------- 1 | # ![](images/tweak-icon.png) Tweak Help 2 | 3 | Shortcut: {{ site.data.keymaps.tweak_tool }} 4 | 5 | Quick Shortcut: {{ site.data.keymaps.tweak_quick }} 6 | 7 | 8 | The Tweak tool allows you to easily adjust vertex positions with a brush. 9 | 10 | ![](images/help_tweak.png) 11 | 12 | ## Transforming 13 | 14 | 15 | | :--- | :--- | :--- | 16 | | {{ site.data.keymaps.brush }} | : | tweak all vertices within brush | 17 | | {{ site.data.keymaps.brush_alt }} | : | tweak only selected vertices within brush | 18 | 19 | ## Changing Brush Options 20 | 21 | 22 | | :--- | :--- | :--- | 23 | | {{ site.data.keymaps.brush_radius }} | : | adjust brush size | 24 | | {{ site.data.keymaps.brush_strength }} | : | adjust brush strength | 25 | | {{ site.data.keymaps.brush_falloff }} | : | adjust brush falloff | 26 | 27 | These options can also be stored as presets in the Brush Options panel. 28 | 29 | To quickly switch between presets, use the {{ site.data.keymaps.pie_menu_alt0 }} pie menu. 30 | 31 | ## Masking 32 | 33 | Tweak has several options to control which vertices are or are not moved. 34 | Each option is below, along with setting and description. 35 | 36 | ### Boundary 37 | 38 | 39 | | :--- | :--- | :--- | 40 | | Exclude | : | Tweak vertices not along boundary | 41 | | Slide | : | Tweak vertices along boundary, but move them by sliding along boundary | 42 | | Include | : | Tweak all vertices within brush, regardless of being along boundary | 43 | 44 | ### Symmetry 45 | 46 | 47 | | :--- | :--- | :--- | 48 | | Exclude | : | Tweak vertices not along symmetry plane | 49 | | Slide | : | Tweak vertices along symmetry plane, but move them by sliding along symmetry plane | 50 | | Include | : | Tweak all vertices within brush, regardless of being along symmetry plane | 51 | 52 | ### Hidden 53 | 54 | 55 | | :--- | :--- | :--- | 56 | | Exclude | : | Tweak only visible vertices | 57 | | Include | : | Tweak all vertices within brush, regardless of visibility | 58 | 59 | ### Selected 60 | 61 | 62 | | :--- | :--- | :--- | 63 | | Exclude | : | Tweak only unselected vertices | 64 | | Only | : | Tweak only selected vertices | 65 | | All | : | Tweak all vertices within brush, regardless of selection | 66 | 67 | -------------------------------------------------------------------------------- /docs_config/CNAME: -------------------------------------------------------------------------------- 1 | docs.retopoflow.com -------------------------------------------------------------------------------- /docs_config/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Hello! This is where you manage which Jekyll version is used to run. 4 | # When you want to use a different version, change it below, save the 5 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so: 6 | # 7 | # bundle exec jekyll serve 8 | # 9 | # This will help ensure the proper Jekyll version is running. 10 | # Happy Jekylling! 11 | gem "jekyll", "~> 3.9.0" 12 | 13 | # This is the default theme for new Jekyll sites. You may change this to anything you like. 14 | gem "minima", "~> 2.0" 15 | 16 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and 17 | # uncomment the line below. To upgrade, run `bundle update github-pages`. 18 | # gem "github-pages", group: :jekyll_plugins 19 | 20 | # If you have any plugins, put them here! 21 | group :jekyll_plugins do 22 | gem "jekyll-feed", "~> 0.6" 23 | end 24 | 25 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 26 | # and associated library. 27 | install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do 28 | gem "tzinfo", "~> 1.2" 29 | gem "tzinfo-data" 30 | end 31 | 32 | # Performance-booster for watching directories on Windows 33 | gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform? 34 | 35 | # kramdown v2 ships without the gfm parser by default. If you're using 36 | # kramdown v1, comment out this line. 37 | gem "kramdown-parser-gfm" 38 | 39 | gem "github-pages", group: :jekyll_plugins 40 | -------------------------------------------------------------------------------- /docs_config/_config.yml: -------------------------------------------------------------------------------- 1 | # theme: jekyll-theme-tactile 2 | theme: jekyll-theme-minimal 3 | title: RetopoFlow 4 | description: A suite of retopology tools for Blender 5 | logo: images/retopoflow_3_feature.png 6 | show_downloads: false 7 | -------------------------------------------------------------------------------- /docs_config/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | --- 3 | --- 4 | 5 | @import "{{ site.theme }}"; 6 | */ 7 | 8 | body { 9 | background: rgba(32, 32, 32, 1.0); 10 | color: rgb(216, 216, 216); 11 | font-size: 14px; 12 | } 13 | 14 | section a { 15 | text-decoration-line: underline; 16 | color: rgb(221, 221, 221); 17 | } 18 | 19 | h1, h2, h3 { 20 | color: white; 21 | } 22 | 23 | h1 a { 24 | color: white; 25 | } 26 | 27 | h2 { 28 | margin-top: 48px; 29 | margin-bottom: 12px; 30 | } 31 | 32 | strong { 33 | color: white; 34 | } 35 | 36 | code { 37 | /*display: inline-block;*/ 38 | border: 1px solid rgba(0,0,0,0.5); 39 | background: rgba(64, 64, 64, 0.75); 40 | color: white; 41 | padding: 2px 4px; 42 | } 43 | 44 | img { 45 | vertical-align: bottom; 46 | } 47 | 48 | li img { 49 | width: 24px; 50 | height: 24px; 51 | padding-top: 8px; 52 | padding-right: 8px; 53 | } 54 | 55 | h1 img { 56 | width: 32px; 57 | height: 32px; 58 | } 59 | 60 | a:hover { 61 | font-weight: unset; 62 | color: white; 63 | } 64 | 65 | th, td { 66 | border: 0px; 67 | } 68 | th { 69 | color: #888; 70 | } 71 | 72 | 73 | /* undo theme styling on header and footer */ 74 | header { 75 | padding-left: 1px; 76 | } 77 | header ul { 78 | list-style: none; 79 | /*height: fit-content;*/ 80 | height: auto; 81 | background: rgba(32, 32, 32, 1.0);; 82 | border: 0px; 83 | } 84 | header li { 85 | width: auto; 86 | float: none; 87 | border: 0px; 88 | height: auto; 89 | } 90 | header ul li a { 91 | line-height: unset; 92 | text-align: left; 93 | height: auto; 94 | color: rgb(221, 221, 221); 95 | font-size: 16px; 96 | } 97 | header ul li a:hover { 98 | font-weight: unset; 99 | color: white; 100 | } 101 | header ul li a:focus { 102 | font-weight: unset; 103 | color: white; 104 | border: 0px; 105 | } 106 | header ul li a:active { 107 | background: transparent; 108 | } 109 | footer { 110 | color: rgb(96, 96, 96); 111 | background-color: rgba(32, 32, 32, 1.0); 112 | position: fixed; 113 | bottom: 0; 114 | } 115 | footer a { 116 | color: rgb(96, 96, 96); 117 | text-decoration: underline; 118 | } -------------------------------------------------------------------------------- /help/addon_updater.md: -------------------------------------------------------------------------------- 1 | # RetopoFlow Updater System 2 | 3 | Keep RetopoFlow up-to-date with the latest official releases using the updater system! 4 | 5 | 1. Click the "Check for updates" button in the RetopoFlow menu. 6 | 2. If the "Update now" button... 7 | 8 | - stays disabled: no updates are ready at the moment. 9 | - becomes enabled: click it to download and install the latest release of RetopoFlow. 10 | 11 | For those who would like to try the pre-releases or try out latest bug fixes, use the "Updater System". 12 | 13 | IMPORTANT: The RetopoFlow Updater System can break your RetopoFlow installation! 14 | To fix a broken RetopoFlow install, simply download and install the latest version from [Blender Market](https://blendermarket.com/products/retopoflow). 15 | 16 | ![](images/addon_updater_button.png max-height:200px) 17 | 18 | The RetopoFlow Updater System will show the last 10 or so releases/pre-releases. 19 | Choose one of the releases then click the "Load" button to download and install that exact version. 20 | 21 | ![](images/addon_updater_system.png max-height:400px) 22 | 23 | If you wish to try a specific branch or commit, specify the branch or commit hash in the "Advanced: Commit / Branch" text box, then click the "Load" button. 24 | 25 | ![](images/addon_updater_advanced.png max-height:150px) -------------------------------------------------------------------------------- /help/contours.md: -------------------------------------------------------------------------------- 1 | # ![](images/contours-icon.png) Contours Help 2 | 3 | Shortcut: {{contours tool}} 4 | 5 | The Contours tool gives you a quick and easy way to retopologize cylindrical forms. 6 | For example, it's ideal for organic forms, such as arms, legs, tentacles, tails, horns, etc. 7 | 8 | The tool works by drawing strokes perpendicular to the form to define the contour of the shape. 9 | Each additional stroke drawn will either extrude the current selection or cut a new loop into the edges drawn over. 10 | 11 | You may draw strokes in any order, from any direction. 12 | 13 | ![](images/help_contours.png) 14 | 15 | 16 | ## Creating 17 | 18 | | | | | 19 | | --- | --- | --- | 20 | | {{insert}} | : | draw contour stroke perpendicular to form. newly created contour extends selection if applicable. | 21 | | {{increase count}} | : | increase segment counts in selected loop | 22 | | {{decrease count}} | : | decrease segment counts in selected loop | 23 | | {{fill}} | : | bridge selected edge loops | 24 | 25 | 26 | ## Selecting 27 | 28 | | | | | 29 | | --- | --- | --- | 30 | | {{select single, select single add}} | : | select edge | 31 | | {{select smart, select smart add}} | : | smart select loop | 32 | | {{select paint, select paint add}} | : | paint edge selection | 33 | | {{select path add}} | : | select edges along shortest path | 34 | | {{select all}} | : | select / deselect all | 35 | | {{deselect all}} | : | deselect all | 36 | 37 | ## Transforming 38 | 39 | | | | | 40 | | --- | --- | --- | 41 | | {{action}} | : | grab and slide selected geometry under mouse | 42 | | {{grab}} | : | slide selected loop | 43 | | {{rotate plane}} | : | rotate selected loop in plane | 44 | | {{rotate screen}} | : | rotate selected loop in screen | 45 | | {{smooth edge flow}} | : | smooths edge flow of selected geometry | 46 | 47 | ## Other 48 | 49 | | | | | 50 | | --- | --- | --- | 51 | | {{delete}} | : | delete/dissolve/collapse selected | 52 | 53 | ## Tips 54 | 55 | - Extrude Contours from an existing edge loop by selecting it first. 56 | - Contours works with symmetry, enabling you to contour torsos and other symmetrical objects! 57 | -------------------------------------------------------------------------------- /help/faq.md: -------------------------------------------------------------------------------- 1 | # RetopoFlow FAQ 2 | 3 | Below are answers to some common questions with RetopoFlow. 4 | 5 | 6 | ## Q: I cannot create new geometry! Help!? 7 | 8 | All of the tools (except Patches, Tweak, and Relax) create geometry using {{insert}} action. 9 | Selection uses the {{select single}} action. 10 | See [General Help](general.md) for more actions. 11 | 12 | 13 | ## Q: Why can I not select the geometry? 14 | 15 | If you have symmetry turned on, you can only select the geometry on the non-mirrored side of the model. 16 | Sometimes the geometry can snap to source surfaces that are "hidden" (see next Q). 17 | 18 | 19 | ## Q: Why is my geometry below the source mesh? 20 | 21 | Sometimes when the source mesh contains objects that overlap (or nearly overlap), RetopoFlow will snap geometry to the inner surface. 22 | Use the "Push and Snap" operation under Options > Target Cleaning to push the vertices out along normal before snapping them back to the source surface. 23 | 24 | 25 | ## Q: I have symmetry turned on, but why is it not working? 26 | 27 | RetopoFlow's symmetry follows Blender's symmetry model, where symmetry is based on the origin of the target object. 28 | In fact, enabling symmetry in RetopoFlow will add a Mirror Modifier to the target object in Blender. 29 | 30 | RetopoFlow will create the new target object similar to Blender---at the 3D Cursor---so make sure to position correctly the 3D Cursor before creating a new target mesh. 31 | If you have already started working on a target mesh, edit the origin as you would in Blender. 32 | 33 | 34 | ## Q: How do I continue working on a previous target? 35 | 36 | To continue working on a target mesh, select the target, switch to Edit Mode, then choose one of the RetopoFlow tools from the RetopoFlow menu. 37 | 38 | -------------------------------------------------------------------------------- /help/images/addon_updater_advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/addon_updater_advanced.png -------------------------------------------------------------------------------- /help/images/addon_updater_advanced.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/addon_updater_advanced.thumb.png -------------------------------------------------------------------------------- /help/images/addon_updater_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/addon_updater_button.png -------------------------------------------------------------------------------- /help/images/addon_updater_button.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/addon_updater_button.thumb.png -------------------------------------------------------------------------------- /help/images/addon_updater_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/addon_updater_system.png -------------------------------------------------------------------------------- /help/images/addon_updater_system.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/addon_updater_system.thumb.png -------------------------------------------------------------------------------- /help/images/blendermarket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/blendermarket.png -------------------------------------------------------------------------------- /help/images/blendermarket.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/blendermarket.thumb.png -------------------------------------------------------------------------------- /help/images/blendermarket_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/blendermarket_screenshot.png -------------------------------------------------------------------------------- /help/images/blendermarket_screenshot.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/blendermarket_screenshot.thumb.png -------------------------------------------------------------------------------- /help/images/contours-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/contours-icon.png -------------------------------------------------------------------------------- /help/images/contours-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/contours-icon.thumb.png -------------------------------------------------------------------------------- /help/images/debugging_enable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/debugging_enable.png -------------------------------------------------------------------------------- /help/images/debugging_enable.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/debugging_enable.thumb.png -------------------------------------------------------------------------------- /help/images/debugging_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/debugging_open.png -------------------------------------------------------------------------------- /help/images/debugging_open.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/debugging_open.thumb.png -------------------------------------------------------------------------------- /help/images/delete_dialog_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/delete_dialog_pie.png -------------------------------------------------------------------------------- /help/images/delete_dialog_pie.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/delete_dialog_pie.thumb.png -------------------------------------------------------------------------------- /help/images/global_exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/global_exception.png -------------------------------------------------------------------------------- /help/images/global_exception.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/global_exception.thumb.png -------------------------------------------------------------------------------- /help/images/help_contours.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_contours.png -------------------------------------------------------------------------------- /help/images/help_contours.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_contours.thumb.png -------------------------------------------------------------------------------- /help/images/help_knife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_knife.png -------------------------------------------------------------------------------- /help/images/help_knife.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_knife.thumb.png -------------------------------------------------------------------------------- /help/images/help_loops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_loops.png -------------------------------------------------------------------------------- /help/images/help_loops.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_loops.thumb.png -------------------------------------------------------------------------------- /help/images/help_patches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_patches.png -------------------------------------------------------------------------------- /help/images/help_patches.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_patches.thumb.png -------------------------------------------------------------------------------- /help/images/help_polypen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_polypen.png -------------------------------------------------------------------------------- /help/images/help_polypen.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_polypen.thumb.png -------------------------------------------------------------------------------- /help/images/help_polypen_modes_options_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_polypen_modes_options_pie.png -------------------------------------------------------------------------------- /help/images/help_polypen_modes_options_pie.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_polypen_modes_options_pie.thumb.png -------------------------------------------------------------------------------- /help/images/help_polystrips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_polystrips.png -------------------------------------------------------------------------------- /help/images/help_polystrips.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_polystrips.thumb.png -------------------------------------------------------------------------------- /help/images/help_relax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_relax.png -------------------------------------------------------------------------------- /help/images/help_relax.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_relax.thumb.png -------------------------------------------------------------------------------- /help/images/help_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_select.png -------------------------------------------------------------------------------- /help/images/help_select.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_select.thumb.png -------------------------------------------------------------------------------- /help/images/help_strokes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_strokes.png -------------------------------------------------------------------------------- /help/images/help_strokes.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_strokes.thumb.png -------------------------------------------------------------------------------- /help/images/help_strokes_modes_options_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_strokes_modes_options_pie.png -------------------------------------------------------------------------------- /help/images/help_strokes_modes_options_pie.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_strokes_modes_options_pie.thumb.png -------------------------------------------------------------------------------- /help/images/help_themes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_themes.png -------------------------------------------------------------------------------- /help/images/help_themes.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_themes.thumb.png -------------------------------------------------------------------------------- /help/images/help_tweak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_tweak.png -------------------------------------------------------------------------------- /help/images/help_tweak.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/help_tweak.thumb.png -------------------------------------------------------------------------------- /help/images/install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/install.png -------------------------------------------------------------------------------- /help/images/install.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/install.thumb.png -------------------------------------------------------------------------------- /help/images/keymap_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/keymap_all.png -------------------------------------------------------------------------------- /help/images/keymap_all.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/keymap_all.thumb.png -------------------------------------------------------------------------------- /help/images/keymap_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/keymap_button.png -------------------------------------------------------------------------------- /help/images/keymap_button.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/keymap_button.thumb.png -------------------------------------------------------------------------------- /help/images/keymap_insert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/keymap_insert.png -------------------------------------------------------------------------------- /help/images/keymap_insert.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/keymap_insert.thumb.png -------------------------------------------------------------------------------- /help/images/knife-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/knife-icon.png -------------------------------------------------------------------------------- /help/images/knife-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/knife-icon.thumb.png -------------------------------------------------------------------------------- /help/images/loops-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/loops-icon.png -------------------------------------------------------------------------------- /help/images/loops-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/loops-icon.thumb.png -------------------------------------------------------------------------------- /help/images/orange-turbine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/orange-turbine.png -------------------------------------------------------------------------------- /help/images/orange-turbine.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/orange-turbine.thumb.png -------------------------------------------------------------------------------- /help/images/patches-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/patches-icon.png -------------------------------------------------------------------------------- /help/images/patches-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/patches-icon.thumb.png -------------------------------------------------------------------------------- /help/images/pie_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/pie_menu.png -------------------------------------------------------------------------------- /help/images/pie_menu.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/pie_menu.thumb.png -------------------------------------------------------------------------------- /help/images/polypen-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/polypen-icon.png -------------------------------------------------------------------------------- /help/images/polypen-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/polypen-icon.thumb.png -------------------------------------------------------------------------------- /help/images/polystrips-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/polystrips-icon.png -------------------------------------------------------------------------------- /help/images/polystrips-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/polystrips-icon.thumb.png -------------------------------------------------------------------------------- /help/images/relax-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/relax-icon.png -------------------------------------------------------------------------------- /help/images/relax-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/relax-icon.thumb.png -------------------------------------------------------------------------------- /help/images/retopoflow_3_feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/retopoflow_3_feature.png -------------------------------------------------------------------------------- /help/images/retopoflow_3_feature.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/retopoflow_3_feature.thumb.png -------------------------------------------------------------------------------- /help/images/select-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/select-icon.png -------------------------------------------------------------------------------- /help/images/select-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/select-icon.thumb.png -------------------------------------------------------------------------------- /help/images/selection_options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/selection_options.png -------------------------------------------------------------------------------- /help/images/selection_options.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/selection_options.thumb.png -------------------------------------------------------------------------------- /help/images/start_rf_create_new_target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/start_rf_create_new_target.png -------------------------------------------------------------------------------- /help/images/start_rf_create_new_target.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/start_rf_create_new_target.thumb.png -------------------------------------------------------------------------------- /help/images/start_rf_quickstart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/start_rf_quickstart.png -------------------------------------------------------------------------------- /help/images/start_rf_quickstart.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/start_rf_quickstart.thumb.png -------------------------------------------------------------------------------- /help/images/start_rf_tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/start_rf_tool.png -------------------------------------------------------------------------------- /help/images/start_rf_tool.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/start_rf_tool.thumb.png -------------------------------------------------------------------------------- /help/images/strokes-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/strokes-icon.png -------------------------------------------------------------------------------- /help/images/strokes-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/strokes-icon.thumb.png -------------------------------------------------------------------------------- /help/images/tweak-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/tweak-icon.png -------------------------------------------------------------------------------- /help/images/tweak-icon.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/tweak-icon.thumb.png -------------------------------------------------------------------------------- /help/images/warning_viewlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/warning_viewlock.png -------------------------------------------------------------------------------- /help/images/warning_viewlock.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/warning_viewlock.thumb.png -------------------------------------------------------------------------------- /help/images/warnings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/warnings.png -------------------------------------------------------------------------------- /help/images/warnings.thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/help/images/warnings.thumb.png -------------------------------------------------------------------------------- /help/issue_template.md: -------------------------------------------------------------------------------- 1 | **PLEASE READ THE FOLLOWING AND USE THE TEMPLATE TO POST YOUR ISSUE** 2 | 3 | *Questions not directly related to the RetopoFlow project are considered general and should be posted elsewhere (e.g. git, blender, python, etc).* 4 | 5 | **Before raising the issue, please check the following first:** 6 | 7 | - [ ] Read through the README.md file in the branch used to assure the process taken is correct 8 | - [ ] Check the existing [issues](https://github.com/CGCookie/retopoflow/issues) and [pull requests](https://github.com/CGCookie/retopoflow/pulls) to make sure the issue has not already been reported and/or fixed. 9 | - [ ] You can replicate the bug and will provide as much info as possible with blend files, screenshots, logfiles, as well as show the expected result and actual result. 10 | 11 | Please prefix your issue name with one of the following: **[BUG]** **[PROPOSAL]** **[QUESTION]** 12 | 13 | 14 | Issue Template 15 | ----------------------------------- 16 | 17 | RetopoFlow Version: {*add here*} 18 | 19 | Blender Version/Hash: {*add here*} 20 | 21 | Platform Version/Distribution: {*add here*} 22 | 23 | 24 | **Issue:** 25 | 26 | {*enter your issue here*} 27 | 28 | {*add any screenshots of the issue here*} 29 | 30 | 31 | **How to Reproduce:** 32 | 33 | - {*add your list replication steps*} 34 | 35 | {*attach any files needed to replicate the issue*} 36 | 37 | 38 | 39 | Automatically Generated Info 40 | ----------------------------------- -------------------------------------------------------------------------------- /help/issue_template_simple.md: -------------------------------------------------------------------------------- 1 | **PLEASE READ THE FOLLOWING AND USE THE TEMPLATE TO POST YOUR ISSUE** 2 | 3 | *Questions not directly related to the RetopoFlow project are considered general and should be posted elsewhere (e.g. git, blender, python, etc).* 4 | 5 | **Before raising the issue, please check the following first:** 6 | 7 | - [ ] Read through the README.md file in the branch used to assure the process taken is correct 8 | - [ ] Check the existing [issues](https://github.com/CGCookie/retopoflow/issues) and [pull requests](https://github.com/CGCookie/retopoflow/pulls) to make sure the issue has not already been reported and/or fixed. 9 | - [ ] You can replicate the bug and will provide as much info as possible with blend files, screenshots, logfiles, as well as show the expected result and actual result. 10 | 11 | Please prefix your issue name with one of the following: **[BUG]** **[PROPOSAL]** **[QUESTION]** 12 | 13 | 14 | Issue Template 15 | ----------------------------------- 16 | 17 | **Issue:** 18 | 19 | {*enter your issue here*} 20 | 21 | {*add any screenshots of the issue here*} 22 | 23 | 24 | **How to Reproduce:** 25 | 26 | - {*add your list replication steps*} 27 | 28 | {*attach any files needed to replicate the issue*} 29 | 30 | 31 | 32 | Automatically Generated Info 33 | ----------------------------------- -------------------------------------------------------------------------------- /help/keymap_editor.md: -------------------------------------------------------------------------------- 1 | # RetopoFlow Keymap Editor 2 | 3 | RetopoFlow has a very basic keymap editor to allow some customization of interaction. 4 | 5 | Start the editor by clicking the Keymap button in the Config section of the RetopoFlow Blender menu. 6 | 7 | ![](images/keymap_button.png max-height:150px) 8 | 9 | IMPORTANT: This editor is an early prototype, and not all keymap settings will work as expected. 10 | 11 | Navigate the action categories to find lists of actions, each with a set of interactions that can be customized. 12 | 13 | - Click on the big button with interactions as text (example: Ctrl+LMB) will edit that specific interaction for the RetopoFlow action. 14 | - Click on the button with a `✕` to delete that interaction. 15 | - Click the `+ Add New Keymap` to add a new interaction for the action. 16 | - Click the `Reset Keymap` button to reset that action's keymaps to the default interactions. 17 | - Click the `Reset All` button at the bottom to reset _all_ of the custom keymaps back to their default interactions. 18 | 19 | ![](images/keymap_all.png max-height:400px) 20 | 21 | When editing an interaction, a window will display with all the ways to map an interaction to the action. 22 | 23 | ![](images/keymap_insert.png max-height:300px) 24 | 25 | 26 | -------------------------------------------------------------------------------- /help/knife.md: -------------------------------------------------------------------------------- 1 | # ![](images/knife-icon.png) Knife Help 2 | 3 | Shortcut: {{knife tool}} 4 | 5 | Quick Shortcut: {{knife quick}} 6 | 7 | The Knife tool allows you to cut into the existing geometry similarly to Blender's Knife tool. 8 | 9 | ![](images/help_knife.png) 10 | 11 | Note: the Knife tool will only cut into existing geometry; it will not create new vertices, edges, or faces. 12 | 13 | If nothing is selected, the first insert will 14 | 15 | - insert a new detached vertex if the mouse is hovering a face, 16 | - split the hovered edge, 17 | - select the hovered vertex, or 18 | - set a knife starting point (does _not_ create a new vertex). 19 | 20 | The subsequent insertions will cut in new edges, splitting faces and edges accordingly. 21 | 22 | Note: an existing face will not be split until there are distinct entrance and exit vertices. 23 | Until the face can split, the created vertices and edges will be non-manifold (possibly detached) geometry. 24 | 25 | 26 | 27 | ## Creating 28 | 29 | | | | | 30 | | --- | --- | --- | 31 | | {{insert}} | : | insert geometry connected to selected geometry | 32 | | {{knife reset}} | : | resets the knife starting point | 33 | 34 | ## Selecting 35 | 36 | | | | | 37 | | --- | --- | --- | 38 | | {{select single, select single add}} | : | select geometry | 39 | | {{select paint, select paint add}} | : | paint geometry selection | 40 | | {{select path add}} | : | select along shortest path | 41 | | {{select all}} | : | select / deselect all | 42 | | {{deselect all}} | : | deselect all | 43 | 44 | 45 | ## Transforming 46 | 47 | | | | | 48 | | --- | --- | --- | 49 | | {{grab}} | : | grab and move selected geometry | 50 | | {{action}} | : | grab and move selected geometry under mouse | 51 | | {{smooth edge flow}} | : | smooths edge flow of selected geometry | 52 | 53 | ## Other 54 | 55 | | | | | 56 | | --- | --- | --- | 57 | | {{delete}} | : | delete/dissolve/collapse selected | 58 | | {{rip}} | : | rip selected edge | 59 | | {{rip fill}} | : | rip and fill selected edge | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /help/loops.md: -------------------------------------------------------------------------------- 1 | # ![](images/loops-icon.png) Loops Help 2 | 3 | Shortcut: {{loops tool}} 4 | 5 | Quick Shortcut: {{loops quick}} 6 | 7 | 8 | The Loops tool allows you to insert new edge loops along a face loop and slide any edge loop along the source mesh. 9 | The Loops tool also works on any strip of edges. 10 | 11 | ![](images/help_loops.png) 12 | 13 | ## Creating 14 | 15 | | | | | 16 | | --- | --- | --- | 17 | | {{insert}} | : | insert edge loop | 18 | 19 | 20 | ## Selecting 21 | 22 | | | | | 23 | | --- | --- | --- | 24 | | {{select single, select single add}} | : | select edges | 25 | | {{select smart, select smart add}} | : | smart select loop | 26 | | {{select paint, select paint add}} | : | paint edge selection | 27 | | {{select path add}} | : | select edges along shortest path | 28 | | {{select all}} | : | select / deselect all | 29 | | {{deselect all}} | : | deselect all | 30 | 31 | 32 | ## Transforming 33 | 34 | | | | | 35 | | --- | --- | --- | 36 | | {{slide}} | : | slide loop | 37 | | {{action}} | : | if mouse over unselected geometry, smart select loop under mouse.
grab and slide selected geometry under mouse | 38 | | {{smooth edge flow}} | : | smooths edge flow of selected geometry | 39 | 40 | ## Other 41 | 42 | | | | | 43 | | --- | --- | --- | 44 | | {{delete}} | : | delete/dissolve/collapse selected | 45 | | {{rip}} | : | rip selected edge | 46 | | {{rip fill}} | : | rip and fill selected edge | 47 | -------------------------------------------------------------------------------- /help/patches.md: -------------------------------------------------------------------------------- 1 | # ![](images/patches-icon.png) Patches Help 2 | 3 | Shortcut: {{patches tool}} 4 | 5 | 6 | The Patches tool helps fill in holes in your topology. 7 | Select the strip of boundary edges that you wish to fill. 8 | 9 | ![](images/help_patches.png) 10 | 11 | ## Creating 12 | 13 | | | | | 14 | | --- | --- | --- | 15 | | {{action alt1}} | : | toggle vertex as a corner | 16 | | {{fill}} | : | create visualized patch | 17 | | {{increase count}} | : | increase segment count when bridging | 18 | | {{decrease count}} | : | decrease segment count when bridging | 19 | 20 | 21 | ## Selecting 22 | 23 | | | | | 24 | | --- | --- | --- | 25 | | {{select single, select single add}} | : | select edge | 26 | | {{select smart, select smart add}} | : | smart select boundary edges | 27 | | {{select paint, select paint add}} | : | paint edge selection | 28 | | {{select path add}} | : | select edges along shortest path | 29 | | {{select all}} | : | select / deselect all | 30 | | {{deselect all}} | : | deselect all | 31 | 32 | 33 | ## Transforming 34 | 35 | | | | | 36 | | --- | --- | --- | 37 | | {{action}} | : | grab and move selected geometry under mouse | 38 | | {{grab}} | : | grab and move selected geometry | 39 | 40 | 41 | ## Notes 42 | 43 | The Patches tool currently only handles a limited number of selected regions. 44 | More support coming soon! 45 | 46 | - 2 connected strips in an L-shape 47 | - 2 parallel strips: the two strips must contain the same number of edges 48 | - 3 connected strips in a C-shape: first and last strips must contain the same number of edges 49 | - 4 strips in a rectangular loop: opposite strips must contain the same number of edges 50 | 51 | 52 | If no pre-visualized regions show after selection, no geometry will be created after pressing {{fill}}. 53 | 54 | Adjust the Angle parameter to help Patches determine which connected edges should be in the same strip. 55 | Alternatively, you can manually toggle vertex corners using {{action alt0}}. 56 | -------------------------------------------------------------------------------- /help/polystrips.md: -------------------------------------------------------------------------------- 1 | # ![](images/polystrips-icon.png) PolyStrips Help 2 | 3 | Shortcut: {{polystrips tool}} 4 | 5 | 6 | The PolyStrips tool provides quick and easy ways to map out key face loops for complex models. 7 | For example, if you need to retopologize a human face, creature, or any other complex organic or hard-surface object. 8 | 9 | PolyStrips works by hand drawing strokes on to the high-resolution source object. 10 | The strokes are instantly converted into spline-based strips of polygons. 11 | 12 | Any continuous quad strip may be manipulated with PolyStrips via the auto-generated spline handles. 13 | 14 | ![](images/help_polystrips.png) 15 | 16 | ## Creating 17 | 18 | | | | | 19 | | --- | --- | --- | 20 | | {{insert}} | : | draw strip of quads | 21 | | {{brush radius}} | : | adjust brush size | 22 | | {{action}} | : | grab and move selected geometry | 23 | | {{increase count}} | : | increase segment counts in selected strip | 24 | | {{decrease count}} | : | decrease segment counts in selected strip | 25 | 26 | 27 | ## Selecting 28 | 29 | | | | | 30 | | --- | --- | --- | 31 | | {{select single, select single add}} | : | select face | 32 | | {{select paint, select paint add}} | : | paint face selection | 33 | | {{select path add}} | : | select faces along shortest path | 34 | | {{select all}} | : | select / deselect all | 35 | | {{deselect all}} | : | deselect all | 36 | 37 | 38 | ## Control Points 39 | 40 | The following actions apply to when the mouse is hovering over control points of selected strip. 41 | 42 | | | | | 43 | | --- | --- | --- | 44 | | {{action}} | : | grab and move control point under mouse | 45 | | {{action alt0}} | : | grab and move all inner control points around neighboring outer control point | 46 | | {{action alt1}} | : | scale strip width by dragging on inner control point | 47 | 48 | 49 | ## Transforming 50 | 51 | | | | | 52 | | --- | --- | --- | 53 | | {{action}} | : | grab and move selected geometry under mouse | 54 | | {{grab}} | : | grab and move selected geometry | 55 | 56 | 57 | ## Other 58 | 59 | | | | | 60 | | --- | --- | --- | 61 | | {{delete}} | : | delete/dissolve/collapse selected | 62 | | {{rip}} | : | rip selected edge | 63 | | {{rip fill}} | : | rip and fill selected edge | 64 | -------------------------------------------------------------------------------- /help/relax.md: -------------------------------------------------------------------------------- 1 | # ![](images/relax-icon.png) Relax Help 2 | 3 | Shortcut: {{relax tool}} 4 | 5 | Quick Shortcut: {{relax quick}} 6 | 7 | 8 | The Relax tool allows you to easily relax the vertex positions using a brush. 9 | 10 | ![](images/help_relax.png) 11 | 12 | ## Transforming 13 | 14 | | | | | 15 | | --- | --- | --- | 16 | | {{brush}} | : | relax all vertices within brush | 17 | | {{brush alt}} | : | relax only selected vertices within brush | 18 | 19 | ## Changing Brush Options 20 | 21 | | | | | 22 | | --- | --- | --- | 23 | | {{brush radius}} | : | adjust brush size | 24 | | {{brush strength}} | : | adjust brush strength | 25 | | {{brush falloff}} | : | adjust brush falloff | 26 | 27 | These options can also be stored as presets in the Brush Options panel. 28 | 29 | To quickly switch between presets, use the {{pie menu alt0}} pie menu. 30 | 31 | ## Masking 32 | 33 | Relax has several options to control which vertices are or are not moved. 34 | Each option is below, along with setting and description. 35 | 36 | ### Boundary 37 | 38 | | | | | 39 | | --- | --- | --- | 40 | | Exclude | : | Relax vertices not along boundary | 41 | | Slide | : | Relax vertices along boundary, but move them by sliding along boundary | 42 | | Include | : | Relax all vertices within brush, regardless of being along boundary | 43 | 44 | ### Symmetry 45 | 46 | | | | | 47 | | --- | --- | --- | 48 | | Exclude | : | Relax vertices not along symmetry plane | 49 | | Slide | : | Relax vertices along symmetry plane, but move them by sliding along symmetry plane | 50 | | Include | : | Relax all vertices within brush, regardless of being along symmetry plane | 51 | 52 | ### Hidden 53 | 54 | | | | | 55 | | --- | --- | --- | 56 | | Exclude | : | Relax only visible vertices | 57 | | Include | : | Relax all vertices within brush, regardless of visibility | 58 | 59 | ### Selected 60 | 61 | | | | | 62 | | --- | --- | --- | 63 | | Exclude | : | Relax only unselected vertices | 64 | | Only | : | Relax only selected vertices | 65 | | All | : | Relax all vertices within brush, regardless of selection | 66 | 67 | -------------------------------------------------------------------------------- /help/select.md: -------------------------------------------------------------------------------- 1 | # ![](images/select-icon.png) Select Help 2 | 3 | Shortcut: {{select tool}} 4 | 5 | Quick Shortcut: {{select quick}} 6 | 7 | The select tool allows you to box select vertices. 8 | 9 | Note: This tool is very basic at the moment. 10 | 11 | ![](images/help_select.png) 12 | 13 | 14 | ## Selecting 15 | 16 | | | | | 17 | | --- | --- | --- | 18 | | {{select box}} | : | box select vertices | 19 | | {{select box del}} | : | remove vertices from selection | 20 | | {{select box add}} | : | add vertices to selection | 21 | 22 | 23 | ## General 24 | 25 | | | | | 26 | | --- | --- | --- | 27 | | {{grab}} | : | grab and move selected geometry | 28 | | {{rotate}} | : | rotate selected geometry | 29 | | {{scale}} | : | scale selected geometry | 30 | | {{delete}} | : | delete/dissolve/collapse selected | 31 | | {{rip}} | : | rip selected edge | 32 | | {{rip fill}} | : | rip and fill selected edge | 33 | -------------------------------------------------------------------------------- /help/strokes.md: -------------------------------------------------------------------------------- 1 | # ![](images/strokes-icon.png) Strokes Help 2 | 3 | Shortcut: {{strokes tool}} 4 | 5 | 6 | The Strokes tool helps fill in holes in your topology. 7 | This tool lets you insert edge strips and extruding edges by brushing a stroke on the source. 8 | 9 | ![](images/help_strokes.png) 10 | 11 | ## Creating 12 | 13 | | | | | 14 | | --- | --- | --- | 15 | | {{insert}} | : | insert edge strip and bridge from selected geometry | 16 | | {{increase count}} | : | increase span/loop counts in bridge | 17 | | {{decrease count}} | : | decrease span/loop counts in bridge | 18 | 19 | 20 | ## Selecting 21 | 22 | | | | | 23 | | --- | --- | --- | 24 | | {{select single, select single add}} | : | select edges | 25 | | {{select smart, select smart add}} | : | smart select loop | 26 | | {{select paint, select paint add}} | : | paint edge selection | 27 | | {{select path add}} | : | select edges along shortest path | 28 | | {{select all}} | : | select / deselect all | 29 | | {{deselect all}} | : | deselect all | 30 | 31 | 32 | ## Transforming 33 | 34 | | | | | 35 | | --- | --- | --- | 36 | | {{action}} | : | grab and slide selected geometry under mouse | 37 | | {{grab}} | : | slide selected loop | 38 | 39 | ## Other 40 | 41 | | | | | 42 | | --- | --- | --- | 43 | | {{delete}} | : | delete/dissolve/collapse selected | 44 | 45 | 46 | ## Span Insertion Modes 47 | 48 | When extruding a strip, you can specify the number of spans to create using two different modes: Brush Size and Fixed. 49 | Switch between span insert modes using the Strokes Options, or hold {{pie menu alt0}} to bring up a the Strokes pie menu. 50 | 51 | If the Span Insert Mode is set to Brush Size, the number of spans will be created to have a size approximately the size of the brush. 52 | This means that a smaller brush will insert more, smaller spans, and a larger brush will insert fewer, larger spans. 53 | 54 | If the Span Insert Mode is set to Fixed, the number of spans will be exactly equal to the number specified by Fixed spans. 55 | 56 | ![](images/help_strokes_modes_options_pie.png max-height:250px) 57 | 58 | 59 | ## Tips 60 | 61 | Creating geometry is dependent on your selection: 62 | 63 | - When nothing is selected, a new edge strip is added 64 | - When an edge strip is selected and stroke is not a loop, the selected edge strip is extruded to the stroke as a span 65 | - When an edge loop is selected and stroke is a loop, the selected edge loop is extruded to the stroke as a loop 66 | 67 | Note: only edges on boundary of target are considered in selection. 68 | 69 | If stroke starts or ends on existing vertex, the Strokes tool will try to bridge the extruded geometry. 70 | -------------------------------------------------------------------------------- /help/table_of_contents.md: -------------------------------------------------------------------------------- 1 | # Table of Contents 2 | 3 | Help Shortcut: {{all help}} 4 | 5 | Below are links to all of the help documents built into RetopoFlow. 6 | 7 | ## General 8 | 9 | The following documents provide help generally across all of RetopoFlow. 10 | 11 | - [Quick Start Guide](quick_start.md) 12 | - [A Welcome to You from Us](welcome.md) 13 | - [RetopoFlow FAQ](faq.md) 14 | - [General Hotkeys and Options](general.md) 15 | 16 | ## Tools 17 | 18 | The following documents provide help for specific RetopoFlow tools. 19 | 20 | - ![Select icon](images/select-icon.png width:24px;height:24px;padding:0px) [Select](select.md) 21 | - ![Contours icon](images/contours-icon.png width:24px;height:24px;padding:0px) [Contours](contours.md) 22 | - ![PolyStrips icon](images/polystrips-icon.png width:24px;height:24px;padding:0px) [PolyStrips](polystrips.md) 23 | - ![Strokes icon](images/strokes-icon.png width:24px;height:24px;padding:0px) [Strokes](strokes.md) 24 | - ![Patches icon](images/patches-icon.png width:24px;height:24px;padding:0px) [Patches](patches.md) 25 | - ![PolyPen icon](images/polypen-icon.png width:24px;height:24px;padding:0px) [PolyPen](polypen.md) 26 | - ![Knife icon](images/knife-icon.png width:24px;height:24px;padding:0px) [Knife](knife.md) 27 | - ![Loops icon](images/loops-icon.png width:24px;height:24px;padding:0px) [Loops](loops.md) 28 | - ![Tweak icon](images/tweak-icon.png width:24px;height:24px;padding:0px) [Tweak](tweak.md) 29 | - ![Relax icon](images/relax-icon.png width:24px;height:24px;padding:0px) [Relax](relax.md) 30 | 31 | ## Additional Information 32 | 33 | The following links provide additional information. 34 | 35 | - [Change list](changelist.md) 36 | - [Warnings Details](warnings.md) 37 | - Blender Market: [RetopoFlow](https://blendermarket.com/products/retopoflow) 38 | - Twitter: [RetopoFlow](https://twitter.com/RetopoFlow), [RetopoFlow Dev](https://twitter.com/RetopoFlow_Dev) 39 | - GitHub: [Issues](https://github.com/CGCookie/retopoflow/issues) 40 | 41 | The following provide additional information about more advanced RetopoFlow features. 42 | 43 | - [Debbuging](debugging.md) 44 | - [Updater System](addon_updater.md) 45 | - [Keymap Editor](keymap_editor.md) 46 | -------------------------------------------------------------------------------- /help/tweak.md: -------------------------------------------------------------------------------- 1 | # ![](images/tweak-icon.png) Tweak Help 2 | 3 | Shortcut: {{tweak tool}} 4 | 5 | Quick Shortcut: {{tweak quick}} 6 | 7 | 8 | The Tweak tool allows you to easily adjust vertex positions with a brush. 9 | 10 | ![](images/help_tweak.png) 11 | 12 | ## Transforming 13 | 14 | | | | | 15 | | --- | --- | --- | 16 | | {{brush}} | : | tweak all vertices within brush | 17 | | {{brush alt}} | : | tweak only selected vertices within brush | 18 | 19 | ## Changing Brush Options 20 | 21 | | | | | 22 | | --- | --- | --- | 23 | | {{brush radius}} | : | adjust brush size | 24 | | {{brush strength}} | : | adjust brush strength | 25 | | {{brush falloff}} | : | adjust brush falloff | 26 | 27 | These options can also be stored as presets in the Brush Options panel. 28 | 29 | To quickly switch between presets, use the {{pie menu alt0}} pie menu. 30 | 31 | ## Masking 32 | 33 | Tweak has several options to control which vertices are or are not moved. 34 | Each option is below, along with setting and description. 35 | 36 | ### Boundary 37 | 38 | | | | | 39 | | --- | --- | --- | 40 | | Exclude | : | Tweak vertices not along boundary | 41 | | Slide | : | Tweak vertices along boundary, but move them by sliding along boundary | 42 | | Include | : | Tweak all vertices within brush, regardless of being along boundary | 43 | 44 | ### Symmetry 45 | 46 | | | | | 47 | | --- | --- | --- | 48 | | Exclude | : | Tweak vertices not along symmetry plane | 49 | | Slide | : | Tweak vertices along symmetry plane, but move them by sliding along symmetry plane | 50 | | Include | : | Tweak all vertices within brush, regardless of being along symmetry plane | 51 | 52 | ### Hidden 53 | 54 | | | | | 55 | | --- | --- | --- | 56 | | Exclude | : | Tweak only visible vertices | 57 | | Include | : | Tweak all vertices within brush, regardless of visibility | 58 | 59 | ### Selected 60 | 61 | | | | | 62 | | --- | --- | --- | 63 | | Exclude | : | Tweak only unselected vertices | 64 | | Only | : | Tweak only selected vertices | 65 | | All | : | Tweak all vertices within brush, regardless of selection | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /hive.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RetopoFlow", 3 | "description": "A suite of retopology tools for Blender through a unified retopology mode", 4 | "author": "Orange Turbine: Jonathan Denning, Jonathan Lampel, Jonathan Williamson, Patrick Moore, Patrick Crawford, Christopher Gearhart, JF Matheu", 5 | "version": "3.4.7", 6 | "release": "official", 7 | "source": "Blender Market", 8 | "blender hard minimum version": "3.5.1", 9 | "blender minimum version": "3.6.0", 10 | "blender maximum version": "", 11 | "product url": "https://blendermarket.com/products/retopoflow", 12 | "documentation url": "https://docs.retopoflow.com", 13 | "issue url": "https://github.com/CGCookie/retopoflow/issues", 14 | "blender location": "View 3D > Header", 15 | "blender category": "3D View" 16 | } -------------------------------------------------------------------------------- /icons/blendermarket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/blendermarket.png -------------------------------------------------------------------------------- /icons/contours-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/contours-icon.png -------------------------------------------------------------------------------- /icons/knife-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/knife-icon.png -------------------------------------------------------------------------------- /icons/loops-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/loops-icon.png -------------------------------------------------------------------------------- /icons/orange-turbine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/orange-turbine.png -------------------------------------------------------------------------------- /icons/patches-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/patches-icon.png -------------------------------------------------------------------------------- /icons/polypen-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/polypen-icon.png -------------------------------------------------------------------------------- /icons/polystrips-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/polystrips-icon.png -------------------------------------------------------------------------------- /icons/relax-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/relax-icon.png -------------------------------------------------------------------------------- /icons/select-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/select-icon.png -------------------------------------------------------------------------------- /icons/strokes-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/strokes-icon.png -------------------------------------------------------------------------------- /icons/tweak-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/icons/tweak-icon.png -------------------------------------------------------------------------------- /matcaps/license.txt: -------------------------------------------------------------------------------- 1 | These matcap images are licensed as CC0 or public domain. 2 | 3 | Thanks to the Blender community for contributing these matcaps. 4 | -------------------------------------------------------------------------------- /matcaps/retopoflow_dark.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/matcaps/retopoflow_dark.exr -------------------------------------------------------------------------------- /matcaps/retopoflow_light.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/matcaps/retopoflow_light.exr -------------------------------------------------------------------------------- /retopoflow/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = [ 23 | 'retopoflow', 24 | ] -------------------------------------------------------------------------------- /retopoflow/html/alert_dialog.html: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 |
5 |
6 | Crash Details 7 |

 8 |             
 9 |         
10 |
11 |
12 |
13 | 14 | 15 |
16 |
-------------------------------------------------------------------------------- /retopoflow/html/delete_dialog.html: -------------------------------------------------------------------------------- 1 | 2 |

Delete / Dissolve / Collapse

3 |
4 |
5 |

Delete

6 |
7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |

Dissolve

16 |
17 | 18 | 19 | 20 | 21 |
22 |
23 |
24 |

Collapse

25 |
26 | 27 |
28 |
29 |
30 |

Merge

31 |
32 | 33 | 34 |
35 |
36 |
37 |
-------------------------------------------------------------------------------- /retopoflow/html/geometry.html: -------------------------------------------------------------------------------- 1 | 2 |

Poly Count

3 |
4 | 5 | 6 |

Poly Count

7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
Verts:
0
Edges:
0
Faces:
0
22 |
23 |
24 | -------------------------------------------------------------------------------- /retopoflow/html/help_dialog.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 |

RetopoFlow Help System

13 |
14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 |
22 |
-------------------------------------------------------------------------------- /retopoflow/html/loading_dialog.html: -------------------------------------------------------------------------------- 1 | 2 |

Loading RetopoFlow...

3 |
Loading...
4 |
5 | -------------------------------------------------------------------------------- /retopoflow/html/main_full.html: -------------------------------------------------------------------------------- 1 | 2 |

RetopoFlow

3 |
4 |
5 |
6 | Documentation 7 |
8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 25 | 26 | 27 |
28 |
-------------------------------------------------------------------------------- /retopoflow/html/main_tiny.html: -------------------------------------------------------------------------------- 1 | 2 |

RF

3 |
4 |
-------------------------------------------------------------------------------- /retopoflow/html/pie_menu.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
-------------------------------------------------------------------------------- /retopoflow/html/quit_dialog.html: -------------------------------------------------------------------------------- 1 | 2 |

Quit RetopoFlow?

3 |
4 |
5 | 6 | 7 |
8 | 12 |
13 |
-------------------------------------------------------------------------------- /retopoflow/html/updater_dialog.html: -------------------------------------------------------------------------------- 1 | 2 |

RetopoFlow Updater System

3 |
4 |
5 |

You can use the RetopoFlow Updater System to download and install a specific version of RetopoFlow.

6 |

Current RetopoFlow Version:

7 |

NOTE: Versions before 3.1.0 do NOT have the RetopoFlow Updater System.

8 | 10 |
11 |

Choose one of the following versions, then click Install

12 |
13 |
14 |
15 | 16 | 17 |
18 |
19 |
20 |
21 |
22 |

RetopoFlow has been successfully updated to version:

23 |

Restart Blender to see the changes.

24 |
25 | 26 |
27 |
28 |
29 |

RetopoFlow failed to update to version:

30 |

Error Message:

31 |
32 | 33 | 34 | 35 |
36 |
37 |
38 |
39 | 40 | 41 |
42 |
-------------------------------------------------------------------------------- /retopoflow/rf/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = [] -------------------------------------------------------------------------------- /retopoflow/rf/rf_grease.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | 23 | class RetopoFlow_Grease: 24 | def setup_grease(self): 25 | self.grease_marks = [] 26 | -------------------------------------------------------------------------------- /retopoflow/rf/rf_instrument.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | import bpy 23 | import json 24 | from queue import Queue 25 | 26 | 27 | from ...config.options import options 28 | 29 | class RetopoFlow_Instrumentation: 30 | instrument_queue = Queue() 31 | instrument_thread = None 32 | 33 | def instrument_write(self, action): 34 | if not options['instrument']: return 35 | 36 | tb_name = options.get_path('instrument_filename') 37 | if tb_name not in bpy.data.texts: bpy.data.texts.new(tb_name) 38 | tb = bpy.data.texts[tb_name] 39 | 40 | target_json = self.rftarget.to_json() 41 | data = {'action': action, 'target': target_json} 42 | data_str = json.dumps(data, separators=[',',':'], indent=0) 43 | self.instrument_queue.put(data_str) 44 | 45 | # write data to end of textblock asynchronously 46 | # TODO: try writing to file (text/binary), because writing to textblock is _very_ slow! :( 47 | def write_out(): 48 | while True: 49 | if self.instrument_queue.empty(): 50 | time.sleep(0.1) 51 | continue 52 | data_str = self.instrument_queue.get() 53 | data_str = data_str.splitlines() 54 | tb.write('') # position cursor to end 55 | for line in data_str: 56 | tb.write(line) 57 | tb.write('\n') 58 | if not self.instrument_thread: 59 | # executor only needed to start the following instrument_thread 60 | executor = ThreadPoolExecutor() 61 | self.instrument_thread = executor.submit(write_out) 62 | -------------------------------------------------------------------------------- /retopoflow/rftool_contours/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = ['contours'] -------------------------------------------------------------------------------- /retopoflow/rftool_contours/contours_options.html: -------------------------------------------------------------------------------- 1 |
2 | Contours 3 |
4 | 8 | 12 |
13 | 16 | 17 |
18 |
19 | 22 | 23 |
24 | 28 |
29 |
30 | -------------------------------------------------------------------------------- /retopoflow/rftool_contours/contours_props.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | import os 23 | import re 24 | import math 25 | from itertools import chain 26 | 27 | import bpy 28 | from mathutils import Matrix 29 | 30 | from ..rftool import RFTool 31 | 32 | from ...addon_common.common.boundvar import BoundBool, BoundInt 33 | from ...addon_common.common.utils import delay_exec 34 | from ...config.options import options 35 | 36 | 37 | class Contours_Props: 38 | @RFTool.on_init 39 | def init_props(self): 40 | self._var_init_count = BoundInt('''options['contours count']''', min_value=3, max_value=500) 41 | self._var_cut_count = BoundInt('''self.var_cut_count''', min_value=3, max_value=500) 42 | self._var_uniform_cut = BoundBool('''options['contours uniform']''') 43 | self._var_nonmanifold = BoundBool('''options['contours non-manifold check']''') 44 | 45 | @property 46 | def var_cut_count(self): 47 | return getattr(self, '_var_cut_count_value', 0) 48 | @var_cut_count.setter 49 | def var_cut_count(self, v): 50 | if self.var_cut_count == v: return 51 | self._var_cut_count_value = v 52 | if self._var_cut_count.disabled: return 53 | self.rfcontext.undo_push('change segment count', repeatable=True) 54 | self.change_count(count=v) 55 | 56 | -------------------------------------------------------------------------------- /retopoflow/rftool_knife/knife_options.html: -------------------------------------------------------------------------------- 1 |
2 | Knife 3 |
4 |
5 |

Automerge

6 |
7 | 11 |
12 | 13 | 14 |
15 |
16 |
17 |
18 |

Knife Options

19 |
20 |
21 | 22 | 23 |
24 |
25 |
26 |
27 |
-------------------------------------------------------------------------------- /retopoflow/rftool_patches/patches_options.html: -------------------------------------------------------------------------------- 1 |
2 | Patches 3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 |
-------------------------------------------------------------------------------- /retopoflow/rftool_polystrips/polystrips_options.html: -------------------------------------------------------------------------------- 1 |
2 | PolyStrips 3 |
4 |
5 | 8 | 9 |
10 |
11 | 14 | 15 |
16 |
17 |
-------------------------------------------------------------------------------- /retopoflow/rftool_polystrips/polystrips_props.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | import os 23 | import re 24 | import math 25 | from itertools import chain 26 | 27 | import bpy 28 | from mathutils import Matrix 29 | 30 | from ..rftool import RFTool 31 | 32 | from ...addon_common.common.boundvar import BoundInt, BoundFloat 33 | from ...addon_common.common.utils import delay_exec 34 | from ...config.options import options 35 | 36 | 37 | class PolyStrips_Props: 38 | @RFTool.on_init 39 | def init_props(self): 40 | self._var_cut_count = BoundInt('''self.var_cut_count''', min_value=2, max_value=500) 41 | self._var_scale_falloff = BoundFloat('''options['polystrips scale falloff']''', min_value=0.25, max_value=4.0) 42 | 43 | @property 44 | def var_cut_count(self): 45 | return getattr(self, '_var_cut_count_value', 0) 46 | @var_cut_count.setter 47 | def var_cut_count(self, v): 48 | if self.var_cut_count == v: return 49 | self._var_cut_count_value = v 50 | if self._var_cut_count.disabled: return 51 | self.rfcontext.undo_push('change segment count', repeatable=True) 52 | self.change_count(count=v) 53 | 54 | -------------------------------------------------------------------------------- /retopoflow/rfwidgets/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = [] -------------------------------------------------------------------------------- /retopoflow/rfwidgets/rfwidget_default.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | import math 23 | import random 24 | from mathutils import Matrix, Vector 25 | 26 | from ..rfwidget import RFWidget 27 | 28 | from ...addon_common.common.fsm import FSM 29 | from ...addon_common.common.globals import Globals 30 | from ...addon_common.common.blender import tag_redraw_all 31 | from ...addon_common.common.maths import Vec, Point, Point2D, Direction, Color 32 | from ...config.options import themes 33 | 34 | 35 | ''' 36 | RFWidget_Default has no callbacks/actions. 37 | This RFWidget is useful for very simple cursor setting. 38 | ''' 39 | 40 | class RFWidget_Default_Factory: 41 | ''' 42 | This is a class factory. It is needed, because the FSM is shared across instances. 43 | RFTools might need to share RFWidgets that are independent of each other. 44 | ''' 45 | 46 | @staticmethod 47 | def create(*, action_name=None, cursor='DEFAULT'): 48 | class RFWidget_Default(RFWidget): 49 | rfw_name = 'Default' 50 | rfw_cursor = cursor 51 | 52 | @RFWidget.on_init 53 | def init(self): 54 | self.action_name = action_name 55 | 56 | @FSM.on_state('main') 57 | def modal_main(self): 58 | pass 59 | 60 | return RFWidget_Default 61 | -------------------------------------------------------------------------------- /retopoflow/rfwidgets/rfwidget_hidden.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | import math 23 | import random 24 | from mathutils import Matrix, Vector 25 | 26 | from ..rfwidget import RFWidget 27 | 28 | from ...addon_common.common.fsm import FSM 29 | from ...addon_common.common.globals import Globals 30 | from ...addon_common.common.blender import tag_redraw_all 31 | from ...addon_common.common.maths import Vec, Point, Point2D, Direction, Color 32 | from ...config.options import themes 33 | 34 | 35 | ''' 36 | RFWidget_Default has no callbacks/actions. 37 | This RFWidget is useful for very simple cursor setting. 38 | ''' 39 | 40 | class RFWidget_Hidden_Factory: 41 | ''' 42 | This is a class factory. It is needed, because the FSM is shared across instances. 43 | RFTools might need to share RFWidgets that are independent of each other. 44 | ''' 45 | 46 | @staticmethod 47 | def create(*, action_name=None, cursor='NONE'): 48 | class RFWidget_Hidden(RFWidget): 49 | rfw_name = 'Hidden' 50 | rfw_cursor = cursor 51 | 52 | @RFWidget.on_init 53 | def init(self): 54 | self.action_name = action_name 55 | 56 | @FSM.on_state('main') 57 | def modal_main(self): 58 | pass 59 | 60 | return RFWidget_Hidden 61 | -------------------------------------------------------------------------------- /scripts/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (C) 2023 CG Cookie 3 | http://cgcookie.com 4 | hello@cgcookie.com 5 | 6 | Created by Jonathan Denning, Jonathan Williamson, and Patrick Moore 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | ''' 21 | 22 | __all__ = [] -------------------------------------------------------------------------------- /scripts/convert_docs_for_web.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import re 5 | import sys 6 | import codecs 7 | 8 | re_keymap = re.compile(r'{{(?P.*?)}}') 9 | re_options = re.compile(r'{\[(?P.*?)\]}') 10 | re_table = re.compile(r'\|(?P
 +)(?P--+)(?P +)\|')
11 | 
12 | def read_file(filename):
13 |     try: return codecs.open(filename, encoding='utf-8').read()
14 |     except: pass
15 |     try: return codecs.open(filename, encoding='utf-16').read()
16 |     except: pass
17 |     return None
18 | 
19 | 
20 | if len(sys.argv) != 2:
21 |     print(f'Usage: {sys.argv[0]} [file.md]')
22 |     sys.exit(1)
23 | 
24 | fn = sys.argv[1]
25 | f = read_file(fn)
26 | 
27 | # convert keymaps {{something foo, bar}}  ==>  , 
28 | nf = []
29 | for l in f.splitlines():
30 |     while True:
31 |         m = re_keymap.search(l)
32 |         if not m: break
33 |         keys = m.group('key').split(',')
34 |         nkeys = []
35 |         for key in keys:
36 |             key = key.strip()
37 |             key = key.replace(' ','_')
38 |             key = f''
39 |             nkeys += [key]
40 |         keys = ', '.join(nkeys)
41 |         l = l[:m.start()] + keys + l[m.end():]
42 |     nf += [l]
43 | f = '\n'.join(nf)
44 | 
45 | # convert options  {[something foo]}  ==>  
46 | nf = []
47 | for l in f.splitlines():
48 |     while True:
49 |         m = re_options.search(l)
50 |         if not m: break
51 |         key = m.group('key')
52 |         key = key.strip()
53 |         key = key.replace(' ', '_')
54 |         key = f''
55 |         l = l[:m.start()] + key + l[m.end():]
56 |     nf += [l]
57 | f = '\n'.join(nf)
58 | 
59 | # convert tables | --- | --- | --- |  ==>  | :--- | :--- | :--- |
60 | nf = []
61 | for l in f.splitlines():
62 |     while True:
63 |         m = re_table.search(l)
64 |         if not m: break
65 |         l = l[:m.start()] + '|' + m.group('pre') + ':' + m.group('dashes') + m.group('post') + '|' + l[m.end():]
66 |     nf += [l]
67 | f = '\n'.join(nf)
68 | 
69 | f = f + '\n\n'
70 | 
71 | # print(type(f))
72 | # print(f)
73 | 
74 | with open(fn, 'w') as fo:
75 |     fo.write(f) #.encode('utf8'))
76 | 


--------------------------------------------------------------------------------
/scripts/create_thumbnails.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/python3
 2 | 
 3 | import os
 4 | import png
 5 | import sys
 6 | import glob
 7 | import shutil
 8 | import subprocess
 9 | 
10 | w,h = 120,120
11 | tempfn = '_temporary.thumb.png'
12 | 
13 | def same_pngs(fnA, fnB):
14 |     wA, hA, dA, mA = png.Reader(filename=fnA).read()
15 |     wB, hB, dB, mB = png.Reader(filename=fnB).read()
16 |     if (wA, hA) != (wB, hB): return False  # different sizes
17 |     for rowA, rowB in zip(dA, dB):
18 |         for colA, colB in zip(rowA, rowB):
19 |             if colA != colB: return False
20 |     # not checking meta data (mA == mB)
21 |     # for example: ignoring the creation timestamp
22 |     return True
23 | 
24 | for fullfn in glob.glob('*.png'):
25 |     if fullfn.endswith('.thumb.png'):
26 |         # do not thumb the thumb files!
27 |         continue
28 |     fullbase, _ = os.path.splitext(fullfn)
29 |     thumbfn = f'{fullbase}.thumb.png'
30 |     subprocess.call(f'convert "{fullfn}" -resize {w}x{h} "{tempfn}"', shell=True)
31 |     if os.path.exists(thumbfn) and same_pngs(tempfn, thumbfn):
32 |         # pixel data did not change
33 |         os.remove(tempfn)
34 |     else:
35 |         shutil.move(tempfn, thumbfn)


--------------------------------------------------------------------------------
/scripts/detect_filename_case_conflicts.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/python3
 2 | 
 3 | import os
 4 | import sys
 5 | import glob
 6 | 
 7 | issue = False
 8 | 
 9 | def check(path):
10 |     global issue
11 |     pwd = os.getcwd()
12 |     os.chdir(path)
13 |     filenames = set(glob.glob('*'))
14 |     lfilenames = {}
15 |     for f in filenames:
16 |         lfilenames.setdefault(f.lower(), [])
17 |         lfilenames[f.lower()].append(f)
18 |     if any(len(v)>1 for k,v in lfilenames.items()):
19 |         issue = True
20 |         print(f'Issues detected in {path}')
21 |         for k,v in lfilenames.items():
22 |             if len(v) == 1: continue
23 |             for f in v: print(f'  {f}')
24 |     for f in filenames:
25 |         if not os.path.isdir(f): continue
26 |         check(os.path.join(path, f))
27 |     os.chdir(pwd)
28 | 
29 | check(os.path.abspath('.'))
30 | 
31 | sys.exit(1 if issue else 0)
32 | 


--------------------------------------------------------------------------------
/scripts/download_b280.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/python3
 2 | 
 3 | import os
 4 | import re
 5 | import glob
 6 | import wget
 7 | import shutil
 8 | import tarfile
 9 | import datetime
10 | 
11 | assert False, 'do not use this anymore'
12 | 
13 | now = datetime.datetime.now()
14 | user = os.path.expanduser('~')
15 | urlroot='https://builder.blender.org'
16 | url='%s/download/' % urlroot
17 | tmp='/tmp/download.html'
18 | blendertar=os.path.join(user, 'software/blender-2.80-%04d%02d%02d.tar.bz2' % (now.year, now.month, now.day))
19 | blenderpath=os.path.join(user, 'software/blender-2.80-%04d%02d%02d' % (now.year, now.month, now.day))
20 | blendersym=os.path.join(user, 'software/blender-2.80')
21 | 
22 | print('finding latest blender 2.80')
23 | tmp=wget.download(url=url, out=tmp, bar=None)
24 | html=open(tmp, 'rt').read()
25 | m = re.search(r'/download/blender-2\.80-[0-9a-f]+-linux-glibc[^-]*?-x86_64\.tar\.bz2', html)
26 | assert m, 'could not find match'
27 | 
28 | url = '%s/%s' % (urlroot, m.group(0))
29 | print('downloading %s' % url)
30 | blendertar=wget.download(url=url, out=blendertar, bar=None)
31 | 
32 | print('extracting from %s' % blendertar)
33 | t = tarfile.open(name=blendertar)
34 | t.extractall(path=blenderpath)
35 | 
36 | innerpath=list(glob.glob(os.path.join(blenderpath,'*')))[0]
37 | print('moving from inner folder (%s) to outer' % innerpath)
38 | for f in glob.glob(os.path.join(innerpath, '*')):
39 |     shutil.move(f, blenderpath)
40 | os.rmdir(innerpath)
41 | 
42 | print('creating new symlink and cleaning up')
43 | os.unlink(blendertar)
44 | os.unlink(blendersym)
45 | os.symlink(blenderpath, blendersym)
46 | 


--------------------------------------------------------------------------------
/scripts/download_b281.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/python3
 2 | 
 3 | import os
 4 | import re
 5 | import glob
 6 | import wget
 7 | import shutil
 8 | import tarfile
 9 | import datetime
10 | 
11 | now = datetime.datetime.now()
12 | user = os.path.expanduser('~')
13 | urlroot='https://builder.blender.org'
14 | url='%s/download/' % urlroot
15 | tmp='/tmp/download.html'
16 | blendertar=os.path.join(user, 'software/blender-2.81-%04d%02d%02d.tar.bz2' % (now.year, now.month, now.day))
17 | blenderpath=os.path.join(user, 'software/blender-2.81-%04d%02d%02d' % (now.year, now.month, now.day))
18 | blendersym=os.path.join(user, 'software/blender-2.81')
19 | 
20 | print('finding latest blender 2.81')
21 | tmp=wget.download(url=url, out=tmp, bar=None)
22 | html=open(tmp, 'rt').read()
23 | m = re.search(r'/download/blender-2\.81-[0-9a-f]+-linux-glibc[^-]*?-x86_64\.tar\.bz2', html)
24 | assert m, 'could not find match'
25 | 
26 | url = '%s/%s' % (urlroot, m.group(0))
27 | print('downloading %s' % url)
28 | blendertar=wget.download(url=url, out=blendertar, bar=None)
29 | 
30 | print('extracting from %s' % blendertar)
31 | t = tarfile.open(name=blendertar)
32 | t.extractall(path=blenderpath)
33 | 
34 | innerpath=list(glob.glob(os.path.join(blenderpath,'*')))[0]
35 | print('moving from inner folder (%s) to outer' % innerpath)
36 | for f in glob.glob(os.path.join(innerpath, '*')):
37 |     shutil.move(f, blenderpath)
38 | os.rmdir(innerpath)
39 | 
40 | print('creating new symlink and cleaning up')
41 | os.unlink(blendertar)
42 | os.unlink(blendersym)
43 | os.symlink(blenderpath, blendersym)
44 | 


--------------------------------------------------------------------------------
/scripts/download_b282.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/python3
 2 | 
 3 | import os
 4 | import re
 5 | import glob
 6 | import wget
 7 | import shutil
 8 | import tarfile
 9 | import datetime
10 | 
11 | now = datetime.datetime.now()
12 | user = os.path.expanduser('~')
13 | urlroot='https://builder.blender.org'
14 | url='%s/download/' % urlroot
15 | tmp='/tmp/download.html'
16 | blendertar=os.path.join(user, 'software/blender-2.82-%04d%02d%02d.tar.bz2' % (now.year, now.month, now.day))
17 | blenderpath=os.path.join(user, 'software/blender-2.82-%04d%02d%02d' % (now.year, now.month, now.day))
18 | blendersym=os.path.join(user, 'software/blender-2.82')
19 | 
20 | print('finding latest blender 2.82')
21 | tmp=wget.download(url=url, out=tmp, bar=None)
22 | html=open(tmp, 'rt').read()
23 | m = re.search(r'/download/blender-2\.82-[0-9a-f]+-linux-glibc[^-]*?-x86_64\.tar\.(bz2|xz)', html)
24 | assert m, 'could not find match'
25 | 
26 | url = '%s/%s' % (urlroot, m.group(0))
27 | print('downloading %s' % url)
28 | blendertar=wget.download(url=url, out=blendertar, bar=None)
29 | 
30 | print('extracting from %s' % blendertar)
31 | t = tarfile.open(name=blendertar)
32 | t.extractall(path=blenderpath)
33 | 
34 | innerpath=list(glob.glob(os.path.join(blenderpath,'*')))[0]
35 | print('moving from inner folder (%s) to outer' % innerpath)
36 | for f in glob.glob(os.path.join(innerpath, '*')):
37 |     shutil.move(f, blenderpath)
38 | os.rmdir(innerpath)
39 | 
40 | print('creating new symlink and cleaning up')
41 | os.unlink(blendertar)
42 | os.unlink(blendersym)
43 | os.symlink(blenderpath, blendersym)
44 | 


--------------------------------------------------------------------------------
/scripts/get_hive_value.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/python3
 2 | 
 3 | import os
 4 | import sys
 5 | import json
 6 | 
 7 | if len(sys.argv) != 2:
 8 |     print(f'Usage: {sys.argv[0]} key')
 9 |     sys.exit(1)
10 | 
11 | hive_path = os.path.join(os.path.dirname(__file__), '..', 'hive.json')
12 | hive = json.load(open(hive_path, 'rt'))
13 | 
14 | print(hive[sys.argv[1]])
15 | 


--------------------------------------------------------------------------------
/scripts/memlimited.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 | 
3 | # runs blender with limited memory (will crash if blender allocates too much)
4 | 
5 | ulimit -Sv 5000000
6 | #shift
7 | ./blender $@


--------------------------------------------------------------------------------
/scripts/modal_event_reporting.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CGCookie/retopoflow/82ed2a97188d903816e296a577b8bbc8bd97c236/scripts/modal_event_reporting.blend


--------------------------------------------------------------------------------