├── .clang-format ├── .github ├── FUNDING.yml └── workflows │ ├── development.yml │ ├── release.yml │ └── update-sponsors.yml ├── .gitignore ├── ACKNOWLEDGEMENTS.html ├── AUTHORS ├── CHANGELOGS ├── CONTRIBUTORS ├── LICENSE ├── README.md ├── SUPPORTERS ├── application ├── application.pro ├── dust3d.icns ├── dust3d.rc ├── favicon.ico ├── resources.qrc ├── resources │ ├── cedar_bridge_irradiance.dds │ ├── cedar_bridge_specular.dds │ ├── dust3d-vertical.png │ ├── dust3d.xcf │ ├── toolbar_add.svg │ ├── toolbar_pointer.svg │ ├── toolbar_radius.svg │ ├── toolbar_radius_disabled.svg │ ├── toolbar_x.svg │ ├── toolbar_x_disabled.svg │ ├── toolbar_y.svg │ ├── toolbar_y_disabled.svg │ ├── toolbar_z.svg │ └── toolbar_z_disabled.svg ├── shaders │ ├── model.frag │ ├── model.vert │ ├── model_core.frag │ ├── model_core.vert │ ├── model_wasm.frag │ ├── model_wasm.vert │ ├── monochrome.frag │ ├── monochrome.vert │ ├── monochrome_core.frag │ ├── monochrome_core.vert │ ├── monochrome_wasm.frag │ └── monochrome_wasm.vert ├── sources │ ├── about_widget.cc │ ├── about_widget.h │ ├── ccd_ik_resolver.cc │ ├── ccd_ik_resolver.h │ ├── component_list_model.cc │ ├── component_list_model.h │ ├── component_preview_grid_widget.cc │ ├── component_preview_grid_widget.h │ ├── component_preview_images_decorator.cc │ ├── component_preview_images_decorator.h │ ├── component_property_widget.cc │ ├── component_property_widget.h │ ├── cut_face_preview.cc │ ├── cut_face_preview.h │ ├── dds_file.cc │ ├── dds_file.h │ ├── debug.cc │ ├── debug.h │ ├── document.cc │ ├── document.h │ ├── document_component.cc │ ├── document_edge.cc │ ├── document_node.cc │ ├── document_part.cc │ ├── document_saver.cc │ ├── document_saver.h │ ├── document_window.cc │ ├── document_window.h │ ├── fbx_file.cc │ ├── fbx_file.h │ ├── float_number_widget.cc │ ├── float_number_widget.h │ ├── flow_layout.cc │ ├── flow_layout.h │ ├── glb_file.cc │ ├── glb_file.h │ ├── graphics_container_widget.cc │ ├── graphics_container_widget.h │ ├── horizontal_line_widget.cc │ ├── horizontal_line_widget.h │ ├── image_forever.cc │ ├── image_forever.h │ ├── image_preview_widget.cc │ ├── image_preview_widget.h │ ├── info_label.cc │ ├── info_label.h │ ├── int_number_widget.cc │ ├── int_number_widget.h │ ├── log_browser.cc │ ├── log_browser.h │ ├── log_browser_dialog.cc │ ├── log_browser_dialog.h │ ├── main.cc │ ├── mesh_generator.cc │ ├── mesh_generator.h │ ├── mesh_preview_images_generator.cc │ ├── mesh_preview_images_generator.h │ ├── model_mesh.cc │ ├── model_mesh.h │ ├── model_offscreen_render.cc │ ├── model_offscreen_render.h │ ├── model_opengl_object.cc │ ├── model_opengl_object.h │ ├── model_opengl_program.cc │ ├── model_opengl_program.h │ ├── model_opengl_vertex.h │ ├── model_widget.cc │ ├── model_widget.h │ ├── monochrome_mesh.cc │ ├── monochrome_mesh.h │ ├── monochrome_opengl_object.cc │ ├── monochrome_opengl_object.h │ ├── monochrome_opengl_program.cc │ ├── monochrome_opengl_program.h │ ├── monochrome_opengl_vertex.h │ ├── part_manage_widget.cc │ ├── part_manage_widget.h │ ├── preferences.cc │ ├── preferences.h │ ├── preview_grid_view.cc │ ├── preview_grid_view.h │ ├── skeleton_graphics_edge_item.cc │ ├── skeleton_graphics_edge_item.h │ ├── skeleton_graphics_node_item.cc │ ├── skeleton_graphics_node_item.h │ ├── skeleton_graphics_origin_item.cc │ ├── skeleton_graphics_origin_item.h │ ├── skeleton_graphics_selection_item.cc │ ├── skeleton_graphics_selection_item.h │ ├── skeleton_graphics_widget.cc │ ├── skeleton_graphics_widget.h │ ├── skeleton_ik_mover.cc │ ├── skeleton_ik_mover.h │ ├── spinnable_toolbar_icon.cc │ ├── spinnable_toolbar_icon.h │ ├── theme.cc │ ├── theme.h │ ├── toolbar_button.cc │ ├── toolbar_button.h │ ├── turnaround_loader.cc │ ├── turnaround_loader.h │ ├── uv_map_generator.cc │ ├── uv_map_generator.h │ └── version.h └── third_party │ ├── QtAwesome │ ├── LICENSE.md │ ├── QtAwesome │ │ ├── QtAwesome.cpp │ │ ├── QtAwesome.h │ │ ├── QtAwesome.pri │ │ ├── QtAwesome.pro │ │ ├── QtAwesome.qrc │ │ ├── QtAwesomeAnim.cpp │ │ ├── QtAwesomeAnim.h │ │ └── fonts │ │ │ └── fontawesome-4.7.0.ttf │ ├── QtAwesomeSample │ │ ├── QtAwesomeSample.pro │ │ └── main.cpp │ └── README.md │ ├── QtWaitingSpinner │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── qtwaitingspinner.pri │ ├── qtwaitingspinner.pro │ ├── waitingspinnerwidget.cpp │ └── waitingspinnerwidget.h │ ├── fbx │ ├── LICENSE │ ├── README.md │ └── src │ │ ├── CMakeLists.txt │ │ ├── fbxdocument.cpp │ │ ├── fbxdocument.h │ │ ├── fbxdump.cpp │ │ ├── fbxnode.cpp │ │ ├── fbxnode.h │ │ ├── fbxproperty.cpp │ │ ├── fbxproperty.h │ │ ├── fbxutil.cpp │ │ ├── fbxutil.h │ │ └── main.cpp │ ├── json │ ├── LICENSE.MIT │ └── json.hpp │ └── miniz │ ├── ChangeLog.md │ ├── LICENSE │ ├── examples │ ├── example1.c │ ├── example2.c │ ├── example3.c │ ├── example4.c │ ├── example5.c │ └── example6.c │ ├── miniz.c │ ├── miniz.h │ └── readme.md ├── ci ├── appimage │ ├── bundle.sh │ ├── dust3d.appdata.xml │ ├── dust3d.desktop │ └── dust3d.png ├── lint.sh └── screenshot.png ├── dust3d ├── base │ ├── axis_aligned_bounding_box.h │ ├── axis_aligned_bounding_box_tree.cc │ ├── axis_aligned_bounding_box_tree.h │ ├── color.h │ ├── combine_mode.cc │ ├── combine_mode.h │ ├── cut_face.cc │ ├── cut_face.h │ ├── debug.h │ ├── ds3_file.cc │ ├── ds3_file.h │ ├── math.h │ ├── matrix4x4.h │ ├── object.h │ ├── part_target.cc │ ├── part_target.h │ ├── position_key.cc │ ├── position_key.h │ ├── quaternion.h │ ├── rectangle.h │ ├── snapshot.h │ ├── snapshot_xml.cc │ ├── snapshot_xml.h │ ├── string.cc │ ├── string.h │ ├── texture_type.cc │ ├── texture_type.h │ ├── uuid.cc │ ├── uuid.h │ ├── vector2.h │ ├── vector3.cc │ └── vector3.h ├── mesh │ ├── base_normal.cc │ ├── base_normal.h │ ├── centripetal_catmull_rom_spline.cc │ ├── centripetal_catmull_rom_spline.h │ ├── hole_stitcher.cc │ ├── hole_stitcher.h │ ├── hole_wrapper.cc │ ├── hole_wrapper.h │ ├── mesh_combiner.cc │ ├── mesh_combiner.h │ ├── mesh_generator.cc │ ├── mesh_generator.h │ ├── mesh_node.h │ ├── mesh_recombiner.cc │ ├── mesh_recombiner.h │ ├── mesh_state.cc │ ├── mesh_state.h │ ├── re_triangulator.cc │ ├── re_triangulator.h │ ├── resolve_triangle_tangent.cc │ ├── resolve_triangle_tangent.h │ ├── rope_mesh.cc │ ├── rope_mesh.h │ ├── section_remesher.cc │ ├── section_remesher.h │ ├── smooth_normal.cc │ ├── smooth_normal.h │ ├── solid_mesh.cc │ ├── solid_mesh.h │ ├── solid_mesh_boolean_operation.cc │ ├── solid_mesh_boolean_operation.h │ ├── stitch_mesh_builder.cc │ ├── stitch_mesh_builder.h │ ├── triangulate.cc │ ├── triangulate.h │ ├── trim_vertices.cc │ ├── trim_vertices.h │ ├── tube_mesh_builder.cc │ └── tube_mesh_builder.h └── uv │ ├── chart_packer.cc │ ├── chart_packer.h │ ├── max_rectangles.cc │ ├── max_rectangles.h │ ├── uv_map_packer.cc │ └── uv_map_packer.h └── third_party ├── GuigueDevillers03 ├── tri_tri_intersect.c └── tri_tri_intersect.h ├── earcut.hpp ├── LICENSE └── include │ └── mapbox │ └── earcut.hpp └── rapidxml-1.13 ├── license.txt ├── manual.html ├── rapidxml.hpp ├── rapidxml_iterators.hpp ├── rapidxml_print.hpp └── rapidxml_utils.hpp /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: huxingyi 2 | -------------------------------------------------------------------------------- /.github/workflows/development.yml: -------------------------------------------------------------------------------- 1 | name: development 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - pipeline 8 | tags: 9 | - '*' 10 | pull_request: 11 | branches: 12 | - '*' 13 | 14 | jobs: 15 | clang-format-check: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Install clang-format 20 | run: | 21 | sudo apt-get update 22 | sudo apt-get install -y clang-format 23 | - name: Run clang-format 24 | run: cd ${GITHUB_WORKSPACE}/ci && sh ./lint.sh && cd ${GITHUB_WORKSPACE} 25 | - name: Check for changes 26 | run: | 27 | if ! git diff --ignore-space-at-eol --exit-code; then 28 | exit 1 29 | fi 30 | linux-build: 31 | runs-on: ubuntu-20.04 32 | steps: 33 | - uses: actions/checkout@v3 34 | - name: Install Qt 35 | run: | 36 | sudo apt-get update 37 | sudo apt-get install -y qt5-default libqt5svg5-dev 38 | - name: Build application 39 | run: | 40 | cd ${GITHUB_WORKSPACE}/application 41 | qmake 42 | make -j`nproc` 43 | win32-msvc-build: 44 | runs-on: windows-2019 45 | steps: 46 | - uses: actions/checkout@v3 47 | - name: Set up Visual Studio shell 48 | uses: egor-tensin/vs-shell@v2 49 | with: 50 | arch: x64 51 | - name: Install Qt 52 | # Generated by https://ddalcino.github.io/aqt-list-server/ 53 | uses: jurplel/install-qt-action@v3 54 | with: 55 | aqtversion: '==2.1.*' 56 | version: '5.15.2' 57 | host: 'windows' 58 | target: 'desktop' 59 | arch: 'win64_msvc2019_64' 60 | archives: 'qttools qtsvg qtimageformats qtbase opengl32sw' 61 | - name: Build application 62 | run: | 63 | cd $env:GITHUB_WORKSPACE/application 64 | qmake -spec win32-msvc 65 | nmake -f Makefile.Release 66 | macos-build: 67 | runs-on: macos-latest 68 | steps: 69 | - uses: actions/checkout@v3 70 | - name: Install Qt 71 | run: | 72 | HOMEBREW_VERBOSE_USING_DOTS=1 brew reinstall --verbose qt@5 73 | HOMEBREW_VERBOSE_USING_DOTS=1 brew link qt@5 --force 74 | export PATH="/usr/local/opt/qt@5/bin:$PATH" 75 | - name: Build application 76 | run: | 77 | cd ${GITHUB_WORKSPACE}/application 78 | qmake 79 | alias nproc="sysctl -n hw.logicalcpu" 80 | make -j`nproc` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node artifact files 2 | node_modules/ 3 | dist/ 4 | 5 | # Compiled Java class files 6 | *.class 7 | 8 | # Compiled Python bytecode 9 | *.py[cod] 10 | 11 | # Log files 12 | *.log 13 | 14 | # Package files 15 | *.jar 16 | 17 | # Maven 18 | target/ 19 | dist/ 20 | 21 | # JetBrains IDE 22 | .idea/ 23 | 24 | # Unit test reports 25 | TEST*.xml 26 | 27 | # Generated by MacOS 28 | .DS_Store 29 | 30 | # Generated by Windows 31 | Thumbs.db 32 | 33 | # Applications 34 | *.app 35 | *.exe 36 | *.war 37 | 38 | # Large media files 39 | *.mp4 40 | *.tiff 41 | *.avi 42 | *.flv 43 | *.mov 44 | *.wmv 45 | 46 | # Build files 47 | *.o 48 | application/.qmake.stash 49 | application/Makefile 50 | application/dust3d 51 | application/moc 52 | application/obj 53 | application/qrc_QtAwesome.cpp 54 | application/qrc_resources.cpp -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Authors ordered by first contribution. 2 | Jeremy HU 3 | Siaržuk Piatroŭski 4 | PowPingDone 5 | anderejd 6 | creepertron95 7 | Karl Robillard 8 | Jete O'Keeffe 9 | Jarred Sumner 10 | Andreas Stallinger 11 | Carl Olson -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # Contributors ordered by first contribution. 2 | Alistair Miles 3 | hdu 4 | Ian Diaz 5 | Skullfurious 6 | Gamefromscratch 7 | RSDuck 8 | xtvjxk123456 9 | Zireael07 10 | glasyalabolas 11 | David Patrick 12 | Abraão Filho 13 | probonopd 14 | John Tsiombikas 15 | Jared Deckard 16 | Brandon Vandegrift 17 | iKlsR 18 | Jimmy Gunawan 19 | mikeruddy 20 | Helspank 21 | Demorde 22 | vanous 23 | justStand 24 | Ruben Niculcea 25 | boynet 26 | fornclake 27 | bvanevery 28 | Toshio Araki 29 | Evan Gruda 30 | KeepFenDou 31 | Kubilay Yalçın 32 | Satish Goda 33 | Sawm Fawk 34 | Erlend Sogge Heggen 35 | Michael Nowak 36 | Nico J. Dolloso 37 | Josh Steinhauer 38 | DeSink 39 | Lewis Lepton 40 | Memo Mind 41 | johhnry 42 | Trevor 43 | Jim Thacker 44 | Sergio Rosa 45 | MrAlexEsisteGia 46 | azagaya 47 | P4prik4 48 | Hugo Locurcio 49 | Christine Garner 50 | askNK 51 | luzpaz -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Dust3D Project 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dust3D 2 | 3 | Dust3D is a cross-platform 3D modeling software that makes it easy to create low poly 3D models for video games, 3D printing, and more. 4 | 5 | ## Getting Started 6 | 7 | These instructions will get you a copy of the Dust3D up and running on your local machine for development and testing purposes. 8 | 9 | ### Prerequisites 10 | 11 | In order to build and run Dust3D, you will need the following software and tools: 12 | 13 | - Qt 14 | - Visual Studio 2019 (Windows only) 15 | - GCC (Linux only) 16 | 17 | #### Windows 18 | 19 | 1. Download and install the `Qt Online Installer` 20 | 2. Run the installer and choose the Qt archives you want to install (required: qtbase, qtsvg) 21 | 3. Install Visual Studio 2019 22 | 23 | #### Linux 24 | 25 | 1. Install Qt using your distribution's package manager (e.g. `apt-get install qt5-default libqt5svg5-dev` on Ubuntu) 26 | 27 | ### Building 28 | 29 | A step by step series of examples that tell you how to get a development environment running 30 | 31 | 1. Clone the repository 32 | ``` 33 | git clone https://github.com/huxingyi/dust3d.git 34 | ``` 35 | 36 | 2. Build using qmake 37 | 38 | #### Windows 39 | 40 | 1. Open the Qt Creator IDE 41 | 2. Select "Open Project" from the File menu 42 | 3. Navigate to the project directory `dust3d/application` and open the `.pro` file 43 | 4. Select the desired build configuration (e.g. Debug or Release) from the dropdown menu at the bottom left of the window 44 | 5. Click the "Run" button to build and run the project 45 | 46 | #### Linux 47 | 48 | 1. Change to the project directory `dust3d/application` 49 | 2. Run `qmake` to generate a Makefile 50 | 3. Build the project using `make` 51 | 52 | ### Releasing 53 | 54 | 1. Make sure all changes are merged to master branch including CHANGELOGS update 55 | 2. Run `git tag 1.0.0-rc.` 56 | 3. Run `git push origin 1.0.0-rc.` 57 | 4. Wait Actions/release finish and download all the Artifacts 58 | 5. Goto `Tags/1.0.0-rc.` and create release from tag 59 | 6. Title the release as `1.0.0-rc.` 60 | 7. Copy description from CHANGELOGS 61 | 8. Drag the Artifacts: `dust3d-1.0.0-rc..zip`, `dust3d-1.0.0-rc..AppImage (Extracted)`, `dust3d-1.0.0-rc..dmg (Extracted)` to binaries. 62 | 9. Publish release 63 | 64 | ## License 65 | 66 | Dust3D is licensed under the MIT License - see the [LICENSE](https://github.com/huxingyi/dust3d/blob/master/LICENSE) file for details. 67 | 68 | -------------------------------------------------------------------------------- /SUPPORTERS: -------------------------------------------------------------------------------- 1 | # Supporters ordered by first donation. 2 | Igor Costa de Faria 3 | Robert Larnach 4 | Erlend Sogge Heggen 5 | Shinji Ogaki 6 | Lewis Lepton 7 | Hugo Locurcio 8 | Roberto Calderon 9 | ytetsu 10 | Troy Bonneau 11 | Ghee36 12 | mangosteen-tree 13 | Andrias Kutsar 14 | Andrea Faulds 15 | Marcus Hilsdorf 16 | Nick Friess 17 | Christine Garner 18 | wavetro 19 | Morgan Hoarau 20 | Erik Smith 21 | Jairo 22 | Frank O'Hara -------------------------------------------------------------------------------- /application/dust3d.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/application/dust3d.icns -------------------------------------------------------------------------------- /application/dust3d.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "favicon.ico" -------------------------------------------------------------------------------- /application/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/application/favicon.ico -------------------------------------------------------------------------------- /application/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | ../ACKNOWLEDGEMENTS.html 4 | ../AUTHORS 5 | ../CONTRIBUTORS 6 | ../SUPPORTERS 7 | shaders/model.vert 8 | shaders/model.frag 9 | shaders/model_core.vert 10 | shaders/model_core.frag 11 | shaders/model_wasm.vert 12 | shaders/model_wasm.frag 13 | shaders/monochrome.vert 14 | shaders/monochrome.frag 15 | shaders/monochrome_core.vert 16 | shaders/monochrome_core.frag 17 | shaders/monochrome_wasm.vert 18 | shaders/monochrome_wasm.frag 19 | resources/cedar_bridge_irradiance.dds 20 | resources/cedar_bridge_specular.dds 21 | resources/dust3d-vertical.png 22 | resources/toolbar_add.svg 23 | resources/toolbar_pointer.svg 24 | resources/toolbar_x.svg 25 | resources/toolbar_x_disabled.svg 26 | resources/toolbar_y.svg 27 | resources/toolbar_y_disabled.svg 28 | resources/toolbar_z.svg 29 | resources/toolbar_z_disabled.svg 30 | resources/toolbar_radius.svg 31 | resources/toolbar_radius_disabled.svg 32 | 33 | 34 | -------------------------------------------------------------------------------- /application/resources/cedar_bridge_irradiance.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/application/resources/cedar_bridge_irradiance.dds -------------------------------------------------------------------------------- /application/resources/cedar_bridge_specular.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/application/resources/cedar_bridge_specular.dds -------------------------------------------------------------------------------- /application/resources/dust3d-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/application/resources/dust3d-vertical.png -------------------------------------------------------------------------------- /application/resources/dust3d.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/application/resources/dust3d.xcf -------------------------------------------------------------------------------- /application/resources/toolbar_add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 54 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /application/resources/toolbar_pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /application/resources/toolbar_radius.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 51 | 58 | 65 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /application/resources/toolbar_radius_disabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 51 | 58 | 65 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /application/resources/toolbar_x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 52 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /application/resources/toolbar_x_disabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 52 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /application/resources/toolbar_y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 52 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /application/resources/toolbar_y_disabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 52 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /application/resources/toolbar_z.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 52 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /application/resources/toolbar_z_disabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 37 | 40 | 41 | 43 | 47 | 52 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /application/shaders/model.vert: -------------------------------------------------------------------------------- 1 | #version 110 2 | attribute vec4 vertex; 3 | attribute vec3 normal; 4 | attribute vec3 color; 5 | attribute vec2 texCoord; 6 | attribute float metalness; 7 | attribute float roughness; 8 | attribute vec3 tangent; 9 | attribute float alpha; 10 | uniform mat4 modelMatrix; 11 | uniform mat3 normalMatrix; 12 | uniform mat4 viewMatrix; 13 | uniform mat4 projectionMatrix; 14 | uniform int normalMapEnabled; 15 | varying vec3 pointPosition; 16 | varying vec3 pointNormal; 17 | varying vec3 pointColor; 18 | varying vec2 pointTexCoord; 19 | varying float pointAlpha; 20 | varying float pointMetalness; 21 | varying float pointRoughness; 22 | varying mat3 pointTBN; 23 | 24 | mat3 transpose(mat3 m) 25 | { 26 | return mat3(m[0][0], m[1][0], m[2][0], 27 | m[0][1], m[1][1], m[2][1], 28 | m[0][2], m[1][2], m[2][2]); 29 | } 30 | 31 | void main() 32 | { 33 | pointPosition = (modelMatrix * vertex).xyz; 34 | pointNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz); 35 | pointColor = color; 36 | pointTexCoord = texCoord; 37 | pointAlpha = alpha; 38 | pointMetalness = metalness; 39 | pointRoughness = roughness; 40 | 41 | gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0); 42 | 43 | if (1 == normalMapEnabled) { 44 | vec3 T = normalize(normalMatrix * tangent); 45 | vec3 N = normalize(normalMatrix * normal); 46 | T = normalize(T - dot(T, N) * N); 47 | vec3 B = cross(N, T); 48 | pointTBN = mat3(T, B, N); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /application/shaders/model_core.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | uniform samplerCube environmentIrradianceMapId; 3 | uniform samplerCube environmentSpecularMapId; 4 | uniform sampler2D textureId; 5 | uniform int textureEnabled; 6 | uniform sampler2D normalMapId; 7 | uniform int normalMapEnabled; 8 | uniform sampler2D metalnessRoughnessAoMapId; 9 | uniform int metalnessMapEnabled; 10 | uniform int roughnessMapEnabled; 11 | uniform int aoMapEnabled; 12 | uniform vec3 eyePosition; 13 | in vec3 pointPosition; 14 | in vec3 pointNormal; 15 | in vec3 pointColor; 16 | in vec2 pointTexCoord; 17 | in float pointAlpha; 18 | in float pointMetalness; 19 | in float pointRoughness; 20 | in mat3 pointTBN; 21 | out vec4 fragColor; 22 | 23 | const float PI = 3.1415926; 24 | 25 | vec3 fresnelSchlickRoughness(float NoV, vec3 f0, float roughness) 26 | { 27 | return f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(clamp(1.0 - NoV, 0.0, 1.0), 5.0); 28 | } 29 | 30 | void main() 31 | { 32 | vec3 color = pointColor; 33 | float alpha = pointAlpha; 34 | if (1 == textureEnabled) { 35 | vec4 textColor = texture(textureId, pointTexCoord); 36 | color = textColor.rgb; 37 | alpha = textColor.a; 38 | } 39 | vec3 normal = pointNormal; 40 | if (1 == normalMapEnabled) { 41 | normal = texture(normalMapId, pointTexCoord).rgb; 42 | normal = pointTBN * normalize(normal * 2.0 - 1.0); 43 | } 44 | float metalness = pointMetalness; 45 | if (1 == metalnessMapEnabled) { 46 | metalness = texture(metalnessRoughnessAoMapId, pointTexCoord).b; 47 | } 48 | float roughness = pointRoughness; 49 | if (1 == roughnessMapEnabled) { 50 | roughness = texture(metalnessRoughnessAoMapId, pointTexCoord).g; 51 | } 52 | float ambientOcclusion = 1.0; 53 | if (1 == aoMapEnabled) { 54 | ambientOcclusion = texture(metalnessRoughnessAoMapId, pointTexCoord).r; 55 | } 56 | 57 | vec3 n = normal; 58 | vec3 v = normalize(eyePosition - pointPosition); 59 | vec3 r = reflect(-v, n); 60 | 61 | float NoV = abs(dot(n, v)) + 1e-5; 62 | 63 | vec3 irradiance = texture(environmentIrradianceMapId, r).rgb; 64 | vec3 diffuse = irradiance * (1.0 - metalness) * color; 65 | 66 | vec3 f0 = mix(vec3(0.04), color, metalness); 67 | vec3 fresnelFactor = fresnelSchlickRoughness(NoV, f0, roughness); 68 | vec3 specular = fresnelFactor * texture(environmentSpecularMapId, r, 0.0).rgb; 69 | 70 | color = (diffuse + specular) * ambientOcclusion; 71 | 72 | color = color / (color + vec3(1.0)); 73 | color = pow(color, vec3(1.0/2.2)); 74 | 75 | fragColor = vec4(color, alpha); 76 | } -------------------------------------------------------------------------------- /application/shaders/model_core.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout(location = 0) in vec4 vertex; 3 | layout(location = 1) in vec3 normal; 4 | layout(location = 2) in vec3 color; 5 | layout(location = 3) in vec2 texCoord; 6 | layout(location = 4) in float metalness; 7 | layout(location = 5) in float roughness; 8 | layout(location = 6) in vec3 tangent; 9 | layout(location = 7) in float alpha; 10 | uniform mat4 modelMatrix; 11 | uniform mat3 normalMatrix; 12 | uniform mat4 viewMatrix; 13 | uniform mat4 projectionMatrix; 14 | uniform int normalMapEnabled; 15 | out vec3 pointPosition; 16 | out vec3 pointNormal; 17 | out vec3 pointColor; 18 | out vec2 pointTexCoord; 19 | out float pointAlpha; 20 | out float pointMetalness; 21 | out float pointRoughness; 22 | out mat3 pointTBN; 23 | 24 | mat3 transpose(mat3 m) 25 | { 26 | return mat3(m[0][0], m[1][0], m[2][0], 27 | m[0][1], m[1][1], m[2][1], 28 | m[0][2], m[1][2], m[2][2]); 29 | } 30 | 31 | void main() 32 | { 33 | pointPosition = (modelMatrix * vertex).xyz; 34 | pointNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz); 35 | pointColor = color; 36 | pointTexCoord = texCoord; 37 | pointAlpha = alpha; 38 | pointMetalness = metalness; 39 | pointRoughness = roughness; 40 | 41 | gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0); 42 | 43 | if (1 == normalMapEnabled) { 44 | vec3 T = normalize(normalMatrix * tangent); 45 | vec3 N = normalize(normalMatrix * normal); 46 | T = normalize(T - dot(T, N) * N); 47 | vec3 B = cross(N, T); 48 | pointTBN = mat3(T, B, N); 49 | } 50 | } -------------------------------------------------------------------------------- /application/shaders/model_wasm.vert: -------------------------------------------------------------------------------- 1 | attribute vec4 vertex; 2 | attribute vec3 normal; 3 | attribute vec3 color; 4 | attribute vec2 texCoord; 5 | attribute float metalness; 6 | attribute float roughness; 7 | attribute vec3 tangent; 8 | attribute float alpha; 9 | uniform mat4 modelMatrix; 10 | uniform mat3 normalMatrix; 11 | uniform mat4 viewMatrix; 12 | uniform mat4 projectionMatrix; 13 | uniform int normalMapEnabled; 14 | varying vec3 pointPosition; 15 | varying vec3 pointNormal; 16 | varying vec3 pointColor; 17 | varying vec2 pointTexCoord; 18 | varying float pointAlpha; 19 | varying float pointMetalness; 20 | varying float pointRoughness; 21 | varying mat3 pointTBN; 22 | 23 | mat3 transpose(mat3 m) 24 | { 25 | return mat3(m[0][0], m[1][0], m[2][0], 26 | m[0][1], m[1][1], m[2][1], 27 | m[0][2], m[1][2], m[2][2]); 28 | } 29 | 30 | void main() 31 | { 32 | pointPosition = (modelMatrix * vertex).xyz; 33 | pointNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz); 34 | pointColor = color; 35 | pointTexCoord = texCoord; 36 | pointAlpha = alpha; 37 | pointMetalness = metalness; 38 | pointRoughness = roughness; 39 | 40 | gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0); 41 | 42 | if (1 == normalMapEnabled) { 43 | vec3 T = normalize(normalMatrix * tangent); 44 | vec3 N = normalize(normalMatrix * normal); 45 | T = normalize(T - dot(T, N) * N); 46 | vec3 B = cross(N, T); 47 | pointTBN = mat3(T, B, N); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /application/shaders/monochrome.frag: -------------------------------------------------------------------------------- 1 | #version 110 2 | varying vec3 pointPosition; 3 | varying vec3 pointColor; 4 | varying float pointAlpha; 5 | 6 | void main() 7 | { 8 | gl_FragColor = vec4(pointColor, pointAlpha); 9 | } 10 | -------------------------------------------------------------------------------- /application/shaders/monochrome.vert: -------------------------------------------------------------------------------- 1 | #version 110 2 | attribute vec4 vertex; 3 | attribute vec3 color; 4 | attribute float alpha; 5 | uniform mat4 modelMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 projectionMatrix; 8 | varying vec3 pointPosition; 9 | varying vec3 pointColor; 10 | varying float pointAlpha; 11 | 12 | void main() 13 | { 14 | pointPosition = (modelMatrix * vertex).xyz; 15 | pointColor = color; 16 | pointAlpha = alpha; 17 | 18 | gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0); 19 | } 20 | -------------------------------------------------------------------------------- /application/shaders/monochrome_core.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | in vec3 pointColor; 3 | in float pointAlpha; 4 | out vec4 fragColor; 5 | void main() 6 | { 7 | fragColor = vec4(pointColor, pointAlpha); 8 | } -------------------------------------------------------------------------------- /application/shaders/monochrome_core.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | layout(location = 0) in vec4 vertex; 3 | layout(location = 1) in vec3 color; 4 | layout(location = 2) in float alpha; 5 | uniform mat4 modelMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 projectionMatrix; 8 | out vec3 pointPosition; 9 | out vec3 pointColor; 10 | out float pointAlpha; 11 | 12 | void main() 13 | { 14 | pointPosition = (modelMatrix * vertex).xyz; 15 | pointColor = color; 16 | pointAlpha = alpha; 17 | 18 | gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0); 19 | } -------------------------------------------------------------------------------- /application/shaders/monochrome_wasm.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | varying vec3 pointPosition; 4 | varying vec3 pointColor; 5 | varying float pointAlpha; 6 | 7 | void main() 8 | { 9 | gl_FragColor = vec4(pointColor, pointAlpha); 10 | } 11 | -------------------------------------------------------------------------------- /application/shaders/monochrome_wasm.vert: -------------------------------------------------------------------------------- 1 | attribute vec4 vertex; 2 | attribute vec3 color; 3 | attribute float alpha; 4 | uniform mat4 modelMatrix; 5 | uniform mat4 viewMatrix; 6 | uniform mat4 projectionMatrix; 7 | varying vec3 pointPosition; 8 | varying vec3 pointColor; 9 | varying float pointAlpha; 10 | 11 | void main() 12 | { 13 | pointPosition = (modelMatrix * vertex).xyz; 14 | pointColor = color; 15 | pointAlpha = alpha; 16 | 17 | gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0); 18 | } 19 | -------------------------------------------------------------------------------- /application/sources/about_widget.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "about_widget.h" 6 | #include "model_widget.h" 7 | #include "version.h" 8 | 9 | AboutWidget::AboutWidget() 10 | { 11 | QTextEdit* versionInfoLabel = new QTextEdit; 12 | versionInfoLabel->setText(QString("%1 %2 (version: %3 build: %4 %5)\nopengl: %6 shader: %7 core: %8").arg(APP_NAME).arg(APP_HUMAN_VER).arg(APP_VER).arg(__DATE__).arg(__TIME__).arg(ModelWidget::m_openGLVersion).arg(ModelWidget::m_openGLShadingLanguageVersion).arg(ModelWidget::m_openGLIsCoreProfile ? "true" : "false")); 13 | versionInfoLabel->setReadOnly(true); 14 | 15 | QVBoxLayout* mainLayout = new QVBoxLayout; 16 | mainLayout->addWidget(versionInfoLabel); 17 | 18 | setLayout(mainLayout); 19 | setFixedSize(QSize(350, 100)); 20 | 21 | setWindowTitle(applicationTitle(tr("About"))); 22 | } 23 | -------------------------------------------------------------------------------- /application/sources/about_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_ABOUT_WIDGET_H_ 2 | #define DUST3D_APPLICATION_ABOUT_WIDGET_H_ 3 | 4 | #include 5 | 6 | class AboutWidget : public QDialog { 7 | Q_OBJECT 8 | public: 9 | AboutWidget(); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /application/sources/ccd_ik_resolver.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_CCD_IK_SOLVER_H_ 2 | #define DUST3D_APPLICATION_CCD_IK_SOLVER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | struct CcdIkNode { 9 | QVector3D position; 10 | QVector3D axis; 11 | double minLimitDegrees; 12 | double maxLimitDegrees; 13 | }; 14 | 15 | class CcdIkSolver { 16 | public: 17 | CcdIkSolver(); 18 | void setMaxRound(int maxRound); 19 | void setDistanceThreshod(float threshold); 20 | int addNodeInOrder(const QVector3D& position); 21 | void solveTo(const QVector3D& position); 22 | const QVector3D& getNodeSolvedPosition(int index); 23 | int getNodeCount(); 24 | void setNodeHingeConstraint(int nodeIndex, 25 | const QVector3D& axis, double minLimitDegrees, double maxLimitDegrees); 26 | void setSolveFrom(int fromNodeIndex); 27 | 28 | private: 29 | float angleInRangle360BetweenTwoVectors(QVector3D a, QVector3D b, QVector3D planeNormal); 30 | void iterate(); 31 | 32 | std::vector m_nodes; 33 | QVector3D m_destination; 34 | int m_maxRound = 4; 35 | float m_distanceThreshold2 = 0.001 * 0.001; 36 | float m_distanceCeaseThreshold2 = 0.001 * 0.001; 37 | int m_fromNodeIndex = 0; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /application/sources/component_list_model.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_COMPONENT_LIST_MODEL_H_ 2 | #define DUST3D_APPLICATION_COMPONENT_LIST_MODEL_H_ 3 | 4 | #include "document.h" 5 | #include 6 | #include 7 | #include 8 | 9 | class ComponentListModel : public QAbstractListModel { 10 | Q_OBJECT 11 | signals: 12 | void listingComponentChanged(const dust3d::Uuid& componentId); 13 | 14 | public: 15 | ComponentListModel(const Document* document, QObject* parent = nullptr); 16 | int rowCount(const QModelIndex& parent = QModelIndex()) const; 17 | int columnCount(const QModelIndex& parent = QModelIndex()) const; 18 | QVariant data(const QModelIndex& index, int role) const; 19 | const Document::Component* modelIndexToComponent(const QModelIndex& index) const; 20 | QModelIndex componentIdToIndex(const dust3d::Uuid& componentId) const; 21 | const dust3d::Uuid modelIndexToComponentId(const QModelIndex& index) const; 22 | const dust3d::Uuid listingComponentId() const; 23 | public slots: 24 | void setListingComponentId(const dust3d::Uuid& componentId); 25 | void reload(); 26 | 27 | private: 28 | const Document* m_document = nullptr; 29 | dust3d::Uuid m_listingComponentId; 30 | std::unordered_map m_componentIdToIndexMap; 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /application/sources/component_preview_grid_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_COMPONENT_PREVIEW_GRID_WIDGET_H_ 2 | #define DUST3D_APPLICATION_COMPONENT_PREVIEW_GRID_WIDGET_H_ 3 | 4 | #include "component_list_model.h" 5 | #include "document.h" 6 | #include "preview_grid_view.h" 7 | #include 8 | #include 9 | #include 10 | 11 | class ComponentPreviewGridWidget : public PreviewGridView { 12 | Q_OBJECT 13 | signals: 14 | void unselectAllOnCanvas(); 15 | void selectPartOnCanvas(const dust3d::Uuid& partId); 16 | 17 | public: 18 | ComponentPreviewGridWidget(Document* document, QWidget* parent = nullptr); 19 | ComponentListModel* componentListModel(); 20 | std::vector getSelectedComponents() const; 21 | std::vector getSelectedComponentIds() const; 22 | std::vector getSelectedPartIds() const; 23 | 24 | private: 25 | std::unique_ptr m_componentListModel; 26 | Document* m_document = nullptr; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /application/sources/component_preview_images_decorator.cc: -------------------------------------------------------------------------------- 1 | #include "component_preview_images_decorator.h" 2 | #include "theme.h" 3 | #include 4 | #include 5 | #include 6 | 7 | ComponentPreviewImagesDecorator::ComponentPreviewImagesDecorator(std::unique_ptr> previewInputs) 8 | { 9 | m_previewInputs = std::move(previewInputs); 10 | } 11 | 12 | std::unique_ptr>> ComponentPreviewImagesDecorator::takeResultImages() 13 | { 14 | return std::move(m_resultImages); 15 | } 16 | 17 | void ComponentPreviewImagesDecorator::decorate() 18 | { 19 | if (nullptr == m_previewInputs) 20 | return; 21 | 22 | m_resultImages = std::make_unique>>(); 23 | 24 | QPointF iconOffset(Theme::previewIconMargin, 0); 25 | for (auto& it : *m_previewInputs) { 26 | if (it.isDirectory) { 27 | QPainter painter(it.image.get()); 28 | painter.setRenderHints(QPainter::Antialiasing); 29 | QPolygonF polygon; 30 | polygon << iconOffset + QPointF(it.image->width() / 4, 0) << iconOffset + QPointF(it.image->width() / 2, 0); 31 | polygon << iconOffset + QPointF(0.0, it.image->height() / 2) << iconOffset + QPointF(0.0, it.image->height() / 4); 32 | QPainterPath painterPath; 33 | painterPath.addPolygon(polygon); 34 | painter.setBrush(Theme::green); 35 | painter.setPen(Qt::NoPen); 36 | painter.drawPath(painterPath); 37 | } 38 | m_resultImages->emplace(it.id, std::move(it.image)); 39 | } 40 | } 41 | 42 | void ComponentPreviewImagesDecorator::process() 43 | { 44 | decorate(); 45 | emit finished(); 46 | } 47 | -------------------------------------------------------------------------------- /application/sources/component_preview_images_decorator.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_COMPONENT_PREVIEW_IMAGES_DECORATOR_H_ 2 | #define DUST3D_APPLICATION_COMPONENT_PREVIEW_IMAGES_DECORATOR_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class ComponentPreviewImagesDecorator : public QObject { 11 | Q_OBJECT 12 | public: 13 | struct PreviewInput { 14 | dust3d::Uuid id; 15 | std::unique_ptr image; 16 | bool isDirectory = false; 17 | }; 18 | 19 | ComponentPreviewImagesDecorator(std::unique_ptr> previewInputs); 20 | std::unique_ptr>> takeResultImages(); 21 | signals: 22 | void finished(); 23 | public slots: 24 | void process(); 25 | 26 | private: 27 | std::unique_ptr> m_previewInputs; 28 | std::unique_ptr>> m_resultImages; 29 | void decorate(); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /application/sources/cut_face_preview.cc: -------------------------------------------------------------------------------- 1 | #include "cut_face_preview.h" 2 | #include "theme.h" 3 | #include 4 | #include 5 | 6 | static std::map g_standardCutFaceMap; 7 | 8 | QImage* buildCutFaceTemplatePreviewImage(const std::vector& cutTemplate) 9 | { 10 | QImage* image = new QImage(Theme::partPreviewImageSize, Theme::partPreviewImageSize, QImage::Format_ARGB32); 11 | image->fill(Qt::transparent); 12 | 13 | if (cutTemplate.empty()) 14 | return image; 15 | 16 | QPainter painter; 17 | painter.begin(image); 18 | painter.setRenderHint(QPainter::Antialiasing); 19 | #if QT_VERSION < 0x060000 20 | painter.setRenderHint(QPainter::HighQualityAntialiasing); 21 | #endif 22 | 23 | QPen pen(Theme::red, 2); 24 | painter.setPen(pen); 25 | 26 | QBrush brush; 27 | brush.setColor(Theme::white); 28 | brush.setStyle(Qt::SolidPattern); 29 | 30 | painter.setBrush(brush); 31 | 32 | const float scale = 0.7f; 33 | QPolygon polygon; 34 | for (size_t i = 0; i <= cutTemplate.size(); ++i) { 35 | const auto& it = cutTemplate[i % cutTemplate.size()]; 36 | polygon.append(QPoint((it.x() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize, 37 | (it.y() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize)); 38 | } 39 | 40 | QPainterPath path; 41 | path.addPolygon(polygon); 42 | painter.fillPath(path, brush); 43 | painter.drawPath(path); 44 | 45 | painter.end(); 46 | 47 | return image; 48 | } 49 | 50 | const QImage* cutFacePreviewImage(dust3d::CutFace cutFace) 51 | { 52 | auto findItem = g_standardCutFaceMap.find((int)cutFace); 53 | if (findItem != g_standardCutFaceMap.end()) 54 | return findItem->second; 55 | std::vector cutTemplate = dust3d::CutFaceToPoints(cutFace); 56 | QImage* image = buildCutFaceTemplatePreviewImage(cutTemplate); 57 | g_standardCutFaceMap.insert({ (int)cutFace, image }); 58 | return image; 59 | } 60 | -------------------------------------------------------------------------------- /application/sources/cut_face_preview.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_CUT_FACE_PREVIEW_H_ 2 | #define DUST3D_APPLICATION_CUT_FACE_PREVIEW_H_ 3 | 4 | #include 5 | #include 6 | 7 | QImage* buildCutFaceTemplatePreviewImage(const std::vector& cutTemplate); 8 | const QImage* cutFacePreviewImage(dust3d::CutFace cutFace); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /application/sources/dds_file.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_DDS_FILE_H_ 2 | #define DUST3D_APPLICATION_DDS_FILE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class DdsFileReader { 9 | public: 10 | DdsFileReader(const QString& filename); 11 | QOpenGLTexture* createOpenGLTexture(); 12 | std::unique_ptr>> createOpenGLTextures(); 13 | 14 | private: 15 | QString m_filename; 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /application/sources/debug.cc: -------------------------------------------------------------------------------- 1 | #include "debug.h" 2 | 3 | QDebug operator<<(QDebug debug, const dust3d::Uuid& uuid) 4 | { 5 | QDebugStateSaver stateSaver(debug); 6 | debug.nospace() << uuid.toString().c_str(); 7 | return debug; 8 | } 9 | 10 | QDebug operator<<(QDebug debug, const std::string& string) 11 | { 12 | QDebugStateSaver stateSaver(debug); 13 | debug.nospace() << string.c_str(); 14 | return debug; 15 | } 16 | -------------------------------------------------------------------------------- /application/sources/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_DEBUG_H_ 2 | #define DUST3D_APPLICATION_DEBUG_H_ 3 | 4 | #include 5 | #include 6 | 7 | QDebug operator<<(QDebug debug, const dust3d::Uuid& uuid); 8 | QDebug operator<<(QDebug debug, const std::string& string); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /application/sources/document_edge.cc: -------------------------------------------------------------------------------- 1 | #include "document.h" 2 | 3 | Document::Edge::Edge(const dust3d::Uuid& withId) 4 | { 5 | id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; 6 | } 7 | 8 | dust3d::Uuid Document::Edge::neighborOf(dust3d::Uuid nodeId) const 9 | { 10 | if (nodeIds.size() != 2) 11 | return dust3d::Uuid(); 12 | return nodeIds[0] == nodeId ? nodeIds[1] : nodeIds[0]; 13 | } 14 | -------------------------------------------------------------------------------- /application/sources/document_node.cc: -------------------------------------------------------------------------------- 1 | #include "document.h" 2 | #include "mesh_generator.h" 3 | 4 | Document::Node::Node(const dust3d::Uuid& withId) 5 | { 6 | id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; 7 | } 8 | 9 | void Document::Node::setRadius(float toRadius) 10 | { 11 | if (toRadius < MeshGenerator::m_minimalRadius) 12 | toRadius = MeshGenerator::m_minimalRadius; 13 | else if (toRadius > 1) 14 | toRadius = 1; 15 | radius = toRadius; 16 | } 17 | 18 | void Document::Node::setCutRotation(float toRotation) 19 | { 20 | if (toRotation < -1) 21 | toRotation = -1; 22 | else if (toRotation > 1) 23 | toRotation = 1; 24 | cutRotation = toRotation; 25 | hasCutFaceSettings = true; 26 | } 27 | 28 | void Document::Node::setCutFace(dust3d::CutFace face) 29 | { 30 | cutFace = face; 31 | cutFaceLinkedId = dust3d::Uuid(); 32 | hasCutFaceSettings = true; 33 | } 34 | 35 | void Document::Node::setCutFaceLinkedId(const dust3d::Uuid& linkedId) 36 | { 37 | if (linkedId.isNull()) { 38 | clearCutFaceSettings(); 39 | return; 40 | } 41 | cutFace = dust3d::CutFace::UserDefined; 42 | cutFaceLinkedId = linkedId; 43 | hasCutFaceSettings = true; 44 | } 45 | 46 | void Document::Node::clearCutFaceSettings() 47 | { 48 | cutFace = dust3d::CutFace::Quad; 49 | cutFaceLinkedId = dust3d::Uuid(); 50 | cutRotation = 0; 51 | hasCutFaceSettings = false; 52 | } 53 | 54 | float Document::Node::getX(bool rotated) const 55 | { 56 | if (rotated) 57 | return m_y; 58 | return m_x; 59 | } 60 | 61 | float Document::Node::getY(bool rotated) const 62 | { 63 | if (rotated) 64 | return m_x; 65 | return m_y; 66 | } 67 | 68 | float Document::Node::getZ(bool rotated) const 69 | { 70 | (void)rotated; 71 | return m_z; 72 | } 73 | 74 | void Document::Node::setX(float x) 75 | { 76 | m_x = x; 77 | } 78 | 79 | void Document::Node::setY(float y) 80 | { 81 | m_y = y; 82 | } 83 | 84 | void Document::Node::setZ(float z) 85 | { 86 | m_z = z; 87 | } 88 | 89 | void Document::Node::addX(float x) 90 | { 91 | m_x += x; 92 | } 93 | 94 | void Document::Node::addY(float y) 95 | { 96 | m_y += y; 97 | } 98 | 99 | void Document::Node::addZ(float z) 100 | { 101 | m_z += z; 102 | } 103 | -------------------------------------------------------------------------------- /application/sources/document_saver.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_DOCUMENT_SAVER_H_ 2 | #define DUST3D_APPLICATION_DOCUMENT_SAVER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | class DocumentSaver : public QObject { 14 | Q_OBJECT 15 | public: 16 | DocumentSaver(const QString* filename, 17 | dust3d::Snapshot* snapshot, 18 | QByteArray* turnaroundPngByteArray); 19 | ~DocumentSaver(); 20 | static bool save(const QString* filename, 21 | dust3d::Snapshot* snapshot, 22 | const QByteArray* turnaroundPngByteArray); 23 | static bool save(QByteArray& byteArray, 24 | dust3d::Snapshot* snapshot, 25 | const QByteArray* turnaroundPngByteArray); 26 | static bool save(dust3d::Ds3FileWriter& ds3Writer, 27 | dust3d::Snapshot* snapshot, 28 | const QByteArray* turnaroundPngByteArray); 29 | static void collectUsedResourceIds(const dust3d::Snapshot* snapshot, 30 | std::set& imageIds); 31 | signals: 32 | void finished(); 33 | public slots: 34 | void process(); 35 | 36 | private: 37 | const QString* m_filename = nullptr; 38 | dust3d::Snapshot* m_snapshot = nullptr; 39 | QByteArray* m_turnaroundPngByteArray = nullptr; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /application/sources/fbx_file.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_FBX_FILE_H_ 2 | #define DUST3D_APPLICATION_FBX_FILE_H_ 3 | 4 | #include "fbxdocument.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | class FbxFileWriter : public QObject { 14 | Q_OBJECT 15 | public: 16 | FbxFileWriter(dust3d::Object& object, 17 | const QString& filename, 18 | QImage* textureImage = nullptr, 19 | QImage* normalImage = nullptr, 20 | QImage* metalnessImage = nullptr, 21 | QImage* roughnessImage = nullptr, 22 | QImage* ambientOcclusionImage = nullptr); 23 | bool save(); 24 | 25 | private: 26 | void createFbxHeader(); 27 | void createCreationTime(); 28 | void createFileId(); 29 | void createCreator(); 30 | void createGlobalSettings(); 31 | void createDocuments(); 32 | void createReferences(); 33 | void createDefinitions(size_t deformerCount, 34 | size_t textureCount = 0, 35 | size_t videoCount = 0, 36 | bool hasAnimtion = false, 37 | size_t animationStackCount = 0, 38 | size_t animationLayerCount = 0, 39 | size_t animationCurveNodeCount = 0, 40 | size_t animationCurveCount = 0); 41 | void createTakes(); 42 | std::vector matrixToVector(const QMatrix4x4& matrix); 43 | int64_t secondsToKtime(double seconds); 44 | 45 | int64_t m_next64Id = 612150000; 46 | QString m_filename; 47 | QString m_baseName; 48 | fbx::FBXDocument m_fbxDocument; 49 | std::map m_uuidTo64Map; 50 | static std::vector m_identityMatrix; 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /application/sources/float_number_widget.cc: -------------------------------------------------------------------------------- 1 | #include "float_number_widget.h" 2 | #include "theme.h" 3 | #include 4 | #include 5 | #include 6 | 7 | FloatNumberWidget::FloatNumberWidget(QWidget* parent, bool singleLine) 8 | : QWidget(parent) 9 | { 10 | m_slider = new QSlider(Qt::Horizontal, this); 11 | m_slider->setRange(0, 100); 12 | m_slider->setFixedWidth(Theme::sidebarPreferredWidth * 0.6); 13 | 14 | m_label = new QLabel(this); 15 | m_label->setAlignment(Qt::AlignLeft); 16 | 17 | connect(m_slider, &QAbstractSlider::valueChanged, [=](int value) { 18 | float fvalue = value / 100.0; 19 | updateValueLabel(fvalue); 20 | emit valueChanged(fvalue); 21 | }); 22 | 23 | QBoxLayout* layout = nullptr; 24 | if (singleLine) { 25 | layout = new QHBoxLayout(this); 26 | layout->setContentsMargins(2, 2, 2, 2); 27 | layout->addWidget(m_slider); 28 | layout->addWidget(m_label); 29 | } else { 30 | layout = new QVBoxLayout(this); 31 | layout->setContentsMargins(2, 2, 2, 2); 32 | layout->addWidget(m_label); 33 | layout->addWidget(m_slider); 34 | } 35 | } 36 | 37 | void FloatNumberWidget::setSliderFixedWidth(float width) 38 | { 39 | m_slider->setFixedWidth(width); 40 | } 41 | 42 | void FloatNumberWidget::updateValueLabel(float value) 43 | { 44 | QString valueString = QString().asprintf("%.2f", value); 45 | if (m_itemName.isEmpty()) 46 | m_label->setText(valueString); 47 | else 48 | m_label->setText(m_itemName + ": " + valueString); 49 | } 50 | 51 | void FloatNumberWidget::setItemName(const QString& name) 52 | { 53 | m_itemName = name; 54 | updateValueLabel(value()); 55 | } 56 | 57 | void FloatNumberWidget::setRange(float min, float max) 58 | { 59 | m_slider->setRange(min * 100, max * 100); 60 | } 61 | 62 | void FloatNumberWidget::increaseValue() 63 | { 64 | m_slider->triggerAction(QSlider::SliderPageStepAdd); 65 | } 66 | 67 | void FloatNumberWidget::descreaseValue() 68 | { 69 | m_slider->triggerAction(QSlider::SliderPageStepSub); 70 | } 71 | 72 | float FloatNumberWidget::value() const 73 | { 74 | return m_slider->value() / 100.0; 75 | } 76 | 77 | void FloatNumberWidget::setValue(float value) 78 | { 79 | m_slider->setValue(value * 100); 80 | } 81 | -------------------------------------------------------------------------------- /application/sources/float_number_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_FLOAT_NUMBER_WIDGET_H_ 2 | #define DUST3D_APPLICATION_FLOAT_NUMBER_WIDGET_H_ 3 | 4 | #include 5 | 6 | QT_FORWARD_DECLARE_CLASS(QLabel) 7 | QT_FORWARD_DECLARE_CLASS(QSlider) 8 | 9 | class FloatNumberWidget : public QWidget { 10 | Q_OBJECT 11 | public: 12 | explicit FloatNumberWidget(QWidget* parent = nullptr, bool singleLine = true); 13 | void setRange(float min, float max); 14 | float value() const; 15 | void setItemName(const QString& name); 16 | void setSliderFixedWidth(float width); 17 | 18 | public slots: 19 | void increaseValue(); 20 | void descreaseValue(); 21 | void setValue(float value); 22 | 23 | signals: 24 | void valueChanged(float value); 25 | 26 | private: 27 | void updateValueLabel(float value); 28 | 29 | private: 30 | QLabel* m_label = nullptr; 31 | QSlider* m_slider = nullptr; 32 | QString m_itemName; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /application/sources/glb_file.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_GLB_FILE_H_ 2 | #define DUST3D_APPLICATION_GLB_FILE_H_ 3 | 4 | #include "document.h" 5 | #include "json.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | class GlbFileWriter : public QObject { 16 | Q_OBJECT 17 | public: 18 | GlbFileWriter(dust3d::Object& object, 19 | const QString& filename, 20 | QImage* textureImage = nullptr, 21 | QImage* normalImage = nullptr, 22 | QImage* ormImage = nullptr); 23 | bool save(); 24 | bool save(QDataStream& output); 25 | 26 | private: 27 | QString m_filename; 28 | bool m_outputNormal = true; 29 | bool m_outputUv = true; 30 | QByteArray m_binByteArray; 31 | QByteArray m_jsonByteArray; 32 | 33 | private: 34 | nlohmann::json m_json; 35 | 36 | public: 37 | static bool m_enableComment; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /application/sources/graphics_container_widget.cc: -------------------------------------------------------------------------------- 1 | #include "graphics_container_widget.h" 2 | 3 | GraphicsContainerWidget::GraphicsContainerWidget() 4 | { 5 | setMouseTracking(true); 6 | } 7 | 8 | void GraphicsContainerWidget::resizeEvent(QResizeEvent* event) 9 | { 10 | if (m_graphicsWidget && m_graphicsWidget->size() != event->size()) 11 | emit containerSizeChanged(event->size()); 12 | } 13 | 14 | void GraphicsContainerWidget::mousePressEvent(QMouseEvent* event) 15 | { 16 | if (m_modelWidget) 17 | m_modelWidget->inputMousePressEventFromOtherWidget(event); 18 | } 19 | 20 | void GraphicsContainerWidget::mouseMoveEvent(QMouseEvent* event) 21 | { 22 | if (m_modelWidget) 23 | m_modelWidget->inputMouseMoveEventFromOtherWidget(event); 24 | } 25 | 26 | void GraphicsContainerWidget::mouseReleaseEvent(QMouseEvent* event) 27 | { 28 | if (m_modelWidget) 29 | m_modelWidget->inputMouseReleaseEventFromOtherWidget(event); 30 | } 31 | 32 | void GraphicsContainerWidget::wheelEvent(QWheelEvent* event) 33 | { 34 | if (m_graphicsWidget) { 35 | m_graphicsWidget->inputWheelEventFromOtherWidget(event); 36 | return; 37 | } 38 | 39 | if (m_modelWidget) 40 | m_modelWidget->inputWheelEventFromOtherWidget(event); 41 | } 42 | 43 | void GraphicsContainerWidget::setGraphicsWidget(SkeletonGraphicsWidget* graphicsWidget) 44 | { 45 | m_graphicsWidget = graphicsWidget; 46 | } 47 | 48 | void GraphicsContainerWidget::setModelWidget(ModelWidget* modelWidget) 49 | { 50 | m_modelWidget = modelWidget; 51 | } 52 | -------------------------------------------------------------------------------- /application/sources/graphics_container_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_GRAPHICS_CONTAINER_WIDGET_H_ 2 | #define DUST3D_APPLICATION_GRAPHICS_CONTAINER_WIDGET_H_ 3 | 4 | #include "model_widget.h" 5 | #include "skeleton_graphics_widget.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class GraphicsContainerWidget : public QWidget { 12 | Q_OBJECT 13 | signals: 14 | void containerSizeChanged(QSize size); 15 | 16 | public: 17 | GraphicsContainerWidget(); 18 | void setGraphicsWidget(SkeletonGraphicsWidget* graphicsWidget); 19 | void setModelWidget(ModelWidget* modelWidget); 20 | 21 | protected: 22 | void resizeEvent(QResizeEvent* event) override; 23 | void mousePressEvent(QMouseEvent* event) override; 24 | void mouseMoveEvent(QMouseEvent* event) override; 25 | void mouseReleaseEvent(QMouseEvent* event) override; 26 | void wheelEvent(QWheelEvent* event) override; 27 | 28 | private: 29 | ModelWidget* m_modelWidget = nullptr; 30 | SkeletonGraphicsWidget* m_graphicsWidget = nullptr; 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /application/sources/horizontal_line_widget.cc: -------------------------------------------------------------------------------- 1 | #include "horizontal_line_widget.h" 2 | 3 | HorizontalLineWidget::HorizontalLineWidget() 4 | : QWidget() 5 | { 6 | setFixedHeight(1); 7 | setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 8 | setStyleSheet(QString("background-color: #565656;")); 9 | setContentsMargins(0, 0, 0, 0); 10 | } 11 | -------------------------------------------------------------------------------- /application/sources/horizontal_line_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_HORIZONTAL_LINE_WIDGET_H_ 2 | #define DUST3D_APPLICATION_HORIZONTAL_LINE_WIDGET_H_ 3 | 4 | #include 5 | 6 | class HorizontalLineWidget : public QWidget { 7 | Q_OBJECT 8 | public: 9 | HorizontalLineWidget(); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /application/sources/image_forever.cc: -------------------------------------------------------------------------------- 1 | #include "image_forever.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct ImageForeverItem { 8 | QImage* image; 9 | dust3d::Uuid id; 10 | QByteArray* imageByteArray; 11 | }; 12 | static std::map g_foreverMap; 13 | static QMutex g_mapMutex; 14 | 15 | const QImage* ImageForever::get(const dust3d::Uuid& id) 16 | { 17 | QMutexLocker locker(&g_mapMutex); 18 | auto findResult = g_foreverMap.find(id); 19 | if (findResult == g_foreverMap.end()) 20 | return nullptr; 21 | return findResult->second.image; 22 | } 23 | 24 | void ImageForever::copy(const dust3d::Uuid& id, QImage& image) 25 | { 26 | QMutexLocker locker(&g_mapMutex); 27 | auto findResult = g_foreverMap.find(id); 28 | if (findResult == g_foreverMap.end()) 29 | return; 30 | image = *findResult->second.image; 31 | } 32 | 33 | const QByteArray* ImageForever::getPngByteArray(const dust3d::Uuid& id) 34 | { 35 | QMutexLocker locker(&g_mapMutex); 36 | auto findResult = g_foreverMap.find(id); 37 | if (findResult == g_foreverMap.end()) 38 | return nullptr; 39 | return findResult->second.imageByteArray; 40 | } 41 | 42 | dust3d::Uuid ImageForever::add(const QImage* image, dust3d::Uuid toId) 43 | { 44 | QMutexLocker locker(&g_mapMutex); 45 | if (nullptr == image) 46 | return dust3d::Uuid(); 47 | dust3d::Uuid newId = toId.isNull() ? dust3d::Uuid::createUuid() : toId; 48 | if (g_foreverMap.find(newId) != g_foreverMap.end()) 49 | return newId; 50 | QImage* newImage = new QImage(*image); 51 | QByteArray* imageByteArray = new QByteArray(); 52 | QBuffer pngBuffer(imageByteArray); 53 | pngBuffer.open(QIODevice::WriteOnly); 54 | newImage->save(&pngBuffer, "PNG"); 55 | g_foreverMap[newId] = { newImage, newId, imageByteArray }; 56 | return newId; 57 | } 58 | 59 | void ImageForever::remove(const dust3d::Uuid& id) 60 | { 61 | QMutexLocker locker(&g_mapMutex); 62 | auto findImage = g_foreverMap.find(id); 63 | if (findImage == g_foreverMap.end()) 64 | return; 65 | delete findImage->second.image; 66 | delete findImage->second.imageByteArray; 67 | g_foreverMap.erase(id); 68 | } 69 | -------------------------------------------------------------------------------- /application/sources/image_forever.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_IMAGE_FOREVER_H_ 2 | #define DUST3D_APPLICATION_IMAGE_FOREVER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class ImageForever { 9 | public: 10 | static const QImage* get(const dust3d::Uuid& id); 11 | static void copy(const dust3d::Uuid& id, QImage& image); 12 | static const QByteArray* getPngByteArray(const dust3d::Uuid& id); 13 | static dust3d::Uuid add(const QImage* image, dust3d::Uuid toId = dust3d::Uuid()); 14 | static void remove(const dust3d::Uuid& id); 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /application/sources/image_preview_widget.cc: -------------------------------------------------------------------------------- 1 | #include "image_preview_widget.h" 2 | #include 3 | 4 | ImagePreviewWidget::ImagePreviewWidget(QWidget* parent) 5 | : QWidget(parent) 6 | { 7 | } 8 | 9 | void ImagePreviewWidget::updateImage(const QImage& image) 10 | { 11 | m_image = image; 12 | update(); 13 | } 14 | 15 | void ImagePreviewWidget::updateBackgroundColor(const QColor& color) 16 | { 17 | m_backgroundColor = color; 18 | } 19 | 20 | void ImagePreviewWidget::mousePressEvent(QMouseEvent* event) 21 | { 22 | emit clicked(); 23 | } 24 | 25 | void ImagePreviewWidget::paintEvent(QPaintEvent* event) 26 | { 27 | QPainter painter(this); 28 | if (!m_image.isNull()) 29 | painter.drawImage(QRect(0, 0, width(), height()), m_image, QRect(0, 0, m_image.width(), m_image.height())); 30 | else 31 | painter.fillRect(QRect(0, 0, width(), height()), QBrush(m_backgroundColor)); 32 | } 33 | -------------------------------------------------------------------------------- /application/sources/image_preview_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_IMAGE_PREVIEW_WIDGET_H_ 2 | #define DUST3D_APPLICATION_IMAGE_PREVIEW_WIDGET_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class ImagePreviewWidget : public QWidget { 10 | Q_OBJECT 11 | signals: 12 | void clicked(); 13 | 14 | public: 15 | ImagePreviewWidget(QWidget* parent = nullptr); 16 | void updateImage(const QImage& image); 17 | void updateBackgroundColor(const QColor& color); 18 | 19 | protected: 20 | void paintEvent(QPaintEvent* event); 21 | void mousePressEvent(QMouseEvent* event); 22 | 23 | private: 24 | QImage m_image; 25 | QColor m_backgroundColor; 26 | 27 | void resizeImage(QImage* image, const QSize& newSize); 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /application/sources/info_label.cc: -------------------------------------------------------------------------------- 1 | #include "info_label.h" 2 | #include "theme.h" 3 | #include 4 | 5 | InfoLabel::InfoLabel(const QString& text, QWidget* parent) 6 | : QWidget(parent) 7 | { 8 | m_icon = new QLabel(QChar(fa::infocircle)); 9 | Theme::initAwesomeLabel(m_icon); 10 | 11 | m_label = new QLabel(text); 12 | m_label->setWordWrap(true); 13 | 14 | QHBoxLayout* mainLayout = new QHBoxLayout; 15 | mainLayout->addWidget(m_icon); 16 | mainLayout->addWidget(m_label); 17 | mainLayout->addStretch(); 18 | 19 | setLayout(mainLayout); 20 | } 21 | 22 | void InfoLabel::setText(const QString& text) 23 | { 24 | m_label->setText(text); 25 | } 26 | -------------------------------------------------------------------------------- /application/sources/info_label.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_INFO_LABEL_H_ 2 | #define DUST3D_APPLICATION_INFO_LABEL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class InfoLabel : public QWidget { 9 | public: 10 | InfoLabel(const QString& text = QString(), QWidget* parent = nullptr); 11 | void setText(const QString& text); 12 | 13 | private: 14 | QLabel* m_label = nullptr; 15 | QLabel* m_icon = nullptr; 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /application/sources/int_number_widget.cc: -------------------------------------------------------------------------------- 1 | #include "int_number_widget.h" 2 | #include "theme.h" 3 | #include 4 | #include 5 | #include 6 | 7 | IntNumberWidget::IntNumberWidget(QWidget* parent, bool singleLine) 8 | : QWidget(parent) 9 | { 10 | m_slider = new QSlider(Qt::Horizontal, this); 11 | m_slider->setRange(0, 100); 12 | m_slider->setFixedWidth(Theme::sidebarPreferredWidth * 0.6); 13 | 14 | m_label = new QLabel(this); 15 | m_label->setAlignment(Qt::AlignLeft); 16 | 17 | connect(m_slider, &QAbstractSlider::valueChanged, [=](int value) { 18 | updateValueLabel(value); 19 | emit valueChanged(value); 20 | }); 21 | 22 | QBoxLayout* layout = nullptr; 23 | if (singleLine) { 24 | layout = new QHBoxLayout(this); 25 | layout->setContentsMargins(2, 2, 2, 2); 26 | layout->addWidget(m_slider); 27 | layout->addWidget(m_label); 28 | } else { 29 | layout = new QVBoxLayout(this); 30 | layout->setContentsMargins(2, 2, 2, 2); 31 | layout->addWidget(m_label); 32 | layout->addWidget(m_slider); 33 | } 34 | } 35 | 36 | void IntNumberWidget::updateValueLabel(int value) 37 | { 38 | QString valueString = QString::number(value); 39 | if (m_itemName.isEmpty()) 40 | m_label->setText(valueString); 41 | else 42 | m_label->setText(m_itemName + ": " + valueString); 43 | } 44 | 45 | void IntNumberWidget::setItemName(const QString& name) 46 | { 47 | m_itemName = name; 48 | updateValueLabel(value()); 49 | } 50 | 51 | void IntNumberWidget::setRange(int min, int max) 52 | { 53 | m_slider->setRange(min, max); 54 | } 55 | 56 | void IntNumberWidget::increaseValue() 57 | { 58 | m_slider->triggerAction(QSlider::SliderPageStepAdd); 59 | } 60 | 61 | void IntNumberWidget::descreaseValue() 62 | { 63 | m_slider->triggerAction(QSlider::SliderPageStepSub); 64 | } 65 | 66 | int IntNumberWidget::value() const 67 | { 68 | return m_slider->value(); 69 | } 70 | 71 | void IntNumberWidget::setValue(int value) 72 | { 73 | m_slider->setValue(value); 74 | } 75 | -------------------------------------------------------------------------------- /application/sources/int_number_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_INT_NUMBER_WIDGET_H_ 2 | #define DUST3D_APPLICATION_INT_NUMBER_WIDGET_H_ 3 | 4 | #include 5 | 6 | QT_FORWARD_DECLARE_CLASS(QLabel) 7 | QT_FORWARD_DECLARE_CLASS(QSlider) 8 | 9 | class IntNumberWidget : public QWidget { 10 | Q_OBJECT 11 | public: 12 | explicit IntNumberWidget(QWidget* parent = nullptr, bool singleLine = true); 13 | void setRange(int min, int max); 14 | int value() const; 15 | void setItemName(const QString& name); 16 | 17 | public slots: 18 | void increaseValue(); 19 | void descreaseValue(); 20 | void setValue(int value); 21 | 22 | signals: 23 | void valueChanged(int value); 24 | 25 | private: 26 | void updateValueLabel(int value); 27 | 28 | private: 29 | QLabel* m_label = nullptr; 30 | QSlider* m_slider = nullptr; 31 | QString m_itemName; 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /application/sources/log_browser.cc: -------------------------------------------------------------------------------- 1 | #include "log_browser.h" 2 | #include "log_browser_dialog.h" 3 | #include 4 | #include 5 | 6 | bool LogBrowser::m_enableOutputToFile = true; 7 | 8 | LogBrowser::LogBrowser(QObject* parent) 9 | : QObject(parent) 10 | { 11 | qRegisterMetaType("QtMsgType"); 12 | m_browserDialog = new LogBrowserDialog; 13 | connect(this, &LogBrowser::sendMessage, m_browserDialog, &LogBrowserDialog::outputMessage, Qt::QueuedConnection); 14 | 15 | if (m_enableOutputToFile) { 16 | QString filePath = "application.log"; 17 | m_outputTo = fopen(filePath.toUtf8().constData(), "w"); 18 | } 19 | } 20 | 21 | LogBrowser::~LogBrowser() 22 | { 23 | delete m_browserDialog; 24 | if (m_outputTo) 25 | fclose(m_outputTo); 26 | } 27 | 28 | void LogBrowser::showDialog() 29 | { 30 | m_browserDialog->show(); 31 | m_browserDialog->activateWindow(); 32 | m_browserDialog->raise(); 33 | } 34 | 35 | void LogBrowser::hideDialog() 36 | { 37 | m_browserDialog->hide(); 38 | } 39 | 40 | bool LogBrowser::isDialogVisible() 41 | { 42 | return m_browserDialog->isVisible(); 43 | } 44 | 45 | void LogBrowser::outputMessage(QtMsgType type, const QString& msg, const QString& source, int line) 46 | { 47 | if (m_outputTo) { 48 | fprintf(m_outputTo, "[%s:%d]: %s\n", source.toUtf8().constData(), line, msg.toUtf8().constData()); 49 | fflush(m_outputTo); 50 | } 51 | emit sendMessage(type, msg, source, line); 52 | } 53 | -------------------------------------------------------------------------------- /application/sources/log_browser.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_LOG_BROWSER_H_ 2 | #define DUST3D_APPLICATION_LOG_BROWSER_H_ 3 | 4 | #include 5 | #include 6 | 7 | class LogBrowserDialog; 8 | 9 | class LogBrowser : public QObject { 10 | Q_OBJECT 11 | public: 12 | explicit LogBrowser(QObject* parent = 0); 13 | ~LogBrowser(); 14 | 15 | public slots: 16 | void outputMessage(QtMsgType type, const QString& msg, const QString& source, int line); 17 | void showDialog(); 18 | void hideDialog(); 19 | bool isDialogVisible(); 20 | 21 | signals: 22 | void sendMessage(QtMsgType type, const QString& msg, const QString& source, int line); 23 | 24 | private: 25 | LogBrowserDialog* m_browserDialog = nullptr; 26 | FILE* m_outputTo = nullptr; 27 | static bool m_enableOutputToFile; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /application/sources/log_browser_dialog.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_LOG_BROWSER_DIALOG_H_ 2 | #define DUST3D_APPLICATION_LOG_BROWSER_DIALOG_H_ 3 | 4 | #include 5 | 6 | class QTextBrowser; 7 | class QPushButton; 8 | 9 | class LogBrowserDialog : public QDialog { 10 | Q_OBJECT 11 | public: 12 | LogBrowserDialog(QWidget* parent = 0); 13 | ~LogBrowserDialog(); 14 | 15 | public slots: 16 | void outputMessage(QtMsgType type, const QString& msg, const QString& source, int line); 17 | 18 | protected slots: 19 | void save(); 20 | 21 | protected: 22 | virtual void keyPressEvent(QKeyEvent* e); 23 | virtual void closeEvent(QCloseEvent* e); 24 | 25 | QTextBrowser* m_browser; 26 | QPushButton* m_clearButton; 27 | QPushButton* m_saveButton; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /application/sources/mesh_generator.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MESH_GENERATOR_H_ 2 | #define DUST3D_APPLICATION_MESH_GENERATOR_H_ 3 | 4 | #include "model_mesh.h" 5 | #include "monochrome_mesh.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class MeshGenerator : public QObject, public dust3d::MeshGenerator { 12 | Q_OBJECT 13 | public: 14 | MeshGenerator(dust3d::Snapshot* snapshot); 15 | ~MeshGenerator(); 16 | ModelMesh* takeResultMesh(); 17 | std::map>* takeComponentPreviewMeshes(); 18 | std::map>* takeComponentPreviewImages(); 19 | MonochromeMesh* takeWireframeMesh(); 20 | public slots: 21 | void process(); 22 | signals: 23 | void finished(); 24 | 25 | private: 26 | std::unique_ptr m_resultMesh; 27 | std::unique_ptr>> m_componentPreviewMeshes; 28 | std::unique_ptr>> m_componentPreviewImages; 29 | std::unique_ptr m_wireframeMesh; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /application/sources/mesh_preview_images_generator.cc: -------------------------------------------------------------------------------- 1 | #include "mesh_preview_images_generator.h" 2 | #include "theme.h" 3 | #include 4 | 5 | void MeshPreviewImagesGenerator::addInput(const dust3d::Uuid& inputId, std::unique_ptr previewMesh, bool useFrontView) 6 | { 7 | m_previewInputMap.insert({ inputId, PreviewInput { std::move(previewMesh), useFrontView } }); 8 | } 9 | 10 | void MeshPreviewImagesGenerator::process() 11 | { 12 | generate(); 13 | 14 | emit finished(); 15 | } 16 | 17 | std::map* MeshPreviewImagesGenerator::takeImages() 18 | { 19 | return m_partImages.release(); 20 | } 21 | 22 | void MeshPreviewImagesGenerator::generate() 23 | { 24 | m_partImages = std::make_unique>(); 25 | 26 | m_offscreenRender->setZRotation(0); 27 | m_offscreenRender->setEyePosition(QVector3D(0, 0, -4.0)); 28 | for (auto& it : m_previewInputMap) { 29 | if (it.second.useFrontView) { 30 | m_offscreenRender->setXRotation(0); 31 | m_offscreenRender->setYRotation(0); 32 | } else { 33 | m_offscreenRender->setXRotation(30 * 16); 34 | m_offscreenRender->setYRotation(-45 * 16); 35 | } 36 | m_offscreenRender->updateMesh(it.second.mesh.release()); 37 | (*m_partImages)[it.first] = m_offscreenRender->toImage(QSize(Theme::partPreviewImageSize, Theme::partPreviewImageSize)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /application/sources/mesh_preview_images_generator.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MESH_PREVIEW_IMAGES_GENERATOR_H_ 2 | #define DUST3D_APPLICATION_MESH_PREVIEW_IMAGES_GENERATOR_H_ 3 | 4 | #include "model_offscreen_render.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class MeshPreviewImagesGenerator : public QObject { 12 | Q_OBJECT 13 | public: 14 | MeshPreviewImagesGenerator(ModelOffscreenRender* modelOffscreenRender) 15 | : m_offscreenRender(modelOffscreenRender) 16 | { 17 | } 18 | 19 | struct PreviewInput { 20 | std::unique_ptr mesh; 21 | bool useFrontView = false; 22 | }; 23 | 24 | ~MeshPreviewImagesGenerator() 25 | { 26 | delete m_offscreenRender; 27 | } 28 | 29 | void addInput(const dust3d::Uuid& inputId, std::unique_ptr previewMesh, bool useFrontView = false); 30 | void generate(); 31 | std::map* takeImages(); 32 | signals: 33 | void finished(); 34 | public slots: 35 | void process(); 36 | 37 | private: 38 | std::map m_previewInputMap; 39 | ModelOffscreenRender* m_offscreenRender = nullptr; 40 | std::unique_ptr> m_partImages; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /application/sources/model_offscreen_render.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MODEL_OFFSCREEN_RENDER_H_ 2 | #define DUST3D_APPLICATION_MODEL_OFFSCREEN_RENDER_H_ 3 | 4 | #include "model_mesh.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class ModelOffscreenRender : public QOffscreenSurface { 11 | public: 12 | ModelOffscreenRender(const QSurfaceFormat& format, QScreen* targetScreen = Q_NULLPTR); 13 | ~ModelOffscreenRender(); 14 | void setXRotation(int angle); 15 | void setYRotation(int angle); 16 | void setZRotation(int angle); 17 | void setEyePosition(const QVector3D& eyePosition); 18 | void setMoveToPosition(const QVector3D& moveToPosition); 19 | void setRenderThread(QThread* thread); 20 | void updateMesh(ModelMesh* mesh); 21 | QImage toImage(const QSize& size); 22 | 23 | private: 24 | int m_xRot = 0; 25 | int m_yRot = 0; 26 | int m_zRot = 0; 27 | QVector3D m_eyePosition; 28 | QVector3D m_moveToPosition; 29 | QOpenGLContext* m_context = nullptr; 30 | QOpenGLFramebufferObject* m_renderFbo = nullptr; 31 | ModelMesh* m_mesh = nullptr; 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /application/sources/model_opengl_object.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MODEL_OPENGL_OBJECT_H_ 2 | #define DUST3D_APPLICATION_MODEL_OPENGL_OBJECT_H_ 3 | 4 | #include "model_mesh.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class ModelOpenGLObject { 11 | public: 12 | void update(std::unique_ptr mesh); 13 | void draw(); 14 | 15 | private: 16 | void copyMeshToOpenGL(); 17 | QOpenGLVertexArrayObject m_vertexArrayObject; 18 | QOpenGLBuffer m_buffer; 19 | std::unique_ptr m_mesh; 20 | bool m_meshIsDirty = false; 21 | QMutex m_meshMutex; 22 | int m_meshTriangleVertexCount = 0; 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /application/sources/model_opengl_program.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_ 2 | #define DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class ModelOpenGLProgram : public QOpenGLShaderProgram { 11 | public: 12 | void load(bool isCoreProfile = false); 13 | int getUniformLocationByName(const std::string& name); 14 | bool isCoreProfile() const; 15 | void bindMaps(); 16 | void releaseMaps(); 17 | void updateTextureImage(std::unique_ptr image); 18 | void updateNormalMapImage(std::unique_ptr image); 19 | void updateMetalnessRoughnessAmbientOcclusionMapImage(std::unique_ptr image, 20 | bool hasMetalnessMap = false, 21 | bool hasRoughnessMap = false, 22 | bool hasAmbientOcclusionMap = false); 23 | 24 | private: 25 | void addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName); 26 | void activeAndBindTexture(int location, QOpenGLTexture* texture); 27 | 28 | bool m_isLoaded = false; 29 | bool m_isCoreProfile = false; 30 | std::map m_uniformLocationMap; 31 | 32 | std::unique_ptr m_environmentIrradianceMap; 33 | std::unique_ptr m_environmentSpecularMap; 34 | std::unique_ptr>> m_environmentIrradianceMaps; 35 | std::unique_ptr>> m_environmentSpecularMaps; 36 | std::unique_ptr m_textureImage; 37 | std::unique_ptr m_normalMapImage; 38 | std::unique_ptr m_metalnessRoughnessAmbientOcclusionMapImage; 39 | std::unique_ptr m_texture; 40 | std::unique_ptr m_normalMap; 41 | std::unique_ptr m_metalnessRoughnessAmbientOcclusionMap; 42 | bool m_hasMetalnessMap = false; 43 | bool m_hasRoughnessMap = false; 44 | bool m_hasAmbientOcclusionMap = false; 45 | QMutex m_imageMutex; 46 | bool m_imageIsDirty = false; 47 | bool m_metalnessMapEnabled = false; 48 | bool m_roughnessMapEnabled = false; 49 | bool m_ambientOcclusionMapEnabled = false; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /application/sources/model_opengl_vertex.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MODEL_OPENGL_VERTEX_H_ 2 | #define DUST3D_APPLICATION_MODEL_OPENGL_VERTEX_H_ 3 | 4 | #include 5 | 6 | #pragma pack(push) 7 | #pragma pack(1) 8 | typedef struct 9 | { 10 | GLfloat posX; 11 | GLfloat posY; 12 | GLfloat posZ; 13 | GLfloat normX; 14 | GLfloat normY; 15 | GLfloat normZ; 16 | GLfloat colorR; 17 | GLfloat colorG; 18 | GLfloat colorB; 19 | GLfloat texU; 20 | GLfloat texV; 21 | GLfloat metalness; 22 | GLfloat roughness; 23 | GLfloat tangentX; 24 | GLfloat tangentY; 25 | GLfloat tangentZ; 26 | GLfloat alpha = 1.0; 27 | } ModelOpenGLVertex; 28 | #pragma pack(pop) 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /application/sources/monochrome_mesh.cc: -------------------------------------------------------------------------------- 1 | #include "monochrome_mesh.h" 2 | #include 3 | 4 | MonochromeMesh::MonochromeMesh(const MonochromeMesh& mesh) 5 | { 6 | m_lineVertices = mesh.m_lineVertices; 7 | } 8 | 9 | MonochromeMesh::MonochromeMesh(MonochromeMesh&& mesh) 10 | { 11 | m_lineVertices = std::move(mesh.m_lineVertices); 12 | } 13 | 14 | MonochromeMesh::MonochromeMesh(const dust3d::Object& object) 15 | { 16 | std::set> halfEdges; 17 | for (const auto& face : object.triangleAndQuads) { 18 | if (3 == face.size()) { 19 | halfEdges.insert({ face[0], face[1] }); 20 | halfEdges.insert({ face[1], face[0] }); 21 | halfEdges.insert({ face[1], face[2] }); 22 | halfEdges.insert({ face[2], face[1] }); 23 | halfEdges.insert({ face[2], face[0] }); 24 | halfEdges.insert({ face[0], face[2] }); 25 | continue; 26 | } 27 | halfEdges.insert({ face[0], face[1] }); 28 | halfEdges.insert({ face[1], face[0] }); 29 | halfEdges.insert({ face[1], face[2] }); 30 | halfEdges.insert({ face[2], face[1] }); 31 | halfEdges.insert({ face[2], face[3] }); 32 | halfEdges.insert({ face[3], face[2] }); 33 | halfEdges.insert({ face[3], face[0] }); 34 | halfEdges.insert({ face[0], face[3] }); 35 | } 36 | m_lineVertices.reserve(halfEdges.size() * 2); 37 | for (const auto& halfEdge : halfEdges) { 38 | // For two halfedges shared one edge, only output one line 39 | if (halfEdge.first > halfEdge.second) 40 | continue; 41 | const auto& from = object.vertices[halfEdge.first]; 42 | const auto& to = object.vertices[halfEdge.second]; 43 | m_lineVertices.emplace_back(MonochromeOpenGLVertex { 44 | (GLfloat)from.x(), 45 | (GLfloat)from.y(), 46 | (GLfloat)from.z() }); 47 | m_lineVertices.emplace_back(MonochromeOpenGLVertex { 48 | (GLfloat)to.x(), 49 | (GLfloat)to.y(), 50 | (GLfloat)to.z() }); 51 | } 52 | } 53 | 54 | const MonochromeOpenGLVertex* MonochromeMesh::lineVertices() 55 | { 56 | if (m_lineVertices.empty()) 57 | return nullptr; 58 | return &m_lineVertices[0]; 59 | } 60 | 61 | int MonochromeMesh::lineVertexCount() 62 | { 63 | return (int)m_lineVertices.size(); 64 | } 65 | -------------------------------------------------------------------------------- /application/sources/monochrome_mesh.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MONOCHROME_MESH_H_ 2 | #define DUST3D_APPLICATION_MONOCHROME_MESH_H_ 3 | 4 | #include "monochrome_opengl_vertex.h" 5 | #include 6 | #include 7 | 8 | class MonochromeMesh { 9 | public: 10 | MonochromeMesh(const MonochromeMesh& mesh); 11 | MonochromeMesh(MonochromeMesh&& mesh); 12 | MonochromeMesh(const dust3d::Object& object); 13 | const MonochromeOpenGLVertex* lineVertices(); 14 | int lineVertexCount(); 15 | 16 | private: 17 | std::vector m_lineVertices; 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /application/sources/monochrome_opengl_object.cc: -------------------------------------------------------------------------------- 1 | #include "monochrome_opengl_object.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void MonochromeOpenGLObject::update(std::unique_ptr mesh) 7 | { 8 | QMutexLocker lock(&m_meshMutex); 9 | m_mesh = std::move(mesh); 10 | m_meshIsDirty = true; 11 | } 12 | 13 | void MonochromeOpenGLObject::draw() 14 | { 15 | copyMeshToOpenGL(); 16 | if (0 == m_meshLineVertexCount) 17 | return; 18 | QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); 19 | QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject); 20 | f->glDrawArrays(GL_LINES, 0, m_meshLineVertexCount); 21 | } 22 | 23 | void MonochromeOpenGLObject::copyMeshToOpenGL() 24 | { 25 | std::unique_ptr mesh; 26 | bool meshChanged = false; 27 | if (m_meshIsDirty) { 28 | QMutexLocker lock(&m_meshMutex); 29 | if (m_meshIsDirty) { 30 | m_meshIsDirty = false; 31 | meshChanged = true; 32 | mesh = std::move(m_mesh); 33 | } 34 | } 35 | if (!meshChanged) 36 | return; 37 | m_meshLineVertexCount = 0; 38 | if (mesh) { 39 | QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject); 40 | if (m_buffer.isCreated()) 41 | m_buffer.destroy(); 42 | m_buffer.create(); 43 | m_buffer.bind(); 44 | m_buffer.allocate(mesh->lineVertices(), mesh->lineVertexCount() * sizeof(MonochromeOpenGLVertex)); 45 | m_meshLineVertexCount = mesh->lineVertexCount(); 46 | QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); 47 | f->glEnableVertexAttribArray(0); 48 | f->glEnableVertexAttribArray(1); 49 | f->glEnableVertexAttribArray(2); 50 | f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), 0); 51 | f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast(3 * sizeof(GLfloat))); 52 | f->glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast(6 * sizeof(GLfloat))); 53 | m_buffer.release(); 54 | } 55 | } -------------------------------------------------------------------------------- /application/sources/monochrome_opengl_object.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_ 2 | #define DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_ 3 | 4 | #include "monochrome_mesh.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class MonochromeOpenGLObject { 11 | public: 12 | void update(std::unique_ptr mesh); 13 | void draw(); 14 | 15 | private: 16 | void copyMeshToOpenGL(); 17 | QOpenGLVertexArrayObject m_vertexArrayObject; 18 | QOpenGLBuffer m_buffer; 19 | std::unique_ptr m_mesh; 20 | bool m_meshIsDirty = false; 21 | QMutex m_meshMutex; 22 | int m_meshLineVertexCount = 0; 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /application/sources/monochrome_opengl_program.cc: -------------------------------------------------------------------------------- 1 | #include "monochrome_opengl_program.h" 2 | #include 3 | #include 4 | #include 5 | 6 | static const QString& loadShaderSource(const QString& name) 7 | { 8 | static std::map s_shaderSources; 9 | auto findShader = s_shaderSources.find(name); 10 | if (findShader != s_shaderSources.end()) { 11 | return findShader->second; 12 | } 13 | QFile file(name); 14 | file.open(QFile::ReadOnly | QFile::Text); 15 | QTextStream stream(&file); 16 | auto insertResult = s_shaderSources.insert({ name, stream.readAll() }); 17 | return insertResult.first->second; 18 | } 19 | 20 | void MonochromeOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName) 21 | { 22 | if (!addShaderFromSourceCode(type, loadShaderSource(resourceName))) 23 | dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString(); 24 | } 25 | 26 | bool MonochromeOpenGLProgram::isCoreProfile() const 27 | { 28 | return m_isCoreProfile; 29 | } 30 | 31 | void MonochromeOpenGLProgram::load(bool isCoreProfile) 32 | { 33 | if (m_isLoaded) 34 | return; 35 | 36 | m_isCoreProfile = isCoreProfile; 37 | if (m_isCoreProfile) { 38 | addShaderFromResource(QOpenGLShader::Vertex, ":/shaders/monochrome_core.vert"); 39 | addShaderFromResource(QOpenGLShader::Fragment, ":/shaders/monochrome_core.frag"); 40 | } else { 41 | #if defined(Q_OS_WASM) 42 | addShaderFromResource(QOpenGLShader::Vertex, ":/shaders/monochrome_wasm.vert"); 43 | addShaderFromResource(QOpenGLShader::Fragment, ":/shaders/monochrome_wasm.frag"); 44 | #else 45 | addShaderFromResource(QOpenGLShader::Vertex, ":/shaders/monochrome.vert"); 46 | addShaderFromResource(QOpenGLShader::Fragment, ":/shaders/monochrome.frag"); 47 | #endif 48 | } 49 | bindAttributeLocation("vertex", 0); 50 | bindAttributeLocation("color", 1); 51 | bindAttributeLocation("alpha", 2); 52 | link(); 53 | bind(); 54 | m_isLoaded = true; 55 | } 56 | 57 | int MonochromeOpenGLProgram::getUniformLocationByName(const std::string& name) 58 | { 59 | auto findLocation = m_uniformLocationMap.find(name); 60 | if (findLocation != m_uniformLocationMap.end()) 61 | return findLocation->second; 62 | int location = uniformLocation(name.c_str()); 63 | m_uniformLocationMap.insert({ name, location }); 64 | return location; 65 | } 66 | -------------------------------------------------------------------------------- /application/sources/monochrome_opengl_program.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_ 2 | #define DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class MonochromeOpenGLProgram : public QOpenGLShaderProgram { 9 | public: 10 | void load(bool isCoreProfile = false); 11 | int getUniformLocationByName(const std::string& name); 12 | bool isCoreProfile() const; 13 | 14 | private: 15 | void addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName); 16 | 17 | bool m_isLoaded = false; 18 | bool m_isCoreProfile = false; 19 | std::map m_uniformLocationMap; 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /application/sources/monochrome_opengl_vertex.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_VERTEX_H_ 2 | #define DUST3D_APPLICATION_MONOCHROME_OPENGL_VERTEX_H_ 3 | 4 | #include 5 | 6 | #pragma pack(push) 7 | #pragma pack(1) 8 | typedef struct 9 | { 10 | GLfloat posX; 11 | GLfloat posY; 12 | GLfloat posZ; 13 | GLfloat colorR = 0.0; 14 | GLfloat colorG = 0.0; 15 | GLfloat colorB = 0.0; 16 | GLfloat alpha = 1.0; 17 | } MonochromeOpenGLVertex; 18 | #pragma pack(pop) 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /application/sources/part_manage_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_PART_MANAGE_WIDGET_H_ 2 | #define DUST3D_APPLICATION_PART_MANAGE_WIDGET_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class Document; 11 | class ComponentPreviewGridWidget; 12 | class ComponentPropertyWidget; 13 | class QPushButton; 14 | 15 | class PartManageWidget : public QWidget { 16 | Q_OBJECT 17 | signals: 18 | void unselectAllOnCanvas(); 19 | void selectPartOnCanvas(const dust3d::Uuid& partId); 20 | void setPartTarget(const dust3d::Uuid& partId, dust3d::PartTarget target); 21 | void groupComponents(const std::vector& componentIds); 22 | void removeComponent(const dust3d::Uuid& componentId); 23 | void ungroupComponent(const dust3d::Uuid& componentId); 24 | void moveComponentUp(const dust3d::Uuid& componentId); 25 | void moveComponentDown(const dust3d::Uuid& componentId); 26 | void moveComponentToTop(const dust3d::Uuid& componentId); 27 | void moveComponentToBottom(const dust3d::Uuid& componentId); 28 | void groupOperationAdded(); 29 | public slots: 30 | void selectComponentByPartId(const dust3d::Uuid& partId); 31 | void showSelectedComponentProperties(); 32 | void showContextMenu(const QPoint& pos); 33 | 34 | public: 35 | PartManageWidget(Document* document, QWidget* parent = nullptr); 36 | 37 | private: 38 | Document* m_document = nullptr; 39 | ComponentPreviewGridWidget* m_componentPreviewGridWidget = nullptr; 40 | QPushButton* m_levelUpButton = nullptr; 41 | QPushButton* m_selectButton = nullptr; 42 | QPushButton* m_lockButton = nullptr; 43 | QPushButton* m_unlockButton = nullptr; 44 | QPushButton* m_showButton = nullptr; 45 | QPushButton* m_hideButton = nullptr; 46 | QPushButton* m_unlinkButton = nullptr; 47 | QPushButton* m_linkButton = nullptr; 48 | QPushButton* m_propertyButton = nullptr; 49 | std::unique_ptr m_contextMenu; 50 | void updateToolButtons(); 51 | void updateLevelUpButton(); 52 | bool hasSelectedGroupedComponent(); 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /application/sources/preferences.cc: -------------------------------------------------------------------------------- 1 | #include "preferences.h" 2 | 3 | #define MAX_RECENT_FILES 7 4 | 5 | Preferences& Preferences::instance() 6 | { 7 | static Preferences* s_preferences = nullptr; 8 | if (nullptr == s_preferences) { 9 | s_preferences = new Preferences; 10 | } 11 | return *s_preferences; 12 | } 13 | 14 | void Preferences::loadDefault() 15 | { 16 | } 17 | 18 | Preferences::Preferences() 19 | { 20 | loadDefault(); 21 | } 22 | 23 | QSize Preferences::documentWindowSize() const 24 | { 25 | return m_settings.value("documentWindowSize", QSize()).toSize(); 26 | } 27 | 28 | void Preferences::setDocumentWindowSize(const QSize& size) 29 | { 30 | m_settings.setValue("documentWindowSize", size); 31 | } 32 | 33 | QStringList Preferences::recentFileList() const 34 | { 35 | return m_settings.value("recentFileList").toStringList(); 36 | } 37 | 38 | int Preferences::maxRecentFiles() const 39 | { 40 | return MAX_RECENT_FILES; 41 | } 42 | 43 | void Preferences::setCurrentFile(const QString& fileName) 44 | { 45 | QStringList files = m_settings.value("recentFileList").toStringList(); 46 | 47 | files.removeAll(fileName); 48 | files.prepend(fileName); 49 | while (files.size() > MAX_RECENT_FILES) 50 | files.removeLast(); 51 | 52 | m_settings.setValue("recentFileList", files); 53 | } 54 | 55 | void Preferences::reset() 56 | { 57 | auto files = m_settings.value("recentFileList").toStringList(); 58 | m_settings.clear(); 59 | m_settings.setValue("recentFileList", files); 60 | 61 | loadDefault(); 62 | } 63 | -------------------------------------------------------------------------------- /application/sources/preferences.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_PREFERENCES_H_ 2 | #define DUST3D_APPLICATION_PREFERENCES_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Preferences : public QObject { 9 | Q_OBJECT 10 | public: 11 | static Preferences& instance(); 12 | Preferences(); 13 | QSize documentWindowSize() const; 14 | void setDocumentWindowSize(const QSize&); 15 | QStringList recentFileList() const; 16 | int maxRecentFiles() const; 17 | public slots: 18 | void setCurrentFile(const QString& fileName); 19 | void reset(); 20 | 21 | private: 22 | QSettings m_settings; 23 | void loadDefault(); 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /application/sources/preview_grid_view.cc: -------------------------------------------------------------------------------- 1 | #include "preview_grid_view.h" 2 | #include "theme.h" 3 | 4 | PreviewGridView::PreviewGridView(QWidget* parent) 5 | : QListView(parent) 6 | { 7 | QPalette viewPalette = palette(); 8 | viewPalette.setColor(QPalette::Window, Qt::transparent); 9 | viewPalette.setColor(QPalette::Base, Qt::transparent); 10 | setPalette(viewPalette); 11 | 12 | auto borderSize = Theme::previewIconBorderSize; 13 | auto margin = Theme::previewIconMargin; 14 | auto borderRadius = Theme::previewIconBorderRadius; 15 | setStyleSheet( 16 | "QListView::item {border:" + QString::number(borderSize) + "px solid transparent; margin:" + QString::number(margin) + "px; background-color: " + Theme::gray.name() + "; border-radius: " + QString::number(borderRadius) + ";}" + "QListView::item:selected {border-color: " + Theme::red.name() + ";}"); 17 | 18 | setViewMode(QListView::IconMode); 19 | setGridSize(QSize(Theme::partPreviewImageSize, Theme::partPreviewImageSize)); 20 | setMovement(QListView::Snap); 21 | setFlow(QListView::LeftToRight); 22 | setSelectionMode(QAbstractItemView::ExtendedSelection); 23 | setResizeMode(QListView::Adjust); 24 | } -------------------------------------------------------------------------------- /application/sources/preview_grid_view.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_PREVIEW_GRID_VIEW_H_ 2 | #define DUST3D_APPLICATION_PREVIEW_GRID_VIEW_H_ 3 | 4 | #include 5 | 6 | class PreviewGridView : public QListView { 7 | Q_OBJECT 8 | public: 9 | PreviewGridView(QWidget* parent = nullptr); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /application/sources/skeleton_graphics_edge_item.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_SKELETON_GRAPHICS_EDGE_ITEM_H_ 2 | #define DUST3D_APPLICATION_SKELETON_GRAPHICS_EDGE_ITEM_H_ 3 | 4 | #include "document.h" 5 | #include 6 | 7 | class SkeletonGraphicsNodeItem; 8 | 9 | class SkeletonGraphicsEdgeItem : public QGraphicsPolygonItem { 10 | public: 11 | SkeletonGraphicsEdgeItem(); 12 | void setRotated(bool rotated); 13 | void setEndpoints(SkeletonGraphicsNodeItem* first, SkeletonGraphicsNodeItem* second); 14 | SkeletonGraphicsNodeItem* firstItem(); 15 | SkeletonGraphicsNodeItem* secondItem(); 16 | void updateAppearance(); 17 | dust3d::Uuid id(); 18 | void setId(dust3d::Uuid id); 19 | Document::Profile profile(); 20 | void setHovered(bool hovered); 21 | void setChecked(bool checked); 22 | void setDeactivated(bool deactivated); 23 | void reverse(); 24 | bool deactivated(); 25 | bool checked(); 26 | bool hovered(); 27 | 28 | private: 29 | dust3d::Uuid m_uuid; 30 | SkeletonGraphicsNodeItem* m_firstItem; 31 | SkeletonGraphicsNodeItem* m_secondItem; 32 | QPolygonF m_selectionPolygon; 33 | bool m_hovered = false; 34 | bool m_checked = false; 35 | Document::Profile m_profile = Document::Profile::Unknown; 36 | bool m_deactivated = false; 37 | bool m_rotated = false; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /application/sources/skeleton_graphics_node_item.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_SKELETON_NODE_ITEM_H_ 2 | #define DUST3D_APPLICATION_SKELETON_NODE_ITEM_H_ 3 | 4 | #include "document.h" 5 | #include 6 | 7 | class SkeletonGraphicsNodeItem : public QGraphicsEllipseItem { 8 | public: 9 | SkeletonGraphicsNodeItem(Document::Profile profile = Document::Profile::Unknown); 10 | void setRotated(bool rotated); 11 | void updateAppearance(); 12 | void setOrigin(QPointF point); 13 | QPointF origin(); 14 | float radius(); 15 | void setRadius(float radius); 16 | void setMarkColor(QColor color); 17 | Document::Profile profile(); 18 | dust3d::Uuid id(); 19 | void setId(dust3d::Uuid id); 20 | void setHovered(bool hovered); 21 | void setChecked(bool checked); 22 | void setDeactivated(bool deactivated); 23 | bool deactivated(); 24 | bool checked(); 25 | bool hovered(); 26 | 27 | private: 28 | dust3d::Uuid m_uuid; 29 | Document::Profile m_profile = Document::Profile::Unknown; 30 | bool m_hovered = false; 31 | bool m_checked = false; 32 | QColor m_markColor; 33 | bool m_deactivated = false; 34 | bool m_rotated = false; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /application/sources/skeleton_graphics_origin_item.cc: -------------------------------------------------------------------------------- 1 | #include "skeleton_graphics_origin_item.h" 2 | #include "theme.h" 3 | 4 | SkeletonGraphicsOriginItem::SkeletonGraphicsOriginItem(Document::Profile profile) 5 | : m_profile(profile) 6 | , m_hovered(false) 7 | , m_checked(false) 8 | , m_rotated(false) 9 | { 10 | setData(0, "origin"); 11 | } 12 | void SkeletonGraphicsOriginItem::setRotated(bool rotated) 13 | { 14 | m_rotated = rotated; 15 | } 16 | void SkeletonGraphicsOriginItem::updateAppearance() 17 | { 18 | QColor color = Theme::white; 19 | 20 | switch (m_profile) { 21 | case Document::Profile::Unknown: 22 | break; 23 | case Document::Profile::Main: 24 | color = m_rotated ? Theme::blue : Theme::red; 25 | break; 26 | case Document::Profile::Side: 27 | color = Theme::green; 28 | break; 29 | } 30 | 31 | QColor penColor = color; 32 | penColor.setAlphaF(m_checked ? Theme::checkedAlpha : Theme::normalAlpha); 33 | QPen pen(penColor); 34 | pen.setWidth(0); 35 | setPen(pen); 36 | 37 | QColor brushColor = color; 38 | brushColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha); 39 | QBrush brush(brushColor); 40 | setBrush(brush); 41 | } 42 | void SkeletonGraphicsOriginItem::setOrigin(QPointF point) 43 | { 44 | m_origin = point; 45 | QPolygonF triangle; 46 | const int triangleRadius = 10; 47 | triangle.append(QPointF(point.x() - triangleRadius, point.y())); 48 | triangle.append(QPointF(point.x() + triangleRadius, point.y())); 49 | triangle.append(QPointF(point.x(), point.y() - triangleRadius)); 50 | triangle.append(QPointF(point.x() - triangleRadius, point.y())); 51 | setPolygon(triangle); 52 | updateAppearance(); 53 | } 54 | QPointF SkeletonGraphicsOriginItem::origin() 55 | { 56 | return m_origin; 57 | } 58 | Document::Profile SkeletonGraphicsOriginItem::profile() 59 | { 60 | return m_profile; 61 | } 62 | void SkeletonGraphicsOriginItem::setHovered(bool hovered) 63 | { 64 | m_hovered = hovered; 65 | updateAppearance(); 66 | } 67 | void SkeletonGraphicsOriginItem::setChecked(bool checked) 68 | { 69 | m_checked = checked; 70 | updateAppearance(); 71 | } 72 | bool SkeletonGraphicsOriginItem::checked() 73 | { 74 | return m_checked; 75 | } 76 | bool SkeletonGraphicsOriginItem::hovered() 77 | { 78 | return m_hovered; 79 | } 80 | -------------------------------------------------------------------------------- /application/sources/skeleton_graphics_origin_item.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_SKELETON_ORIGIN_ITEM_H_ 2 | #define DUST3D_APPLICATION_SKELETON_ORIGIN_ITEM_H_ 3 | 4 | #include "document.h" 5 | #include 6 | 7 | class SkeletonGraphicsOriginItem : public QGraphicsPolygonItem { 8 | public: 9 | SkeletonGraphicsOriginItem(Document::Profile profile = Document::Profile::Unknown); 10 | void setRotated(bool rotated); 11 | void updateAppearance(); 12 | void setOrigin(QPointF point); 13 | QPointF origin(); 14 | Document::Profile profile(); 15 | void setHovered(bool hovered); 16 | void setChecked(bool checked); 17 | bool checked(); 18 | bool hovered(); 19 | 20 | private: 21 | Document::Profile m_profile = Document::Profile::Unknown; 22 | bool m_hovered = false; 23 | bool m_checked = false; 24 | QPointF m_origin; 25 | bool m_rotated = false; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /application/sources/skeleton_graphics_selection_item.cc: -------------------------------------------------------------------------------- 1 | #include "skeleton_graphics_selection_item.h" 2 | #include "theme.h" 3 | 4 | SkeletonGraphicsSelectionItem::SkeletonGraphicsSelectionItem() 5 | { 6 | QColor penColor = Theme::white; 7 | QPen pen(penColor); 8 | pen.setWidth(0); 9 | pen.setStyle(Qt::DashLine); 10 | setPen(pen); 11 | } 12 | 13 | void SkeletonGraphicsSelectionItem::updateRange(QPointF beginPos, QPointF endPos) 14 | { 15 | setRect(QRectF(beginPos, endPos).normalized()); 16 | } -------------------------------------------------------------------------------- /application/sources/skeleton_graphics_selection_item.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_SKELETON_SELECTION_ITEM_H_ 2 | #define DUST3D_APPLICATION_SKELETON_SELECTION_ITEM_H_ 3 | 4 | #include "document.h" 5 | #include 6 | 7 | class SkeletonGraphicsSelectionItem : public QGraphicsRectItem { 8 | public: 9 | SkeletonGraphicsSelectionItem(); 10 | void updateRange(QPointF beginPos, QPointF endPos); 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /application/sources/skeleton_ik_mover.cc: -------------------------------------------------------------------------------- 1 | #include "skeleton_ik_mover.h" 2 | #include "ccd_ik_resolver.h" 3 | #include 4 | 5 | SkeletonIkMover::SkeletonIkMover() 6 | { 7 | } 8 | 9 | SkeletonIkMover::~SkeletonIkMover() 10 | { 11 | } 12 | 13 | void SkeletonIkMover::setTarget(const QVector3D& target) 14 | { 15 | m_target = target; 16 | } 17 | 18 | void SkeletonIkMover::setUpdateVersion(unsigned long long version) 19 | { 20 | m_updateVersion = version; 21 | } 22 | 23 | unsigned long long SkeletonIkMover::getUpdateVersion() 24 | { 25 | return m_updateVersion; 26 | } 27 | 28 | void SkeletonIkMover::addNode(dust3d::Uuid id, QVector3D position) 29 | { 30 | SkeletonIkNode ikNode; 31 | ikNode.id = id; 32 | ikNode.position = ikNode.newPosition = position; 33 | m_ikNodes.push_back(ikNode); 34 | } 35 | 36 | const std::vector& SkeletonIkMover::ikNodes() 37 | { 38 | return m_ikNodes; 39 | } 40 | 41 | void SkeletonIkMover::process() 42 | { 43 | resolve(); 44 | 45 | emit finished(); 46 | } 47 | 48 | void SkeletonIkMover::resolve() 49 | { 50 | CcdIkSolver solver; 51 | for (auto i = 0u; i < m_ikNodes.size(); i++) { 52 | solver.addNodeInOrder(m_ikNodes[i].position); 53 | } 54 | solver.solveTo(m_target); 55 | for (auto i = 0u; i < m_ikNodes.size(); i++) { 56 | m_ikNodes[i].newPosition = solver.getNodeSolvedPosition(i); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /application/sources/skeleton_ik_mover.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_SKELETON_IK_MOVER_H_ 2 | #define DUST3D_APPLICATION_SKELETON_IK_MOVER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct SkeletonIkNode { 10 | dust3d::Uuid id; 11 | QVector3D position; 12 | QVector3D newPosition; 13 | }; 14 | 15 | class SkeletonIkMover : public QObject { 16 | Q_OBJECT 17 | public: 18 | SkeletonIkMover(); 19 | ~SkeletonIkMover(); 20 | void setTarget(const QVector3D& target); 21 | void setUpdateVersion(unsigned long long version); 22 | unsigned long long getUpdateVersion(); 23 | void addNode(dust3d::Uuid id, QVector3D position); 24 | const std::vector& ikNodes(); 25 | signals: 26 | void finished(); 27 | public slots: 28 | void process(); 29 | 30 | private: 31 | void resolve(); 32 | 33 | private: 34 | unsigned long long m_updateVersion = 0; 35 | std::vector m_ikNodes; 36 | QVector3D m_target; 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /application/sources/spinnable_toolbar_icon.cc: -------------------------------------------------------------------------------- 1 | #include "spinnable_toolbar_icon.h" 2 | #include "theme.h" 3 | 4 | SpinnableToolbarIcon::SpinnableToolbarIcon(QWidget* parent) 5 | : QWidget(parent) 6 | { 7 | setFixedSize(Theme::toolIconSize, Theme::toolIconSize); 8 | 9 | m_spinner = new WaitingSpinnerWidget(this); 10 | m_spinner->setColor(Theme::white); 11 | m_spinner->setInnerRadius(Theme::toolIconSize / 8); 12 | m_spinner->setLineLength(Theme::toolIconSize / 4); 13 | m_spinner->setNumberOfLines(9); 14 | m_spinner->hide(); 15 | } 16 | 17 | void SpinnableToolbarIcon::showSpinner(bool showSpinner) 18 | { 19 | if (showSpinner) { 20 | m_spinner->start(); 21 | m_spinner->show(); 22 | } else { 23 | m_spinner->stop(); 24 | m_spinner->hide(); 25 | } 26 | } 27 | 28 | bool SpinnableToolbarIcon::isSpinning() 29 | { 30 | return m_spinner->isVisible(); 31 | } 32 | -------------------------------------------------------------------------------- /application/sources/spinnable_toolbar_icon.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_SPINNABLE_TOOLBAR_ICON_H_ 2 | #define DUST3D_APPLICATION_SPINNABLE_TOOLBAR_ICON_H_ 3 | 4 | #include "toolbar_button.h" 5 | #include "waitingspinnerwidget.h" 6 | #include 7 | 8 | class SpinnableToolbarIcon : public QWidget { 9 | public: 10 | SpinnableToolbarIcon(QWidget* parent = nullptr); 11 | void showSpinner(bool showSpinner = true); 12 | bool isSpinning(); 13 | 14 | private: 15 | WaitingSpinnerWidget* m_spinner = nullptr; 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /application/sources/theme.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_THEME_H_ 2 | #define DUST3D_APPLICATION_THEME_H_ 3 | 4 | #include "QtAwesome.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class Theme { 13 | public: 14 | static QColor white; 15 | static QColor red; 16 | static QColor green; 17 | static QColor blue; 18 | static QColor black; 19 | static QColor gray; 20 | static float normalAlpha; 21 | static float checkedAlpha; 22 | static float edgeAlpha; 23 | static float fillAlpha; 24 | static int toolIconFontSize; 25 | static int toolIconSize; 26 | static int miniIconFontSize; 27 | static int miniIconSize; 28 | static int partPreviewImageSize; 29 | static int sidebarPreferredWidth; 30 | static int previewIconBorderSize; 31 | static int previewIconMargin; 32 | static int previewIconBorderRadius; 33 | 34 | static void initialize(); 35 | static QtAwesome* awesome(); 36 | static void initAwesomeButton(QPushButton* button); 37 | static void initAwesomeLabel(QLabel* label); 38 | static void initAwesomeMiniButton(QPushButton* button); 39 | static void updateAwesomeMiniButton(QPushButton* button, QChar icon, bool highlighted, bool enabled, bool unnormal = false); 40 | static void initAwesomeToolButton(QPushButton* button); 41 | static void initAwesomeToolButtonWithoutFont(QPushButton* button); 42 | static void initAwsome(); 43 | static void initToolButton(QPushButton* button); 44 | static void initCheckbox(QCheckBox* checkbox); 45 | static void initIconButton(QPushButton* button); 46 | static void initLineEdit(QLineEdit* edit); 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /application/sources/toolbar_button.cc: -------------------------------------------------------------------------------- 1 | #include "toolbar_button.h" 2 | #include "theme.h" 3 | #include 4 | #include 5 | 6 | ToolbarButton::ToolbarButton(const QString& filename, QWidget* parent) 7 | : QPushButton(parent) 8 | { 9 | auto margin = Theme::toolIconSize / 5; 10 | 11 | setFixedSize(Theme::toolIconSize, Theme::toolIconSize); 12 | setFocusPolicy(Qt::NoFocus); 13 | 14 | QSvgWidget* svgWidget = new QSvgWidget(filename); 15 | m_iconWidget = svgWidget; 16 | 17 | QGridLayout* containerLayout = new QGridLayout; 18 | containerLayout->setSpacing(0); 19 | containerLayout->setContentsMargins(margin, margin, margin, margin); 20 | containerLayout->addWidget(svgWidget); 21 | 22 | setLayout(containerLayout); 23 | } 24 | 25 | void ToolbarButton::setIcon(const QString& filename) 26 | { 27 | m_iconWidget->load(filename); 28 | } 29 | -------------------------------------------------------------------------------- /application/sources/toolbar_button.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_TOOLBAR_BUTTON_H_ 2 | #define DUST3D_APPLICATION_TOOLBAR_BUTTON_H_ 3 | 4 | #include 5 | #include 6 | 7 | class QSvgWidget; 8 | 9 | class ToolbarButton : public QPushButton { 10 | Q_OBJECT 11 | public: 12 | ToolbarButton(const QString& filename = QString(), QWidget* parent = nullptr); 13 | void setIcon(const QString& filename); 14 | 15 | private: 16 | QSvgWidget* m_iconWidget = nullptr; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /application/sources/turnaround_loader.cc: -------------------------------------------------------------------------------- 1 | #include "turnaround_loader.h" 2 | #include 3 | 4 | TurnaroundLoader::TurnaroundLoader(const QString& filename, QSize viewSize) 5 | { 6 | m_filename = filename; 7 | m_viewSize = viewSize; 8 | } 9 | 10 | TurnaroundLoader::TurnaroundLoader(const QImage& image, QSize viewSize) 11 | { 12 | m_inputImage = image; 13 | m_viewSize = viewSize; 14 | } 15 | 16 | TurnaroundLoader::~TurnaroundLoader() 17 | { 18 | delete m_resultImage; 19 | } 20 | 21 | QImage* TurnaroundLoader::takeResultImage() 22 | { 23 | QImage* returnImage = m_resultImage; 24 | m_resultImage = nullptr; 25 | return returnImage; 26 | } 27 | 28 | void TurnaroundLoader::process() 29 | { 30 | if (m_inputImage.isNull()) { 31 | QImage image(m_filename); 32 | m_resultImage = new QImage(image.scaled(m_viewSize, Qt::KeepAspectRatio)); 33 | } else { 34 | m_resultImage = new QImage(m_inputImage.scaled(m_viewSize, Qt::KeepAspectRatio)); 35 | } 36 | emit finished(); 37 | } 38 | -------------------------------------------------------------------------------- /application/sources/turnaround_loader.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_TURNAROUND_LOADER_H_ 2 | #define DUST3D_APPLICATION_TURNAROUND_LOADER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class TurnaroundLoader : public QObject { 10 | Q_OBJECT 11 | public: 12 | TurnaroundLoader(const QString& filename, QSize viewSize); 13 | TurnaroundLoader(const QImage& image, QSize viewSize); 14 | ~TurnaroundLoader(); 15 | QImage* takeResultImage(); 16 | signals: 17 | void finished(); 18 | public slots: 19 | void process(); 20 | 21 | private: 22 | QImage* m_resultImage = nullptr; 23 | QImage m_inputImage; 24 | QString m_filename; 25 | QSize m_viewSize; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /application/sources/uv_map_generator.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_UV_MAP_GENERATOR_H_ 2 | #define DUST3D_APPLICATION_UV_MAP_GENERATOR_H_ 3 | 4 | #include "model_mesh.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class UvMapGenerator : public QObject { 13 | Q_OBJECT 14 | public: 15 | UvMapGenerator(std::unique_ptr object, std::unique_ptr snapshot); 16 | void generate(); 17 | std::unique_ptr takeResultTextureColorImage(); 18 | std::unique_ptr takeResultTextureNormalImage(); 19 | std::unique_ptr takeResultTextureRoughnessImage(); 20 | std::unique_ptr takeResultTextureMetalnessImage(); 21 | std::unique_ptr takeResultTextureAmbientOcclusionImage(); 22 | std::unique_ptr takeResultMesh(); 23 | std::unique_ptr takeObject(); 24 | bool hasTransparencySettings() const; 25 | static QImage* combineMetalnessRoughnessAmbientOcclusionImages(QImage* metalnessImage, 26 | QImage* roughnessImage, 27 | QImage* ambientOcclusionImage); 28 | signals: 29 | void finished(); 30 | public slots: 31 | void process(); 32 | 33 | private: 34 | std::unique_ptr m_object; 35 | std::unique_ptr m_snapshot; 36 | std::unique_ptr m_mapPacker; 37 | std::unique_ptr m_textureColorImage; 38 | std::unique_ptr m_textureNormalImage; 39 | std::unique_ptr m_textureRoughnessImage; 40 | std::unique_ptr m_textureMetalnessImage; 41 | std::unique_ptr m_textureAmbientOcclusionImage; 42 | std::unique_ptr m_mesh; 43 | bool m_hasTransparencySettings = false; 44 | static size_t m_textureSize; 45 | void packUvs(); 46 | void generateTextureColorImage(); 47 | void generateUvCoords(); 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /application/sources/version.h: -------------------------------------------------------------------------------- 1 | #ifndef DUST3D_APPLICATION_VERSION_H_ 2 | #define DUST3D_APPLICATION_VERSION_H_ 3 | 4 | #include 5 | 6 | #define APP_COMPANY PROJECT_DEFINED_APP_COMPANY 7 | #define APP_NAME PROJECT_DEFINED_APP_NAME 8 | #define APP_VER PROJECT_DEFINED_APP_VER 9 | #define APP_HUMAN_VER PROJECT_DEFINED_APP_HUMAN_VER 10 | #define APP_HOMEPAGE_URL PROJECT_DEFINED_APP_HOMEPAGE_URL 11 | #define APP_REPOSITORY_URL PROJECT_DEFINED_APP_REPOSITORY_URL 12 | #define APP_ISSUES_URL PROJECT_DEFINED_APP_ISSUES_URL 13 | #define APP_REFERENCE_GUIDE_URL PROJECT_DEFINED_APP_REFERENCE_GUIDE_URL 14 | #define APP_UPDATES_CHECKER_URL PROJECT_DEFINED_APP_UPDATES_CHECKER_URL 15 | #define APP_PLATFORM PROJECT_DEFINED_APP_PLATFORM 16 | 17 | inline QString applicationTitle(const QString& text) 18 | { 19 | return text + QObject::tr(" - ") + APP_NAME; 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /application/third_party/QtAwesome/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | =========== 3 | 4 | Copyright 2013-2015 [Reliable Bits Software by Blommers IT](http://blommersit.nl). All Rights Reserved. 5 | Author [Rick Blommers](mailto:rick@blommersit.nl) 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 8 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation 9 | the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 15 | THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 16 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | 19 | 20 | Font Awesome License 21 | ==================== 22 | 23 | [https://github.com/FortAwesome/Font-Awesome](https://github.com/FortAwesome/Font-Awesome) 24 | 25 | The Font Awesome font is licensed under the SIL Open Font License - [http://scripts.sil.org/OFL](http://scripts.sil.org/OFL) 26 | The Font Awesome pictograms are licensed under the CC BY 3.0 License - [http://creativecommons.org/licenses/by/3.0/](http://creativecommons.org/licenses/by/3.0/) 27 | "Font Awesome by Dave Gandy - http://fortawesome.github.com/Font-Awesome" 28 | 29 | 30 | -------------------------------------------------------------------------------- /application/third_party/QtAwesome/QtAwesome/QtAwesome.pri: -------------------------------------------------------------------------------- 1 | 2 | INCLUDEPATH += $$PWD 3 | 4 | SOURCES += $$PWD/QtAwesome.cpp \ 5 | $$PWD/QtAwesomeAnim.cpp 6 | 7 | HEADERS += $$PWD/QtAwesome.h \ 8 | $$PWD/QtAwesomeAnim.h 9 | 10 | RESOURCES += $$PWD/QtAwesome.qrc 11 | 12 | 13 | -------------------------------------------------------------------------------- /application/third_party/QtAwesome/QtAwesome/QtAwesome.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2013-04-18T13:28:42 4 | # 5 | #------------------------------------------------- 6 | 7 | TARGET = QtAwesome 8 | TEMPLATE = lib 9 | CONFIG += staticlib c++11 10 | QT += widgets 11 | 12 | SOURCES += QtAwesome.cpp QtAwesomeAnim.cpp 13 | HEADERS += QtAwesome.h QtAwesomeAnim.h 14 | 15 | isEmpty(PREFIX) { 16 | unix { 17 | PREFIX = /usr 18 | } else { 19 | PREFIX = $$[QT_INSTALL_PREFIX] 20 | } 21 | } 22 | 23 | install_headers.files = QtAwesome.h QtAwesomeAnim.h 24 | install_headers.path = $$PREFIX/include 25 | target.path = $$PREFIX/lib 26 | INSTALLS += install_headers target 27 | 28 | RESOURCES += \ 29 | QtAwesome.qrc 30 | -------------------------------------------------------------------------------- /application/third_party/QtAwesome/QtAwesome/QtAwesome.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | fonts/fontawesome-4.7.0.ttf 4 | 5 | 6 | -------------------------------------------------------------------------------- /application/third_party/QtAwesome/QtAwesome/QtAwesomeAnim.cpp: -------------------------------------------------------------------------------- 1 | #include "QtAwesomeAnim.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | QtAwesomeAnimation::QtAwesomeAnimation(QWidget *parentWidget, int interval, int step) 11 | : parentWidgetRef_( parentWidget ) 12 | , timer_( 0 ) 13 | , interval_( interval ) 14 | , step_( step ) 15 | , angle_( 0.0f ) 16 | { 17 | 18 | } 19 | 20 | void QtAwesomeAnimation::setup( QPainter &painter, const QRect &rect) 21 | { 22 | // first time set the timer 23 | if( !timer_ ) 24 | { 25 | timer_ = new QTimer(); 26 | connect(timer_,SIGNAL(timeout()), this, SLOT(update()) ); 27 | timer_->start(interval_); 28 | } 29 | else 30 | { 31 | //timer, angle, self.step = self.info[self.parent_widget] 32 | float x_center = rect.width() * 0.5; 33 | float y_center = rect.height() * 0.5; 34 | painter.translate(x_center, y_center); 35 | painter.rotate(angle_); 36 | painter.translate(-x_center, -y_center); 37 | } 38 | } 39 | 40 | 41 | void QtAwesomeAnimation::update() 42 | { 43 | angle_ += step_; 44 | angle_ = std::fmod( angle_, 360); 45 | parentWidgetRef_->update(); 46 | } 47 | -------------------------------------------------------------------------------- /application/third_party/QtAwesome/QtAwesome/QtAwesomeAnim.h: -------------------------------------------------------------------------------- 1 | #ifndef QTAWESOMEANIMATION_H 2 | #define QTAWESOMEANIMATION_H 3 | 4 | #include 5 | 6 | class QPainter; 7 | class QRect; 8 | class QTimer; 9 | class QWidget; 10 | 11 | /// 12 | /// Basic Animation Support for QtAwesome (Inspired by https://github.com/spyder-ide/qtawesome) 13 | /// 14 | class QtAwesomeAnimation : public QObject 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | QtAwesomeAnimation( QWidget* parentWidget, int interval=10, int step=1); 20 | 21 | void setup( QPainter& painter, const QRect& rect ); 22 | 23 | public slots: 24 | void update(); 25 | 26 | private: 27 | QWidget* parentWidgetRef_; 28 | QTimer* timer_; 29 | int interval_; 30 | int step_; 31 | float angle_; 32 | 33 | }; 34 | 35 | 36 | #endif // QTAWESOMEANIMATION_H 37 | -------------------------------------------------------------------------------- /application/third_party/QtAwesome/QtAwesome/fonts/fontawesome-4.7.0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/application/third_party/QtAwesome/QtAwesome/fonts/fontawesome-4.7.0.ttf -------------------------------------------------------------------------------- /application/third_party/QtAwesome/QtAwesomeSample/QtAwesomeSample.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2013-04-18T15:05:07 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = QtAwesomeSample 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp 16 | 17 | HEADERS += 18 | 19 | 20 | include(../QtAwesome/QtAwesome.pri) 21 | -------------------------------------------------------------------------------- /application/third_party/QtAwesome/QtAwesomeSample/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT Licensed 3 | * 4 | * Copyright 2011-2015 - Reliable Bits Software by Blommers IT. All Rights Reserved. 5 | * Author Rick Blommers 6 | */ 7 | 8 | #include "QtAwesome.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | QApplication app(argc, argv); 19 | QMainWindow w; 20 | 21 | QtAwesome* awesome = new QtAwesome(&w); 22 | awesome->initFontAwesome(); 23 | 24 | QVBoxLayout* layout = new QVBoxLayout(); 25 | 26 | // a simple beer button 27 | //===================== 28 | { 29 | QPushButton* beerButton = new QPushButton( "Cheers!"); 30 | 31 | QVariantMap options; 32 | options.insert("anim", qVariantFromValue( new QtAwesomeAnimation(beerButton) ) ); 33 | beerButton->setIcon( awesome->icon( fa::beer, options ) ); 34 | 35 | layout->addWidget(beerButton); 36 | } 37 | 38 | // a simple beer checkbox button 39 | //============================== 40 | { 41 | QPushButton* toggleButton = new QPushButton("Toggle Me"); 42 | toggleButton->setCheckable(true); 43 | 44 | QVariantMap options; 45 | options.insert("color", QColor(Qt::green) ); 46 | options.insert("text-off", QString(fa::squareo) ); 47 | options.insert("color-off", QColor(Qt::red) ); 48 | toggleButton->setIcon( awesome->icon( fa::checksquareo, options )); 49 | 50 | 51 | layout->addWidget(toggleButton); 52 | } 53 | 54 | 55 | // add the samples 56 | QWidget* samples = new QWidget(); 57 | samples->setLayout(layout); 58 | w.setCentralWidget(samples); 59 | 60 | w.show(); 61 | 62 | return app.exec(); 63 | } 64 | -------------------------------------------------------------------------------- /application/third_party/QtWaitingSpinner/.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | *.pro.user 16 | *.pro.user.* 17 | moc_*.cpp 18 | qrc_*.cpp 19 | Makefile 20 | *-build-* 21 | 22 | QtWaitingSpinner 23 | QtWaitingSpinner.exe 24 | build-QtWaitingSpinnerTest-Desktop-Debug* 25 | build-QtWaitingSpinnerTest-GCC-Debug* 26 | build-QtWaitingSpinnerTest-Desktop_Qt_5_3_GCC_64bit-Debug* 27 | -------------------------------------------------------------------------------- /application/third_party/QtWaitingSpinner/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Original Work Copyright (c) 2012-2015 Alexander Turkin 4 | Modified 2014 by William Hallatt 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /application/third_party/QtWaitingSpinner/qtwaitingspinner.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += \ 2 | $$PWD 3 | 4 | LIBS += \ 5 | -L../qtwaitingspinner -lqtwaitingspinner 6 | -------------------------------------------------------------------------------- /application/third_party/QtWaitingSpinner/qtwaitingspinner.pro: -------------------------------------------------------------------------------- 1 | QT += widgets 2 | 3 | TEMPLATE = lib 4 | CONFIG += staticlib 5 | TARGET = qtwaitingspinner 6 | 7 | SOURCES += \ 8 | waitingspinnerwidget.cpp 9 | 10 | HEADERS += \ 11 | waitingspinnerwidget.h 12 | -------------------------------------------------------------------------------- /application/third_party/fbx/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jakub Skořepa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /application/third_party/fbx/README.md: -------------------------------------------------------------------------------- 1 | # C++ Library for reading and writing FBX files 2 | 3 | This library allows you to read and write fbx files. 4 | 5 | It currently supports full fbx binary format. It works even with larger files. 6 | 7 | Also includes fbxdump which allows you to inspect fbx files in json format. 8 | 9 | # References 10 | 11 | [FBX format description](https://code.blender.org/2013/08/fbx-binary-file-format-specification/) 12 | 13 | [FBX file structure](https://web.archive.org/web/20160605023014/https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure) 14 | 15 | # Javascript port 16 | 17 | [fbx.js](https://github.com/jskorepa/fbx.js) 18 | -------------------------------------------------------------------------------- /application/third_party/fbx/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(fbx-writer) 3 | 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -std=c++17 -lstdc++") 5 | 6 | find_package( ZLIB REQUIRED ) 7 | 8 | include_directories( ${ZLIB_INCLUDE_DIRS} ) 9 | 10 | set(SOURCE_FILES fbxdocument.cpp fbxnode.cpp fbxutil.cpp fbxproperty.cpp) 11 | 12 | add_executable(fbx-writer main.cpp ${SOURCE_FILES}) 13 | target_link_libraries(fbx-writer ${ZLIB_LIBRARIES}) 14 | 15 | add_executable(fbxdump fbxdump.cpp ${SOURCE_FILES}) 16 | target_link_libraries(fbxdump ${ZLIB_LIBRARIES}) 17 | -------------------------------------------------------------------------------- /application/third_party/fbx/src/fbxdocument.h: -------------------------------------------------------------------------------- 1 | #ifndef FBXDOCUMENT_H 2 | #define FBXDOCUMENT_H 3 | 4 | #include "fbxnode.h" 5 | 6 | namespace fbx { 7 | 8 | class FBXDocument 9 | { 10 | public: 11 | FBXDocument(); 12 | void read(std::ifstream &input); 13 | void read(std::string fname); 14 | void write(std::string fname); 15 | void write(std::ofstream &output); 16 | 17 | void createBasicStructure(); 18 | 19 | std::vector nodes; 20 | 21 | std::uint32_t getVersion(); 22 | void print(); 23 | 24 | private: 25 | std::uint32_t version; 26 | }; 27 | 28 | } // namespace fbx 29 | 30 | #endif // FBXDOCUMENT_H 31 | -------------------------------------------------------------------------------- /application/third_party/fbx/src/fbxdump.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "fbxdocument.h" 6 | using std::cout; 7 | using std::cerr; 8 | using std::endl; 9 | using std::string; 10 | using namespace fbx; 11 | 12 | bool findNode(std::string name, FBXNode where) { 13 | if(where.getName() == name) { 14 | where.print(); 15 | return true; 16 | } 17 | for(FBXNode n : where.getChildren()) { 18 | if(findNode(name, n)) { 19 | return true; 20 | } 21 | } 22 | return false; 23 | } 24 | 25 | int main(int argc, char** argv) { 26 | if(argc < 2) { 27 | cerr << "Specify file which you want to dump" << endl; 28 | return 1; 29 | } 30 | 31 | try { 32 | fbx::FBXDocument d; 33 | d.read(argv[1]); 34 | if(argc >= 3) { 35 | for(auto n : d.nodes) { 36 | if(findNode(argv[2], n)) break; 37 | } 38 | } else { 39 | d.print(); 40 | } 41 | 42 | } catch(string s) { 43 | cerr << "ERROR: " << s << endl; 44 | return 2; 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /application/third_party/fbx/src/fbxnode.h: -------------------------------------------------------------------------------- 1 | #ifndef FBXNODE_H 2 | #define FBXNODE_H 3 | 4 | #include "fbxproperty.h" 5 | 6 | namespace fbx { 7 | 8 | class FBXNode 9 | { 10 | public: 11 | FBXNode(); 12 | FBXNode(std::string name); 13 | 14 | std::uint32_t read(std::ifstream &input, uint32_t start_offset); 15 | std::uint32_t write(std::ofstream &output, uint32_t start_offset); 16 | void print(std::string prefix=""); 17 | bool isNull(); 18 | 19 | void addProperty(int16_t); 20 | void addProperty(bool); 21 | void addProperty(int32_t); 22 | void addProperty(float); 23 | void addProperty(double); 24 | void addProperty(int64_t); 25 | void addProperty(const std::vector); 26 | void addProperty(const std::vector); 27 | void addProperty(const std::vector); 28 | void addProperty(const std::vector); 29 | void addProperty(const std::vector); 30 | void addProperty(const std::vector, uint8_t type); 31 | void addProperty(const std::string); 32 | void addProperty(const char*); 33 | void addProperty(FBXProperty); 34 | 35 | void addPropertyNode(const std::string name, int16_t); 36 | void addPropertyNode(const std::string name, bool); 37 | void addPropertyNode(const std::string name, int32_t); 38 | void addPropertyNode(const std::string name, float); 39 | void addPropertyNode(const std::string name, double); 40 | void addPropertyNode(const std::string name, int64_t); 41 | void addPropertyNode(const std::string name, const std::vector); 42 | void addPropertyNode(const std::string name, const std::vector); 43 | void addPropertyNode(const std::string name, const std::vector); 44 | void addPropertyNode(const std::string name, const std::vector); 45 | void addPropertyNode(const std::string name, const std::vector); 46 | void addPropertyNode(const std::string name, const std::vector, uint8_t type); 47 | void addPropertyNode(const std::string name, const std::string); 48 | void addPropertyNode(const std::string name, const char*); 49 | 50 | void addChild(FBXNode child); 51 | uint32_t getBytes(); 52 | 53 | const std::vector getChildren(); 54 | const std::string getName(); 55 | private: 56 | std::vector children; 57 | std::vector properties; 58 | std::string name; 59 | }; 60 | 61 | } // namespace fbx 62 | 63 | #endif // FBXNODE_H 64 | -------------------------------------------------------------------------------- /application/third_party/fbx/src/fbxproperty.h: -------------------------------------------------------------------------------- 1 | #ifndef FBXPROPERTY_H 2 | #define FBXPROPERTY_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace fbx { 9 | 10 | // WARNING: (copied from fbxutil.h) 11 | // this assumes that float is 32bit and double is 64bit 12 | // both conforming to IEEE 754, it does not assume endianness 13 | // it also assumes that signed integers are two's complement 14 | union FBXPropertyValue { 15 | int16_t i16; // Y 16 | bool boolean; // C, b 17 | int32_t i32; // I, i 18 | float f32; // F, f 19 | double f64; // D, d 20 | int64_t i64; // L, l 21 | }; 22 | 23 | class FBXProperty 24 | { 25 | public: 26 | FBXProperty(std::ifstream &input); 27 | // primitive values 28 | FBXProperty(int16_t); 29 | FBXProperty(bool); 30 | FBXProperty(int32_t); 31 | FBXProperty(float); 32 | FBXProperty(double); 33 | FBXProperty(int64_t); 34 | // arrays 35 | FBXProperty(const std::vector); 36 | FBXProperty(const std::vector); 37 | FBXProperty(const std::vector); 38 | FBXProperty(const std::vector); 39 | FBXProperty(const std::vector); 40 | // raw / string 41 | FBXProperty(const std::vector, uint8_t type); 42 | FBXProperty(const std::string); 43 | FBXProperty(const char *); 44 | 45 | void write(std::ofstream &output); 46 | 47 | std::string to_string(); 48 | char getType(); 49 | 50 | bool is_array(); 51 | uint32_t getBytes(); 52 | private: 53 | uint8_t type; 54 | FBXPropertyValue value; 55 | std::vector raw; 56 | std::vector values; 57 | }; 58 | 59 | } // namespace fbx 60 | 61 | #endif // FBXPROPERTY_H 62 | -------------------------------------------------------------------------------- /application/third_party/fbx/src/fbxutil.h: -------------------------------------------------------------------------------- 1 | #ifndef FBXUTIL_H 2 | #define FBXUTIL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace fbx { 12 | // WARNING: 13 | // this assumes that float is 32bit and double is 64bit 14 | // both conforming to IEEE 754, it does not assume endianness 15 | // it also assumes that signed integers are two's complement 16 | class Reader { 17 | public: 18 | Reader(std::ifstream *input); 19 | Reader(char *input); 20 | 21 | std::uint8_t readUint8(); 22 | std::int8_t readInt8(); 23 | std::uint16_t readUint16(); 24 | std::int16_t readInt16(); 25 | std::uint32_t readUint32(); 26 | std::int32_t readInt32(); 27 | std::uint64_t readUint64(); 28 | std::string readString(uint32_t length); 29 | float readFloat(); 30 | double readDouble(); 31 | 32 | void read(char*, uint32_t); 33 | private: 34 | uint8_t getc(); 35 | std::ifstream *ifstream; 36 | char *buffer; 37 | uint32_t i; 38 | }; 39 | class Writer { 40 | public: 41 | Writer(std::ofstream *output); 42 | 43 | void write(std::uint8_t); 44 | void write(std::int8_t); 45 | void write(std::uint16_t); 46 | void write(std::int16_t); 47 | void write(std::uint32_t); 48 | void write(std::int32_t); 49 | void write(std::uint64_t); 50 | void write(std::int64_t); 51 | void write(std::string); 52 | void write(float); 53 | void write(double); 54 | private: 55 | void putc(uint8_t); 56 | std::ofstream *ofstream; 57 | }; 58 | } 59 | 60 | #endif // FBXUTIL_H 61 | -------------------------------------------------------------------------------- /application/third_party/fbx/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "fbxdocument.h" 5 | 6 | using std::cout; 7 | using std::endl; 8 | using namespace fbx; 9 | 10 | int main(int argc, char** argv) 11 | { 12 | if(argc < 2) { 13 | std::cout << "Specify file which you want to \"copy\"" << std::endl; 14 | return 1; 15 | } 16 | 17 | try { 18 | fbx::FBXDocument doc; 19 | std::cout << "Reading " << argv[1] << std::endl; 20 | doc.read(argv[1]); 21 | 22 | //doc.print(); 23 | std::cout << "Writing test.fbx" << std::endl; 24 | doc.write("test.fbx"); 25 | } catch(std::string e) { 26 | std::cout << e << std::endl; 27 | return 2; 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /application/third_party/json/LICENSE.MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-2018 Niels Lohmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /application/third_party/miniz/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013-2014 RAD Game Tools and Valve Software 2 | Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC 3 | 4 | All Rights Reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /ci/appimage/bundle.sh: -------------------------------------------------------------------------------- 1 | # Exit when any command fails 2 | set -e 3 | 4 | # Download appimage tools 5 | wget --no-verbose -O ./ci/appimage/AppRun-patched-x86_64 https://github.com/huxingyi/dust3d/blob/1.0.0-rc.6/ci/AppRun-patched-x86_64?raw=true 6 | wget --no-verbose -O ./ci/appimage/exec-x86_64.so https://github.com/huxingyi/dust3d/blob/1.0.0-rc.6/ci/exec-x86_64.so?raw=true 7 | wget --no-verbose -O ./ci/appimage/linuxdeployqt.AppImage https://github.com/huxingyi/dust3d/blob/1.0.0-rc.6/ci/linuxdeployqt.AppImage?raw=true 8 | 9 | # Create directories 10 | mkdir -p appdir/usr/share/metainfo 11 | mkdir -p appdir/usr/share/applications 12 | mkdir -p appdir/usr/bin 13 | mkdir -p appdir/usr/optional/libstdc++ 14 | 15 | # Print GLIBC version 16 | ldd --version 17 | 18 | # Print libstdc related 19 | sudo ls /usr/lib/x86_64-linux-gnu/ | grep libstdc 20 | 21 | # Copy libstdc++ 22 | cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 appdir/usr/optional/libstdc++/libstdc++.so.6 23 | 24 | # Copy exec 25 | cp ./ci/appimage/exec-x86_64.so appdir/usr/optional/exec.so 26 | 27 | # Copy application related files 28 | cp ./ci/appimage/dust3d.png appdir/dust3d.png 29 | cp ./ci/appimage/dust3d.appdata.xml appdir/usr/share/metainfo/dust3d.appdata.xml 30 | cp ./ci/appimage/dust3d.desktop appdir/usr/share/applications/dust3d.desktop 31 | cp ./application/dust3d appdir/usr/bin/dust3d 32 | 33 | # Make bundle 34 | chmod a+x ./ci/appimage/linuxdeployqt.AppImage 35 | unset QTDIR; unset QT_PLUGIN_PATH 36 | ./ci/appimage/linuxdeployqt.AppImage appdir/usr/share/applications/dust3d.desktop -bundle-non-qt-libs -verbose=2 37 | rm appdir/AppRun 38 | cp ./ci/appimage/AppRun-patched-x86_64 appdir/AppRun 39 | chmod a+x appdir/AppRun 40 | ./ci/appimage/linuxdeployqt.AppImage --appimage-extract 41 | export PATH=$(readlink -f ./squashfs-root/usr/bin):$PATH 42 | rm -f "./appdir/usr/lib/libxcb-dri2.so" "./appdir/usr/lib/libxcb-dri3.so" 43 | ./squashfs-root/usr/bin/appimagetool -g ./appdir/ Dust3D-x86_64.AppImage 44 | -------------------------------------------------------------------------------- /ci/appimage/dust3d.appdata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ​ dust3d.desktop 4 | ​ FSFAP 5 | ​ MIT 6 | ​ Dust3D 7 | ​ A quick 3D modeling tool 8 | ​ 9 | ​ 10 | ​

11 | ​ Dust3D is a brand new 3D modeling software. It helps you create a 3D watertight base model in seconds. Use it to speed up your character modeling in game making, 3D printing, and so on. 12 | ​

13 | ​
14 | ​ 15 | ​ 16 | ​ 17 | ​ Dust3D main window 18 | ​ https://raw.githubusercontent.com/huxingyi/dust3d/master/ci/screenshot.png 19 | ​ 20 | ​ 21 | ​ 22 | ​ https://github.com/huxingyi/dust3d 23 | https://github.com/huxingyi/dust3d/issues 24 | http://docs.dust3d.org/ 25 | ​ 26 | ​
-------------------------------------------------------------------------------- /ci/appimage/dust3d.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=Dust3D 4 | Icon=dust3d 5 | Exec=dust3d 6 | Categories=Graphics; 7 | Comment=A quick 3D modeling tool 8 | -------------------------------------------------------------------------------- /ci/appimage/dust3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/ci/appimage/dust3d.png -------------------------------------------------------------------------------- /ci/lint.sh: -------------------------------------------------------------------------------- 1 | # When using -style=file, clang-format uses the .clang-format file in the closest parent directory of the input file. 2 | find ../application/sources/ ../dust3d/ -iname *.h -o -iname *.cc | xargs clang-format -style=file -i -------------------------------------------------------------------------------- /ci/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxingyi/dust3d/bef208338e8d25d1cad9a42c121d13c1bf249d50/ci/screenshot.png -------------------------------------------------------------------------------- /dust3d/base/combine_mode.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | namespace dust3d { 26 | 27 | CombineMode CombineModeFromString(const char* modeString) 28 | { 29 | std::string mode = modeString; 30 | if (mode == "Normal") 31 | return CombineMode::Normal; 32 | if (mode == "Inversion") 33 | return CombineMode::Inversion; 34 | if (mode == "Uncombined") 35 | return CombineMode::Uncombined; 36 | return CombineMode::Normal; 37 | } 38 | 39 | const char* CombineModeToString(CombineMode mode) 40 | { 41 | switch (mode) { 42 | case CombineMode::Normal: 43 | return "Normal"; 44 | case CombineMode::Inversion: 45 | return "Inversion"; 46 | case CombineMode::Uncombined: 47 | return "Uncombined"; 48 | default: 49 | return "Normal"; 50 | } 51 | } 52 | 53 | std::string CombineModeToDispName(CombineMode mode) 54 | { 55 | switch (mode) { 56 | case CombineMode::Normal: 57 | return std::string("Normal"); 58 | case CombineMode::Inversion: 59 | return std::string("Inversion"); 60 | case CombineMode::Uncombined: 61 | return std::string("Uncombined"); 62 | default: 63 | return std::string("Normal"); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /dust3d/base/combine_mode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_COMBINE_MODE_H_ 24 | #define DUST3D_BASE_COMBINE_MODE_H_ 25 | 26 | #include 27 | 28 | namespace dust3d { 29 | 30 | enum class CombineMode { 31 | Normal = 0, 32 | Inversion, 33 | Uncombined, 34 | Count 35 | }; 36 | 37 | CombineMode CombineModeFromString(const char* modeString); 38 | const char* CombineModeToString(CombineMode mode); 39 | std::string CombineModeToDispName(CombineMode mode); 40 | 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /dust3d/base/cut_face.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_CUT_FACE_H_ 24 | #define DUST3D_BASE_CUT_FACE_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace dust3d { 32 | 33 | enum class CutFace { 34 | Quad = 0, 35 | Pentagon, 36 | Hexagon, 37 | Triangle, 38 | UserDefined, 39 | Count 40 | }; 41 | 42 | CutFace CutFaceFromString(const char* faceString); 43 | std::string CutFaceToString(CutFace cutFace); 44 | std::vector CutFaceToPoints(CutFace cutFace); 45 | void normalizeCutFacePoints(std::vector* points); 46 | void cutFacePointsFromNodes(std::vector& points, const std::vector>& nodes, bool isRing = false, 47 | std::vector* pointsIds = nullptr); 48 | 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /dust3d/base/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_DEBUG_H_ 24 | #define DUST3D_BASE_DEBUG_H_ 25 | 26 | #include 27 | 28 | namespace dust3d { 29 | 30 | class Debug { 31 | public: 32 | Debug() = default; 33 | 34 | Debug(Debug const&) = delete; 35 | 36 | Debug& operator=(Debug const&) = delete; 37 | 38 | Debug& operator=(Debug&&) = delete; 39 | 40 | Debug(Debug&& instance) noexcept 41 | : m_firstItem(false) 42 | { 43 | instance.m_lastItem = false; 44 | } 45 | 46 | ~Debug() 47 | { 48 | if (m_lastItem) 49 | std::cout << '\n'; 50 | } 51 | 52 | template 53 | friend Debug operator<<(Debug instance, const T& value) 54 | { 55 | if (instance.m_firstItem) 56 | instance.m_firstItem = false; 57 | else 58 | std::cout << ' '; 59 | 60 | std::cout << value; 61 | return instance; 62 | } 63 | 64 | private: 65 | bool m_firstItem = true; 66 | bool m_lastItem = true; 67 | }; 68 | 69 | } 70 | 71 | #ifndef dust3dDebug 72 | 73 | #define DEBUG_STRINGIZE1(x) #x 74 | #define DEBUG_STRINGIZE2(x) DEBUG_STRINGIZE1(x) 75 | 76 | #define dust3dDebug dust3d::Debug() << __FILE__ "(" DEBUG_STRINGIZE2(__LINE__) ")#" << __func__ << ":" 77 | 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /dust3d/base/math.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_MATH_H_ 24 | #define DUST3D_BASE_MATH_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | namespace Math { 31 | 32 | constexpr double Pi = 3.14159265358979323846; 33 | 34 | inline bool isZero(double number) 35 | { 36 | return std::abs(number) <= std::numeric_limits::epsilon(); 37 | } 38 | 39 | inline bool isEqual(double a, double b) 40 | { 41 | return isZero(a - b); 42 | } 43 | 44 | inline double radiansFromDegrees(double degrees) 45 | { 46 | return degrees * (Pi / 180.0); 47 | } 48 | 49 | inline double radiansToDegrees(double radians) 50 | { 51 | return radians * (180.0 / Pi); 52 | } 53 | 54 | } 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /dust3d/base/part_target.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | namespace dust3d { 26 | 27 | PartTarget PartTargetFromString(const char* targetString) 28 | { 29 | std::string target = targetString; 30 | if (target == "Model") 31 | return PartTarget::Model; 32 | if (target == "CutFace") 33 | return PartTarget::CutFace; 34 | if (target == "StitchingLine") 35 | return PartTarget::StitchingLine; 36 | return PartTarget::Model; 37 | } 38 | 39 | const char* PartTargetToString(PartTarget target) 40 | { 41 | switch (target) { 42 | case PartTarget::Model: 43 | return "Model"; 44 | case PartTarget::CutFace: 45 | return "CutFace"; 46 | case PartTarget::StitchingLine: 47 | return "StitchingLine"; 48 | default: 49 | return "Model"; 50 | } 51 | } 52 | 53 | std::string PartTargetToDispName(PartTarget target) 54 | { 55 | switch (target) { 56 | case PartTarget::Model: 57 | return std::string("Model"); 58 | case PartTarget::CutFace: 59 | return std::string("Cut Face"); 60 | case PartTarget::StitchingLine: 61 | return std::string("Stitching Line"); 62 | default: 63 | return std::string("Model"); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /dust3d/base/part_target.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_PART_TARGET_H_ 24 | #define DUST3D_BASE_PART_TARGET_H_ 25 | 26 | #include 27 | 28 | namespace dust3d { 29 | 30 | enum class PartTarget { 31 | Model = 0, 32 | CutFace, 33 | StitchingLine, 34 | Count 35 | }; 36 | 37 | PartTarget PartTargetFromString(const char* targetString); 38 | const char* PartTargetToString(PartTarget target); 39 | std::string PartTargetToDispName(PartTarget target); 40 | 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /dust3d/base/position_key.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | namespace dust3d { 26 | 27 | long PositionKey::m_toIntFactor = 100000; 28 | 29 | PositionKey::PositionKey(const Vector3& v) 30 | : PositionKey(v.x(), v.y(), v.z()) 31 | { 32 | } 33 | 34 | PositionKey::PositionKey(double x, double y, double z) 35 | { 36 | m_intX = (long)(x * m_toIntFactor); 37 | m_intY = (long)(y * m_toIntFactor); 38 | m_intZ = (long)(z * m_toIntFactor); 39 | } 40 | 41 | bool PositionKey::operator<(const PositionKey& right) const 42 | { 43 | if (m_intX < right.m_intX) 44 | return true; 45 | if (m_intX > right.m_intX) 46 | return false; 47 | if (m_intY < right.m_intY) 48 | return true; 49 | if (m_intY > right.m_intY) 50 | return false; 51 | if (m_intZ < right.m_intZ) 52 | return true; 53 | if (m_intZ > right.m_intZ) 54 | return false; 55 | return false; 56 | } 57 | 58 | bool PositionKey::operator==(const PositionKey& right) const 59 | { 60 | return m_intX == right.m_intX && m_intY == right.m_intY && m_intZ == right.m_intZ; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /dust3d/base/position_key.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_POSITION_KEY_H_ 24 | #define DUST3D_BASE_POSITION_KEY_H_ 25 | 26 | #include 27 | 28 | namespace dust3d { 29 | 30 | class PositionKey { 31 | public: 32 | PositionKey(const Vector3& v); 33 | PositionKey(double x, double y, double z); 34 | bool operator<(const PositionKey& right) const; 35 | bool operator==(const PositionKey& right) const; 36 | 37 | private: 38 | long m_intX; 39 | long m_intY; 40 | long m_intZ; 41 | 42 | static long m_toIntFactor; 43 | }; 44 | 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /dust3d/base/snapshot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_SNAPSHOT_H_ 24 | #define DUST3D_BASE_SNAPSHOT_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | 31 | class Snapshot { 32 | public: 33 | std::map canvas; 34 | std::map> nodes; 35 | std::map> edges; 36 | std::map> parts; 37 | std::map> components; 38 | std::map rootComponent; 39 | }; 40 | 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /dust3d/base/snapshot_xml.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_SNAPSHOT_XML_H_ 24 | #define DUST3D_BASE_SNAPSHOT_XML_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | 31 | void loadSnapshotFromXmlString(Snapshot* snapshot, char* xmlString); 32 | void saveSnapshotToXmlString(const Snapshot& snapshot, std::string& xmlString); 33 | 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /dust3d/base/string.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | namespace dust3d { 27 | namespace String { 28 | 29 | std::string join(const std::vector& stringList, const char* separator) 30 | { 31 | return std::accumulate(stringList.begin(), stringList.end(), std::string(), 32 | [=](const std::string& a, const std::string& b) -> std::string { 33 | return a + (a.length() > 0 ? separator : "") + b; 34 | }); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dust3d/base/texture_type.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_BASE_TEXTURE_TYPE_H_ 24 | #define DUST3D_BASE_TEXTURE_TYPE_H_ 25 | 26 | #include 27 | 28 | namespace dust3d { 29 | 30 | enum class TextureType { 31 | None, 32 | BaseColor, 33 | Normal, 34 | Metallic, 35 | Roughness, 36 | AmbientOcclusion, 37 | Count 38 | }; 39 | 40 | const char* TextureTypeToString(TextureType type); 41 | TextureType TextureTypeFromString(const char* typeString); 42 | std::string TextureTypeToDispName(TextureType type); 43 | 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /dust3d/base/uuid.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | namespace dust3d { 26 | 27 | Uuid::RandomGenerator* Uuid::m_generator = new Uuid::RandomGenerator; 28 | 29 | } // namespace dust3d 30 | -------------------------------------------------------------------------------- /dust3d/base/vector3.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | namespace dust3d { 26 | 27 | Vector3 Vector3::rotated(const Vector3& unitAxis, double angle) const 28 | { 29 | double c = std::cos(angle); 30 | double s = std::sin(angle); 31 | return *this * c + Vector3::crossProduct(unitAxis, *this) * s + unitAxis * Vector3::dotProduct(unitAxis, *this) * (1.0 - c); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /dust3d/mesh/base_normal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2022 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_BASE_NORMAL_H_ 24 | #define DUST3D_MESH_BASE_NORMAL_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | 31 | class BaseNormal { 32 | public: 33 | static std::pair findNearestAxis(const Vector3& direction); 34 | static inline const Vector3& axisDirection(size_t index) 35 | { 36 | static const std::vector axisList = { 37 | Vector3 { 1, 0, 0 }, 38 | Vector3 { 0, 1, 0 }, 39 | Vector3 { 0, 0, 1 }, 40 | }; 41 | return axisList[index]; 42 | } 43 | static inline const Vector3& nextAxisDirection(size_t index) 44 | { 45 | return axisDirection((index + 1) % 3); 46 | } 47 | static std::vector calculateCircleVertices(double radius, 48 | size_t points, 49 | const Vector3& aroundAxis = Vector3(0.0, 0.0, 1.0), 50 | const Vector3& startDirection = Vector3(0.0, 1.0, 0.0), 51 | const Vector3& origin = Vector3(0.0, 0.0, 0.0)); 52 | static Vector3 calculateCircleBaseNormal(const std::vector& vertices); 53 | static Vector3 calculateTubeBaseNormal(const std::vector& vertices); 54 | }; 55 | 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /dust3d/mesh/centripetal_catmull_rom_spline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_CENTRIPETAL_CATMULL_ROM_SPLINE_H_ 24 | #define DUST3D_MESH_CENTRIPETAL_CATMULL_ROM_SPLINE_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | 31 | class CentripetalCatmullRomSpline { 32 | public: 33 | struct SplineNode { 34 | int source = -1; 35 | Vector3 position; 36 | }; 37 | 38 | CentripetalCatmullRomSpline(bool isClosed); 39 | void addPoint(int source, const Vector3& position, bool isKnot); 40 | bool interpolate(); 41 | const std::vector& splineNodes(); 42 | 43 | private: 44 | std::vector m_splineNodes; 45 | std::vector m_splineKnots; 46 | 47 | bool m_isClosed = false; 48 | bool interpolateClosed(); 49 | bool interpolateOpened(); 50 | float atKnot(float t, const Vector3& p0, const Vector3& p1); 51 | void interpolateSegment(std::vector& knots, 52 | size_t from, size_t to); 53 | }; 54 | 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /dust3d/mesh/hole_stitcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_HOLE_STITCHER_H_ 24 | #define DUST3D_MESH_HOLE_STITCHER_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace dust3d { 31 | 32 | class HoleStitcher { 33 | public: 34 | ~HoleStitcher(); 35 | void setVertices(const std::vector* vertices); 36 | bool stitch(const std::vector, Vector3>>& edgeLoops); 37 | const std::vector>& newlyGeneratedFaces(); 38 | void getFailedEdgeLoops(std::vector& failedEdgeLoops); 39 | 40 | private: 41 | const std::vector* m_positions; 42 | std::vector> m_newlyGeneratedFaces; 43 | HoleWrapper* m_wrapper = nullptr; 44 | 45 | bool stitchByQuads(const std::vector, Vector3>>& edgeLoops); 46 | }; 47 | 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /dust3d/mesh/mesh_combiner.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_MESH_COMBINER_H_ 24 | #define DUST3D_MESH_MESH_COMBINER_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace dust3d { 32 | 33 | class MeshCombiner { 34 | public: 35 | enum class Method { 36 | Union, 37 | Diff 38 | }; 39 | 40 | enum class Source { 41 | None, 42 | First, 43 | Second 44 | }; 45 | 46 | class Mesh { 47 | public: 48 | Mesh() = default; 49 | Mesh(const std::vector& vertices, const std::vector>& faces); 50 | Mesh(const Mesh& other); 51 | ~Mesh(); 52 | void fetch(std::vector& vertices, std::vector>& faces) const; 53 | bool isNull() const; 54 | 55 | friend MeshCombiner; 56 | 57 | private: 58 | std::unique_ptr m_solidMesh; 59 | std::unique_ptr> m_vertices; 60 | std::unique_ptr>> m_triangles; 61 | }; 62 | 63 | static Mesh* combine(const Mesh& firstMesh, const Mesh& secondMesh, Method method, 64 | std::vector>* combinedVerticesComeFrom = nullptr); 65 | }; 66 | 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /dust3d/mesh/mesh_node.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2022 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_MESH_NODE_H_ 24 | #define DUST3D_MESH_MESH_NODE_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | 31 | struct MeshNode { 32 | Vector3 origin; 33 | double radius; 34 | Uuid sourceId; 35 | }; 36 | 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /dust3d/mesh/mesh_state.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2022 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_MESH_STATE_H_ 24 | #define DUST3D_MESH_MESH_STATE_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace dust3d { 31 | 32 | class MeshState { 33 | public: 34 | std::unique_ptr mesh; 35 | std::vector, std::array>> seamTriangleUvs; 36 | std::vector> brokenTriangles; 37 | 38 | MeshState() = default; 39 | MeshState(const std::vector& vertices, const std::vector>& faces); 40 | MeshState(const MeshState& other); 41 | void fetch(std::vector& vertices, std::vector>& faces) const; 42 | bool isNull() const; 43 | static std::unique_ptr combine(const MeshState& first, const MeshState& second, 44 | MeshCombiner::Method method); 45 | static bool isWatertight(const std::vector>& faces); 46 | }; 47 | 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /dust3d/mesh/resolve_triangle_tangent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_RESOLVE_TRIANGLE_TANGENT_H_ 24 | #define DUST3D_MESH_RESOLVE_TRIANGLE_TANGENT_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | 31 | void resolveTriangleTangent(const dust3d::Object& object, std::vector& tangents); 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /dust3d/mesh/rope_mesh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2022 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_ROPE_MESH_H_ 24 | #define DUST3D_MESH_ROPE_MESH_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | 31 | class RopeMesh { 32 | public: 33 | struct BuildParameters { 34 | double defaultRadius = 0.008; 35 | size_t sectionSegments = 8; 36 | }; 37 | 38 | RopeMesh(const BuildParameters& parameters); 39 | void addRope(const std::vector& positions, bool isCircle); 40 | const std::vector& resultVertices(); 41 | const std::vector>& resultTriangles(); 42 | 43 | private: 44 | std::vector m_resultVertices; 45 | std::vector> m_resultTriangles; 46 | BuildParameters m_buildParameters; 47 | std::vector cornerInterpolated(const std::vector& positions, double cornerRadius, bool isCircle); 48 | }; 49 | 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /dust3d/mesh/section_remesher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2022 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_SECTION_REMESHER_H_ 24 | #define DUST3D_MESH_SECTION_REMESHER_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace dust3d { 31 | 32 | class SectionRemesher { 33 | public: 34 | SectionRemesher(const std::vector& vertices, double ringV, double centerV); 35 | void remesh(); 36 | const std::vector& generatedVertices(); 37 | const std::vector>& generatedFaces(); 38 | const std::vector>& generatedFaceUvs(); 39 | 40 | private: 41 | std::vector> m_generatedFaces; 42 | std::vector> m_generatedFaceUvs; 43 | 44 | std::vector m_vertices; 45 | double m_ringV = 0.0; 46 | double m_centerV = 0.0; 47 | std::vector m_ringUs; 48 | 49 | void remeshConvex(const std::vector& ringVertices, const std::vector& ringUs); 50 | bool isConvex(const std::vector& ringVertices); 51 | }; 52 | 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /dust3d/mesh/smooth_normal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_SMOOTH_NORMAL_H_ 24 | #define DUST3D_MESH_SMOOTH_NORMAL_H_ 25 | 26 | #include 27 | 28 | namespace dust3d { 29 | 30 | void smoothNormal(const std::vector& vertices, 31 | const std::vector>& triangles, 32 | const std::vector& triangleNormals, 33 | const std::vector* thresholdAngleDegrees, 34 | std::vector>* triangleVertexNormals); 35 | 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /dust3d/mesh/triangulate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_TRIANGULATE_H_ 24 | #define DUST3D_MESH_TRIANGULATE_H_ 25 | 26 | #include 27 | 28 | namespace dust3d { 29 | 30 | void triangulate(const std::vector& vertices, 31 | const std::vector& faceIndices, 32 | std::vector>* triangles); 33 | 34 | void triangulate(const std::vector& vertices, 35 | const std::vector>& faces, 36 | std::vector>* triangles); 37 | 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /dust3d/mesh/trim_vertices.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_MESH_TRIM_VERTICES_H_ 24 | #define DUST3D_MESH_TRIM_VERTICES_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace dust3d { 30 | 31 | void trimVertices(std::vector* vertices, bool normalize); 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /dust3d/uv/chart_packer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | */ 22 | 23 | #ifndef DUST3D_UV_CHART_PACKER_H_ 24 | #define DUST3D_UV_CHART_PACKER_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace dust3d { 31 | 32 | class ChartPacker { 33 | public: 34 | void setCharts(const std::vector>& chartSizes); 35 | const std::vector>& getResult(); 36 | float pack(); 37 | bool tryPack(float textureSize); 38 | 39 | private: 40 | double calculateTotalArea(); 41 | 42 | std::vector> m_chartSizes; 43 | std::vector> m_result; 44 | float m_initialAreaGuessFactor = 1.1; 45 | float m_textureSizeGrowFactor = 0.05; 46 | float m_floatToIntFactor = 10000; 47 | size_t m_tryNum = 0; 48 | float m_textureSizeFactor = 1.0; 49 | float m_paddingSize = 0.005; 50 | size_t m_maxTryNum = 100; 51 | }; 52 | 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /third_party/GuigueDevillers03/tri_tri_intersect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Triangle-Triangle Overlap Test Routines 4 | * July, 2002 5 | * Updated December 2003 6 | * 7 | * This file contains C implementation of algorithms for 8 | * performing two and three-dimensional triangle-triangle intersection test 9 | * The algorithms and underlying theory are described in 10 | * 11 | * "Fast and Robust Triangle-Triangle Overlap Test 12 | * Using Orientation Predicates" P. Guigue - O. Devillers 13 | * 14 | * Journal of Graphics Tools, 8(1), 2003 15 | * 16 | * Several geometric predicates are defined. Their parameters are all 17 | * points. Each point is an array of two or three double precision 18 | * floating point numbers. The geometric predicates implemented in 19 | * this file are: 20 | * 21 | * int tri_tri_overlap_test_3d(p1,q1,r1,p2,q2,r2) 22 | * int tri_tri_overlap_test_2d(p1,q1,r1,p2,q2,r2) 23 | * 24 | * int tri_tri_intersection_test_3d(p1,q1,r1,p2,q2,r2, 25 | * coplanar,source,target) 26 | * 27 | * is a version that computes the segment of intersection when 28 | * the triangles overlap (and are not coplanar) 29 | * 30 | * each function returns 1 if the triangles (including their 31 | * boundary) intersect, otherwise 0 32 | * 33 | * 34 | * Other information are available from the Web page 35 | * http://www.acm.org/jgt/papers/GuigueDevillers03/ 36 | * 37 | */ 38 | 39 | #ifndef TRI_TRI_INTERSECT_H 40 | #define TRI_TRI_INTERSECT_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | int tri_tri_intersection_test_3d(double p1[3], double q1[3], double r1[3], 47 | double p2[3], double q2[3], double r2[3], 48 | int * coplanar, 49 | double source[3],double target[3]); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /third_party/earcut.hpp/LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2015, Mapbox 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any purpose 6 | with or without fee is hereby granted, provided that the above copyright notice 7 | and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 11 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 13 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 15 | THIS SOFTWARE. 16 | 17 | MIT License for modified changes 18 | Copyright (c) 2016-2021 Jeremy HU . All rights reserved. 19 | --------------------------------------------------------------------------------