├── .gitattributes
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── TODO.md
├── core
├── CMakeLists.txt
├── include
│ └── HMP
│ │ ├── Actions
│ │ ├── Delete.hpp
│ │ ├── DeleteSome.hpp
│ │ ├── Extrude.hpp
│ │ ├── ExtrudeUtils.hpp
│ │ ├── FitCircle.hpp
│ │ ├── MakeConforming.hpp
│ │ ├── Pad.hpp
│ │ ├── Paste.hpp
│ │ ├── Project.hpp
│ │ ├── Refine.hpp
│ │ ├── RefineSome.hpp
│ │ ├── Root.hpp
│ │ ├── Smooth.hpp
│ │ ├── SplitPlane.hpp
│ │ ├── SubdivideAll.hpp
│ │ └── Transform.hpp
│ │ ├── Commander.hpp
│ │ ├── Dag
│ │ ├── Delete.hpp
│ │ ├── Element.hpp
│ │ ├── Extrude.hpp
│ │ ├── Node.hpp
│ │ ├── Node.tpp
│ │ ├── NodeHandle.hpp
│ │ ├── NodeHandle.tpp
│ │ ├── NodeSet.hpp
│ │ ├── NodeSet.tpp
│ │ ├── Operation.hpp
│ │ ├── Refine.hpp
│ │ └── Utils.hpp
│ │ ├── Meshing
│ │ ├── Mesher.hpp
│ │ ├── Utils.hpp
│ │ ├── Utils.tpp
│ │ └── types.hpp
│ │ ├── Project.hpp
│ │ ├── Projection
│ │ ├── Match.hpp
│ │ ├── Utils.hpp
│ │ ├── Utils.tpp
│ │ ├── altProject.hpp
│ │ ├── fill.hpp
│ │ ├── jacobianAdvance.hpp
│ │ ├── percentileAdvance.hpp
│ │ ├── project.hpp
│ │ └── smooth.hpp
│ │ ├── Refinement
│ │ ├── Scheme.hpp
│ │ ├── Schemes.hpp
│ │ ├── Sub3x3AdapterCandidate.hpp
│ │ ├── Sub3x3AdapterCandidateSet.hpp
│ │ └── Utils.hpp
│ │ └── Utils
│ │ ├── DerefRanged.hpp
│ │ ├── MapRanged.hpp
│ │ └── Serialization.hpp
└── src
│ ├── Actions
│ ├── Delete.cpp
│ ├── DeleteSome.cpp
│ ├── Extrude.cpp
│ ├── ExtrudeUtils.cpp
│ ├── FitCircle.cpp
│ ├── MakeConforming.cpp
│ ├── Pad.cpp
│ ├── Paste.cpp
│ ├── Project.cpp
│ ├── Refine.cpp
│ ├── RefineSome.cpp
│ ├── Root.cpp
│ ├── Smooth.cpp
│ ├── SplitPlane.cpp
│ ├── SubdivideAll.cpp
│ └── Transform.cpp
│ ├── Commander.cpp
│ ├── Dag
│ ├── Delete.cpp
│ ├── Element.cpp
│ ├── Extrude.cpp
│ ├── Node.cpp
│ ├── NodeSet.cpp
│ ├── Operation.cpp
│ ├── Refine.cpp
│ └── Utils.cpp
│ ├── Meshing
│ ├── Mesher.cpp
│ └── Utils.cpp
│ ├── Project.cpp
│ ├── Projection
│ ├── Match.cpp
│ ├── Utils.cpp
│ ├── altProject.cpp
│ ├── fill.cpp
│ ├── jacobianAdvance.cpp
│ ├── percentileAdvance.cpp
│ ├── project.cpp
│ └── smooth.cpp
│ ├── Refinement
│ ├── Scheme.cpp
│ ├── Schemes.cpp
│ ├── Sub3x3AdapterCandidate.cpp
│ ├── Sub3x3AdapterCandidateSet.cpp
│ └── Utils.cpp
│ └── Utils
│ └── Serialization.cpp
├── gui
├── CMakeLists.txt
├── include
│ └── HMP
│ │ └── Gui
│ │ ├── App.hpp
│ │ ├── DagViewer
│ │ ├── Layout.hpp
│ │ ├── Widget.hpp
│ │ └── createLayout.hpp
│ │ ├── SidebarWidget.hpp
│ │ ├── Utils
│ │ ├── Controls.hpp
│ │ ├── Controls.tpp
│ │ ├── Drawing.hpp
│ │ ├── FilePicking.hpp
│ │ ├── HrDescriptions.hpp
│ │ ├── Theme.hpp
│ │ ├── Themer.hpp
│ │ └── Transform.hpp
│ │ ├── Widget.hpp
│ │ ├── Widgets
│ │ ├── Actions.hpp
│ │ ├── Ae3d2ShapeExporter.hpp
│ │ ├── Axes.hpp
│ │ ├── Commander.hpp
│ │ ├── Debug.hpp
│ │ ├── DirectVertEdit.hpp
│ │ ├── Highlight.hpp
│ │ ├── Pad.hpp
│ │ ├── Projection.hpp
│ │ ├── Projection.tpp
│ │ ├── Save.hpp
│ │ ├── Smooth.hpp
│ │ ├── Target.hpp
│ │ └── VertEdit.hpp
│ │ └── themer.hpp
└── src
│ ├── App.cpp
│ ├── DagViewer
│ ├── Layout.cpp
│ ├── Widget.cpp
│ └── createLayout.cpp
│ ├── SidebarWidget.cpp
│ ├── Utils
│ ├── Controls.cpp
│ ├── Drawing.cpp
│ ├── FilePicking.cpp
│ ├── HrDescriptions.cpp
│ ├── Theme.cpp
│ ├── Themer.cpp
│ └── Transform.cpp
│ ├── Widget.cpp
│ ├── Widgets
│ ├── Actions.cpp
│ ├── Ae3d2ShapeExporter.cpp
│ ├── Axes.cpp
│ ├── Commander.cpp
│ ├── Debug.cpp
│ ├── DirectVertEdit.cpp
│ ├── Highlight.cpp
│ ├── Pad.cpp
│ ├── Projection.cpp
│ ├── Save.cpp
│ ├── Smooth.cpp
│ ├── Target.cpp
│ └── VertEdit.cpp
│ ├── main.cpp
│ └── themer.cpp
├── models.zip
├── models
├── Fig1
│ └── Cow.mesh
├── Fig12
│ ├── CAD10.mesh
│ ├── CAD11.mesh
│ ├── CAD2.mesh
│ ├── CAD3.mesh
│ ├── CAD4.mesh
│ ├── CAD6.mesh
│ ├── CAD9.mesh
│ ├── Cogwheel2.mesh
│ ├── Curve.mesh
│ ├── Cylinders1.mesh
│ └── Rocket.mesh
├── Fig13
│ ├── Block.mesh
│ ├── CAD1.mesh
│ ├── CAD5.mesh
│ ├── CAD7.mesh
│ ├── CAD8.mesh
│ ├── Cactus.mesh
│ ├── Cylinders2.mesh
│ ├── Ghost.mesh
│ ├── Indorelax.mesh
│ ├── Knob.mesh
│ ├── Torus.mesh
│ └── Vertebra.mesh
├── Fig14
│ ├── Hollow-sphere.mesh
│ └── Tic-tac-toe.mesh
├── Fig15
│ └── SGP.mesh
├── Fig17
│ └── Cogwheel1.mesh
└── Fig2
│ ├── hole.mesh
│ ├── twisting.mesh
│ ├── val11.mesh
│ ├── val3.mesh
│ └── val5.mesh
├── schemes
├── adapter2FacesSubdivide3x3.rse
├── adapterEdgeSubdivide3x3.rse
├── adapterFaceSubdivide3x3.rse
├── inset.rse
├── planeSplit
├── subdivide2x2.rse
└── subdivide3x3.rse
├── tutorials.md
└── videos.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Visual Studio
2 | .vs/
3 | CMakePresets.json
4 | CMakeSettings.json
5 | cmake-build-debug
6 | .idea
7 |
8 | # Visual Studio Code
9 | .vscode/
10 |
11 | # MacOS
12 | .DS_Store
13 |
14 | # CMake output
15 | out/
16 | build/
17 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 3.14)
2 |
3 | include (FetchContent)
4 | set (FETCHCONTENT_QUIET FALSE)
5 |
6 | project ("HexBox" VERSION 0.3)
7 |
8 | add_compile_definitions(HMP_NAME=\"${CMAKE_PROJECT_NAME}\")
9 | add_compile_definitions(HMP_VERSION=\"${CMAKE_PROJECT_VERSION}\")
10 |
11 | option (HMP_GUI_ENABLE_DAG_VIEWER "Enable dag viewer widget" OFF)
12 | option (HMP_GUI_ENABLE_AE3D2SHAPE_EXPORTER "Enable ae-3d2shape exporter" OFF)
13 | option (HMP_ENABLE_ALT_PROJ "Enable alternative projection" ON)
14 | option (HMP_AGGRESSIVE_DEBUG "Enable ASAN and debug libc" OFF)
15 | option (HMP_AGGRESSIVE_WARNINGS "Enable a lot of warnings" OFF)
16 | option (HMP_GUI_CAPTURE "Setup for recording modeling sessions" OFF)
17 |
18 | # cinolib
19 | set (CINOLIB_HEADER_ONLY OFF)
20 | set (CINOLIB_USES_OPENGL_GLFW_IMGUI ON)
21 | FetchContent_Declare (
22 | cinolib
23 | GIT_REPOSITORY "https://github.com/francescozoccheddu/cinolib.git"
24 | GIT_TAG "ad8f8ca2884b56de958b237ff28eb47b0646daf3"
25 | GIT_SHALLOW TRUE
26 | GIT_PROGRESS TRUE
27 | )
28 | FetchContent_MakeAvailable (cinolib)
29 |
30 | # ogdf
31 | if (HMP_GUI_ENABLE_DAG_VIEWER)
32 | FetchContent_Declare (
33 | ogdf
34 | GIT_REPOSITORY "https://github.com/ogdf/ogdf.git"
35 | GIT_TAG "dogwood-202202"
36 | GIT_SHALLOW TRUE
37 | GIT_PROGRESS TRUE
38 | )
39 | FetchContent_MakeAvailable (ogdf)
40 | endif()
41 |
42 | # fprotais/hexsmoothing
43 | if (HMP_ENABLE_ALT_PROJ)
44 | add_compile_definitions(HMP_ENABLE_ALT_PROJ)
45 | FetchContent_Declare (
46 | fprotais
47 | GIT_REPOSITORY "https://github.com/fprotais/hexsmoothing"
48 | GIT_TAG "b538f7270d91a5e8baaa25287c06ab4a5c5d4cfb"
49 | GIT_SHALLOW FALSE
50 | GIT_PROGRESS TRUE
51 | )
52 | FetchContent_MakeAvailable (fprotais)
53 | endif()
54 |
55 | # updatable_priority_queue
56 | FetchContent_Declare (
57 | updatable_priority_queue
58 | GIT_REPOSITORY "https://github.com/Ten0/updatable_priority_queue.git"
59 | GIT_TAG "8a7facc90855f64ad463d7edd393eff0fc6d97af"
60 | GIT_PROGRESS TRUE
61 | )
62 | FetchContent_MakeAvailable (updatable_priority_queue)
63 |
64 | # cpputils
65 | FetchContent_Declare (
66 | cpputils
67 | GIT_REPOSITORY "https://github.com/francescozoccheddu/cpputils.git"
68 | GIT_TAG "56414519fe56d47413def942ecd29073d1c5be8e"
69 | GIT_SHALLOW FALSE
70 | GIT_PROGRESS TRUE
71 | )
72 | FetchContent_MakeAvailable (cpputils)
73 |
74 | # hexa-modeling-prototype
75 | add_subdirectory ("core")
76 | add_subdirectory ("gui")
77 |
78 | # compile options
79 |
80 | if (HMP_AGGRESSIVE_DEBUG)
81 | add_compile_definitions(_GLIBCXX_DEBUG HMP_AGGRESSIVE_DEBUG)
82 | add_compile_options(-fsanitize=address)
83 | add_link_options(-fsanitize=address)
84 | endif()
85 |
86 | if (HMP_AGGRESSIVE_WARNINGS)
87 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
88 | target_compile_options(core PRIVATE -Wall -Wextra -Wpedantic -Wconversion -Wunused)
89 | target_compile_options(gui PRIVATE -Wall -Wextra -Wpedantic -Wconversion -Wunused)
90 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
91 | target_compile_options(core PRIVATE /W4)
92 | target_compile_options(gui PRIVATE /W4)
93 | endif()
94 | endif()
95 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023
4 | F. Zoccheddu, E. Gobbetti, M. Livesu, N. Pietroni, G. Cherchi
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 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,
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 THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HexBox: Interactive Box Modeling of Hexahedral Meshes
2 |
3 | > **Note**
4 | > We are preparing an amazing tutorial on how to use HexBox. Stay tuned :wink:
5 |
6 |

7 |
8 | HexBox is an intuitive modeling method and interactive tool for creating and editing hexahedral meshes.
9 | Hexbox brings the major and widely validated surface modeling paradigm of surface box modeling into the world of hex meshing.
10 | This is the reference implementation of the paper
11 |
12 | [***HexBox: Interactive Box Modeling of Hexahedral Meshes***](https://www.gianmarcocherchi.com/pdf/hexbox.pdf)
13 | F. Zoccheddu, [E. Gobbetti](https://www.crs4.it/peopledetails/8/enrico-gobbetti/), [M. Livesu](http://pers.ge.imati.cnr.it/livesu/), [N. Pietroni](https://www.nicopietroni.com), [G. Cherchi](http://www.gianmarcocherchi.com)
14 | _Computer Graphics Forum (SGP 2023)_
15 |
16 | ## Setup
17 |
18 | 1. Clone this repository:
19 |
20 | ```Shell
21 | git clone https://github.com/cg3hci/HexBox.git
22 | cd HexBox
23 | ```
24 |
25 | 2. Generate the build system:
26 |
27 | ```Shell
28 | mkdir build
29 | cd build
30 | cmake ..
31 | ```
32 |
33 | 3. Build:
34 |
35 | ```Shell
36 | cmake --build .
37 | ```
38 |
39 | 4. Run the `gui` executable.
40 |
41 | 5. Enjoy! 😉
42 |
43 | > **Note**
44 | > We are preparing a tutorial on how to use HexBox. Meanwhile, we print the list of commands and shortcuts in the terminal.
45 |
46 | ## Compatibility
47 |
48 | HexBox requires [CMake](https://cmake.org/) 3.14+, a modern C++20 compiler, and OpenGL 2.0. As of today, it has been successfully tested on MSVC v143 on Windows 11, GCC 10 and Clang 14 on Ubuntu 22.10 and Clang 14 on MacOS.
49 |
50 | ## Videos, Tutorials and Models
51 |
52 | HexBox is meant to be a live project. On [this](videos.md) page you can find the video examples that were originally attached to the SGP submission. We are operating to create additional tutorials and tips & tricks to build a community around our tool, helping users to make the best of it.
53 |
54 | **[Tutorials](tutorials.md)**
55 |
56 | **[Here](models.zip)** you can find the models we shown in the paper, produced with our tool.
57 |
58 | ## Acknowledgement
59 |
60 | If you use HexBox on your projects, please consider citing our paper using the following BibTeX entry:
61 |
62 | ```bibtex
63 | @article{hexbox2023,
64 | title = {HexBox: Interactive Box Modeling of Hexahedral Meshes},
65 | author = {Zoccheddu, F. and Gobbetti, E. and Livesu, M. and Pietroni, N. and Cherchi, G.},
66 | journal = {Computer Graphics Forum},
67 | volume = {42},
68 | number = {5},
69 | year = {2023},
70 | issn = {1467-8659},
71 | doi = {10.1111/cgf.14899}
72 | }
73 | ```
74 |
75 |
76 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | # Issues and possible improvements
2 | Sorted by priority:
3 | - **\[IMPROVEMENT\]** Revert `HMP::Actions::ExtrudeUtils::apply` new vertex creation to the old method.
4 | - **\[IMPROVEMENT\]** `HMP::Projection::jacobianAdvance` is too defensive. Try working on one vertex at a time somehow.
5 | - **\[FEATURE\]** Add a negative weight factor for elements with multiple faces on surface in `HMP::Projection::smoothInternal`.
6 | - **\[BUG\]** `HMP::Dag::Extrude` and `HMP::Dag::Refine` relative fis and vis are cloned incorrectly during a paste operation, so I am recalculating them from scratch in `HMP::Actions::Paste::fixAdjacencies_TEMP_NAIVE`. This implies that:
7 | 1. The otherwise flawless "*Paste-the-same-way-to-get-the-same-result*" principle is violated (not a big deal; GUI helps a lot here);
8 | 2. I cannot profit from `HMP::Refinement::Scheme::facesSurfVisIs` until this is fixed.
9 | - **\[BUG\]** `HMP::Actions::Root::~Root()` leads to `HMP::Dag::Node` double free on app exit (I think the `HMP::Dag::Node` detachment system is broken).
10 | - **\[IMPROVEMENT\]** `HMP::Refinement::Utils::apply` should use `HMP::Refinement::Scheme::facesSurfVisIs` in place of `HMP::Refinement::Utils::weldAdjacencies_TEMP_NAIVE` (how do I rotate the scheme vertices and match the adjacent faces?).
11 | - **\[IMPROVEMENT\]** Improve `HMP::Actions::MakeConforming` either by implementing a balancing preprocessing phase, or by defining more adapter schemes.
12 | - **\[FEATURE\]** The extrude operation could automatically determine the number of parents, or at least give the user a warning in case of unintentionally duplicate vertices.
13 | - **\[IMPROVEMENT\]** `HMP::Actions::MakeConforming` performance can be improved a lot by keeping a queue of non-conforming refinements.
14 | - **\[FEATURE\]** Perhaps pasting a subtree should not preserve the source size (or maybe the choice could be left to the user).
15 | - **\[REFACTOR\]** `HMP::Meshing::Utils` is a dumpsite full of duplicated code. Keep the few essential primitives and throw everything else away.
16 | - **\[IMPROVEMENT\]** `OGDF` is overkill for what I need. Consider replacing it with a lighter implementation of the Sugiyama layout algorithm.
17 | - **\[IMPROVEMENT\]** The `HMP::Gui::Widgets::DirectVertEdit` scale and rotation implementation is a bit janky. (Also, a global axis-aligned translation feature would be welcome).
18 | - **\[FEATURE\]** Add a command to select all the vertices in a subtree.
19 | - **\[FEATURE\]** Allow the user to change the transform origin when editing vertices (or add a command to lock the origin in the current location).
20 | - **\[FEATURE\]** Add As-Rigid-As-Possible vertex editing support.
21 | - **\[REFACTOR\]** All the `HMP::Meshing::Actions` could be replaced with a set of more primitive actions (`MoveVert`, `ShowElement`, `AddElements`, `WeldElements` and `ActionSequence` maybe?).
22 | - **\[IMPROVEMENT\]** The `HMP::Gui::DagViewer::Widget` view should try to remain stable on layout change.
23 | - **\[IMPROVEMENT\]** The camera pan speed could be adjusted depending on the relative mesh position (as I do in the `HMP::Gui::Widgets::DirectVertEdit` translation operation).
24 |
--------------------------------------------------------------------------------
/core/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 3.14)
2 |
3 | add_library (core STATIC
4 | "src/Actions/Delete.cpp"
5 | "src/Actions/DeleteSome.cpp"
6 | "src/Actions/FitCircle.cpp"
7 | "src/Actions/Extrude.cpp"
8 | "src/Actions/Root.cpp"
9 | "src/Actions/MakeConforming.cpp"
10 | "src/Actions/Paste.cpp"
11 | "src/Actions/Project.cpp"
12 | "src/Actions/Refine.cpp"
13 | "src/Actions/RefineSome.cpp"
14 | "src/Actions/Transform.cpp"
15 | "src/Actions/ExtrudeUtils.cpp"
16 | "src/Actions/Pad.cpp"
17 | "src/Actions/Smooth.cpp"
18 | "src/Actions/SubdivideAll.cpp"
19 | "src/Actions/SplitPlane.cpp"
20 | "src/Dag/Delete.cpp"
21 | "src/Dag/Element.cpp"
22 | "src/Dag/Extrude.cpp"
23 | "src/Dag/Node.cpp"
24 | "src/Dag/NodeSet.cpp"
25 | "src/Dag/Operation.cpp"
26 | "src/Dag/Refine.cpp"
27 | "src/Dag/Utils.cpp"
28 | "src/Meshing/Mesher.cpp"
29 | "src/Meshing/Utils.cpp"
30 | "src/Refinement/Scheme.cpp"
31 | "src/Refinement/Schemes.cpp"
32 | "src/Refinement/Utils.cpp"
33 | "src/Refinement/Sub3x3AdapterCandidate.cpp"
34 | "src/Refinement/Sub3x3AdapterCandidateSet.cpp"
35 | "src/Projection/project.cpp"
36 | "src/Projection/Utils.cpp"
37 | "src/Projection/fill.cpp"
38 | "src/Projection/smooth.cpp"
39 | "src/Projection/percentileAdvance.cpp"
40 | "src/Projection/jacobianAdvance.cpp"
41 | "src/Projection/Match.cpp"
42 | "src/Utils/Serialization.cpp"
43 | "src/Commander.cpp"
44 | "src/Project.cpp"
45 | )
46 |
47 | set_target_properties (core PROPERTIES
48 | CXX_STANDARD 20
49 | CXX_EXTENSIONS OFF
50 | CXX_STANDARD_REQUIRED ON
51 | )
52 |
53 | if (MSVC AND CINOLIB_HEADER_ONLY)
54 | target_compile_options (core PRIVATE /bigobj)
55 | endif()
56 |
57 | target_include_directories (core
58 | PUBLIC "include"
59 | PRIVATE ${updatable_priority_queue_SOURCE_DIR}
60 | )
61 |
62 | target_link_libraries (core
63 | PUBLIC cinolib
64 | PUBLIC cpputils
65 | )
66 |
67 | if (HMP_ENABLE_ALT_PROJ)
68 |
69 | target_sources(core
70 | PRIVATE "src/Projection/altProject.cpp"
71 | )
72 |
73 | target_link_libraries(core
74 | PUBLIC libhexsmoothing
75 | )
76 |
77 | endif()
78 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Delete.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace HMP::Actions
9 | {
10 |
11 | class Delete final: public Commander::Action
12 | {
13 |
14 | private:
15 |
16 | Dag::Element& m_element;
17 | const Dag::NodeHandle m_operation;
18 |
19 | void apply() override;
20 | void unapply() override;
21 |
22 | public:
23 |
24 | Delete(Dag::Element& _element);
25 |
26 | const Dag::Element& element() const;
27 | const Dag::Delete& operation() const;
28 |
29 | };
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/DeleteSome.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | namespace HMP::Actions
13 | {
14 |
15 | class DeleteSome final : public Commander::Action
16 | {
17 |
18 | private:
19 |
20 |
21 | static std::pair dereferenceOperation(const std::pair, Dag::Element*>& _pair);
22 |
23 | const std::vector, Dag::Element* const>> m_operations;
24 |
25 | void apply() override;
26 | void unapply() override;
27 |
28 | public:
29 |
30 | using Operations = decltype(cpputils::range::ofc(m_operations).map(&dereferenceOperation));
31 |
32 | DeleteSome(const std::vector& _elements);
33 |
34 | Operations operations() const;
35 |
36 | };
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Extrude.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace HMP::Actions
12 | {
13 |
14 | class Extrude final: public Commander::Action
15 | {
16 |
17 | private:
18 |
19 | const cpputils::collections::FixedVector m_elements;
20 | const Dag::NodeHandle m_operation;
21 | Meshing::Mesher::State m_oldState;
22 |
23 | void apply() override;
24 | void unapply() override;
25 |
26 |
27 | public:
28 |
29 | using Elements = decltype(cpputils::range::ofc(m_elements).dereference().immutable());
30 |
31 | Extrude(const cpputils::collections::FixedVector& _elements, const cpputils::collections::FixedVector& _fis, I _firstVi, bool _clockwise);
32 |
33 | Elements elements() const;
34 |
35 | const Dag::Extrude& operation() const;
36 |
37 | };
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/ExtrudeUtils.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace HMP::Actions::ExtrudeUtils
12 | {
13 |
14 | HexVertIds apply(const Meshing::Mesher& _mesher, const Dag::Extrude& _extrude, std::vector& _newVerts);
15 |
16 | Dag::Extrude& prepare(const cpputils::collections::FixedVector& _fis, I _firstVi, bool _clockwise);
17 |
18 | }
--------------------------------------------------------------------------------
/core/include/HMP/Actions/FitCircle.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | namespace HMP::Actions
8 | {
9 |
10 | class FitCircle final : public Commander::Action
11 | {
12 |
13 | private:
14 |
15 | std::vector m_vids;
16 | std::vector m_otherVerts;
17 | bool m_prepared;
18 |
19 | void apply() override;
20 | void unapply() override;
21 |
22 | public:
23 |
24 | FitCircle(const std::vector& _vids);
25 |
26 | const std::vector& vids() const;
27 |
28 | };
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/MakeConforming.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | namespace HMP::Actions
15 | {
16 |
17 | class MakeConforming final: public Commander::Action
18 | {
19 |
20 | private:
21 |
22 | static std::pair dereferenceOperation(const std::pair, Dag::Element*>& _pair);
23 |
24 | std::vector, Dag::Element* const>> m_operations;
25 | Meshing::Mesher::State m_oldState;
26 | bool m_prepared;
27 |
28 | void apply() override;
29 | void unapply() override;
30 |
31 | void installSub3x3Adapters();
32 |
33 | public:
34 |
35 | using Operations = decltype(cpputils::range::ofc(m_operations).map(&dereferenceOperation));
36 |
37 | MakeConforming();
38 |
39 | Operations operations() const;
40 |
41 | };
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Pad.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace HMP::Actions
11 | {
12 |
13 | class Pad final: public Commander::Action
14 | {
15 |
16 | private:
17 |
18 | static std::pair dereferenceOperation(const std::pair>& _pair);
19 |
20 | const Real m_length;
21 | const I m_smoothIterations;
22 | const Real m_smoothSurfVertWeight;
23 | const Real m_cornerShrinkFactor;
24 | std::vector>> m_operations;
25 | std::vector m_otherVerts;
26 | std::vector m_newVerts;
27 | Meshing::Mesher::State m_oldState;
28 | bool m_prepared;
29 |
30 | void swapVerts();
31 | void apply() override;
32 | void unapply() override;
33 |
34 | public:
35 |
36 | using Operations = decltype(cpputils::range::ofc(m_operations).map(&dereferenceOperation));
37 |
38 | Pad(Real _length, I _smoothIterations = 1, Real _smoothSurfVertWeight = 1.0, Real _cornerShrinkFactor = 0.5);
39 |
40 | const Real length() const;
41 |
42 | const I smoothIterations() const;
43 |
44 | const Real smoothSurfVertWeight() const;
45 |
46 | const Real cornerShrinkFactor() const;
47 |
48 | Operations operations() const;
49 |
50 | };
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Paste.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace HMP::Actions
11 | {
12 |
13 | class Paste final: public Commander::Action
14 | {
15 |
16 | private:
17 |
18 | const cpputils::collections::FixedVector m_elements;
19 | const Dag::Extrude& m_sourceOperation;
20 | const cpputils::collections::FixedVector& m_fis;
21 | const I m_firstVi;
22 | const bool m_clockwise;
23 | Dag::NodeHandle m_operation;
24 | Meshing::Mesher::State m_oldState;
25 | bool m_prepared{ false };
26 | std::vector m_newVerts;
27 |
28 | void apply() override;
29 |
30 | void unapply() override;
31 |
32 | public:
33 |
34 | using Elements = decltype(cpputils::range::ofc(m_elements).dereference().immutable());
35 |
36 | Paste(const cpputils::collections::FixedVector& _elements, const cpputils::collections::FixedVector& _fis, I _firstVi, bool _clockwise, const Dag::Extrude& _source);
37 |
38 | Elements elements() const;
39 |
40 | const Dag::Extrude& operation() const;
41 |
42 | };
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Project.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace HMP::Actions
11 | {
12 |
13 | class Project final: public Commander::Action
14 | {
15 |
16 | public:
17 |
18 | using TargetMesh = cinolib::Polygonmesh<>;
19 |
20 | private:
21 |
22 | const TargetMesh m_target;
23 | const std::vector m_pointFeats;
24 | const std::vector m_pathFeats;
25 | const Projection::Options m_options;
26 | std::vector m_otherVerts;
27 | bool m_prepared;
28 |
29 | void apply() override;
30 | void unapply() override;
31 |
32 | public:
33 |
34 | Project(TargetMesh&& _target, const std::vector& _pointFeats, const std::vector& _pathFeats, const Projection::Options& _options);
35 | Project(const TargetMesh& _target, const std::vector& _pointFeats, const std::vector& _pathFeats, const Projection::Options& _options);
36 |
37 | const TargetMesh& target() const;
38 |
39 | const Projection::Options options() const;
40 |
41 | };
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Refine.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace HMP::Actions
12 | {
13 |
14 | class Refine final: public Commander::Action
15 | {
16 |
17 | private:
18 |
19 | const std::vector>> m_operations;
20 | const I m_depth;
21 | Meshing::Mesher::State m_oldState;
22 |
23 | void apply() override;
24 | void unapply() override;
25 |
26 | public:
27 |
28 | Refine(Dag::Element& _element, I _forwardFi, I _firstVi, Refinement::EScheme _scheme, I _depth = 1);
29 |
30 | const Dag::Element& element() const;
31 | const Dag::Refine& operation() const;
32 | I depth() const;
33 |
34 | };
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/RefineSome.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | namespace HMP::Actions
13 | {
14 |
15 | class RefineSome final : public Commander::Action
16 | {
17 |
18 | private:
19 |
20 |
21 | static std::pair dereferenceOperation(const std::pair, Dag::Element*>& _pair);
22 |
23 | const std::vector, Dag::Element* const>> m_operations;
24 | Meshing::Mesher::State m_oldState;
25 |
26 | void apply() override;
27 | void unapply() override;
28 |
29 | public:
30 |
31 | using Operations = decltype(cpputils::range::ofc(m_operations).map(&dereferenceOperation));
32 |
33 | RefineSome(const std::vector& _elements);
34 |
35 | Operations operations() const;
36 |
37 | };
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Root.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace HMP::Actions
9 | {
10 |
11 | class Root final: public Commander::Action
12 | {
13 |
14 | private:
15 |
16 | Dag::Element& m_newRoot;
17 | const std::vector m_newVerts;
18 | Dag::NodeHandle m_otherRoot;
19 | std::vector m_otherVerts;
20 |
21 | void apply() override;
22 | void unapply() override;
23 |
24 | public:
25 |
26 | Root(Dag::Element& _root, const std::vector& _verts);
27 |
28 | const Dag::Element& newRoot() const;
29 |
30 | const std::vector& newVerts() const;
31 |
32 | };
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Smooth.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace HMP::Actions
9 | {
10 |
11 | class Smooth final: public Commander::Action
12 | {
13 |
14 | private:
15 |
16 | const I m_surfIterations, m_internalIterations;
17 | const Real m_surfVertWeight;
18 | std::vector m_otherVerts;
19 | bool m_prepared;
20 |
21 | void apply() override;
22 | void unapply() override;
23 |
24 | public:
25 |
26 | Smooth(I _surfaceIterations, I _internalIterations, Real _surfVertWeight = 1.0);
27 |
28 | const I surfaceIterations() const;
29 |
30 | const I internalIterations() const;
31 |
32 | const Real surfVertWeight() const;
33 |
34 | };
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/SplitPlane.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | namespace HMP::Actions
13 | {
14 |
15 | class SplitPlane final : public Commander::Action
16 | {
17 |
18 | private:
19 |
20 | static std::pair dereferenceOperation(const std::pair, Dag::Element*>& _pair);
21 |
22 | std::vector, Dag::Element* const>> m_operations;
23 | Id m_eid;
24 | bool m_prepared;
25 | Meshing::Mesher::State m_oldState;
26 |
27 | void apply() override;
28 | void unapply() override;
29 |
30 | public:
31 |
32 | using Operations = decltype(cpputils::range::ofc(m_operations).map(&dereferenceOperation));
33 |
34 | SplitPlane(Id _eid);
35 |
36 | Id eid() const;
37 |
38 | Operations operations() const;
39 |
40 | };
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/SubdivideAll.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace HMP::Actions
10 | {
11 |
12 | class SubdivideAll final: public Commander::Action
13 | {
14 |
15 | private:
16 |
17 | static std::pair dereferenceOperation(const std::pair>& _pair);
18 |
19 | std::vector>> m_operations;
20 | Meshing::Mesher::State m_oldState;
21 | std::vector m_newVerts;
22 | bool m_prepared;
23 |
24 | void apply() override;
25 | void unapply() override;
26 |
27 | public:
28 |
29 | using Operations = decltype(cpputils::range::ofc(m_operations).map(&dereferenceOperation));
30 |
31 | SubdivideAll();
32 |
33 | Operations operations() const;
34 |
35 | };
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/core/include/HMP/Actions/Transform.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace HMP::Actions
11 | {
12 |
13 | class Transform final: public Commander::Action
14 | {
15 |
16 | private:
17 |
18 | const Mat4 m_transform;
19 | const std::optional> m_vids;
20 | std::vector m_otherVerts;
21 | bool m_prepared;
22 |
23 | void apply() override;
24 | void unapply() override;
25 |
26 | public:
27 |
28 | Transform(const Mat4& _transform, const std::optional>& _vids = std::nullopt);
29 |
30 | const Mat4& transform() const;
31 |
32 | const std::optional>& vids() const;
33 |
34 | };
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/core/include/HMP/Commander.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace HMP
10 | {
11 |
12 | class Project;
13 |
14 | class Commander final: public cpputils::mixins::ReferenceClass
15 | {
16 |
17 | public:
18 |
19 | class Action;
20 |
21 | class ActionBase: public cpputils::mixins::ReferenceClass
22 | {
23 |
24 | private:
25 |
26 | friend class Action;
27 |
28 | Commander* m_commander;
29 | bool m_applied;
30 |
31 | ActionBase();
32 |
33 | void attach(Commander& _commander);
34 |
35 | void prepareAndApply();
36 | void prepareAndUnapply();
37 |
38 | protected:
39 |
40 | virtual ~ActionBase() = default;
41 |
42 | Meshing::Mesher& mesher();
43 | const Meshing::Mesher& mesher() const;
44 |
45 | Dag::NodeHandle& root();
46 | const Dag::Element* root() const;
47 |
48 | virtual void apply() = 0;
49 | virtual void unapply() = 0;
50 |
51 | public:
52 |
53 | bool attached() const;
54 | bool applied() const;
55 |
56 | };
57 |
58 | class Stack;
59 |
60 | class StackBase: public cpputils::mixins::ReferenceClass, public HMP::Utils::ConstDerefRanged>
61 | {
62 |
63 | private:
64 |
65 | friend class Stack;
66 |
67 | std::deque m_data;
68 | I m_limit;
69 |
70 | StackBase();
71 |
72 | Action& pop();
73 | void push(Action& _action);
74 |
75 | public:
76 |
77 | I limit() const;
78 | void limit(I _count);
79 | void removeOldest(I _count);
80 | void keepLatest(I _count);
81 | void clear();
82 |
83 | };
84 |
85 | class Action: public ActionBase
86 | {
87 |
88 | private:
89 |
90 | friend class Commander;
91 |
92 | using ActionBase::attach;
93 | using ActionBase::prepareAndApply;
94 | using ActionBase::prepareAndUnapply;
95 |
96 | public:
97 |
98 | using ActionBase::ActionBase;
99 |
100 | };
101 |
102 | class Stack final: public StackBase
103 | {
104 |
105 | private:
106 |
107 | friend class Commander;
108 |
109 | using StackBase::StackBase;
110 | using StackBase::pop;
111 | using StackBase::push;
112 |
113 | };
114 |
115 | private:
116 |
117 | Project& m_project;
118 | Stack m_applied, m_unapplied;
119 |
120 | public:
121 |
122 | Commander(Project& _project);
123 | ~Commander();
124 |
125 | void apply(Action& _action);
126 |
127 | void undo();
128 | void redo();
129 |
130 | bool canUndo() const;
131 | bool canRedo() const;
132 |
133 | Stack& unapplied();
134 | const Stack& unapplied() const;
135 |
136 | Stack& applied();
137 | const Stack& applied() const;
138 |
139 |
140 | };
141 |
142 | }
--------------------------------------------------------------------------------
/core/include/HMP/Dag/Delete.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | namespace HMP::Dag
6 | {
7 |
8 | class Delete final : public Operation
9 | {
10 |
11 | public:
12 |
13 | Delete();
14 |
15 | };
16 |
17 | }
--------------------------------------------------------------------------------
/core/include/HMP/Dag/Element.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | namespace HMP::Dag
7 | {
8 |
9 | class Element final: public Node
10 | {
11 |
12 | public:
13 |
14 | using Set = NodeSet;
15 |
16 | private:
17 |
18 | using Node::isElement;
19 | using Node::isOperation;
20 | using Node::element;
21 | using Node::operation;
22 |
23 | public:
24 |
25 | Element();
26 |
27 | Set parents, children;
28 | HexVertIds vids;
29 | Id pid;
30 |
31 | Set& forward(bool _descending);
32 | const Set& forward(bool _descending) const;
33 | Set& back(bool _descending);
34 | const Set& back(bool _descending) const;
35 |
36 | };
37 |
38 | }
--------------------------------------------------------------------------------
/core/include/HMP/Dag/Extrude.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | namespace HMP::Dag
8 | {
9 |
10 | class Extrude final: public Operation
11 | {
12 |
13 | public:
14 |
15 | enum class ESource
16 | {
17 | Face, Edge, Vertex
18 | };
19 |
20 | static ESource sourceByParentCount(I _parentCount);
21 |
22 | Extrude();
23 |
24 | I firstVi;
25 | cpputils::collections::FixedVector fis;
26 | ESource source;
27 | bool clockwise;
28 |
29 | };
30 |
31 | }
--------------------------------------------------------------------------------
/core/include/HMP/Dag/Node.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace HMP::Dag
11 | {
12 |
13 | template , bool TDescending = true>
14 | class NodeHandle;
15 |
16 | class Element;
17 | class Operation;
18 |
19 | class Node : public cpputils::mixins::ReferenceClass
20 | {
21 |
22 | private:
23 |
24 | static I s_allocatedNodeCount;
25 |
26 | public:
27 |
28 | static I allocatedNodeCount();
29 |
30 | public:
31 |
32 | using Set = NodeSet;
33 |
34 | enum class EType
35 | {
36 | Element, Operation
37 | };
38 |
39 | private:
40 |
41 | template , bool>
42 | friend class NodeHandle;
43 |
44 | Internal::NodeSetData m_parentsImpl, m_childrenImpl;
45 |
46 | I m_handles;
47 |
48 | static void deleteDangling(std::queue& _dangling, bool _descending);
49 | bool onAttach(Node& _node, bool _descending);
50 | bool onDetach(Node& _node, bool _deleteDangling, bool _descending);
51 | bool onDetachAll(bool _deleteDangling, bool _descending);
52 |
53 | bool onParentAttach(Node& _parent);
54 | bool onParentDetach(Node& _parent, bool _deleteDangling);
55 | bool onParentsDetachAll(bool _deleteDangling);
56 | bool onChildAttach(Node& _child);
57 | bool onChildDetach(Node& _child, bool _deleteDangling);
58 | bool onChildrenDetachAll(bool _deleteDangling);
59 |
60 | protected:
61 |
62 | Node(EType _type);
63 | virtual ~Node();
64 |
65 | virtual void onParentAttaching(Node& _parent) const;
66 | virtual void onChildAttaching(Node& _child) const;
67 |
68 | Internal::NodeSetHandle& parentsHandle();
69 | Internal::NodeSetHandle& childrenHandle();
70 |
71 | public:
72 |
73 | const EType type;
74 | Set parents, children;
75 |
76 | bool isElement() const;
77 | bool isOperation() const;
78 |
79 | bool isRoot() const;
80 | bool isLeaf() const;
81 |
82 | Element& element();
83 | const Element& element() const;
84 | Operation& operation();
85 | const Operation& operation() const;
86 |
87 | template TNode>
88 | TNode& as();
89 |
90 | template TNode>
91 | const TNode& as() const;
92 |
93 | Set& forward(bool _descending);
94 | const Set& forward(bool _descending) const;
95 | Set& back(bool _descending);
96 | const Set& back(bool _descending) const;
97 |
98 | };
99 |
100 | }
101 |
102 | #define HMP_DAG_NODE_IMPL
103 | #include
104 | #undef HMP_DAG_NODE_IMPL
105 |
106 | #include
107 | #include
108 |
--------------------------------------------------------------------------------
/core/include/HMP/Dag/Node.tpp:
--------------------------------------------------------------------------------
1 | #ifndef HMP_DAG_NODE_IMPL
2 | #error __FILE__ should not be directly included
3 | #endif
4 |
5 | #include
6 |
7 | namespace HMP::Dag
8 | {
9 |
10 | template TNode>
11 | TNode& Node::as()
12 | {
13 | return static_cast(*this);
14 | }
15 |
16 | template TNode>
17 | const TNode& Node::as() const
18 | {
19 | return static_cast(*this);
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/core/include/HMP/Dag/NodeHandle.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | namespace HMP::Dag
7 | {
8 |
9 | template TNode, bool TDescending>
10 | class NodeHandle final
11 | {
12 |
13 | private:
14 |
15 | TNode* m_node;
16 |
17 | void attach(TNode* _node);
18 | void detach();
19 |
20 | public:
21 |
22 | NodeHandle(TNode* _node = nullptr);
23 | NodeHandle(TNode& _node);
24 | NodeHandle(const NodeHandle& _copy);
25 | NodeHandle(NodeHandle&& _moved);
26 |
27 | ~NodeHandle();
28 |
29 | NodeHandle& operator=(TNode* _node);
30 | NodeHandle& operator=(TNode& _node);
31 | NodeHandle& operator=(const NodeHandle& _copy);
32 | NodeHandle& operator=(NodeHandle&& _moved);
33 |
34 | template TOtherNode, bool TOtherDescending>
35 | bool operator==(const NodeHandle& _other) const;
36 |
37 | TNode& operator*() const;
38 | TNode* operator->() const;
39 | operator TNode* () const;
40 |
41 | void free();
42 |
43 | };
44 |
45 | }
46 |
47 | #define HMP_DAG_NODEHANDLE_IMPL
48 | #include
49 | #undef HMP_DAG_NODEHANDLE_IMPL
--------------------------------------------------------------------------------
/core/include/HMP/Dag/NodeHandle.tpp:
--------------------------------------------------------------------------------
1 | #ifndef HMP_DAG_NODEHANDLE_IMPL
2 | #error __FILE__ should not be directly included
3 | #endif
4 |
5 | #include
6 |
7 | namespace HMP::Dag
8 | {
9 |
10 | template TNode, bool TDescending>
11 | void NodeHandle::attach(TNode* _node)
12 | {
13 | detach();
14 | m_node = _node;
15 | if (m_node)
16 | {
17 | m_node->m_handles++;
18 | }
19 | }
20 |
21 | template TNode, bool TDescending>
22 | void NodeHandle::detach()
23 | {
24 | if (m_node)
25 | {
26 | m_node->m_handles--;
27 | if (!m_node->m_handles && m_node->back(TDescending).empty())
28 | {
29 | m_node->forward(TDescending).detachAll(true);
30 | delete m_node;
31 | }
32 | m_node = nullptr;
33 | }
34 | }
35 |
36 | template TNode, bool TDescending>
37 | NodeHandle::NodeHandle(TNode* _node)
38 | : m_node{}
39 | {
40 | attach(_node);
41 | }
42 |
43 | template TNode, bool TDescending>
44 | NodeHandle::NodeHandle(TNode& _node)
45 | : m_node{}
46 | {
47 | attach(&_node);
48 | }
49 |
50 | template TNode, bool TDescending>
51 | NodeHandle::NodeHandle(const NodeHandle& _copy)
52 | : m_node{}
53 | {
54 | attach(_copy.m_node);
55 | }
56 |
57 | template TNode, bool TDescending>
58 | NodeHandle::NodeHandle(NodeHandle&& _moved)
59 | : m_node{}
60 | {
61 | attach(_moved.m_node);
62 | _moved.detach();
63 | }
64 |
65 | template TNode, bool TDescending>
66 | NodeHandle::~NodeHandle()
67 | {
68 | detach();
69 | }
70 |
71 | template TNode, bool TDescending>
72 | NodeHandle& NodeHandle::operator=(TNode* _node)
73 | {
74 | attach(_node);
75 | return *this;
76 | }
77 |
78 | template TNode, bool TDescending>
79 | NodeHandle& NodeHandle::operator=(TNode& _node)
80 | {
81 | attach(&_node);
82 | return *this;
83 | }
84 |
85 | template TNode, bool TDescending>
86 | NodeHandle& NodeHandle::operator=(const NodeHandle& _copy)
87 | {
88 | attach(_copy.m_node);
89 | return *this;
90 | }
91 |
92 | template TNode, bool TDescending>
93 | NodeHandle& NodeHandle::operator=(NodeHandle&& _moved)
94 | {
95 | attach(_moved.m_node);
96 | _moved.detach();
97 | return *this;
98 | }
99 |
100 | template TNode, bool TDescending>
101 | template TOtherNode, bool TOtherDescending>
102 | bool NodeHandle::operator==(const NodeHandle& _other) const
103 | {
104 | return _other.m_node == m_node;
105 | }
106 |
107 | template TNode, bool TDescending>
108 | TNode& NodeHandle::operator*() const
109 | {
110 | return *m_node;
111 | }
112 |
113 | template TNode, bool TDescending>
114 | TNode* NodeHandle::operator->() const
115 | {
116 | return m_node;
117 | }
118 |
119 | template TNode, bool TDescending>
120 | NodeHandle::operator TNode* () const
121 | {
122 | return m_node;
123 | }
124 |
125 | template TNode, bool TDescending>
126 | void NodeHandle::free()
127 | {
128 | if (m_node)
129 | {
130 | m_node->m_handles--;
131 | m_node = nullptr;
132 | }
133 | }
134 |
135 | }
--------------------------------------------------------------------------------
/core/include/HMP/Dag/NodeSet.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace HMP::Dag
12 | {
13 |
14 | class Node;
15 |
16 | template
17 | class NodeSet;
18 |
19 | namespace Internal
20 | {
21 |
22 | template
23 | class NodeSetBase;
24 |
25 | class NodeSetData final: public cpputils::mixins::ReferenceClass
26 | {
27 |
28 | private:
29 |
30 | template
31 | friend class NodeSetBase;
32 |
33 | std::unordered_map::iterator> m_map{};
34 | std::list m_list{};
35 |
36 | public:
37 |
38 | bool add(Node& _node);
39 | bool remove(Node& _node);
40 | bool clear();
41 |
42 | };
43 |
44 | class NodeSetHandle final: public cpputils::mixins::ReferenceClass
45 | {
46 |
47 | private:
48 |
49 | template
50 | friend class NodeSetBase;
51 |
52 | template
53 | friend class Dag::NodeSet;
54 |
55 | NodeSetData& m_data;
56 | const std::function m_onAttach;
57 | const std::function